Index: tags/1.0.5/AUTHORS =================================================================== --- tags/1.0.5/AUTHORS (nonexistent) +++ tags/1.0.5/AUTHORS (revision 10414) @@ -0,0 +1,3 @@ +sch-rnd author: Tibor 'Igor2' Palinkas +contact: http://www.repo.hu/projects/sch-rnd/contact.html + Index: tags/1.0.5/COPYING =================================================================== --- tags/1.0.5/COPYING (nonexistent) +++ tags/1.0.5/COPYING (revision 10414) @@ -0,0 +1,502 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! Index: tags/1.0.5/Changelog =================================================================== --- tags/1.0.5/Changelog (nonexistent) +++ tags/1.0.5/Changelog (revision 10414) @@ -0,0 +1,2391 @@ +1.0.5 (r10409) +~~~~~~~~~~~~~~ + [build] + -Fix: central makefile typo made src_3rd and font linstall/uninstall do a normal install instead + + [core] + -Fix: add gtk4_gl in the preferred GUI list + -Fix: wrong syntax description for buffer internal actions + -Fix: wrong description for buffer internal actions + + [doc] + -Fix: 06_hierarchy: reference is by uuid, not uid (ambiguity) + -Fix: excess in desing doc chapter 4 + -Update: {des6:7}: not only root sheets are listed in the project file + -Add: top sheet is a root sheet in {imp6:6} + -Add: hierarchic design examples and doc + -Add: export_spice unslotting section anchor so it can be directly linked + -Add: {des6:28} specifies that the same hierarchic prefixes are used for components that are used for networks. + -Add: hierarchic: {des6:8} specifies the fallback behavior of ^/ addressing: if nothing is found, no global net is created but error is thrown + -Add: desgind doc {des6:15} defines the term "sheet reference symbol" explicitly to make it easier to link back from other docs + -Add: list more features on the main page + + [export_abst] + -Fix: don't crash on invalid (NULL) components and ports + -Add: hierarchic: when listing ports, prefix them with their referer name + -Add: indicate if a port or component or net is marked omit + + [export_tedax_footprint] + -Add: new plugin for exporting sheet graphics as a tEDAx footprint + + [hlibrary_fs] + -Add: new plugin for hlibrary (hierarchic sheets library from the local file system) + + [io_geda] + -Fix: don't crash if pinnum is NULL in postprocess + -Fix: potential crash when loading symbols with attributes before the first object + + [lib] + -Fix: memory leak: sheet free should remove config state as well + -Fix: memory leak: attrib compile always frees src + -Fix: memory leak: attrib copy all func + -Fix: memory leak: lib_add_all() path handling + -Fix: memory leak: free project's p4 vector on project uninit + -Fix: memory leak: free project p4 internal config list at the very end + -Fix: memory leak: free plug_io list at the end + -Fix: memory leak: in plug library path handling + -Fix: memory leak: caused by a typo + -Fix: memory leak: netname while dealing with hierarchic sheet ref syms + -Fix: memory leak: pen free should free pen font name and style + -Fix: memory leak: sheet_uninit() shall free fullpath as well + -Fix: memory leak: around symbol name translation + -Fix: memory leak: abstract "sheet ports" shall be freed with the abstract model + -Fix: don't crash on no project file available + -Fix: if a wirenet has only junctions, it's also considered an empty wirenet + -Fix: library refresh: need to replace old root with new root in every existing sheet, as roots are shared + -Fix: don't crash on saving in plug_io when realpath() fails (happens for write permission problems as well) + -Fix: wirenet split/merge: don't crash when line object's parent is NULL + -Fix: make sure if wires are split off to a new wirenet in some operation (e.g. line move) the new wirenet seg is checked for wirenet merges + -Fix: compiler should not attempt to directly compile hierarchic external sheets, they are like aux sheets, they are compiled only through hierarchic references + -Split: anet_get() and anet_new(); the former should be read-only and later work from short name + -Add: support for hierarchic design + -Add: compiler looks up net names with scope + -Add: enable the sheet local scope on net lookup + -Add: attribute copy function that changes the key of the attribute during the copy + -Add: sheet type "external" for sheets loaded for hierarchic + -Add: when an object from a wirenet is removed also remove all floaters if there are only floaters left in the wirenet + -Add: integrity check internal API: ASSERT1() that can print an argument + -Add: integrity check: floater-only wirenet error message include wirenet ID so it's easier to find + + [lib_anymap] + -Fix: memleak: free root hash + + [lib_netlist_exp] + -Fix: export netlist with the fallback name attribute only on hierarchy level 0; else use the global name (that has hierarchic path in it) to avoid collisions + -Fix: hierarchic: export components with full hierarchic namem on hlev > 0 if there's no display name + -Fix: hierarchic: if there's no name attrib but there's refdes attribu, use that (instead of full hierarchic name) + -Fix: hierarchic: if display/name or refdes is available, prefer that over more fancy solutions + + [lib_ngrp] + -Add: hierarchic: disable descend: we are not supporting non-graphical sheet hierarchies for now + + [lib_target] + -Fix: memhandling: avoid double free on whitelist/blakclist by settign back isused to 0 after a free + + [library] + -Add: shterm "symbols" (really terminal groups) for hierarchic design: subsheet terminal (in, out, inout) + -Add: hierarchic: create empty hlibrary/ so that the standard search doesn't fail and the user knows where to put files + + [menu] + -Import: cursor keys, enter and {k r} from pcb-rnd + + [query] + -Add: search dialog: print current scope sheet or project name + -Add: dlg_search: "scope follow" + + [sch-rnd] + -Fix: memory leak: on font load + -Fix: memory leak: free all projects on exit + -Fix: memory leak: log messages after export + -Fix: memory leak: on rnd font (&loadme key) + -Fix: memory leak: in rnd font key + -Fix: set hidlib crosshair to crosshair coords on move-to so actions implemented in the hidlib can track the crosshair + -Fix: prompt for quit-confirmation if any open sheet has changed, not only the sheet currently active + -Fix: when creating a new unlisted sheet in a project, make sure it ends up within the project in the layer selector, even tho it is not listed + -Fix: recalculate sheet bbox before sheet export to make exports reproducible + -Split: lib reload all into a separate function so it can be reused for hlibrary + -Add: move csch cfg registration into a macro so it's easier to register more config nodes + -Add: config subtree for the compile's hierarchic corner cases (mismatched netname handling) + -Add: HlibraryRehash() action with hlibrary search path for reusable hierarchic sheets + + [sch_dialogs] + -Add: abstract dialog: remark column so that objects that are omitted can be indicated + -Add: abstract dialog: checkbox to hide omitted items + -Add: when listing abstract net's ports indicate subsheet portand omited ports + -Add: hierarchic: when listing ports, prefix them with their referer name + -Add: project properites dialog has a section for external sheets (hierarchic refernces to the hlibrary) and the toggle button converts them to aux + + [sch_rnd] + -Fix: memory leak on freeing all designs on exit (config state) + + [sim] + -Fix: memleak in sch_sim_hook_eng_call(): when removing a fungw function, free it + + [sim_ngspice] + -Fix: memleak: unload should call over to target_spice + + [std_cschem] + -Fix: hierarchic: always prepend hierarcic prefix to component name + -Add: hierarchic: implement engine binding for wirenet_name_to_net_name to prefix net names with hierarchic path + -Add: hierarchic: implement attrib-net-name-to-net-name translator engine hook so that connect attribute's net names are properly prefixed with the hierarchy + + [std_forge] + -Fix: memleak: attrib source + + [tagret_spice] + -Cleanup: make new bridge net creation simpler (always alloc) + + [target_pcb] + -Fix: uninitialized fields in target context struct + -Fix: memleak on whitelist/blacklist system + + [target_spice] + -Fix: memory leak on script_data + -Fix: generate both global and local component name to not break hierarchy + -Add: hierarchic: when generating full component name for a slotted device, prepend hierarchic prefix + -Add: hierarchic: prepend first character of the original component name before adding hierarchic path - first chaacter determines device type in the ancient spice format + -Add: include hierarchic prefix in display name - that's what gets exported + + [tests] + -Fix: export_spice should return false on failure + -Fix: std_forge_cond: use detected librnd extra ldflags for -L's when linking + -Add: test cases for hierarchic features + + +1.0.4 (r10002) +~~~~~~~~~~~~~~ + [boxsym-rnd] + -Add: optional shape_fill command: when argument is true, use sym-decor-fill on the shape polygon + -Add: use sch-rnd to figure true text dimensions before laying out labels + + [build] + -Update: bump dependency to librnd 4.1.0 + -Change: switch over to using librnd 4.1.0's font2 engine + + [doc] + -Del: recommendation of using svn head of librnd - since sch-rnd is stable for a long time already, stable librnd should always work from release tarballs + -Fix: typo in funcmap example: attiny has PA6 and PA7, not PB6 and PB7 + -Fix: empty groups and broken connections in the slot example sheet + -Change: switch over irc from kiwi to mibbit + -Add: {des3:37}: allow &name; entities in text, in-line with Ringdove font2 customs + -Add: mention shape_fill in boxsym-rnd examples + -Import: Zoom() action details from pcb-rnd + + [export_bom] + -Add: list_sep in default config to serve as an example + + [font2] + -Add: render invisible horizontal tabs properly - matters a lot for non-graphical sheet + + [gui] + -Add: implement ZoomTo(selected) by wrapping the standard librnd Zoom() action + + [io_altium] + -Fix: when slotted symbol inactive pins are not created, do not throw error on attributes for those pins not being added to the non-existing pins + -Fix: net label not on wire: it's not a fatal error + -Fix: rectangle x1;y1;x2;y2 default value is 0 when omitted from the file + -Fix: pin x1;y1 default value is 0 when omitted from the file + -Fix: note x1;y1 defautl value is 0 + -Fix: arc missing start/end angle defaults to 0 + -Fix: sheet ports with style==3 should have ports on both ends + -Fix: net labels can be placed on terminals - add a short 45 degree stub wire so the wirenet name floater can be placed + -Change: don't print error message on attribute with no name - this seems to be a normal case there + + [io_geda] + -Fix: got external symbol rotation angle the wrong dir + -Tune: external symbol placement: don't shift in x directionby bbox + -Add: library symbol mapping: resolve paths so that $() substitution works + + [io_orcad] + -Add: first stable version + + [lib] + -Fix: lib mapping error messages shouldn't hardwire 'Symbol' but use the given library master's name + -Fix: make sure saving backups does not change sheet file name to the file nameof the backup being saved (fixes the bug "sym edit mode backup save renames file") + + [lib_anympap] + -Fix: don't crash if entry is not found (due to missing local lib root for example) + + [lib_plot] + -Cleanup: remove local y flip, using preview's y flip exposed in librnd 4.1.0 + -Add: adaptive text rendering on labels, depending on zoom level + -Add: draw arrow on the x axis + + [libcschem] + -Fix: integrity check false positive: in symbol edit mode the sheet is dummy and will not have an uuid, don't throw an error on that + + [librnd4] + -Del: remove csch_basename() in favor of the rnd_ variant in librnd 4.1.0 + -Del: remove csch_parent_dir_name() in favor of the rnd_ variant in librnd 4.1.0 + -Del: remove csch_relative_path_files() in favor of the rnd_ variant in librnd 4.1.0 + -Del: remove libcschem util_path.[ch] -> functionality moved to librnd 4.1.0 + + [sch-rnd] + -Fix: uninitialized local var in the initial sheet/project loader logic + -Fix: xmirrored font rendering misalignment when string has leading spaces (happens with fontv2) + -Fix: don't initialize new sheet's filename too late (caused lib paths depending on $(rc.path.design) to disfunction) + -Change: enable human readable coords in 'k' format by default now that we depend on librnd >=4.1.0 + -Add: standard librnd Export() action + -Add: FontInfo() action for scripting (for example for boxsym-rnd to figure real text dimensions) + -Add: API to calculate selection bbox + + [sch_dialogs] + -Del: remove local timed change implementation, use librnd 4.1's + + [sim] + -Del: remove local implementation of mk/rm temp dir, use librnd4.1's + + [sim_ngspice] + -Cleanup: use rnd_hid_export_using() instead of locally implemented code for looking up the exporter + + [std_forge] + -Change: switch over to librnd 4.1's timed change implementation + + [tests] + -Update: slot ref for the recent fixes in the example (source of the test) + +1.0.3 (r9600) +~~~~~~~~~~~~~ + [act_read] + -Fix: memory leak on idpath free + -Add: action: RtreeList (search the whole rtree or a region of it) + + [backann] + -Fix: dialog: don't crash on 'details' button if referred object is not found + -Fix: allow creating new attributes (don't require existing attributes to be edited) on an attr change input on bap + -Fix: when processing conn removal: if a piece of wire line connects more than one terminal, mark it a tricky case, the line can not be removed without side effects + -Add: support tEDAx back annotation packs; auto-detect file format + -Add: handle objects lists for mutliple object delete in autofix + -Add: component add instruction with autofix + -Add: component del instruction with autofix (can remove multiple symbols) + -Add: pin_attr instroction + -Add: grconn removal: if a complicated wire line intersects the terminal at the end of the wire line, remember it can be fixed by truncating the line + -Add: conn removal corner case: when the last conn is removed from a wirenet and it was a graphical connection, remove the whole wirenet group + + [boxsym-rnd] + -Add: pin "funcmap" property + + [core] + -Add: integrity check includes sheet load name in the report because of multi-sheet support + -Add: config node for orthogonal rubber banding + + [doc] + -Add: developer doc about symedit + -Add: funcmap example (using attiny24) + -Add: attrib_exort_name: add a full example of workflow prefixing + + [export_abst] + -Fix: API function proto mismatch: export_abst should get an options arg, even if it is ignored + + [export_spice] + -Fix: API function proto mismatch: export_abst should get an options arg, even if it is ignored + + [export_tedax] + -Fix: API function proto mismatch: export_abst should get an options arg, even if it is ignored + + [funcmap] + -Add: funcmap plugin + + [gui] + -Add: popup menu calls for clicking on empty area on the sheet (different menu name for sheet and symbol-as-sheet) + -Add: indicate rubber band mode in the bottom status line + -Add: indicate orthogonal rubber band mode in the bottom status line + + [io_altium] + -Cleanup: remove gschem and gEDA references from comments (copy&paste error) + + [io_lihata] + -Add: special case loading a cschem-group-v1 (symbol-as-sheet for symbol editing) + -Add: load symbol-as-sheet as the direct group, not as a (sym) group under the direct group; this way it's less of a special case for the rest of the editor + -Add: copy symbol related pens from default sheet when loading symbol-as-a-sheet + -Add: corner case handling: when saving a group, skip saving pens marked ->copied_from_default; in sheet-as-symbol editing these are the pens created at sheet_init + + [io_ngrp_fawk] + -Fix: fgw_eng_unreg() needs the name of the engine to be passed + + [lib] + -Fix: do not merge parallel diagonal lines if they do not intersect + -Fix: line merge on overlap: on full overlap just remove the line instead of truncating it + -Fix: generate the "port xy has a non-graphical connection to net foo, but no graphical connection" error message only when the terminal explicitly requests it (would be a drc check later) + -Fix: when polygon ->has_fill changes remove or insert in the fill rtree so the change is visible in render + -Fix: library rehash: make sure old, already free'd roots are not added to the list again + -Fix: reset sheet aids even when the sheet is then not compiled to make sure there are no dangling references to a previous compilation + -Fix: never attempt to remove sheet->direct or sheet->indirect when they become empty for a group removal + -Fix: when a pen property changes make sure all bboxes of all objects that use this pen for stroke are recalculated + -Add: util_sheet for standard sheet initialization usable in any loader + -Add: special case sheet save: if sheet's ->is_symbol is true, save direct group as a group only to be used as a symbol + -Add: implement loose_sym + -Add: object endpoint hash table + -Add: util_endpoint - various helpers for dealing with object endpoints + -Add: implement csch_endpoint_list_connected() + -Add: publish low level "wire line within wirenet" create function + -Add: publish low level wire line merge call + -Add: line merge option for removing stub on full overlap + -Add: connected endpoint mapper: optional filter function so the caller can decide which objects and endpoints are included + -Add: htepu offers an x;y-only variant of the keyeq/hash functions for the case when only unique coords of endpoints are interesting but not the cause of them (object and index) + -Add: poly contour object (and corner) lookup by coords + -Add: integrity check looks for ghost objects (objects removed from the data tree but not from the rtree) + -Add: p4 API (per project per plugin storage) + -Add: more details on the library mapping error message when all plugin realpaths failed: path may not exist + -Add: DiscardAbstract() action to free the abstract model - useful for hunting down memory leaks + -Add: drc event and central infrastructure: basics (drc context, violation struct) + -Add: drc not ran error message tips: the typical DRC will also need the project compiled + -Add: drc references to the abstract model + -Add: DRC(print): print violations to stdout + -Add: DRC(log) + -Add: utility call that decides if any endpoint of a polygon contour object falls on an x;y coord + + [lib_alien] + -Fix: missing header watchdogs + + [lib_anymap] + -Add: new plugin for hosting the common code of map-like engine plugins (devmap, funcmap) + -Fix: don't insert multiple map objects with the same name from the sssym cache + + [lib_ngrp] + -Cleanup: warnings on passing the wrong type of object (need to pass generic hdrs) + + [lib_tedax] + -Add: new plugin (in core) for handling tEDAx files: multiple plugins need to read or write tEDAx independently + -Move: tEDAx getline from io_ngrp_tedax to lib_tedax for reuse + + [lib_ucdf] + -Add: split out ucdf.o into a wrapper lib plugin so multiple plugins can use it through pup dependencies (io_altium and io_orcad are going to need it) + + [menu] + -Add: popup menu for sheet and symbol-as-sheet: propedit, attr edit, pen dialog + -Add: copy rubber band mode menu item from pcb-rnd + -Add: menu item for orthogonal rubber band mode + -Add: poyledit in the toolbar + -Add: menu for unselecting all on all sheets of the current project + -Add: funcmap menus + -Add: loose sym submenu in Mode + -Del: remove realign grid - we don't have that feature in sch-rnd + + [propedit] + -Add: implement setting or toggling loose_sym on sheet + -Add: special case in symedit: include direct group's non-geo properties (uuid) + -Add: symedit corner case: propset on sheet uuid should work (and set direct group's uuid) + + [renumber] + -Add: action args for running on all sheets of the current project + -Add: dialog box support for running on all sheets of the current project + -Add: help text for the Renumber and RenumberDialog actions + + [sch-rnd] + -Fix: sheet init: don't overwrite existing pens when copying default pens; this lets sheet-as-symbol editing's loader preserve custom pens defined in the symbol + -Fix: sheet load: make sure engines are initialized before sheet post-load events are called so event handlers find engines set up + -Fix: corner case: when a new root sheet or aux sheet is created with no project and the user refuses project file creation, turn the new sheet into unlisted - no project file means it can not be listed + -Fix: don't mess up an existing project file's lht doc when creating a new page, that would invalidate other existing sheets already in that project + -Fix: better env vars on System(): save crosshair coords in cschem coords instead of mm (but keep the old ones as well for compatibility) + -Fix: screen search for gui: always ignore junctions; junctions shouldn't be moved or resized + -Fix: draw code shouldn't crash if abstract object is not available (when deciding about DNP and omit graphics) + -Move: sheet setup utility function from lib_alien to sch_rnd: will be needed in non-alien IO and potentially other parts of the code + -Add: sheet init: optionally set new pen's ->copied_from_default to 1 + -Add: change tool stroke pen names from the detault to sym- prefixed ones in symbol editor mode (on design role) + -Add: Unselect(AllProject) to unselect all objects in all sheets of the current project + -Add: include funcmap in standard views + + [sch_dialogs] + -Fix: tree view: invoke propedit or attr edit using the target object's sheet (hidlib) instead of the dialog's own - this fixes the bug that in a multi-sheet setup the dialog always edited the objects for the sheet it was invoked for + -Add: attr edit works on sheet scope (sheet attributes can be edited) + -Add: attribute dialog: button for creating floaters from abstract attributes + -Add: tooltips to explain the difference between the two floater buttons + -Add: refine the error message thrown when an engine could not be added to a view (hints on typo and missing plugin) + + [sim] + -Fix: missing success return val on sim temperature set + -Fix: invalid memory write (argv[] too small) + + [sim_ngspice] + -Add: handle the case of explicitly invalid analysis type or presentation type (throw error) + + [std_devmap] + -Cleanup: split anymap from devmap + -Cleanup: rewrite context management: use p4 instead of per sheet engine data + -Fix: when cleaning sheet local cache, also clean the indirect group so the cache doesn't re-appear on save + + [std_tools] + -Add: don't let wirenet drawn in symbol edit mode + -Add: when rubber band is enabled, map endpoints to grab and draw them while moving + -Add: rubber band mode for wire move, optional ortho rubber band mode + -Add: poly edit tool: grab and move polygon corners (use ctrl for ortho move) + -Add: recognize when the arrow tool is used on a poly corner and go to the poly edit mode + + [symbol] + -Fix: common_sym: mirx and miry fields are integers, shouldn't include pen name + -Add: mark rail-type symbols's terminals with the drc/require_graphical_conn=1 attribute to generate an error message when they are not connected anywhere + -Add: common_sym: if pin label2 starts with a %, enable dyntext on it; typical for funcmap labels + + [target_spice] + -Fix: missing return on component0 hook + +1.0.2 (r8963) +~~~~~~~~~~~~~ + [build] + -Add: support for byaccic and ureglex + -Fix: building deps require -I. because of byaccic generated code + + [doc] + -Add: include the new view. and stance. substitutions in the design doc + -Add: design doc on forge: explain it happens during compilation + -Add: design doc on forge: document conditional forge expression syntax + -Add: design doc on forge: make it explicit that conditional forge performs operations only if condition is true + -Add: design doc on forge: specify stances + -Add: design doc on forge: implementation notes on stance based build options, with a practical example on model + -Add: design doc on forge: example on the sub_major stance + -Add: design doc on forge: list all standard id.id substitutions in conditional forge expressions + -Add: design doc on forge: link stance section from dyntext (03_drawing) + -Add: omit and dnp examples + -Add: attribute export naming + -Add: document target_pcb + -Add: document target_spice + -Add: export_tedax: document omit and dnp + -Add: export_spice: document attributes, omit and dnp + -Add: export_spice and export_tedax are of type netlist + -Add: document export_bom + -Add: document export_abst + -Add: export_bom: refer to pcb-rnd's export_bom doc and describe the differences + + [export_bom] + -Add: BoM export based on pcb-rnd's templating bom code + + [export_spice] + -Add: respect component and network omits + + [export_tedax] + -Fix: wrong command on exporting pinname + -Fix: don't print pinname command if port's name is not available + -Add: export extra component and network attributes that have export_name + -Add: respect component and network omits + + [io_altium] + -Fix: don't require RECORD=10 (rect) cornerxradius and corneryradius in non-rounded case + + [io_lihata] + -Fix: write: quote attribute key when needed, it may contain ':' + + [io_ngrp_fawk] + -Fix: typo in test_parse (potentially missed truncated file) + + [lib] + -Fix: csch_attrib_copy_all_undoable(): create dst attribute before adding array items in it + -Fix: csch_attrib_copy_all_undoable(): preserve order of array items when array needs to be copied over from src to dst + -Fix: csch_attrib_copy_all_undoable(): allocate attr history source for the array copy operation + -Fix: also merge attributes when abstract nets are merged - fixes forge and omit on nets connected to vcc/gnd/rail + -Fix: undoable attr array val change memory management bug: do not attempt to free special value not allocated (deletion marker) + -Fix: arc mirror low level corner case: when updating delta angle, if start and endpoint are the same, that's either 0 or 360 degree; remember if the original arc had 360 deg and use that value withut calculating atan2() for the endpoint (common case: full circle) + -Fix: when propagating bboxes up, if child obj is a group, use it's bbox_flt instead of bbx when calculating parent's bbox_flt; fixes the bug that direct groups' bbox_flt did not include floaters embedded in symbols + -Fix: wire merge vs. conn ordering bug + -Fix: group rotation operation: no need to invert angle depending on mirror + -Fix: lib backend's realpath: const correctness to patch up memory leaks + -Fix: memory leaks around csch_lib_add() path handling + -Move: projet file flush from sch-rnd to libcschem, as the stance code is going to depend on it + -Add: remember view id in the abstract model during/after the compilation + -Add: remember project in abstract model during compilation - some plugins may need it + -Add: generic version of the stance value resolver (moved from std_forge, more parts of the code will need this) + -Add: generic version of the view property resolver (that returns the view name string for view.name, moved from std_forge) + -Add: dyntext support for view.name and substitute %stance.% + -Add: stance helpers: set stance value, add value to the list of available stance values + -Add: flush project file after stance changes on project role + -Add: support for attribute export name + -Add: postprocessing step in compile to cache omit and dnp attributes for quick rendering + -Add: make the "undoable" part optional in csch_attrib_copy_all_undoable() + -Add: split attribute val compare from attrib compare: attribe merge will need to compare the values only + -Add: csch_attrib_copy_all_undoable(): skip copy or merging if array type attributes have the same value + -Add: csch_attrib_copy_all_undoable(): copy over arrays when src has them but dst doesn't + -Add: csch_attrib_copy_all_undoable(): separate the API from the concrete model; when not undoable, don't require a cobj + -Add: csch_attrib_copy_all_undoable(): require sheet != NULL for the undoable case (assert) + -Add: engine transient storage infra in compiler + -Add: API variant of merge-into that remembers all new object pointers for postprocessing + -Add: csch_lib_add_all() gets an argument for force a re-scan of existing roots (so that a re-scan is really a deep re-scan), with a mechanism that guarantees that each root is mapped only once + -Add: introduce compile component0 call to bypass side effects + -Add: API doc: explain the purpose of engine hooks COMPONENT0..COMPONENT2 + -Add: publish the API of updating object hdr caches (dnp and omit) + -Add: automatically update object hdr cache after COMPONENT0 and COMPONENT1 steps + -Add: project abst export API: send through options[] + + [lib_plot] + -Add: generic plot widget + + [lib_target] + -Add: new support plugin for delivering attributes on export + + [menu] + -Add: test bench dialog menus for selected object and in symbol context popup + -Add: circuit simulation in the project menu + -Add: make StanceDialog() accessible from the menu + -Add: symbol context menu for the conditionals + -Add: conditional dialog submenu for 'omit' in wirenet context menu + + [query] + -Add: project scope for script run API + -Add: query() action view subcommand accepts scope as last argument + -Add: advanced search dialog: add a combo box for search scope (sheet or project) + + [sch-rnd] + -Fix: switch to initial sheet before export so that project config is applied before the export + -Fix: project file creation prompt: check if the file already exists and return 0 (like as we have created it) it so; this makes the function usable for assuring the project file exists, without further checks on the caller's side + -Fix: shift-click unselect: unselect parent objects as well; fixes corner case when a wirenet is selected and wire lines are unselected one by one; as long as the wirenet is selected, the wire unselection is not visible + -Fix: BufferSave() should use file selector window title corresponding to the scope of the save + -Add: stance config: a few static fields and provision for optional extra fields + -Add: default-sheet: print main stances and view name in the titlebox + -Add: conf lists for the possible stance values + -Add: render a big red X over components that are omitted + -Add: render 'DNP' over symbols marked DNP in the abstract model + -Add: draw small red X signs on wirenet lines when wirenet is omitted + -Add: call srand() with current time on startup so random numbers differ from run to run + -Add: expose lower level font draw API with (floating point) scale, rotation and miror-y options + + [sch_dialogs] + -Add: stance dialog (action: StanceDialog()) + -Add: ConditionalDialog() for conditional omit/dnp + -Add: test bench editor dialog + + [sim] + -Add: high level circuit sim support + + [sim_ngspice] + -Add: ngspice support for high level circuit sim + + [std_cschem] + -Add: do not apply connect attribute if component is marked to omit + + [std_devmap] + -Cleanup: move devmap lib related action from sch-rnd to std_devmap for config access + -Fix: devmap lib refresh action uses devmap lib search path (and not sym lib search path) + -Add: when a devmap is not found in the lib, the error message contains a hint on devmap rescan + -Add: device attributes, according to coralEDA std002 + + [std_forge] + -Fix: run in engine hook component0 instead of component1 so omit is prepared before connect is evaluated + -Add: accept conditional attributes with prefix forge-if/ + -Add: apply forge on nets + -Add: TestBenchDialog: GUI for easy access to test benching (test bench affiliation edit on a group of symbols using a table) + + [symbol] + -Add: add spice/omit attribute to connector(), switch() and testpoint: these are mechanical or PCB symbols, not part of any simulation + -Add: set low prio device attribute default value on passives (capacitors, coils, resistors), in accordance with coraleda std 002 + + [target_pcb] + -Add: compile display/dnp from pcb/dnp + -Add: plugin configuration for export attributes + -Add: use lib_target to mark attribute exports; generate attribute export names for network attributes at the end of compilation + -Add: create the display/omit attribute (components and nets) + -Add: whitelist exporting the color attribute (coraleda std 002) + + [target_spice] + -Fix: set display/omit from component0 so std_cschem connect processing is inhibited + -Add: create the display/omit attribute on nets and components + -Add: init global_spicelib_ctx only once; this is relevant since some other plugins, like sim_ngspice will wrap target_spice + + [tests] + -Update: export abst refs: wirenet group attrib always exported + -Update: get std_forge_cond to compile again + -Cleanup: std_forge_cond: do not hardwire gcc-specific flags for compiling the test + -Fix: std_forge_cond: if only one string is given for resolution, it's name1, not name2 + -Fix: std_forge_cond: use librnd's LDFLAGS for compiling the test executable + -Fix: std_forge_cond: work around GNU make so it doesn't try to run yacc on the byaccic grammar + -Add: std_forge_cond: print section headres for easier interpretation fot he log + -Add: std_forge_cond: better test variable names + -Add: std_forge_cond: regression tests + -Add: std_forge_cond: implement 'make test', get it to run from the central make test + -Add: std_forge_cond: need to include librnd's config.h for RND_INLINE + -Add: std_forge_cond: fallback RND_INLINE macro in case librnd didn't declare it (old version?) + -Add: announce when all test passed + -Add: empty string regression test for forgecond + -Add: forge cond tester offers a const called "empty" that returns an empty string + -Add: manual test case for the fix of r8878 (copy of Erich's bugreport) + + [util_wirenet] + -Fix: corner case: when two wirenets are merged hunt for new overlapping lines and merge them on line level + +1.0.1 (r8055) +~~~~~~~~~~~~~ + [act_read] + -Add: SearchObjAt(), SearchObjAtUnsel() and SearchObjAtGuiInspect() actions for scripting, with crosshair option + -Add: SchGetXY() action + + [doc] + -Update: design doc for how root groups within indirect are used (following code best practices) + -Add: spice tutorial for raw_spice (for ngspice and gnucap) + -Add: install resources/ when installing doc + -Add: non-graphical sheet examples work now + -Add: non-graphical sheet doc details for the final implementation + -Add: formally specify tEDAx blocks for non-graphical sheets + -Add: non-graphical sheet: specify the details of vararg fawk functions + -Add: document the raw spice workflow + -Add: missing links to chapters of user doc + -Add: design doc: attrib implementation convention: usr/ attribute key prefix + -Add: spice tutorial + + [examples] + -Add: make slot.rs compatible with raw spice simulation + + [export_spice] + -Add: export self-contained spice netlist (and commands and models, as configured via export options) + + [font] + -Update: import aussiefont v2 files from Edakrill: cleanups, fixes and control chars for \t, \r and \n + + [gui] + -Add: load dialog: build file formats and filters from all registered io plugins that can load a sheet so that geda, tinycad and altium would be on the list + + [io_altium] + -Add: loader for binary and ascii SchDoc sheets + + [io_geda] + -Fix: symbol placement origin bug from external libs + + [io_ngrp_fawk] + -Add: non-graphical sheet support: fawk + + [io_ngrp_tedax] + -Add: non-graphical sheet support: tEDAx + + [io_tinycad] + -Fix: avoid no-name power symbol's rail attribute accidentally turning into an empty array by naming it unknown + -Fix: attribute rename: Ref to name + -Fix: attribute rename: Value to value + -Fix: symbol rot values revised in x-mirror cases (sym_power2.dsn) + -Fix: make sure to close "full-circle" ellipse + -Fix: pin style: when triangle is drawn, move name text by 2 units to avoid overlap + -Fix: pin length and text placement for type 5 and 6 + -Fix: create symdefs in the symbol master group under indirect to comply with the cschem model and let the library pick up symdefs + -Fix: set alien coord mult factor only before sheet load, when the config is already available + -Fix: don't try to modify text objects of group refs, it's enough to modify them on the groups in indirect + -Add: implement (the graphical part of) + -Add: calculate connections in postproc + -Add: support bundled (multisheet) files + -Add: fill in sheet's loadname from the tag and invent a fullpath as well + -Add: read symdef pin's elec property and draw an 'x' if it's 6 + + [lib] + -Fix: avoid addressing out of bounds in conn auto recalc + -Fix: grp_ref: when removing objects to re-generate a group ref, convert affected conns back from ptr to oidpath + -Fix: grp ref modify typo caused uninitialized memory in xformed->removed field + -Fix: in a group ref regen mark conns dirty that are converted back to oidpath format; after finishing an all-ref-update, update all dirty conns + -Fix: don't crash on wirenet creation failure (happens on non-graphical sheets) + -Fix: don't try to destroy NULL sheet lib + -Fix: undoable object move should generate sheet changed event + -Fix: preserve attribute history of the concrete object's attribute when compiling an abstract object + -Fix: make "components created during component iteration in compilation postprocess" safe by loop restart + -Fix: don't crash if io plugin doesn't offer sheet load (it may offer bundled sheet load or none) + -Fix: don't crash if an io plugin doesn't have a group (sym) loader + -Fix: print net name in error message instead of net ptr as string + -Fix: compile: don't free src before use in attribute merge + -Fix: don't crash when name is an array + -Fix: do not throw error but ignore component that has name==NULL (e.g. name is an array) + -Fix: when splitting wirenets for junction recalc, do not lose floaters + -Fix: when splitting a wirenet creating new wirenets, copy all attributes + -Fix: text dup inst2spec: counter-act special text mirror effect on rotation angle + -Fix: corner cases on wirenet splitting vs. floater and attribute copying + -Fix: junction recalc: do not move objects into a new wirenet group if the map says the whole thign is a single segment + -Fix: util wirenet line edit merge: when finding other wire lines to merge to, ignore the line being edited + -Fix: text dup: don't leave ghost objects behind in the rtree when the dup'd text object is on a different display layer than the source text object + -Fix: optional inverse transformation in line modify call; fixes the wrong line endpoint move in within transformed groups (e.g. rotated/mirrored wirenets) + -Fix: when undoing line gometry change, update conn geometry to avoid conn smear (on the undo list connection add/del is done before the line geometry is really modified) + -Fix: csch_text_update(): do not ruin inst vectors with non-parent-transformed spec vectors when do_xform == 0 + -Fix: compiler: resistor terminal connected directly to a vcc terminal and a wire also connected in the same point: shouldn't throw a multiport_net_merge error; the term-term connection is invisible/implicit, so it should merge silently + -Cleanup: use RND_INLINE instead of csch_inline for simplicity; remove csch_inline from config.h + -Cleanup: remove non-existing cgrp calls from the API + -Split: compile single attribute from compile all attributes of a concrete object, so that the single-attribute compiler can be called from plugins + -Split: compiler: code that compiles a single component and its ports into a separate functionso it can be reused later with delayed component creation + -Add: expose the vector of all io's so plugins can search it + -Add: when converting from objects into a symbol or term, rename fill pen as well + -Add: print connection object ID that triggered the error in the error message for easier debugging + -Add: non-graphical sheet implementation + -Add: comment to explain allocation of oidpath API + -Add: csch_conn_ptr2text() to convert object pointer list back to oid list; useful for avoiding dnalging pointers when objects are re-created + -Add: introduce a new group bbox that contains all objects, including floaters; get normal hdr.bbox contain only non-floaters (naked bbox) + -Add: attrib API for appending arrays to existing attributes + -Add: attribute compilation: append array attribs when requested + -Add: csch_compile_attribute() can return destination attribute (from the abstract model) + -Add: separate rtree per layer for tracking poly fulls (for proper fill ordering for rendering overlapping objects) + -Add: cache polygon area (for fill ordering) + -Add: plug_io API for loading bundled files (multi-sheet in single file for io_tinycad for now) + -Add: extend sheet load API so it can optionally take a FILE * already open for the file + -Add: loclib master group search/alloc by group name (instead of master ptr, so group can be created even if the given master is not available) + -Add: compile engine hooks for before/after sheet conn compilation and for after project compilation + -Add: compiler hook for project-before (pair of project-after) + -Add: compile helper API to disconnect an abstract object (e.g. port) from an abstract net + -Add: undoable attribute priority change API + + [lib_alien] + -Fix: do the standard coord conversion in arc-in-poly helper + -Fix: don't throw error on missing postproc action (optional user script per alien format postproc) + -Fix: have to post-process indirect objects in a first pass and re-render all direct objects later, if any indirect changed, so that changes are applied on sheet + -Split: read postproc out to a separate .c and .h because of its size + -Add: helper function to update connection on all terminals + -Add: csch_alien_postproc_rename_redundant_terms() to handle redundantly named pins coming from io_altium + -Add: recursive centerline bbox calculator helper function + -Add: support for emulating ellpitical arc by creating a polygon and line approx + + [lib_netlist_exp] + -Move: generalize and move get refdes/pinnum/netname and alternative attribute getter from export_tedax into lib_netlist_exp + + [lib_ngrp] + -Add: non-graphical sheet handlers to a lib plugin + + [library] + -Fix: default devmap for opamp-1 is lm358, which is an opamp, and not lm393, which si a comparator + -Add: hand crafted bc817 spice model + -Add: spice model for lm358, macromodel, copied from the datasheet of ST ts321 + -Add: spice models for adc and dac bridges for ttl + -Add: install spice models + -Add: spice pinnums with low prio to source symbols + -Add: spice/prefix with low priority in stock symbols where applicable + + [menu] + -Add: devmap library rehash in maintenance menu + -Add: tooltip on the symbol lib rehash (maintenance) menu + + [plugins] + -Cleanup: use RND_INLINE instead of csch_inline for simplicity + + [propedit] + -Fix: typo (missing else) ruined objbin + + [query] + -Fix: advanced search dialog: remove double quote from right side stored string when editing again + -Fix: advanced search dialog: preserve quotes in strings in decompile + -Add: new scope: sheet-indirect + + [sch-rnd] + -Fix: text rendering: use fmod to clamp text rotation to -360..+360 to avoid numerical problems + -Fix: do not complain about implicit project file in quiet mode + -Fix: emergency save shouldn't crash if sheet fullpath is not available (rather skip saving) + -Cleanup: use RND_INLINE instead of csch_inline for simplicity + -Cleanup: free all sheets after -x, to easy valgrinding + -Cleanup: simplify layer draw internal API: set up context only once per sheet draw, reuse caches + -Split: move out poly draw code from draw.c, it's getting large + -Add: default sheet: sheet-decor-fill and sym-decor-fill pens for light background color; default config: use sheet-decor-fill pen for default rect fill pen + -Add: DevmaplibRehash() action to re-scan the devmap library + -Add: draw non-graphical sheets (until we get to display them in a text edit widget much later); configureable non-graphical sheet colors + -Add: spice_raw target in default conf + -Add: action and menu for cleaning the local devmap lib for a sheet + -Add: SymlibReloadAllLocal() for reloading all symlib local libs from ext libs (with menu) + -Add: separate pass for drawing all fills then drawing all strokes, so strokes are always above fills; draw fills in order of their area, bigger first (for proper object overlap) + -Add: try loading sheet file as bundled sheet first (e.g. tinycad) + -Add: when drawing symbol meta, render a tiny x for marking symbol origin (matters in transformations) + + [sch_dialogs] + -Fix: don't crash on library refresh if cursor can not be obtained after the refresh + -Fix: assisted edit action name calculation: replace non-alnum and non-underscore chars with double underscore, so spice/model becomes spice__model + -Fix: dlg_attrib: when chaging attribute prio, do not mess with the value - fixes overwriting array to empty + -Add: more elaborate tooltip on tree refresh button, including you have to select a tree and only that tree is refreshed plus a reference to re-scan in maintenance + -Add: multiline text edit option for string attributes - useful for spice/command + + [std_cschem] + -Fix: don't crash on array name + + [std_tools] + -Fix: throw error instead of crashing when failed to create an object (line, circle, rect and text tool); happens on non-graphical sheets + + [symlib_fs] + -Fix: don't crash if params is NULL for a parametric footprint, just omit printing it + + [target_spice] + -Add: SPICE target plugin (SPICE views) + + [tests] + -Fix: execute sch-rnd in quiet mode when exporting to avoid unnecessary warnings + -Add: auto-test raw spice export + + +1.0.0 (r7144) +~~~~~~~~~~~~~ + [act_read] + -Fix: passing the wrong pointer type (group instead of object) + -Cleanup: GetObjType() const correctness: non-dynamic string is returned for const char * + + [gui] + -Fix: mark the project implicit if number of aux sheets and number of root sheets are both 0; that means there's no sheet list, even if the project file exists + -Fix: SaveAs() returns the return value of SaveTo() instead faking success + -Cleanup: replace dead code with live code and make sure the "file changed on disk" infobar is closed when the sheet is loaded or saved + -Cleanup: use generic parent dir function instead of calculating it locally so that dynbtext %project.name% subst would do the same + + [io_tinycad] + -Fix: avoid reading uninitialized memory when facing unknown power dir/which + + [lib] + -Fix: sheet free: if sheet is part of a project, remove it from the project + -Fix: memleak when figuring if a sheet is on a project list + -Fix: namepspace pollution: sheet_on_list should be private + -Fix: when deciding the type of a sheet (root/aux/unlisted) prefix project file list items with the project file's directory + -Fix: pass generic concrete object instead of group object as the API requires + -Fix: text object: update() removes object from rtree before any bbox recalculation else removal may fail due to mismatching bbox + -Fix: calculate project name for dyntext (%project.name%) the same way as the sheetsel calculates the project name + -Fix: arc in rotated+mirrored parent group got delta modified twice + -Fix: inst2spec dupping of text object should respect new parent group rotation and mirroring + -Add: path util function to return parent dir pointer from a full path + -Add: partially implement inst2spec for text objects (for translation only) + + [sch-rnd] + -Fix: when saving project file, pass full path of the sheet file just in case project file name needs to be calculated + -Fix: pass on project file path name when saving project file so it does not need to be guessed from the sheet's full path + -Fix: handle explicit invalid halign in font rendering: do the same as for 'start' + -Fix: final fallback sheet creation should pass parent project so the sheet is allocated under the right project + -Fix: don't crash when the user attempts to change sheet type for unsaved new sheet with no file name, rather throw an error and suggest a save + -Fix: freeze redraw during select and unselect operations to speed things up on sw render + -Fix: freeze redraw while cutting many objects to buffer and while pasting buffer + -Fix: allow creating new sheet for an existing project with no saved sheet (new sheet in a new project with unsaved initial sheet should take the directory from the project file's path) + -Fix: if name of the sheet changes on save, invalidate all dyntext objects so they get recalculated (so that %project.name% and friends are recalculated) + -Fix: after sheet load map libraries only after config node rc.path.design is already set so that "project local" library is found + -Add: project file creation call can return the newly created project struct + -Add: mutli: API for creating a new anon sheet within a project, without having a file name + -Add: when creating a new project, also create an unsaved empty new sheet, else the project can't be managed from the GUI + -Add: maintain/cache the number of aux sheets in the project struct + + [sch_dialogs] + -Fix: library refresh button shouldn't crash with empty filter text + + [std_tools] + -Fix: move-copy: freeze draw formass-move objects + -Fix: move-copy: freeze redraw for mass-copy objects + + [symbol] + -Change: pin names ("in", "gnd" and "out") of ldo.ry should not be floaters + + [tutorial] + -Add: explicit project file tutorial published + -Add: multipin portmap done + -Add: publish preferences dialog, part 1 + + +0.9.5 beta-test (r7021) +~~~~~~~~~~~~~~~~~~~~~~~ + [backann] + -Fix: off-by-one memory allocation on stack + + [build] + -Del: no need to detect libs/sul/librnd-hid from ./configure, Makefile.conf has the prefix + + [doc] + -Fix: copy&paste error: sch-rnd has symbols, not footprints, and no direct edakrill support yet + -Update: mailing list subscription: gmail is not a "may not work" but a "does not work" + -Import: packaging.txt from pcb-rnd, adapted to sch-rnd + -Update: finalize INSTALL: remove don't-package warning, reference packaging doc + -Add: document io_alien postproc config/scripting + -Add: specify io_tedax pinnumber format + -Add: link in route-rnd + -Add: generate key tree + + [export_tedax] + -Fix: emit pinname lines properly, using display/name -> name, splitting up multi-number pins + -Cleanup: remove pcb dependency from export attribute names; export by current view + -Cleanup: remove footprint, value, device attribute dependency on pcb/ + + [gui] + -Fix: Save(): if there's no file name of current sheet (it's ), always invoke SaveAs() and append .rs + -Fix: don't crash on revert when file is missing + -Fix: sheetsel should be updated on file name change event + -Fix: denfensive programming: broken project with no name shouldn't cause a segfault in the sheetsel, but should throw an error message + -Add: indicate sheet changed state in sheetsel by a * mark after the file name + -Add: sheetsel mark projects [e] when explicit project.lht exists and [i] when project is implied + -Add: sheetsel mark sheets depending on how they are listed in their project file + -Add: sheetsel indicates partially loaded projects + -Add: sheetsel: tooltip explaining all the marks + + [io_geda] + -Add: set alien fmt prefix + -Add: call alien postproc + -Add: default postproc configuration renames the refdes attribute to name + -Add: postprocessor pattern+action config to replace refdes attribtue dyntext with name attribute dyntext + -Add: configurable auto-normalzie for removing gschem's arbtirary, large coord offset + -Add: recalc symbol connections so direct terminal-terminal connections work + -Add: attempt to convert symbol net= attrib to connect= in postproc + -Add: postproc attribute conversion: terminal pinnumber to name for connect attribute to work + -Add: postproc rewrite of terminal name display + -Add: append default lib search path for lepton + -Add: postproc config: convert netname to name + + [io_tinycad] + -Del: hardwired C code for attribute postprocessing + -Fix: expect rectangle fill to be an integer, not a bool + -Fix: symbol label placement in normal case: should always be 0;0 in loclib and moved during placement + -Fix: tune symbol label placement when parent symbol is rotated + -Fix: sort out sym label placement vs. all combinations of symbol direction + -Fix: do not create text object for tinycad's hidden pin numbers (show=0) + -Fix: in sheet postproc remove sym text objects that are not referenced from symbol instanced with show=1; this fixes dyntext objects introduced by one instance in symdef accidentally shown in all other instances (without show=1) + -Fix: rectangle parser did not realize when it was parsing a symdef rectangle (and did not add symdef offsets) + -Fix: symbol label placement in mirx=1 case + -Fix: pin show is really a bitfield for showing the number and name; whether the pin is a power pin really depneds on which==4 + -Cleanup: centralize text object mirx/rot calcualtion, it's the same for all three text object sources + -Cleanup: the function for creating text in a parent object returns the text object (or NULL) so that it can be manipulated on the caller side + -Add: set alien fmt prefix + -Add: run sheet postproc after load + -Add: create_net_label() respects the direction parameter and makes the necessary rotation when style != 0 + -Add: support for parsing sheet rectangles + -Add: create different sheet-decor pens as needed, for different pen thickness while drawing rectangles + -Add: note_text is adjusted to be placed within the note box + -Add: mark multiline note text TODO with a unique label so it's easier to search in the doc + -Add: start documenting limitations and bugs + -Add: create pin's in-body label + -Add: place pin number dyntext + -Add: remember if a pin is a power pin or is in a slot using a attributes on ther term group + -Add: generalize sym_attr_hide() to sym_child_hide() - would be used to hide pins for slotting and power pins + -Add: postprocessing step for removing excess pins from symbol instances + -Add: support for slotting and power pins using pin removal + -Add: remember offset to power-pin-visible dx;dy for symdef + -Add: compensate for different sym reference point when power pins are visible + -Add: support for the ellipse object, using line approximation + -Add: plugin conf + -Add: make coordinate factor (multiplier) configurable + -Add: preparations for the configurable text autorot + -Add: render all group refs and normalize the sheet if needed + -Add: enable the code for optional text auto-rotation + -Add: mark the naked-bbox bug in the code + -Add: support for power 'which' field (all known values) + -Add: compensate text placement for mirrored power + -Add: heuristics for power text placement for all rotations + -Add: support for pin 'shape' (decoration) + + [lib] + -Fix: undoable attribute swap: when removing an attribute, use the key that's always available to avoid null pointer deref + -Fix: don't undoable-del an attribute if it doesn't exist (avoids adding a no-op on the undo list) + -Fix: when a whole group is moved and the group is a wirenet group, recalculate junctions (child lines are not going to be moved separately which may result in broken net) + -Fix: freeze object redraw during compile postproc invalidate - the whole sheet would be rdrawn once, at the end + -Fix: util_export default export file name generation: don't crash if there's no file name for the sheet + -Fix: util_export default export file name generation: append "*" if replacing an existing knonw "extension" is not possible + -Fix: util_export default export file name generation: make sure there's enough room to append the '*' + -Fix: util_export default export file name generation: if no new "extension" can be appended, append at least a _ so we are not overwriting the input file + -Fix: wire merging: when a wire is moved from one wirenet group to another, manage connection merging properly so no multiple connections between the destination wirenet group and the same terminal are created + -Fix: util_wirenet left undo serial inc locked when bailing out for not drawing fully overlapping wires + -Fix: compilation: don't stop adding conn's objects to an abstract net after the first object (fixes missing connections when more than one non-wirenet object is connected) + -Fix: wirenet: don't create junction between overlapping same-direction lines, they should be merged + -Fix: when merging a group into another, copy/merge attributes as well + -Fix: recalc conn after group geometry change undo swap to avoid leaving stale conn graphics after a group move is undone + -Fix: junction calculations shall be done in sheet coord system, not in (potentially transformed) wirenet coord system because bboxes are in the sheet coord system too + -Fix: wirenet draw: disable wirenet split calculation when new line is added - drawing a new line will never split existing wirenets (fixes aron's merge bug by making sure line ptr is not modified) + -Fix: auto attr placement should inverse-xform target coords because text placement coords are in the parent group's coord system (spec coords, not inst coords) + -Fix: compile infinite loop: do not merge a network with itself + -Fix: move emitting the sheet saved event from sch-rnd to lib to guarantee it always runs + -Fix: update sheet full path after save, before the events are sent out for updating the file-change-notification system + -Fix: when a sheet is saved under a different name, also update loadname (not only fullpath) + -Fix: group-reverse transform second line endpoint as well when drawing a wire - fixes the bug of the second clicked wire endpoint going off randomly when wirenet it extends is transformed + -Fix: csch_conn_recalc_coords() needs to remove and readd conn in the rtree because its bbox is changing + -Fix: floater placement: when calculating floater coords, remain in group relative (spec coords); convert sheet coords to spect coords only where needed, on the hint coord input + -Fix: project file not found is not a warning, just an info for implicit projects + -Fix: when creating new wirenet groups while splitting wirenets copy the selected flag of the source wirenet to the newly created on; fixes the bug of losing selection when moving wirenets + -Fix: recalc conn coords when objects are added or removed from a conn from undo/redo + -Fix: when rotating text, invert rotation direction on single-mirror cases + -Fix: don't crash on NULL fullpath at save-as + -Fix: do not add indirect objects to the rtree - fixes io_tinycad bug of rendering local lib symbols as ghost symbols around 0;0 + -Fix: don't crash when project-exporting implicit project (no project file): just use implicit-project for file name base + -Fix: child xform: don't assert() when bumping into deleted transformation entries during apply, just skip + -Add: undoable attribute rename call + -Add: extra sheet field for making a bridge between query() and propset() for alien io configured attr edits + -Add: extend attribute apply API so it can change the priority of the newly created attributes (will be needed by plugins when copying attribs) + -Add: implement per sheet invalidation box mechanism for redraw freeze to minimize batched object redraws on sw rendering + -Add: enable connection between two terminals directly (will always result in an anon net) + -Add: implement array type attribute single string append/prepend API + -Add: TODOs and error message on unhandled attr merge + -Add: integrity check: make sure sheet's direct group is not transformed + -Add: group helper function: inverse transformation of coords by parent group xform + -Add: vararg based group coord inverse transformation API + -Add: extend sheet type from aux/root to handle unlisted and unknown as well + -Add: project util API to decide if a sheet is root ro aux or unlisted for a project + -Add: project util function to figure if a project is partially loaded (not all root sheets are loaded) + -Add: throw bold error message before compilation for partial projects + -Add: mark sheet that's being saved so GUI indication can be inhibited + -Add: util_path with API for calculating relative path from one file to another + -Add: basename() utility call + -Add: compiler: if there's a project file with explicit list of root sheets, do not compile unlisted sheets + -Add: parser util for replacing the engine list in an existing view lihata conf node + -Add: expose view engine renum function in public API + -Add: csch_cobj_rtree_del() returns 0 on succesful object removal so the caller can figure in a cheap way whether the object was in the rtree + -Add: argument to suppress error message on sheet fails to load + -Add: dup2() API for pens: same as dup() but creates the new pen using a new name (useful when duplicating a pen within the same parent) + -Add: temp fields in the text object for the app to use (needed while reading io_tinycad for marking text objects shown) + -Add: apply the 'remove' child xform in group_refs + + [lib_alien] + -Add: generic postprocessor API with a new format prefix field in the context struct + -Add: generic sheet load postproc using optional user actions + -Add: use query to execute configured actions in sheet postproc (for attribute translation) + -Move: generalize sheet coord normalization function from io_geda so it can be reused with other alien formats + -Move: generalize text rotate adjustment for 180 and 270 degree, io_tinycad will need it as well + + [propedit] + -Fix: recurse into groups on collecting selected objects + -Add: pressing enter in the value input of the "new attribute" dialog should be the same as clicking on ok + -Add: propset(rename/a/key, new) will rename the key to new, keeping value and priority + -Add: @ scope for propset() to be used in alien io attribute transformations + + [query] + -Fix: text's string is really called "text" in the code and in propedit + -Add: helper function to map and append all indirect objects to the query scope + + [sch-rnd] + -Del: zoom-to-found menu (there's no concept of "found" in sch-rnd) + -Del: the "beta testing" experimental warning - the code is getting stable + -Fix: freeze junction recalculation while cutting multiple objects to buffer to avoid modifiation-while-copy + -Fix: freeze junction recalculation on the buffer while copying multiple objects to buffer + -Fix: move loadname overwrite from the GUI to the SaveTo action so it is always executed (even with CLI triggered save) and happens before the filename changed event is emitted + -Fix: reload projet file on 'save as'; a change in the file name may cause a change in the project file + -Fix: when save-as changes project file for a sheet, announce it in the message log and do all the project administration so that the sheet gets moved also in sheetsel + -Fix: realpath project file name before hashing/comparing to avoid stray project.lht entries + -Fix: exit if no sheet could be loaded for a project + -Fix: default zoom menu constants for cschem coords + -Fix: after saving to a different directory if a new project (implicit or explicit) had to be created, call project postproc so that views are loaded from the conf + -Fix: do not throw an error when default sheet can not be loaded while going through a search path (it's normal that only a subsequent item is available) + -Fix: don't update text pen on text edit operation if text is indirect (the indirect tree is never rendered) + -Fix: don't make emergency backups of sheet (force the user to name the sheet) + -Fix: set sheet fullpath to after reverting an unsaved sheet + -Add: initialize new conf node rc.path.dotdir so users can refer to their own config easier + -Add: project submenu in the file menu for managing current project + -Add: action New() to create a new sheet (only in current project for now) + -Add: project file creation API+impl + -Add: ProjectNew() can create the project file and pair it up with an existing/open implicit project + -Add: detect sheet type within the project when a sheet is loaded directly (not via the project file) + -Add: set expected number of root sheets + -Add: when a new aux sheet is created, set sheet type aux + -Add: append relative path of new sheet to project file when root or aux sheet is created + -Add: menu for creating aux and unlisted sheets + -Add: New(): create new project file if it does not exist and a root or aux sheet is created + -Add: ProjectSheetType() action to change the type of a sheet and update the project file accordingly + -Add: ProjectSheetType(): unload target that first makes the sheet unlisted then unloads it + -Add: action for loading rest of the sheets for a partial project (plus menu) + -Add: SaveAll() action (for currprj, current project only for now) (plus menu) + -Add: utility call for regenerating the engine list of a view in the project conf lihata (useful after an edit of project views) + -Add: wrapper for sheet-removal-from-project so the case of project becoming empty can be handled + -Add: remove project (from internal project hash) when last child sheet is unloaded + -Add: throw an error when sheet gets too large + + [sch_dialogs] + -Fix: take the coord field when setting pen size (and convert it from librnd coords to cschem coords); fixes pen dialog tip size set + -Fix: when a new pen is created, select that pen and let the user edit it without needing to select it again + -Fix: when a new pen is created, set sane initial values for its fields + -Fix: abstract dialog restores cursor after recompile + -Fix: force-update text bbox once text string is changed from the gui + -Fix: make sure the drawing area is updated after a text string change from the GUI + -Fix: library refresh button shouldn't crash with empty filter text + -Change: use the lib's undoable attribute rename call instead of local implementation + -Add: sort abstract dialog tree so it's easier to manually search + -Add: abstract dialog: case insensitive regex filter + -Add: abstract dialog: checkbox to filter out anon_ items + -Add: project properties dialog frame (project dialog) + -Add: view dialog: make engine list editable + -Add: view dialog: make it clear that changes are saved in project file immediately + + [std_devmap] + -Fix: use plugin's prio when setting symbol attributes from devmap, instead of using user prio 250 + -Fix: typos in quick_att_portmap() action syntax description + -Fix: devmap should accept only full slot/portname matches (was accidental prefix-match) + + [std_tools] + -Fix: mirror tool respects lock_floaters + + [symbol] + -Fix: stock led should default to led5 for devmap and should have D?? for refdes + + +0.9.4 beta-test (r6370) +~~~~~~~~~~~~~~~~~~~~~~~ + [build] + -Cleanup: missing #includes (exposed by hid.h not always included) + -Fix: make clean should remove objects in src_3rd/ + -Fix: load_cache make clean shouldn't fail when there's nothign to clean + -Fix: build minuid (the executable) because it is going to be installed (for boxsym) + -Add: central make clean recurses into src_3rd as well + + [doc] + -Fix: wrong path to the menu file for keys.html generation + -Del: temporary multi-design support doc - read librnd's instead + -Add: generate file format list + -Add: explain the meaning of per-design and per-app events + + [export_abst] + -Cleanup: don't depend on global csch_hidlib (design is passed as arg) + -Add: calculate default export file name + -Add: indicate the project's abstract model is exported (not the sheet's) + + [export_eps] + -Fix: set expsoe context ->design before calling main expose + + [export_png] + -Fix: set expsoe context ->design before calling main expose + -Del: don't define set_crosshair, use hid_nogui fallback + -Cleanup: don't depend on global csch_hidlib, design is passed on + -Split: sheet export from do_export() in preparation of multi-sheet export + -Add: calculate default export file name + -Add: prepare for multi-file project export + + [export_ps] + -Fix: set expsoe context ->design before calling main expose + -Fix: don't crash on NULL xform when called from lpr + -Del: no need to keep a separate "doing project" global when we have this info in appspec + -Add: calculate default export file name + -Add: support for project-export in ps and eps + -Add: get multi-file exporter option to work in project export + + [export_svg] + -Fix: set expose context ->design before calling main expose + -Cleanup: don't depend on global csch_hidlib (design is passed as arg) + -Add: calculate default export file name + -Add: support for project-export + + [export_tedax] + -Cleanup: don't depend on global csch_hidlib (design is passed as arg) + -Add: calculate default export file name + -Add: indicate the project's netlist is exported (not the sheet's) + + [gui] + -Fix: pass on sheet to autocomp bar update so it doesn't have to query gui-current + -Fix: don't crash if there's no view configured (when generating status bar) + -Cleanup: use rnd_printf() with %rc for printing 'k' coords in status line (instead of local conversion macro) + -Cleanup: get rid of csch_hidlib references + -Add: update sheet hidlib dwg bbox when sheet bbox changes + -Add: bind layer vis changed event to update layer visibility (in case the change happens outside of this module) + + [io_geda] + -Fix: option to emulate no-upside-down-text of gschem + + [lib] + -Fix: csch_printf: don't increment fmt, it's pointing at the last format char already + -Fix: reset project's design list after freeing all sheets so that librnd won't iterate through already free'd sheets + -Fix: don't crash when sheet can not be loaded (e.g. wrong file format) + -Fix: csch_lib_load() should lock redraw: the backend may trigger multiple object updates and if the buffer tool is active (e.g. when placing from the lib), it leads to excess redraws + -Fix: don't crash on revert if file name or load name is NULL + -Fix: add missing "extern" keyword to cschem-unit bits global variables + -Fix: wirenet junction recalculation lock (inhibit) should not be stuck after a paste-wirenet-from-buffer operation + -Fix: don't crash when junction is copied to buffer + -Fix: corner cases that could lead to a crash when copying a large wirenet into buffer + -Fix: integrity: never start wirenet disjoint-test from a floater but do detect if a wirenet is consists only of floaters + -Cleanup: remove CSCH_EVENT_LAYERS_CHANGED: layers are hardwired, they are not going to change + -Cleanup: remove unused csch_project_export_sheets(), project export is done using appspec + -Cleanup: merge export.[ch] content into util_export.[ch] to remove redundancy + -Cleanup: don't include TODO.h where it's not needed + -Change: csch_derive_default_filename() gets an int arg for generating project file name, instead of void *appspec: the lib has no idea what's in appspec + -Add: update parent group's bbox when child object's bbox changes + -Add: update sheet bbox when ->direct subtree bbox change + -Add: bit in sheet struct to notify the GUI on sheet bbox change + -Add: app-specific rnd_printf format plugin for rendering the 'k' suffix values as %rc + -Add: introduce a "cschem" unit suffix and make that the default fallback unit for get_value + -Add: publish cschem unit family and 'k' allow + -Add: register empty-suffixed cschem base coord unit and publish k and base units + -Add: %rr to local printf, to conert rnd_coord_t to csch_coord_t and print it with the 'k' suffix + -Add: export helper: function that updates hid attrib file name (to be used in get_export_options()) + -Add: emit RND_EVENT_SAVE_* and RND_EVENT_LOAD_* events + -Add: cschem_export_filename() takes optional base file name prefix/suffix arguments to ease file name generation in mutli-sheet project exports + -Add: when exporting multiple files as a project, use project file name for the generating the default export name + -Add: event to communicate selection change + + [lib_alien] + -Add: warn for coords too large + + [librnd4] + -Update: follow librnd4 API changes + + [menu] + -Add: property editor on {e p}, same as in pcb-rnd (edits selection) + + [multi] + -Fix: don't rename sheet to project file name after fialed load from project file + -Fix: make "view last conf rev" per project, in a multiple project setup there can be different views perproject + -Fix: don't create views multiple times per project + -Fix: when creating new empty sheet with filename specified, put new sheets in the right project (loading the project if needed) + -Fix: run project postproc after creating new project for new sheet on startup + -Fix: memory leak: free design role config when unloading sheet + -Fix: infobar remembers last file change date per sheet so it can warn for sheets that changed in the background + -Fix: don't remember file name when attempted to load a directory + -Add: explain the usage of sheet "loadname" when loading all sheets for a project + -Add: API convenience on NULL pointers + -Add: get-current call + -Change: pass file name to new_sheet() call so it will have a chance to enter the files in the right project + + [propedit] + -Fix: terminology: board -> sheet + -Add: print coord values with the 'k' prefix when possible + -Add: use coord spinboxes instead of integer spins for coord input + -Add: auto-refresh the dialog on selection change + + [query] + -Del: remove $dwg_area_x and $dwg_area_y: compile-time constants are incompatible with multi-sheet support + -Add: use cschem coord spin boxes for the advanded search dialog + -Add: accept the 'k' unit as *1000 + + [sch-rnd] + -Fix: CP2 and P2C should cast the result to csch_coord_t or rnd_coord_t; when used directly in printf that's how the right type is passed + -Fix: System()'s env var name uses SHEET instead of BOARD for communicating current filename + -Fix: backup/emergency-save all sheets really operates on all sheets, not only on current + -Fix: load system config file from the configured CONFDIR, not from SHAREDIR + -Fix: multi: create multiple new empty sheets if multiple file CLI names are not found on interactive invocation + -Fix: when creating new sheets on startup delay sheet postproc until the config is merged so all library paths are known + -Fix: don't initialize the crosshair before all the configs are merged at least once, for the initial design, else the GUI may try to draw the crosshair with unknown color during startup + -Add: publish sheet_attr_crd() for the GUI + -Add: DAD helper: csch_coord_t spin box + -Add: appspec struct for exporting projects + -Add: project export dialog with menu binding + -Add: safe fallback on appspec with default values + -Add: helper function to decide if an appspec is for project export + -Add: when exporting from the command line with -x, if a project file is passed, do a project-export + -Add: when called from CLI with -x and multiple files, do a project export + -Add: extend --help invocation to indicate project-export on multiple sheets or project.lht + -Add: generate selection change events + -Change: switch over from pcb-rnd's inclib font engine to librnd4's font engine + + [sch_dialogs] + -Cleanup: don't free const char * even if locally allocated + -Cleanup: get rid of csch_hidlib references in infobar and in sheet preferences + -Cleanup: rename pcb_dlg_pref_ to sch_dlg_pref_ to keep namespace clean + -Fix: use the right config node path for setting CLI history size in preferences general tab + -Fix: uninitialized cell terminator for DAD tree-table + -Fix: tree window: invalid memory handling in some corner cases of updating the DAD tree - always have all columns strdup'd even if it's to empty string + -Fix: pen dialog: when pen name is changed on the right side, update it on the left side + -Fix: preferences lib tab: memleak on excess strdup() for 'path expanded' label + -Fix: preferences dialog,library tab: used the wrong context pointer in the help button implementation + -Fix: preferences color: don't crash on empty color list + -Del: preferences dialog, library tab: no need to free tree-table cells, librnd4 will do that + -Add: use cschem coord spinbox in the pen dialog for font height and pen size + + [symbol] + -Fix: switch: style=relay: move the coil a bit up so it doesn't overlap with the switch(es) and terminal falls on the 4k grid + -Fix: switch: style=relay: prefix coil terminal names with "coil" to avoid conflict with switch terminals + -Fix: switch: style=relay: don't draw cap, only coil + + [util] + -Del: deblist script (switched over to packager's doc) + -Del: local implementation of awk_on_formats - use librnd's + -Add: import sign/ from librnd, for release verification + -Tune: boxsym-rnd text scale for aussiefont wide chars + +0.9.3 beta-test (r6000) +~~~~~~~~~~~~~~~~~~~~~~~ + [build] + -Fix: install plugin files + -Fix: every Makefile should recurse using $(MAKE) instead of make, so that the caller's preferred make flavor is used (instead of switching make implementation in the middle of the build) + -Fix: append c89flags to CFLAGS for -Dinline when -ansi -pedantic is also added + -Fix: use -L and -I to librnd when installed to non-standard path + -Add: calculate man5dir in Makefile.conf + -Add: LIBADIR for libarch based lib dir path for sorting out the lib64 problem later + + [devmap] + -Fix: rename footprint from sot23 to SOT23 for compatibility with pcb-rnd stock lib + -Fix: rename footprint from "led5" to "LED5" for compatibility with pcb-rnd stock lib + + [doc] + -Fix: install (5) man to man5dir + -Add: user manual index page + -Add: sch-rnd(1) manual page + -Add: comment on BSD make in INSTALL + + [export_ps] + -Fix: don't export excess showpage on top of the file + + [gui] + -Fix: update the status line when "board is changed" (switched to another sheet) + -Add: Load() GUI file selection dialog filters for loading sheet or project + + [io_lihata] + -Fix: read: throw an error on missing root subtrees instead of crashing + -Fix: read: don't crash on missing attribute subtree, accept that as "no attributes" + -Fix: read: don't crash on missing oid + + [io_tinycad] + -Fix: poly bits and proper filling + -Fix: poly fill implies closed + -Split: label create to a separate function to make room for style code + -Add: implement net label styles (arrows) + -Add: implement net label rotations + -Add: mirx and rot for plain text objects using "direction" + -Add: Package -> footprint translation + + [lib] + -Fix: don't hardwire lib path to puplug, use librnd's LIBARCHDIR so that lib64 doesn't break + -Fix: util_wirenet: when extending a line (merge a newly drawn line in an existing line, making it longer), transform edit coords into wirenet's own coord system so the line doesn't jump away + -Fix: compiler: when compiling a project, do not reset abstract model counters per sheet, only once per project; this fixes redundant anon-naming components and nets + -Fix: don't mess up the abstract model after gui export when the same view is exported that we compiled for in the GUI + -Fix: don't segfault on cnc object uninit when it's has no parent in the object hierarchy + -Fix: util_wirenet: csch_wirenet_recalc_unfreeze() first unfreezes, then recalculates so that new wirenets created during the recalculation are not added the the unfreeze TODO list + -Fix: undable management of connection adds/dels when merging wirenets - fixes a special case of wirenet merge undo + -Fix: when figuring if a newly drawn or geo-edited line causes an endpoint-intersection, do check point-on-line using g2d - with diagonal lines matching up boxes is not enough + -Add: implement CSCH_REM_DEL_EMPTY_PARENT for the remove operation + -Add: remove-sheet-from-project function + -Add: csch_cgrp_replace() for replace symbol low level + -Add: expose attrib del call for alien IO + + [lib_alien] + -Fix: fill in sheet uuid in sheet setup + -Fix: remove tmp sheet (created for reading defaults) from the project after loading alien sheet setup - fixes the bug that a sheet was created on alien load + + [menu] + -Cleanup: unify tool menu with the toolbar and make sure the same F-keys are assigned to the same tools as in pcb-rnd + -Fix: ambiguous wording in menu about object mirroring + + [propedit] + -Fix: use the action API to invoke the pen dialog instead of direct call, to avoid propedit module dependency on sch_dialogs module (which is bad for packaging) + -Fix: use the action API for quickattr editing instead of direct dependency on sch_dialogs + -Fix: integer constant overflow on 32 bit in coord entry min/max + -Update: plugin does not depend on sch_dialogs anymore + + [sch-rnd] + -Fix: sheet files listed in project files are loaded from relative path to the project file, not to sch-rnd CWD so that project files are portable + -Fix: don't hardwire $(PREFIX)/lib for conf_core generation, use arch specific libdir so it works on /lib64 as well + -Add: ReplaceSymbol() action - for replacing a single symbol for now + + [sch_dialogs] + -Add: extend PenDialog() so it can be called to select a new pen; give control over flags like recursive, be able to return a pen name as string and accept optional input pen name for initial selection + -Add: action api for querying if quick attr editor is accessible for an object/attrkey combo + + [std_devmap] + -Fix: don't throw an error when parsing a dir as devmap for a lib refresh + + [symbol] + -Fix: mosfet-p-1 S and D terminals were mixed up + + [tests] + -Add: minimal automatic smoke tester comparing the abstract export of examples to saved refs + -Fix: make sure to exit with error status if any test failed + + +0.9.2 beta-test (5816) +~~~~~~~~~~~~~~~~~~~~~~ + [act_draw] + -Add: accept object:oidpath scope for naming parent group + + [act_read] + -Import: from pcb-rnd + + [boxsym-rnd] + -Fix: use our standard file name ending, .ry, instead of .sym + + [doc] + -Update: index page for beta and plans for the stable + -Update: regroup and reorder state for the beta testing phase + -Import: autostyle from pcb-rnd doc/; use unified headers on the page + -Change: switch over to the unified Ringdove index.html layout on the main page + -Cleanup: cschem vs. sch-rnd: keep cschem only on data model side + -Cleanup: archive the nlnet roadmap: it's pretty much completed + -Cleanup: move some of the old doc used for the design process to archive + -Del: archive use cases - these were relevant for making the initial design + -Del: obsolete style guide - we ended up with a slightly different one in practice + -Del: plans/ + -Move: libcschem doc in developer/, sch-rnd users won't need it + -Import: packaging script from pcb-rnd + -Import: rosetta html generator from pcb-rnd, for scripting examples + -Add: irc page, mirrors page, help wanted page + -Add: link (video) tutorial from the main page + -Add: scripting: cross-link pcb-rnd's doc on generic scripting and different languages + -Add: scripting example: working quick attr editor + -Add: scripting example: voltage divider + -Add: scripting example: text autorotate: object listing and careless rotation to tes tht new API + -Add: scripting example: autolabel: figure wich groups need label, place labels at 0;0 for now + -Add: scripting example: zillion (array copy) + -Add: query: document .anylocked and .level + -Add: lihata format doc links to the project file syntax tutorial + + [gui] + -Fix: status: don't print uninitialized string on grid unit + -Fix: edit act idpath arg converter: free idpath only if it was allocated by the conversion + -Add: edit act: rotate90 accepts idpath specified object (for scripting) + + [io_geda] + -Fix: read_path_xy() accepts comma as separator as well + -Fix: instead of creating a custom group for path, create a polygon (so it can have a fill) + -Add: minimal text alignment: halign should work, vertical align is approximated by move + + [io_tinycad] + -Fix: error message is printed with file name, line and newline + -Add: create symbol groups in indirect for symdef; parse symdefs + -Add: place symbols from the local lib + -Add: parse and place labels (wirenet name floater or sheet decoration text) + -Add: support for objects (sheet decor text) + -Add: support for with a custom group + -Add: parse DETAILS subtree and extract and set administrative sheet attributes like author or page + -Add: parse sheet size, set min height/width attributes + -Add: flip y coords and translate by sheet height to get the same orientation + -Add: parse and create symdef rectangles + -Add: support by creating custom symbols; forge on rail symbols generated for + -Add: parse sheet polygons + -Add: capacitor pin: 'hidden' pin style: draw a 0-length terminal + + [lib] + -Fix: csch_search_all_selected() always recurses to non-atomic groups; this fixes "selected wire can not be deleted using {s r}" + -Fix: when creating a new abstract port (auto-alloc), set parent + -Fix: missing graphical connection is not always an error, e.g. attribute conn of a non-graphical terminal in a symbol + -Fix: sort out how to handle missing graphical connection with drc later on + -Fix: typo caused wrong abstract id2name + -Fix: util_wirenet: do not leave stray empty wirenet groups around after a new line merging existing groups + -Fix: util_wirenet: when drawing a new wire segment attaching to an existing wirenet group, apply the group's transformations on the new line so it is placed properly + -Fix: dup_into() should be able to transform source obj to match the reverse-transformations of destination group so that the final installed coords are not changed; implemented for lines only at the moment + -Fix: more robust merge_into(): expect that source objects are deleted ahead + -Fix: text vs. box intersection calculated properly for rotated text - not for the unrotated gross bbox but for the rotated net text meta rectangle + -Fix: not only wirenet objects may be in a conn, when a line is removed, always remove it from its conn + -Fix: disable wirenet side effects while merging a wirenet group into another wirenet group; this fixes the bug where the merge would remove a middle-object from the source wirenet breaking the source wirenet into new groups that are then not moved + -Fix: when recalculating connections after an object move, if a connection is to keep, still update its coords because the parent object may have moved slightly + -Fix: remove cgrp_inst2spec optimization: it's not enough to look at the group's own transformations, parent's matter too, it's safer to do all this once, with reverse xform + -Fix: when a connection is recalculated, remove objects that are no longer connected + -Fix: if a junction is "drawn" (e.g. in buffer copy), the line objet being drawn may be removed in the process, in wirenet optimization + -Fix: do not update junctions in wirenet recalc freeze, proper recalc of junction after wirenet recalc unfreeze + -Fix: don't crash if there's no objects in wirenet being recalculated + -Fix: don't calculate crossing between wire line and wire non-line in wirenet merges (non-line is typically a label text) + -Fix: when removing a whole wirenet group, remove connection of child objects + -Fix: don't attempt to make a conenction that connects an object to itself + -Fix: don't make connection between child objects of the same group + -Fix: preserve connections in network merge + -Fix: preserve original connections only in "group move into" + -Fix: when finding conns for a terminal look for wires, when finding conns for a wire, look for terminals + -Fix: insert idpath custom fungw type converter on init + -Fix: revert should create a new sheet when reverting to the original sheet is not possible (file does not exist) + -Fix: wirenet: when merging a wirenet into another, remove the leftover empty wirenet group + -Add: refine invalid conn error message with type + -Add: code for caclculating whether a point is within a triangle + -Add: efficient code for calculating whether any of multiple points is in a triangle + -Add: a pointer mark field in object header for temporary storage in sync code + -Add: direct user to the config setting for merging multiple connections per port + -Add: array attribute set API from C const string arrays + -Add: publish attrib side effect function (some io plugins need it) + -Add: all-attribute copy helper + + [lib_alien] + -Cleanup: separate X and Y and non-axis-aligned coord transformations so the per axis offset and mirroring can be introduced later + -Add: expose coord conversion for convenince + -Add: helper functions for creating polygons and line based polygon contours + -Add: option for flipping x and/or y coordinates + -Add: optional x and y translation on coords + -Add: arc-in-poly-contour helper + -Add: helper function to approximate a bezier in a polygon contour + + [menu] + -Add: ctrl+s saves + + [propedit] + -Fix: return coords in long, not in rnd coord (makes no sense to convert to mm) + -Add: propget() also accepts objbin as first arg (like propset); useful for scripting + -Add: when geo is enabled, include bbox coords (also bbox center) + -Add: accessor for reading inst rot, inst mirx and inst miry of text objects + + [query] + -Fix: do not return pointer free'd + -Fix: idpath requires clear memory for idpath target because of vectors + -Fix: .selected returns any-parent-selection as well to be consistent with GUI behavior + -Fix: scope name is "sheet", not "board" in sch-rnd context + -Add: .anylocked: returns true if an object is locked in any way (e.g. group lock) + -Add: .level is evaluated to the object's depth in the tree; 1 means directly on the sheet + + [scconfig] + -Fix: reset all sphash config fields between compiling modules + -Add: print which app required librnd to avoid possible confusion + + [sch-rnd] + -Fix: when buffer-pasting wirenet groups, schedule merge-recalc so they get merged/connected properly + -Fix: don't crash while cutting to buffer if selected object is already removed + -Fix: select wirenet on second selection click on wire + -Fix: when copying a wire into the buffer create the "same" wirenet parent as it had on the sheet (minus metadata) so that it behaves like a wire, not a plain decoration line on paste + -Fix: {s r} (selected remove) deleting junctions won't cause an assert + -Fix: partial wirenet {s r} bug: freeze wirenet recalcs while the remove loop is running so that existing wirenets are not split up + -Fix: normalize wirenet line using inst2spec when put into a buffer-wirenet-group so it remains in position + -Fix: when any dyntext of a wirenet is copied, also copy all attributes of the wirenet + -Fix: buffer clean: use a low level object remove that doesn't have side effects: don't attempt to maintain undo or wirenet merges in buffer when everything is going to be removed anyway + -Fix: do not try copy or paste conn objects, recalculate them instead + -Cleanup: remove obsolete font related config nodes + -Cleanup: move Revert() implementation from lib to sch-rnd: it depends on creating a new sheet which is app-specific + -Add: place wirenet labels on the longest line + -Add: BufferCopy(): optional x and y arguments to override crosshair (for scripting) + -Add: BufferPaste() action for scripting + -Add: API for creating new sheet in-place, in an existing (csch_sheet_t *) + + [sch_dialogs] + -Fix: tree dialog: disable auto-expand because group nodes are of interest in themselves + -Fix: abstract model dialog: do not crash if port's parent is NULL + -Fix: missing has_coords attr from quick_attr to attrib dialog obj converter helper function + -Fix: dlg_attrib #includes its own .h to avoid desync'd function proto + -Fix: tree dialog should refresh preview after compilation finished + -Fix: refresh preview when local lib entry is updated/refreshed + -Fix: don't let the parametric library window open for non-parametric symbol + -Cleanup: const correctness + -Cleanup: remove unused var + -Cleanup: incompatible pointers + -Add: attr editor button in tree view + + [tutorial] + -Add: getting started video + -Add: devmap video + -Add: heavy symbol video + -Add: portmap video + -Add: text video + -Add: dyntext video + + [util] + -Import: awk format helper from pcb-rnd (needed by packages.sh) + + + +0.9.1 beta-test (r5277+bugfix) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [export_png] + -Fix: librnd 3.2.0 does not yet have pixmap export API, disable pixmap exporting + +0.9.0 beta-test (r5277) +~~~~~~~~~~~~~~~~~~~~~~~ + [boxsym-rnd] + -Cleanup: use http url for contact instead of email address (due to spam) + + [devmap library] + -Add: 2n3904 - a real common NPN for the getting started tutorial + -Add: led5 for the getting started tutorial + -Add: polarized rcy, for the getting started video + + [diag] + -Add: UndoSplit() to make undo of batched operations possible step-by-step for debug + + [doc] + -Fix: design: halign values left and right replaced with start and end for clarity (mirroring affects this) + -Fix: lihata native file format spec: wrong root types for sheet and devmap + -Update: direct traffic to pcb-rnd@ instead of cschem@ (mailing list merger) + -Rename: all examples from *.lht to *.rs (and *.rp) + -Add: text mirx and miry in design doc: we had to deal with text mirrors because of inherited transformations anyway, adding an explicit field makes it easier to manage alignments + -Add: lihata format doc: text object mirx and miry + -Add: refine {des3:36} on the single line text case when halign is considered + -Add: document what happens if forge tries to append/prepend array to scalar + -Add: scripting example: quick attribute for tolerance + + [export_abst] + -Add: plugin for exporting the abstract model to text + + [export_png] + -Fix: uninitialized memory on xform + -Fix: when exporting in monochrome, fill polygons with grey above a certain threshold of light colors + -Fix: set fill-gray-threshold bounds to 0..100 (fixes the GUI entry) + -Add: export pixmap objects + + [export_ps] + -Fix: uninitialized memory on xform + -Fix: when exporting in black-and-white, fill polygons with gray above a certain threshold of light colors + -Fix: when exporting in monochrome, fill polygons with gray above a certain threshold of light colors + -Fix: make it clear that gray threshold is considered only in monochrome mode export (both in ps and eps) + -Fix: greyscale poly fill: more accurate approximation of the rgb color using an average of components + -Fix: set fill-gray-threshold bounds to 0..100 (fixes the GUI entry) + -Cleanup: remove some pcb reference leftovers + -Change: make --fill-page default on + -Add: automatic toc; hint on toc being automatically decided + + [export_svg] + -Fix: help uses .rs instead of .sch for example + -Fix: uninitialized xform + + [export_tedax] + -Fix: help uses .rs instead of .sch for example + + [font] + -Change: replace ttf font with pcb-rnd's font engine + -Import: aussiefont from edakrill + + [gui] + -Fix: update top window title only if currently shown sheet's data changes (but not if buffer changes) + -Fix: trigger autocompile on the sheet that had the change (but do not start autocompile timer on buffers) + -Fix: right click context menu respects only_floaters and lock_floaters + -Change: switch over default file name endings to .rs and .ry + + [io_lihata] + -Add: save and load text object mirx and miry + -Change: switch over default file name endings to .rs and .ry + + [lib] + -Fix: wrong sign when applying child xform rot on text + -Fix: text mirror function sets mirror flags instead of rotating + -Fix: text: invert child xform rotation angle on odd mirrors + -Fix: halign enum values renamed from LEFT/RIGHT to START/END to match the spec + -Fix: text mirror: if text is not bbox-specified, do not change spec2 coords (they should be calculated) + -Fix: don't mirror spec2 of text objects - spec2 is really a width+height from spec1 + -Fix: inst2spec on group: don't invert rotation direction + -Fix: cgrp_inst2spec(): do not do inverse transformation, but replicate normal parent transformation, that's how we get the same coords as during render + -Fix: get text rotation vs. mirror right (both for unrotated bbox and precalculated for rendering): rotate first, then mirror + -Fix: remove rotation tweak in text mirror operation: it turned out to be a workaround for a rendering bug + -Fix: rewrite floater_origin() to use raw matrix transformations so that it considers mirroring too + -Fix: text_inst2spec() calculates new x2 and y2 using width and height to preserve orientation of bbox-specified text + -Fix: text_inst2spec() preserves mirror bits + -Fix: cgrp_inst2spec(): rotation angle should be inverted even if parent is not mirrored but target group is + -Fix: integrity test shouldn't segfault (but report error) if connection parent is NULL + -Fix: conn update shouldn't add deleted objects to connecions (but should still run the update to remove it from existing conns) + -Fix: when calculating conn object coords ignore pairs of objects that have the same parent + -Fix: conn object: when a referee is removed, check if remaining referees are from at least 2 different groups; if not, remove the connection + -Fix: don't crash when attrib string val modified to NULL + -Fix: terminology: when creating a new terminal, use "TERMNAME" for initial value instead of PINNAME + -Fix: connection object graphics: don't draw connection mark between same-group objects + -Fix: batch all remove side effects into a single undo slot + -Fix: cnc_conn undo print: print full path of the object being added/removed in a conn + -Fix: conn auto-add: do not (undoably) add an object to a connection if the object is already in the connection (adding it the second time would have no effect but then adding it to the undo list would confuse the system after undo) + -Change: "place terminal" shouldn't mark the terminal name dyntext with the floater flag; the user should modify a name attribute + -Add: remember raw inst_rot and inst_mir* when updating text to make text render's job easier + -Add: text spec mirx and miry + -Add: text_modify() can modify mirx and miry + -Add: apply text mirx/miry when calculating bbox corners + -Add: new layer for hosting text object meta (bbox and orientation) + -Add: symbol-to-component name engine hook + -Add: optimization: do not draw a new wire if it fully overlaps with an existing one + -Add: search: first_gui object with an user specified filter callback + -Add: csch_search_first_gui_inspect_filter() for user filetering on floaters + -Add: comment that allows using the mark field for any sync plugin + -Add: implement csch_attrib_setptr() - saves an strdup()/free() + -Add: undo helper macro for placing marks on the undo list + -Add: better floater placement: if hint coords available, place wire-net floater there + + [menu] + -Add: {a v} changes the value attribute, {a f} changes the footprint attribute + + [place] + -Fix: place terminal and place attrib: mark the sheet changed + + [propedit] + -Add: expose text object mirx and miry + + [query] + -Add: support for text mirx and miry + -Fix: missing halign enum name "center" + -Fix: advanced search tabs: we don't have refdes but name + -Cleanup: pcb-rnd reference leftover in window title + + [renumber] + -Add: plugin for automatically renumbering symbols (filling in the name attribute) + + [sch-rnd] + -Fix: text alignment in mirrored bbox specified case + -Fix: default file naming in buffer save is .sy for symbol + -Fix: buffer: when picking up floater for copy, do a reverse transformation of parent transformations so that the coords in buffer are in the absolute coord system + -Fix: don't hardwire .sch-rnd for dot path in menu paths,use config.h variant so it can be overridden + -Fix: when clicking for selecting an object and there are overlapping objects, ignore the one already selected (lets you cycle through objects) + -Cleanup: pcb references left over in config help + -Change: when saving buffer to symbol, offer sym.rs as default file name, where sym is easy to replace (already selected) + -Move: lock_floaters and only_floaters are handled in central gui search so that things like {a v} don't need to reimplement them + -Add: implement start/end/center text alignment + -Add: implement word and glyph justified rendering + -Add: draw textbbox and origin controlled by text meta layer visibility + -Add: sch_rnd_search_first_gui_inspect() that applies only_floaters and lock_floaters + -Add: menu for listing unnamed symbols (hotkey: {s l u}); rename {s k} to {s l k} for consistency + + [sch_dialogs] + -Fix: allow attribute dialog object search to pickup terminals (use the _inspect() search), e.g. in {a a} + -Add: tree dialog: print connections oid-paths for a conn object + -Add: tree dialog: preview for a conn object should zoom to the bbox of all calculated intersections ("green stuff") and hilight all objects participating in the connection + -Add: apply hint coords for floater placement when attribute dialog invoked for object + + [std_cschem] + -Add: rename components ending with ?? to oid based unique naming (to avoid collisions) and warn the user + -Add: plugin configuration with fix_unnamed_syms (enabled by default) + + [std_forge] + -Add: plugin for cschem standard attribute forging + -Add: put the plugin on default views; run forge before std_cschem for the connect list to work from forge output + + [std_tools] + -Fix: drag&drop move selected: don't ignore selected object when clicked + -Cleanup: remove pcb_ prefix leftover + -Cleanup: remove tool: no need to mark sheet changed, low level code does that + -Add: double click while drawing lines or wires stops drawing + + [symbol] + -Cleanup: rename symbols from *.sym to *.rs + -Fix: opamp, comparator: V- transformation to keep text readable + -Fix: use bbox-defined text for rail symbols with center alignment + -Fix: common awk: terminals are created with all labels properly mirrored so they grow away from terminal origin in all four orientaitons terminals can be placed + -Fix: ldo symbol term label directions + -Change: term label shouldn't be floater but dyntext and the user should modify a name attribute + -Change: common sym awk: term label shouldn't be floater but dyntext and the user should modify a name attribute + + +0.8.4 alpha5 (r4889) +~~~~~~~~~~~~~~~~~~~~ + [act_draw] + -Add: DrawLine(), DrawRelease(), DrawGroup action(), DrawCircle(), DrawArc(), DrawWire(), DrawText() + + [backann] + -Add: back annotation plugin with bap import and GUI + + [boxsym-rnd] + -Fix: strip whitepsace from pin field args + -Fix: pin alignment corner case with only top and bottom pins + -Add: generate group uuids + -Add: don't overwrite input with monolith on file name match, print an error instead + -Add: throw error on multiple definitions (terminal name non-uniq) + -Add: pin label option + -Add: let the user tweak text size estimation factor + + [build] + -Fix: remove redundant broken map_plugins rule + -Add: generate Makefile.conf to help install scripts later + -Add: make install + -Add: install minuid CLI tool into libdir - boxsymrnd depends on it + + [construct] + -Fix: don't even start converting to poly below 3 objects + + [doc] + -Fix: design: specify source format only for the case the data is saved - don't care how it is stored in-memory; clarify when the UID based source format needs to be used + -Fix: pcb-rnd terminology change from element to subcircuit + -Fix: design: components and nets are primarily identified by their name + -Cleanup: unnecessary full path in example + -Cleanup: rename cschem to sch-rnd in svn url + -Change: design doc: uuid (and src_uuid) are not attributes but non-mandatory properties of groups + -Import: action doc scripts from pcb-rnd + -Add: uuid and src_uuid in lihata format doc + -Add: backann example: name nets because anon net name is not stable + -Add: design: project file terminology with the root sheets + -Add: design: {6:29} explains the relation between hierarchy and the optional project file + + [examples] + -Fix: use a.name instead of A.name in dyntext + -Fix: use a.devmap instead of A.devmap + -Add: (instance) uuid in all groups + -Add: full back annotation example + + [export_png] + -Add: screen-colors export option that keeps selection and hilight colors + -Add: --view parameter + + [export_ps] + -Fix: restore view on error + -Add: screen-colors export option that keeps selection and hilight colors + -Add: --view parameter for ps and eps + + [export_svg] + -Add: screen-colors export option that keeps selection and hilight colors + -Add: --view parameter + + [gui] + -Add: autocompile: GUI and implementation + -Add: sheetsel: mark non-root sheets with parenthesis + + [io_lihata] + -Fix: test parse accepts file only if it is of the requested type + -Add: load and preserve project file lihata doc in memory, in the project structure + -Add: save/load grp/grp_ref uuid and src_uuid + + [lib] + -Fix: text update: optimization gone bad: can't skip detailed angle transformation if text is mirrored in any direction, even if input rotation is zero + -Fix: don't crash if group ref target is NULL in csch_cgrp_ref_get_attr() + -Fix: csch_grp_ref_get_top() shouldn't crash when sheet->direct or sheet->indirect is queried + -Fix: sheet revert should also trigger sheet post-load event at the end, it's really a load + -Fix: sheet uninit frees the undo list; sheet init resets/initializes the undo list + -Fix: wrong order of local lib uninit when sheet is uninited may cause broken hash table in symlib_local + -Fix: when converting a group ref to group, copy any attribute of the referee that's not set in the group + -Fix: grp_ref embed to grp changes the sheet so should call sheet_changed + -Fix: compile net merge should copy sources into the new net + -Fix: compile net merge: remove sources from the source group which shall be empty by now + -Fix: don't crash in "find sheet by load name" in case load name of a sheet is NULL - it just shouldn't match + -Fix: integrity check: don't complain about object disjoint from a wirenet if object is a floater (typically it's the netname) + -Fix: attr undo list free: don't crash on swapped attr being NULL (normal case) + -Fix: wirenet draw: group all operations in a single undo slot when a new wire segment merges existing wires + -Fix: default export file name for unknown page is unknown.EXT, not sch-rnd..EXT + -Change: make plug io types a bitfield so multiple types can be probed + -Add: upgrade project struct for remembering the lihata document (for now) and mark that it will be an extension of the librnd project struct at librnd 4.0.0 + -Add: bit to mark if a sheet is not a root in a project + -Add: when compiling a project, start compilation only from root sheets, aux sheets should be reached through root sheets + -Add: generate new (instance) UUID for groups as they are allocated + -Add: copy group source uuid on alloc and dup + -Add: undoable group uuid modify calls + -Add: assert() on group ref being NULL in csch_cgrp_ref_get_attr(): it's usually indication of a bug, reveal it ASAP in debug mode + -Add: extend the object hash API with a more flexible, bitfield ignore + -Add: object hash can ignore floater geo and grp placement (useful for loclib symbols) + -Add: integrity check: every group object shall have an instance uuid + -Add: loclib edit callback in backend API + -Add: utility call that figures if a concrete group is a source of an abstract object + -Add: mark wirenet merge source as ghost so it can be omitted from output + -Add: wirenet util: count junctions on a line object + -Add: wirenet util: function to determine if a new wire line would hit the endpoint of an existing wireline with its middle + -Add: publish attr source append API so that failed writes can be logged + -Add: compile: log failed attribute writes + -Add: attribute source parse: also parse type bits + -Add: publish csch_conn_text2ptr() + -Add: integrity checks on connection objects so strange/invalid cases are caught earlier + -Add: export util: helper functions to compile and restore abstract model around export to handle --view + + [library] + -Fix: use a.devmap instead of A.devmap so that compilation can change the printout + -Fix: excess group in coil-var-3 + -Change: use a.value instead of A.value for display value so it can be calculated during compilation + -Cleanup: use for initial value for all stock librayr symbol - it's dangerous to use a valid-looking value, the user may forget to modify that after placement + + [propedit] + -Add: handle UUIDs + -Add: help text for the most common fields + + [query] + -Fix: remove PCB from query help + -Fix: remove ctx from linked list when dialog is closed + -Add: support for grp .uuid and .src_uuid + -Add: close all the sheet's search dialogs when sheet is unloaded + -Add: close all search dialogs when plugin is unloaded + + [sch-rnd] + -Fix: poly arc fill for negative delta shoudl result in positive steps + -Fix: poly fill approximation assumes 600 DPI on exporters that don't set coord-per-px + -Fix: font rendering compensation for x-mirrored text (180 deg rotation before render) + -Fix: menu: use 'k' for grid units now that librnd supports it + -Fix: don't list 32k and 64k for default grid units, they are out of range + -Fix: wrong uninit sequence: free paths only after hidlib uninit, else saving config to user file (e.g. saving window geometry on exit) will break + -Fix: menu: connection attr quick change is really about symbols not a generic groups, move it in the right submenu + -Change: rename conf node prj.sheets to prj.root_sheets to prepare for hierarchic designs + -Change: crosshair color in default config to make wires more visible + -Change: enable autocompile by default + -Add: draw: xform bits to disable rendering selection and hilight colors + -Add: also list aux sheets in project file for hierarchic designs to be fully specified + -Add: multi: load all sheets of a project file when the project file is loaded directly + -Add: mark non-root (aux) sheets when loading all sheets of a project file + -Add: UUIDs in the default sheet + -Add: when creating a new sheet, make new UUIDs for sheet->direct + -Add: lock floaters, only floaters config & menu + -Add: menu: {a s} for slot change shorthand + + [sch_dialogs] + -Fix: tree preview renders the sheet of the object, not the currently gui-visible sheet + -Fix: library dialog refresh: get the name of the root lib entry and use that to decide if it's the subtree and to log what got refreshed + -Fix: refresh preferences dialog general and lib tabs on board change + -Fix: close open library window when sheet is closed + -Fix: undo dialog shall be global and shall always display data for the current sheet + -Fix: tree dialog has one root per sheet (matters when showing a multi-sheet project) + -Change: disable showing hidlib-name of the sheet - this concept should be moved from librnd to pcb-rnd as legacy + -Change: tree dialog is really per project local, not per sheet local + -Add: need to refresh any open library window in sheet postproc: revert may remove local lib + -Add: library dialog: optional button for loclib edit + -Add: do not display ghost abstract objects + -Add: update tree (but with a shorter timeout) when sheets in a project change + + [std_tools] + -Add: arrow tool repsects only-floater and lock-floater config + + [symbol] + -Change: switch over common_sym awk to rely on externally supplied minuid seed to guarantee unique UUIDs + -Add: license banner for common awk + -Add: uuids in all lib symbols + -Add: common_sym awk: generate uuid field for each group if minuid is initialized + -Add: common sym awk: sym_term() has a label option that overrides the terminal name printout with whatever user requested label + + [symlib_local] + -Fix: print string attribute for name in error log instead of binary garbage + -Fix: symlib_local_free() gets a lib ptr but sh and shna contain groups; look up the group + -Fix: loc_replace(): need to remove from hash/lib first, only then can the group be free'd, else hash removal would fail + -Fix: parsed the wrong string in "object:oidpath" addressing + -Fix: grp -> grp_ref loclib conversion: always keep the role attribute explicitly - it's too important to lose trying to rely on lib refs + -Fix: set board changed after converting grp to loclib grp_ref + -Add: loclib edit callback, invokes attribute editor + -Add: preserve attributes that differ from the loclib version when converting a group to group-ref + + [util] + -Import: deblist and keylist from pcb-rnd for doc to generate + -Import: list_dialogs (devhelper) from pcb-rnd, adapt to sch-rnd + + +0.8.3 alpha4 (r4400) +~~~~~~~~~~~~~~~~~~~~ + [boxsym-rnd] + -Fix: monolithic symbol: avoid overlapping terminals if multiple slots use the same side + -Fix: remember multi-slot coords and insert separator only when side got incremented + -Fix: when generating monolith, prefix slotted pin names with slot number to make them unique + + [build] + -Add: generate, compile, link and use embedded version of default config instead of depending on ./ + -Add: embedded default sheet fallback + -Add: embedded version of the menu file + + [construct] + -Change: allow arc in poly while converting objects to poly + + [doc] + -Add: developer doc on how local symlib copy&paste works (especially in multi-sheet setup) + -Add: lihata file format versions + -Add: lihata format doc + + [export_tedax] + -Add: --view argument for selecting which view to export + + [gui] + -Fix: sheetsel: use the basename of the parent directory of the project file for project name + -Fix: off-by-one bug in sheetsel project basename calculation when there's no '/' in project path + -Del: redundant Unselect() implementation + -Cleanup: get rid of infobar's global sheet dependency where easily possible + + [io_lihata] + -Fix: do not save or load conf subtree in buffer save/load + -Fix: do not save editor/mode in sheet conf subtree (to reduce noise) + -Add: buffer load/save hooks and test-parse + + [lib] + -Fix: remember template name for new sheets so revert-sheet can load the template even tho loadname and hidlib name are NULL (for enforcing save-as) + -Fix: const correctness: csch_cfg_multiport_net_merge is not modified by the lib + -Fix: group dup shouldn't crash if dst allocation (with enforced ID) fails but return NULL + -Fix: project export name: when deduced from sheet, truncate "extension" of the sheet load name and append both view name and a * + -Fix: split up disjoint wirenets after a delayed/inhibited wirenet update + -Cleanup: rename export_netlist to export_project because the real difference is operating on the abstract model exporting the whole project, what the exporter does with it is its own business + -Del: project->symlibs (was in use before project switched to coraleda-standard config approach) + -Add: sheet post unload event + -Add: Unload() action (works for sheets for now) + -Add: event for copy-to-buffer so that local lib can take over + -Add: API for buffer load/save + -Add: csch_cgrp_ref_ptr2text() + -Add: integrity check: grp_ref object must have a referee and if it's a pointer, it must be within the same sheet + -Add: pass on the sheet that triggered project export to figure output name, just in case project does not have a name + -Add: project compilation gets a viewid arg so it doesn't necessarily rely on project's default view (allows reentrant export on a different view) + -Add: get-view-idx-by-name API + -Add: CompileProject() has an optional arrgument for naming a view to use + -Add: "deleted" concept in group ref's child_xform; do not export deleted items + -Add: function to clear the cache portion of child_xforms of a grp ref + -Add: assert() on trying to use removed child xform + -Add: throw an error for "grp-ref with child xform within grp-ref" for now + -Add: integrity check: detect disjoint wirenet groups + -Add: helper macro that converts object[=oidpath] into a keyword (F_Object) and an object pointer resolving the oidpath + + [propedit] + -Fix: don't use int for enum: unsafe when passed as pointer + -Fix: passing incompatible pointer to modify() on polygons + -Fix: remove pcb-rnd-specific scope hints from help + -Add: implement toggle for polygon has_fill and has_stroke + -Add: Propset() + -Add: Proptoggle() + -Add: Propget() action + -Add: Propprint() action + + [scconfig] + -Add: detect system font dir (testing dir existence from a list) and include it in generated config.h + -Add: --fontdir to override autodetection + + [sch-rnd] + -Fix: multi: calculating the wrong project file name (dir, not file) + -Fix: move generating sheet post-load event from lib to sch-rnd's multi so that project config is already loaded by the time the event is emitted + -Fix: multi: properly restore config state after a failed load + -Fix: run group update on pasted object only if it's really a group + -Fix: do not accept rc/font_dirs on project or design role (that's too late for the font engine) + -Fix: print all GUI plugins available (not only the ones loaded) + -Fix: refuse to copy grp_ref objects to buffer - they would break on paste later if the sheet changes or if pasted on another sheet + -Fix: do not export each sheet of a project from project export + -Fix: select the arrow tool after loading a new sheet so that a sheet saved 'mode' wouldn't cause problems + -Fix: typo in the menu file: saving buffer group should work on any group, not just symbols + -Cleanup: remove global project dependency from -x exporting + -Cleanup: remove dumping the abstract model from project netlist export call - there are better ways looking at the abstract model by now + -Change: SaveBuffer() and LoadBuffer() argument for saving whole buffer is "All", not "Sheet" as the save format has a different header + -Add: make font mapping code substitute $() in font dirs so scconfig detected font dirs can be fed in and use scconfig detected font dir by default + -Add: multi: support for sheet unload + -Add: multi: helper for finding next/prev sheet from a given sheet (for fallback after an unload) + -Add: sheet unload menu + -Add: be more explicit about which operations are on sheets in the file menu + -Add: fill in rc.path.design using the sheet's file name + -Add: --show-paths prints library search paths and font dirs + -Add: emit event BUFFER_COPY_CUSTOM and perform the copy only if no plugin did it + -Add: BufferSave() and BufferLoad() works on whole buffers (op is "All") + -Add: fail with an error message when pasting a group-ref (must be handled by plugins, e.g. symlib_local) + -Add: generic project export call gets optional explicit name from the export plugin + -Add: implement RemoveSelected() for {s r} + -Add: UnSelect(All) action with a menu binding + -Add: Select(All) action with menu binding + -Add: Select(Invert) inverts selection + -Add: draw code for arc-in-poly + -Add: remember file name when sch-rnd was started with a file name pointing to a non-existent file and a new sheet had to be created so save won't ask for the file name + + [sch_dialogs] + -Fix: quick attr: accept non-native-action fungw functions for quick_attr callback so that scripts can implement quick_attr as well + -Fix: update (global) undo dialog content after switching sheets + -Add: about box + -Add: attribute dialog: when creating a new attribute, also ask for the value for quicker edit + -Add: attribute dialog: set value on existing attribute in 'new' if both key and value are specified + -Add: EditText() first arg object=oidpath works + -Add: PenDialog() accepts object=oidpath as first arg + + [std_devmap] + -Fix: compiler error message prints devmap name string (not the devmap attribute struct) + + [std_tools] + -Fix: batch undo operations of line endpoing move: in case of wire lines this may be a series of operations to break wirenets + -Fix: reset movecopy endpoint when a new move starts so it doesn't accidentally inherit previous endpoint state + + [symlib_local] + -Fix: copy loclib ref to buffer should create a "purpose=symbol" grp within buffer's indirect where the local symlib is grown + -Fix: don't require keeping the original OID when creating indirect symbol loclib entry - pasting from buffer will oftne have collisions in OIDs + -Add: when loclib grp_ref is copied to buffer, also copy the referee into the indirect subtree of the buffer + -Add: when copying to buffer, rebind ref so it doesn't point to the sheet's indirect + -Add: sanity checks for loclib grp_ref paste + -Add: paste grp_ref with also pasting inderect referee and fixing up the reference + + +0.8.2 alpha3 (r4136) +~~~~~~~~~~~~~~~~~~~~ + [boxsym-rnd] + -Update: use attribute -symbol-generator instead of symbol_generator to avoid collisoin (and dash for consistency) + + [build] + -Fix: explicit rule for building load_cache object + -Fix: explicit rule for building src_3rd ttf_bbox's mapper + + [doc] + -Fix: do not hardwire UID as means of reference from abstract to concrete model, leave the decision to the implementor + -Change: rewrite attribute source syntax to make the GUI be able to trace back sources + -Add: release procedure imported from pcb-rnd, tuned for sch-rnd alpha state + -Add: explain that the indirect subtree hosts different group types, including devmap + -Add: explain the first level of groups within the indirect subtree + -Add: document how --layers works + -Add: computer readable tables of query fields for concrete objects; generated html version + -Add: query: copy relevant parts for functions from pcb-rnd doc + -Add: portmap & devmap & display name document + -Add: document loclib_name field for groups + -Add: attribute key prefix '-' and '+' to control merging + -Add: devmap file format + -Add: document child_xform + [examples] + -Del: old project file example - we've switched to config-tree-based project files + -Fix: portmap example slot2.lht: specify the portmap only once + -Fix: remove redundant copies of the titlebox + -Update: switch over from slot to -slot attrib avoiding attrib collision + -Add: include devmap loclib in devmap example (devmap loclib is mandatory) + + [export_lpr] + -Add: print (using generic lpr implementation from librnd) + + [export_png] + -Change: switch over from local copy of draw_png to using librnd 3.2.0's pixmap draw plugin + -Add: --layers + + [export_ps] + -Change: switch over from local copy of ps/eps draw code to librnd's lib_exp_text + -Add: depend on lib_exp_text + -Add: --layers for ps and eps + + [export_svg] + -Change: switch over from local copy of ps/eps draw code to librnd's lib_exp_text + -Add: depend on lib_exp_text + -Add: --layers + + [gui] + -Fix: potential NULL pointer deref on load + -Fix: overwrite sheet's loadname on save as to keep it in sync (not on plain save) + -Fix: invalidate_all() after compile - a lot of dyntext has changed + -Fix: compile button invokes the action not with the project that was active at setting up GUI but the project that's active at the moment (the user may have switched in multi-sheet setup) + -Import: title.c from pcb-rnd to set app top window title + -Add: action for relative-switching sheets + -Add: adapt title.c for sch-rnd + -Add: sheet selector (multi-sheet support) + + [io_geda] + -Fix: more detailed error messages in path parsing + -Fix: separator in H path xy coords is not comma but space + + [io_lihata] + -Fix: project file header to match pcb-rnd's + -Del: remove old project file loading - switched to librnd + -Cleanup: switch over from csch_message() to rnd_message() + -Add: save/load conf subtree to/from sheet file + -Add: load and save group ->loclib_name + -Add: accept coraleda project in test-parse + + [lib] + -Fix: export util: determine default export file name using loadname of the sheet, not realname (makes a difference if sheet is a symlink) + -Fix: when creating dummy project file, make sure the the proper dummy lihata doc is created for it + -Fix: reverse prio levels of plugins - order should be from lower prio (larger integer) to higher prio (smaller integer) according to the spec + -Fix: attrib source type is not a single char but a string (to match the spec) + -Fix: uninitialized stack var caused wrong net name for comparison/log in wirenet merge + -Fix: segf when compiling on unsaved page + -Fix: compile: when a group ref overwrites an attribute of the referee with the same prio, that's not a compilation error, simple skip the write + -Del: local implementation of project file name calculation (csch_project_name_by_sheet_name()) -> use librnd's + -Del: get rid of local message.[ch] implementation in favor of librnd's + -Change: high level attrib code always gets source as pointer, so that allocation can be simplified in a subsequent commit + -Change: make struct csch_source_arg_s opaque, making the allocation scheme an internal business of the attrib code + -Change: make connections layer visible by default + -Optimize: simplify temp attrib source allocation, save two malloc()s + -Move: local lib support, remember loclib_name, centrally allocate loclibs + -Add: library changed event + -Add: layer visibility table for default exports + -Add: temporary workaround until librnd4.0.0: LoadFrom() uses multi.h API to load multiple sheets instead of replacing current sheet + -Add: csch_lib_clear_sheet_lib() - will be useful for cleaning the library before a global rehash + -Add: preview_text hook for library backends, so non-symlib implementations can get something displayed in the library window + -Add: unset dummy bit on project file when it's written out by librnd + -Add: compiler: implement attribute collision rules, introducing the '-' prefix for omitting attribute promotion + -Add: run standard attribute compilation on ports + -Add: API for attribute source decompile + -Add: utility function for embedding a group_ref (converting it into a group) - floater transformation not yet done + -Add: function to remove a lib entry from the tree + -Add: new drawing layer for symbol meta (bbox & status) + + [library] + -Update: prefix all the misc attributes with the a minus sign so they are not promoted to the component + + [propedit] + -Fix: don't let group ref child objects changed + + [query] + -Fix: clean up user functions before compilation instead of expecting the previous compilation succeeded + -Fix: throw error message if there's user function in expression + -Fix: report compilation errors using rnd_message() instead of --debug-only trace + -Fix: reset lex buffer before parsing a new script (matters after a compilation error) + -Add: include last seen line number in compilation error report + + [scconfig] + -Fix: use configure .sch-rnd dot dir (under $HOME) instead of hardwired string + -Cleanup: switch over to use /local/csch instead of /local/pcb in the db tree + + [sch-rnd] + -Fix: uninit gui support plugin before unloading all plugins so that it won't hold its deps back with refco and every plugin is properly uninited and unloaded + -Fix: typo in buffer code: when buffer place event took over creating the target object, take the right object for result + -Fix: set rnd_render in expose_main() so that gui exporting works + -Fix: buffer paste at 0;0 should call group update with xform (there's no move that would do that) + -Fix: arrow tool shift-click on selected object should unselect it + -Cleanup: remove code dups with pcb-rnd, using librnd's new exec prefix helper + -Cleanup: move export helper function from sch-rnd.c to export.c + -Change: use our own app's config prefix in the default conf for clarity + -Add: explicit rule for compiling src_3rd/libuundo objects + -Add: print runtime librnd version as well + -Add: make it possible to render (draw) using local layer visibility instead of the current GUI's (required for reliable exports) + -Add: export helper: interpret a layer visibility description string and set xform visibility accordingly + -Add: export menu + -Add: print menu + -Add: multisheet: temporary code for switching sheets by saving/loading config states (before librnd 4.0.0) + -Add: SymlibRehash() action + -Add: prj/ conf subtree with list of sheets, allowed to load only from the project file + -Add: refuse to load view conf from the sheet file or cli, scope should be at least project + -Add: emit LOAD_POST event after loading a sheet + -Add: object right click context menu for symbol vs. local library handling (embed/unembed) + -Add: draw dashed bbox on the symbol meta layer + -Add: symbol meta layer: draw an L or E in the top left corner depending on whether the symbol is loclib grp-ref or embedded grp + + [sch_dialogs] + -Fix: missing return value on library dialog error exits + -Fix: library: remember the full path of cursor so it can be restored after extending the local lib + -Fix: don't let {e t} edit group ref child objects + -Fix: tree dialog: track of what object was last shown in preview and do not change zoom/pan, only redraw on status changes as long as object selection did not change + -Fix: generate file name change event on changing sheet name to get the titlebar updated + -Fix: attr dialog: prefix group ref referee keys with a space so they are not found for most context (and cursor is not set to them when a target key is requested) + -Fix: attribute dialog: disable the floater button for group refs (grp refs can't host new objects) + -Fix: attribute dialog: allow limited edit of referenced group attributes + -Fix: attribute dialog: don't let the user change priority value on referenced group's attributes + -Fix: don't crash on library selection if nothing is selected when "use selected" is clicked, take it as a cancel + -Add: update all library GUIs open for the related sheet upon a library changed event + -Add: attribute dialog displays referenced grp's attributes as well + -Add: dyntext edit: when invoked on a grp_ref direct dyntext child refering to the group_ref's attribute, invoke the attribute editor, that's the only way to change the text + -Add: dyntext edit: throw error if grp_ref child was a dyntext but could not be edited + -Add: dyntext edit: widgets to directly access/edit attribute value in the simplest and most common cases + -Add: print error messages when the attr edit button can't figure which attribute to edit + -Add: create the PrintGUI() action using librnd's implementation + -Add: attribute dialog: set the name of the left-right pane for testing save/restore + -Add: tree dialog preview: show original sheet, not current GUI sheet (it is a local dialog) + -Add: if lib backend preview_text() is available, use that for generating the preview instead of trying to draw a symbol (useful for non-symbol libs) + -Add: button for following attribute history row + -Add: AbstractDialog() takes optional abst_id and attr_name to navigate cursors to an existing attribute + -Add: cross-call from abstract attribute history to attr source abstract object (opening the right attribute dialog) + -Add: abstract attribute source traceback button: when concrete object attribute is clicked, open the attribute editor with the object's oidpath and attr name to get the cursor right + -Add: abstract attribute side: when presenting attribute history, auto-select highest prio line, that's the one that determined the final value + -Add: include libmaster's name and sheet name because multiple instances may be open + -Add: special buttons for local lib handling + + [std_devmap] + -Fix: do not modify portmap attribute values while parsing for assisted edit + -Fix: assisted portmap edit: return 'changed' state after modification + -Fix: port map quick edit: memory management bug on initial pcb/pinnum fillin + -Update: prefer -slot over slot for the slot attribute + -Add: more detailed error messages on invalid devmap attributes + -Add: figure which symbol(s) contributed the devmap attribute + -Add: local lib support - automatically save any devmap used on the sheet in the local lib + -Add: implement loclib refresh-from-external-lib + -Add: count/list devmap usage from local lib + + [symlib_fs] + -Fix: when loading a parametric symbol from the rendered temp file, replace group file name with the original parametric symbol file name - nobody is interested in the temp file name + + [symlib_local] + -Add: when enabled, create local lib reference for buffer pasted symbol groups + + [target_pcb] + -Del: no need to manually derive port attributes, they are all compiled centrally + -Fix: when display name is set, description should include where it was copied from + -Fix: typo in attrib source plugin name + + [util] + -Update: example boxsym has "-slot" attr so it doesn't propagate + +0.8.1 alpha2 (r3606) +~~~~~~~~~~~~~~~~~~~~ + [boxsym-rnd] + -Fix: do not emit excess, zero sized box + -Fix: swap order of pins from bottom->top to top->bottom on the left and right side to match the order in the file + + [build] + -Fix: replace "fp" plugin class with "symlib" class as sch-rnd has symbol libraries, not footprints + -Fix: classification of std_* plugins (they are feature, not io) + -Add: ./configure: --enable-bison and --enable-byaccic + -Add: define sphash so that plugins can use it + -Add: new plugin class "engine" to separate them from more generic features + + [doc] + -Add: generated doc on stock parametric symbols + -Add: devmap: specify how non-slotted portmap entries look like + -Add: describe how does the display/name attribute work, explain heavy symbols + -Add: explain portmap and devmap + + [examples] + -Add: a real LDO example circuit (using the stock lib and portmap) + -Add: a working devmap example with 2 of the same n mosfet symbols with different pinouts + -Add: devmap example conn1 gnd and vcc connections + -Add: slotting example with devmap + -Add: inhomogeneous slotting example (clocked SR latch built of 4 NAND gates) + -Del: project file special subtree for symlibs (project file becoming config based) + + [export_png] + -Add: disabled-by-default until draw_png is moved to librnd + + [export_ps] + -Add: export ps (ps and eps) + + [export_svg] + -Add: standard svg export; low level draw copied from pcb-rnd + + [export_tedax] + -Add: register an export HID as well so the standard librnd export mechamism works + -Add: call the generic exporter from the export plugin + -Add: more details in error messages on pin number/refdes + -Fix: use abstract net's ->netname for the final fallback if there's no better attribute based name + -Fix: do not export components with no name; such component is meant to be graphical by definition + -Fix: no parent refdes is not an error, it only means parent component (and all pins) should be omitted from the netlist + -Fix: prefer display/* attributes over pcb/* attributes (do not hardwire workflow) + + [gui] + -Fix: use gui_inspect search for right click so that terminals are picked up over symbols, wirenets and floaters + -Add: compile box in the top status bar + -Add: view button invokes ViewDialog() + + [io_geda] + -Add: plugin main to read gschem sheets and symbols + + [io_lihata] + -Fix: reverse ordering of negative OIDs to preserve object order on a load-save round trip (new negative OIDs are assigned in decreasing order) + -Del: don't load symlib dirs from a special subtree from project file, it'll be part of the normal config tree + -Add: test parse callback + -Add: support for group ref child xform load and save + + [lib] + -Fix: avoid excess object redraws in text update + -Fix: wrong ordering of io plugins by priority: higher value is better + -Fix: if test parse returned okay, rewind() f once again because the real parser may also depend on it; also rewind after test parse when loading group + -Fix: inhibit redraws during load, just in case the loader triggers some + -Fix: wirenet util: don't print warning on ignored text object in wirenet mapping; such text object is typically the netname + -Fix: search all selected: recurse into non-selected groups so that partial selection is found + -Fix: if a new wirenet group is created during recalc freeze, add it to the recalc list (to be recalced after unfreeze) + -Fix: wirenet unfreeze merge: recalc connections as well; calculate final net name on unfreeze merge, communicate renames using error messages so that the user gets notified + -Fix: batch undo ops for drawing a wirenet segment as it often breaks down to multiple junction and conn operations + -Fix: recalc connections on wirenet line move + -Fix: do not add the same library root twice even if it got two map requests + -Fix: reverting before save should get back to the default sheet + -Fix: invalid free(): on sheet uninit remove comm_str only after removing all pens because pen hash depends on comm_str + -Add: fully working net/component compilation that considers engines and views + -Add: API: csch_oidpath_list_clear(), csch_text_invalid_chars() + -Add: API: abstract type name resolver + -Add: pointer domain for object arrays (vtp0 of csch_chdr_t *) + -Add: recursive wirenet recalc freeze/unfreeze with a single recalc at the end + -Add: wirenet: group merges after recalc unfreeze + -Add: i/o API: call for backup sheet save (no side effects like resetting the changed flag) + -Add: remember if a project is dummy (not loaded or saved, just created from scratch) + -Add: abstract objects shall remember their abstract model parent for easier callbacks + -Add: throw an error on port trying to connect to two different nets (except when it is being merged) + -Add: project should remember last compilation abstract model so it can be displayed + -Add: new search flavor, gui_inspect() that allows some of the non-movable/non-selectable objects to be picked up too (symbol lock bypass on terminals) + -Add: project view accessors: return current view or view by name + -Add: helper function to get the abstract object for a concrete object + -Add: dyntext resolves abstract model's attributes using a.key references + -Add: API: introduce an extra argument in project loading to tell if all sheets need to be loaded recursively as well + -Add: API: project util: clear view list + -Add: API: helper function to decide if any parent of an object is selected + -Add: API: object hash functions + -Add: API: group bit for preferring local lib + -Add: group ref child transformations (experimental) + -Change: use \001 instead of for dyntext rendering: should render as an empty box and it takes much less space and likely fits where the non-empty printout would + -Change: auto terminal placement creates a floater for display/pinnum instead of concrete model's name to let filter plugins decide what to print + -Del: lib_find API: always use cached lib + -Move: realpath resolved from symlib_fs to core lib - will be needed by any fs based library + -Move: fs lib mapping call from symlib_fs to core lib - will be used by any lib implementation + -Cleanup: rename library.[ch] to util_lib_fs.[ch] for naming consistency and code repurpose + -Cleanup: remove ->netname of abstract net, keep ->name only (consistent field naming) + -Cleanup: in the concrete model only groups have attributes, remove attr hash from chdr + -Cleanup: unreg actions on unload; related memory leaks + + [lib_alien] + -Split: move read_helper out from io_geda to a reusable lib (multiple io plugins are going to depend on it) + + [library] + -Fix: remove excess, zero sized box from the LDO sym + -Fix: common awk: do not move name2 (pin name) by str length, it's good in its left aligned state + -Fix: gnd symbol connects to net called GND not gnd, more widespread + -Add: common awk: generate pin number with display/pinnum + -Add: devmap for IRF510 in TO220 - perfect for example as the pinout differs from 2n7002 + -Add: switch() --help: make style a proper enum and explain each possible value + -Add: style=rotary support in switch() + -Add: default titlebox symbol + -Change: symbol lib terminal floaters: switch over from concrete model's pin name to display/pinnum + + [propedit] + -Fix: integer overflow on coord entry maximums + + [query] + -Add: concrete model query(), code based on pcb-rnd's quert() + + [sch-rnd] + -Fix: font rendering: font rotation was determined too early, before a potential text_update that would calculate hte final transformed rotation angle + -Fix: timed backup save uses the backup save i/o API so that the changed flag of the sheet is not lost + -Fix: don't redraw while exporting + -Fix: don't postproc sheet twice + -Fix: draw code sets layer group to 1 to comply with HID API requirements + -Fix: do not render sheet if set_layer returns 0 (respect the HID API) + -Fix: invalid memory handling on exit: reset current sheet and project to NULL after freeing them so that emergency save is not done + -Fix: overlapping strncpy() in librnd due to wrong handling of conf file name + -Fix: use librnd's pixmap free instead of a plain free() so all internal fields of the pixmap are free'd too + -Fix: do not call csch_init() twice, it leads to memory leaks + -Fix: don't postprocess the sheet twice after loading from command line + -Cleanup: rename default sheet file for naming consistency (with default project file) + -Cleanup: unregister central resources (events, actions) on exit; memory leak cleanup + -Add: advanced search menu (same as in pcb-rnd) + -Add: menu for listing locked objects using query() + -Add: menu for portmap quick attr + -Add: menu: devmap library browser in window menu + -Add: make multi-port net merge configurable from the conf system + -Add: default views read from the config when creating a dummy project + -Add: project file helpers: create new view, save project file; when creating a new project file, create the first overwrite subtree so it becomes a valid project file + -Add: API: project util function for deleting the nth view + -Add: API: buffer paste: generate event for hooking in and replace direct object dup + -Add: conf node editor/paste_to_local_lib to control whether paste should be using the local lib + + [sch_dialogs] + -Add: upgrade TreeDialog() to handle object arrays for pcb-rnd "view list" equivalent for now + -Add: view dialog + -Add: attr edit: fill in right side abstract attributes + -Add: abstract model browser + -Add: library dialog: optional modal version that returns the full path of the selected row + -Add: parametric lib dialog (using rnd_inclib's) + -Add: extend tree dialog to handle a whole project (multiple sheets) + -Fix: quick attr connect: always enable the 'del' button, because del can be done by text input as well; instead of disabling, when clicked: check if key exists, throw error if not + -Fix: attr dialog: if a new str attr is created, e.g. after {a a}, select the attr row for quicker floater button access + -Fix: attr dialog floater creation: use the wire pen for wirenet name attr with {a a} + -Fix: handle cancel on dyntext attribute picker + -Fix: tree dialog: refresh preview after select/unselect/del on object + -Cleanup: tree dialog: do not depend on ctx->sheet where object is available (switching over to project based operation) + -Cleanup: use frame instead of separator in attribute dialog common buttons now that the related expfill bug is fixed in librnd + + [std_cschem] + -Add: new plugin for handling standard cschem attribute mechanisms (such as component "connect" attrib) + -Move: quick attr edit for symbol connect attribute moved to std_cschem, because that's the plugin processing this attribute by default + + [std_devmap] + -Add: portmap engine + -Add: devmap engine using cached fs lib + + [std_tools] + -Add: copy/move all selected objects if there's selection + + [symlib_fs] + -Add: set the sym_prefer_loclib bit in newly loaded groups + -Add: test-parse files for group-type before adding them in the library (add symbols only) + + [symlib_local] + -Add: prepare for one more layer of groups in indirect so that different backends can easily sotre their data without interference + -Add: create a with-attributes and a no-attributes hash of the local lib while mapping + -Add: event handler for buffer paste symbols, decides if ref needs to be created + -Split: code that finds the local symlib into a reusable function (buffer place will need it as well) + -Add: sort out what to do on symbol paste, fetch local lib root when needed + -Add: look up the root dir and hash table for paste ref placement + + [target_none] + -Add: dummy target that displays original names + + [target_pcb] + -Add: target plugin for the PCB workflow; sets port display/pinnumber + + +0.8.0 alpha1 (r2889) +~~~~~~~~~~~~~~~~~~~~ + +Initial release. Index: tags/1.0.5/INSTALL =================================================================== --- tags/1.0.5/INSTALL (nonexistent) +++ tags/1.0.5/INSTALL (revision 10414) @@ -0,0 +1,81 @@ +0. dependencies + + - mandatory: C compiler + - mandatory: make (BSD make won't work) + - mandatory: librnd >= 4.1.0 + Get it at: http://www.repo.hu/projects/librnd + Standard: install librnd in /usr/local or /usr + Non-standard installation: doc/INSTALL.librnd.txt + +When configuring librnd: + - optional: glib and gtk2 if you are using the GTK GUI + - optional: gtkglext if you need opengl rendering with gtk2 + - optional: libepoxy if you need gtk4 + - optional: motif or lesstif if you are using the lesstif frontend + - optional: gdlib if you want to export/import to/from png, jpg or gif + +NOTE: if you did not install any GUI lib dependency before configuring librnd, +sch-rnd will run with command line interface only. + + +1. Configure + +Run ./configure. + +For compile-time options run ./configure --help. + +Read the summary table and the warnings at the end of ./configure output +and decide if you need the features missing. If there was no error, only +warnings, sch-rnd can be compiled, even if some dependencies were missing. +./configure will try to static link most plugins and disable ones that +have missing dependencies. This process can be controlled using configure +command line switches, see ./configure --help. + + +2. Compiling + +Run make. + +Optionally also run make test. + + +3. Running from source + +cd src/sch-rnd +./sch-rnd + +Note: it is important to cd to src/sch-rnd to run sch-rnd from source; +src/sch-rnd/sch-rnd won't work unless sch-rnd is installed. + +If this doesn't work, please refer to doc/INSTALL*. + + +4. Installation + +To install sch-rnd after it has been built run: + + make install + +from the top level directory. An alternative installation method +is the link-install, which places symlinks instead of copying files so +no subsequent make install is needed after a recompilation if no new +files appeared (useful for developers): + + make linstall + +Note: sch-rnd depends on librnd, which is dynamically linked. If you +install into non-standard path (e.g somewhere under /home or /opt), you need to +make sure your system dl will search for librnd.so in the nonstandard place. +Even in case of standard installation you may need to run ldconfig on some +systems to update the system cache of .so files. + +5. Packaging + +Some major distros already have sch-rnd packages. + +If you are planning to package sch-rnd, please read +doc/developer/packaging.txt and if it is binary packaging, please consider +following the package naming and layout documented in +doc/developer/packaging/packaging/packages.html - this way different +distros will have similar packages which will make both users' and developers' +life easier while supporting the software. Index: tags/1.0.5/Makefile =================================================================== --- tags/1.0.5/Makefile (nonexistent) +++ tags/1.0.5/Makefile (revision 10414) @@ -0,0 +1,46 @@ +all: + cd src && $(MAKE) all + cd util && $(MAKE) all + cd tests && $(MAKE) all && cd .. + +dep: + cd src && $(MAKE) dep + +clean: + cd src && $(MAKE) clean + cd src_3rd && $(MAKE) clean + cd util && $(MAKE) clean + cd tests && $(MAKE) clean && cd .. + +distclean: + cd src && $(MAKE) distclean + cd util && $(MAKE) distclean + cd scconfig && $(MAKE) distclean + cd tests && $(MAKE) distclean && cd .. + +install: + cd src && $(MAKE) install + cd doc && $(MAKE) install + cd library && $(MAKE) install + cd util && $(MAKE) install + cd src_3rd && $(MAKE) install + cd font && $(MAKE) install + +linstall: + cd src && $(MAKE) linstall + cd doc && $(MAKE) linstall + cd library && $(MAKE) linstall + cd util && $(MAKE) linstall + cd src_3rd && $(MAKE) linstall + cd font && $(MAKE) linstall + +uninstall: + cd src && $(MAKE) uninstall + cd doc && $(MAKE) uninstall + cd library && $(MAKE) uninstall + cd util && $(MAKE) uninstall + cd src_3rd && $(MAKE) uninstall + cd font && $(MAKE) uninstall + +test: + cd tests && $(MAKE) test && cd .. Index: tags/1.0.5/Makefile.conf.in =================================================================== --- tags/1.0.5/Makefile.conf.in (nonexistent) +++ tags/1.0.5/Makefile.conf.in (revision 10414) @@ -0,0 +1,49 @@ +put /tmpasm/OFS { } +put /local/csch/CFLAGS_GENERIC cc/cflags +append /local/csch/CFLAGS_GENERIC cc/fpic +append /local/csch/CFLAGS_GENERIC ?/local/csch/cflags_profile +put /local/csch/CFLAGS /local/csch/CFLAGS_GENERIC +uniq /local/csch/CFLAGS +uniq /local/csch/CFLAGS_GENERIC + +put /local/man5dir /local/man1dir +gsub /local/man5dir {1} {5} + +print [@# generated by ./configure, do not modify + +# Compatibility with autotools on DESTDIR - Debian really wants this +# Still keep install_root as well, because that has a better name +Install_root=$(install_root)$(DESTDIR) + +# prefix is @/local/prefix@ +DOCDIR=$(Install_root)@/local/prefix@/share/doc/sch-rnd +LIBDIR=$(Install_root)@/local/prefix@/lib/sch-rnd +LIBADIR=$(Install_root)@/local/prefix@/@/local/libarchdir@/sch-rnd +BINDIR=$(Install_root)@/local/prefix@/bin +DATADIR=$(Install_root)@/local/prefix@/share/sch-rnd +MAN1DIR=$(Install_root)@/local/prefix@@/local/man1dir@ +MAN5DIR=$(Install_root)@/local/prefix@@/local/man5dir@ +CONFDIR=$(Install_root)@/local/confdir@ +RM=@/host/fstools/rm@ +CP=@/host/fstools/cp@ +LN=@/host/fstools/ln@ +MKDIR=@/host/fstools/mkdir@ +SCCBOX=$(ROOT)/scconfig/sccbox +EXE=@/target/sys/ext_exe@ +SCH_RND_HOST_CC=@/host/cc/cc@ +SCH_RND_VER=@/local/version@ + +SCH_RND_CFLAGS=@?cc/argstd/std_c99@ @/local/csch/CFLAGS@ +SCH_RND_C89FLAGS=@/local/csch/c89flags@ @/local/csch/CFLAGS@ +SCH_RND_LDFLAGS=@/local/csch/LDFLAGS@ @?/local/rnd/LDFLAGS@ @?/local/csch/librnd_extra_ldf@ +LIB_RND_LDFLAGS_EXTRA=@?/local/csch/librnd_extra_ldf@ + +# The installation directory to be used from within binaries (with +# install_root/DESTDIR removed) +LIBDIR_INSTALLED=@/local/prefix@/@/local/libarchdir@/sch-rnd + +# Where librnd is installed, full path to the .mak file to auto-setup +LIBRND_PREFIX=@/local/csch/librnd_prefix@ +LIBRND_MAK=$(LIBRND_PREFIX)/share/librnd4/librnd.mak + +@] Index: tags/1.0.5/README =================================================================== --- tags/1.0.5/README (nonexistent) +++ tags/1.0.5/README (revision 10414) @@ -0,0 +1,24 @@ +sch-rnd is a modular schematics editor. + +It is hosted at http://www.repo.hu/projects/sch-rnd +Source code: svn://svn.repo.hu/sch-rnd/trunk + +** THERE IS NO GIT SUPPORT ** - do not make pull requests, don't +send git URLs. sch-rnd is hosted in svn on repo.hu and +the only one way to contribute is using the above repository. + +For installing the release refer to the file 'INSTALL'. +For additional information read the manual (doc/) + +If you are updating you may wish to read the Changelog + +Contact: + email: http://www.repo.hu/projects/sch-rnd/contact.html + chat & IRC: http://www.repo.hu/projects/sch-rnd/irc.html + + +sch-rnd source distribution is organized into: + doc/ documentation + scconfig/ ./configure implementation + src/ core lib, program and plugins + src_3rd/ third-party minilibs (dependencies, not integral parts) Index: tags/1.0.5/Release_notes =================================================================== --- tags/1.0.5/Release_notes (nonexistent) +++ tags/1.0.5/Release_notes (revision 10414) @@ -0,0 +1,20 @@ +Release notes for sch-rnd 1.0.5 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This release has a major new feature: hiearchic design. + +Most notable changes: + +1. support for hierarchic design + +2. export_tedax_footprint plugin: useful if the schematics should be included + on silk layer in pcb-rnd + +3. the advanced search dialog displays scope of the search (sheet, project), + lets the user change it andprovides a "follow" option so the same open + dialog follows sheet/project changes when multiple sheets/projects are + open + +4. minor improvements on displaying omitted components in the abstract model + +5. minor memleak cleanup Index: tags/1.0.5/config.h =================================================================== Index: tags/1.0.5/configure =================================================================== --- tags/1.0.5/configure (nonexistent) +++ tags/1.0.5/configure (revision 10414) @@ -0,0 +1,39 @@ +#!/bin/sh + +if test -z "$LIBRND_PREFIX" +then + for P in /usr/local /opt/librnd /usr $HOME/usr + do + if test -e "$P/include/librnd4/librnd/core/config.h" + then + LIBRND_PREFIX="$P" + break + fi + done +fi + + +case "$LIBRND_PREFIX" in + "") + echo " + +ERROR: Can not find librnd (required for sch-rnd). + +If librnd is not installed, please read INSTALL for details. + +If librnd is installed at a non-standard prefix, please read +doc/INSTALL.librnd.txt and set LIBRND_PREFIX accordingly +(e.g. export LIBRND_PREFIX=/home/foo/sw/librnd) before running ./configure + +" >&2 + exit 1 + ;; + /usr/include) ;; + /usr/local/include) ;; + *) LIBRND_EXTRA_INCLUDE="$LIBRND_PREFIX/include/librnd4" +esac + +cd scconfig +make "LIBRND_PREFIX=$LIBRND_PREFIX" LIBRND_EXTRA_INCLUDE="-I$LIBRND_EXTRA_INCLUDE" && \ +./configure prefix/libs/sul/librnd-3rd=$LIBRND_PREFIX "$@" + Property changes on: tags/1.0.5/configure ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/1.0.5/doc/Autostyle.html =================================================================== --- tags/1.0.5/doc/Autostyle.html (nonexistent) +++ tags/1.0.5/doc/Autostyle.html (revision 10414) @@ -0,0 +1,14 @@ + + + + + + + +
Main + Doc &  Knowledge pool  &  Tutorial + Current state + Events & timeline + sch-rnd [sch-rnd logo] +
+ Index: tags/1.0.5/doc/Autostyle.sh =================================================================== --- tags/1.0.5/doc/Autostyle.sh (nonexistent) +++ tags/1.0.5/doc/Autostyle.sh (revision 10414) @@ -0,0 +1,77 @@ +#!/bin/sh + +autostyle() +{ + awk -v "template=$1" -v "root=$ROOT" ' + BEGIN { + while((getline < template) > 0) { + if (parse_auto(RES, $0)) { + if (RES["action"] == "begin") + curr = RES["ID"] + else + reset_curr = 1 + } + if (curr != "") + AUTO[curr] = AUTO[curr] var_subs($0) "\n" + if (reset_curr) { + curr = "" + reset_curr = 0 + } + } + } + + function var_subs(s) + { + gsub("[$]ROOT[$]", root, s) + return s + } + + function parse_auto(RES, line ,tmp) + { + if (!(line ~ ".*", "", line) + line = tolower(line) + tmp = line + sub("[ \t].*$", "", tmp) + RES["ID"] = tmp + tmp = line + sub("^[^ \t]*[ \t]*", "", tmp) + RES["action"] = tmp + return 1 + } + + { + if (parse_auto(RES, $0)) { + if (RES["action"] == "begin") + skip = 1 + else if (RES["action"] == "end") { + printf("%s", AUTO[RES["ID"]]) + skip = 0 + } + next + } + } + + (!skip) { print $0 } + + ' +} + +for html in $* +do + case $html in + Autostyle.html) ;; + *) + mv $html $html.tmp + autostyle "Autostyle.html" < $html.tmp > $html + if test $? = 0 + then + rm $html.tmp + else + echo "Failed on $html, keeping the original version." + mv $html.tmp $html + fi + esac +done Property changes on: tags/1.0.5/doc/Autostyle.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/1.0.5/doc/INSTALL.librnd.txt =================================================================== --- tags/1.0.5/doc/INSTALL.librnd.txt (nonexistent) +++ tags/1.0.5/doc/INSTALL.librnd.txt (revision 10414) @@ -0,0 +1,99 @@ +Non-standard librnd installation +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +1. Standard librnd installation + + As per FHS, librnd should be installed to prefix /usr/local (when installed + from source) or /usr (when installed from package). If no prefix is specified + when configuring librnd, it will default to /usr/local. + + Another standard prefix is /opt/librnd, in case a per-package root is + preferred. + + When standard librnd installation is chosen, no librnd-specific arguments + need to be passed to sch-rnd ./configure, it will automatically find + librnd (with a preference for source install). + + On some systems ldconfig needs to be ran after the installation so that + the dynamic linker leanrs about the new .so files available. + +2. Installing librnd in a non-standard prefix + + If --prefix was specified at configure time pointing to a non-standard + path, sch-rnd configuration, compilation and execution need extra + preparation. + + Examples in this document assume librnd was configured with + --prefix=/foo/librnd + +2.1. Before sch-rnd ./configure + + Set librnd prefix so ./configure can find it: + + export LIBRND_PREFIX=/foo/librnd + + After that, from the same shell, run ./configure with the usual arguments. + +2.2. Before compiling sch-rnd + + Nothing special, make should work as usual. + + (LIBRND_PREFIX doesn't need to be set, ./configure ironed that in to + compile time config files.) + +2.3. Executing sch-rnd + + This includes: + - executing sch-rnd from source (must happen from within src/) + - executing sch-rnd after installation + - executing any utility, from source or installed (e.g. gsch2sch-rnd) + - running make test + - manually executing any test program + + Failing this step will lead to an error message generated by the dynamic + linker of the operating system, and will look similar to: + + error while loading shared libraries: librnd-hid.so.3: cannot open shared object file: No such file or directory + + Before execution, the operating system's dynamic linker needs to be + configured to look for dynamic libs (.so files) in the non-standard place + librnd is installed in. How this needs to be done may differ from system + to system. + + Please note: this is not specific to librnd or sch-rnd, this happens + with any dynamic linked lib that gets installed to a non-standard place. + If you already have a trick for those, that trick will work with librnd too. + + Here are some examples: + + - GNU/Linux; temporary solution (for a single execution) + + LD_LIBRARY_PATH=/foo/librnd/lib sch-rnd + + - GNU/Linux; temporary solution (for a given shell session) + + export LD_LIBRARY_PATH=/foo/librnd/lib + sch-rnd + + - OSX: same options as above, but use DYLD_LIBRARY_PATH instead of + LD_LIBRARY_PATH + + - GNU/Linux; permanent solution: + + Add /foo/librnd/lib to /etc/ld.so.conf or in a new file under + /etc/ld.so.conf.d/ if that directory exists. Run ldconfig as root to + get ld read your changes. + + +3. Other configure options that may matter + +3.1. ./configure --libarchdir + + The default value of librachdir is "lib", which means the lib dir is + $(PREFIX)/lib. On some systems, e.g. x86_64, it may need to be changed + to "lib64". + + The --libarchdir setting between librnd and sch-rnd must match: + - either not set + - or if set, it must be set explicitly to the same string in both librnd + and sch-rnd ./configure. Index: tags/1.0.5/doc/Makefile =================================================================== --- tags/1.0.5/doc/Makefile (nonexistent) +++ tags/1.0.5/doc/Makefile (revision 10414) @@ -0,0 +1,71 @@ +MENU_RES=../src/sch-rnd/menu-default.lht +ROOT=.. + +all: user/05_ui/keytree.svg user/05_ui/keytree.txt keys.html + ROOT="" ./Autostyle.sh *.html + ROOT="../" ./Autostyle.sh tutorial/index.html user/index.html +# ./datasheet.sh + +include ../Makefile.conf +include $(LIBRND_MAK) + +user/05_ui/keytree.svg: $(MENU_RES) $(KEYLIST) + $(KEYLIST) --dot user/05_ui/src/node_names.txt $(MENU_RES) > user/05_ui/keytree.dot + dot -Tsvg < user/05_ui/keytree.dot >user/05_ui/keytree.svg + +user/05_ui/keytree.txt: $(MENU_RES) $(KEYLIST) + $(KEYLIST) --lst $(MENU_RES) > user/05_ui/keytree.txt + + +keys.html: $(MENU_RES) $(KEYLIST) + $(KEYLIST) $(MENU_RES) > keys.html + +install_main: + $(SCCBOX) $(HOW) *.html *.txt TODO $(DOCDIR)/ + +install: + $(SCCBOX) mkdir -p "$(DOCDIR)" "$(DOCDIR)/resources" + cd design && $(MAKE) install + cd developer && $(MAKE) install + cd examples && $(MAKE) install + cd man && $(MAKE) install + cd resources && $(MAKE) install + cd tutorial && $(MAKE) install + cd user && $(MAKE) install + $(MAKE) install_main HOW="install -f -d" + +linstall: + cd design && $(MAKE) linstall + cd developer && $(MAKE) linstall + cd examples && $(MAKE) linstall + cd man && $(MAKE) linstall + cd resources && $(MAKE) linstall + cd tutorial && $(MAKE) linstall + cd user && $(MAKE) linstall + $(MAKE) install_main HOW="install -f -l -d" + +uninstall: + cd design && $(MAKE) uninstall + cd developer && $(MAKE) uninstall + cd examples && $(MAKE) uninstall + cd man && $(MAKE) uninstall + cd resources && $(MAKE) uninstall + cd tutorial && $(MAKE) uninstall + cd user && $(MAKE) uninstall + $(MAKE) install_main HOW="install -f -u -d" + +clean: + cd design && $(MAKE) clean + cd developer && $(MAKE) clean + cd examples && $(MAKE) clean + cd man && $(MAKE) clean + cd tutorial && $(MAKE) clean + cd user && $(MAKE) clean + +distclean: + cd design && $(MAKE) distclean + cd developer && $(MAKE) distclean + cd examples && $(MAKE) distclean + cd man && $(MAKE) distclean + cd tutorial && $(MAKE) distclean + cd user && $(MAKE) distclean Index: tags/1.0.5/doc/TODO =================================================================== --- tags/1.0.5/doc/TODO (nonexistent) +++ tags/1.0.5/doc/TODO (revision 10414) @@ -0,0 +1,122 @@ +0. old reports waiting for ACK ============================================= + +1. Upcoming release ==================================================== + +2. Later releases ========================================================== +- BUG: bug_files/TODO/unl; sch-rnd project.lht; file/project/new unlisted; save sheet -> it's using the wrong path [report: aron] +- BUG: message log text type "Hirearchic: sheet named 'power_interface_v1.rs' not found in the project, searching the hlibrary..." needs to be spelt "Hierarchic:" [report: erich] +- BUG: ssh -X user@localhost, then start sch-rnd with bug_files/TODO/diode.rs. Use rotate tool repeatedly on D1 refdes. segfault ensues. Backtrace in diode-segfault.txt [report: erich] +- TEST+DOC: + - can load a project file TODO: pool node + -> export project from GUI + -> -x with multiple sheet names + -> -x with project.lht +- librnd 4.3: look for TODO("librnd4.3:...") +- librnd4.1 API upgrade: + - lib_plot/plot_preview.c: LIBRND41 TODOs: e->coord_per_pix is available + -> see bug_files/TODO/sim.patch +- FEATURE: font2: + - check calls to rnd_font_fix_v1(); don't call it if ->height is loaded; maybe not needed at all with font2, multiline is handled in librnd + - baseline: probably a bad idea, skip it (incompatible with multiline and bbox placement, adds a random offset for term lables) +- FEATURE: BoM template language: concat'd lists: + - use case: v1.1 should have color and tolerance in the value + - allow creating new attributes (or rather macros) using the same template + - create one with: %escape.sym.a.color|% %escape.sym.a.value|% %escape.sym.a.tolerance|% + - print it as %escape.macro|(unknown)% for the value column +- FEATURE: symbol meta layer drawing: draw lines from floaters back to their parent? +- FEATURE: io_geda: multiple net= attributes (e.g. in stock 7400) -> should be an array +- FEATURE: DRC (requires query() on the abstract model): + - noslot or rather uniq attribute (e.g. for resistors) + - figure if fully overlapping ports (or symbols) can be or should be detected (see: two gnd symbols on top of eachother) [report: Erich] + - it is easy to accidentally add a footprint to a terminal on a symbol instead of the symbol itself. This is not flagged on netlist export. Should it be harder to do this, or maybe a netlist exporter could indicate if footprints associated with terminals in symbols were not included in the export? [report: Erich] + - accidentally adding a name to a rail exports a connection in the netlist with no associated component. Perhaps this would benefit from some sort of DRC check, like the "footprint attribute put on non-symbol" issue above. [report: Erich] + - component pcb pinnum: check if pins are numbered from 1 (or 0) without discontinuities; could catch typos in footprint creation (example: Aron's orange pi zero usb pins on edakrill) [report: aron] + - move drc/require_graphical_conn check from compiler to DRC, see TODO#rgc + - DRC dialog in sch_dialogs + - DRC menu and hotkey +- BUG: csch_grp_ref_embed(), used in sym loclib paste and right click symbol context menu toref (to loclib) conversion is not undoable [report: Igor2] +- FEATURE: librnd svg export upgrade (enum: color, grayscale, b&w): allow svg schematic export with option of monochrome [report: Erich] + - apply bug_files/TODO/SVG.patch (requires librnd 4.2) +- needs librnd 5.0.0 API upgrade: + - library window "Use selected" should have a tooltip on what exactly it does (for devmap: returns name only, does not update loclib); API: close buttons can't have tooltips [report: aron] +- file format version bump cschem-sheet-v2: + - FEATURE: implement attribute symlinks (see design doc) + - CLEANUP: attrib code decides if an attrib is a string or array by looking at string value != NULL + - replace this with a type enum that has str, symlink and array + - put string value and array into an union + - the file format needs to save an extra bit if it's a symlink + - create hierarchic examples (parameter passdown is already implemented: cschem/param/ in the sheet ref symbol) + - BUG: altium had a =Device or =Footprint attribute somewhere, that should be a symlink [report: aron] + - a connection object should have x;y displacement for the graphical object to be useful (or is it a grp_ref?); at the moment we are not drawing it at all + - text flag for &entity; + - implement new text flag/attr for &entity; (similar to dyntext) + +3. NLnet ========================================================== +- extensions: + - attrib symlinks (see above for file format v2) + - multiline font: switch over to librnd multiline/alignment rendering + - implement the halign property (watch out for x mirror: start is always toward the origin) + - {e T} for multiline edit of single line text; {e t} should also do this if text has \n's + - propedit should get a button for invoking the same {e T} popup + - maybe cache whether text is multiline in an unsaved struct field + - FEATURE: text vertical alignment (add in design doc and code); same rules as in halign [report: Ade] + - easyeda: + - sch + - pcb + - see work/alien/easyeda/testread: + - names are from sphash so strcmp can be avoided during dom parse + - easyeda_low parses the strings after it uses the generic json bridge + - bxl symbols + - devmap is probably impossible as slotted symbols are just drawn multiple times, once per slot + - needs API for multiple symbols from a single file (see pcb-rnd bxl footprint load) + - eagle xml schematics + - eagle xml libraries (lbr) + - high level sim: + - sim-to-spice compilation: + - autodetect net type from pin types + - auto-bridge as needed for mixed mode digital+analog + - DOC: port type attributes (e.g. analog, ttl), also consider DRC, check coraleda std 2 + - lib_sim: elect network type (default is analog) + - API? set port attributes for bridges where needed + - BUG: stance is set temporarily using sch_sim_set_test_bench() for the compilation only but csch_stance_set() prints the permanent setting + - BUG: womit_no_test_bench is not really implemented, see TODO#womit + +4. Low prio ========================================================== +- FEATURE: check feasability: use non-graphical fawk sheet as calculator + - e.g. voltage divider of R1 and R2 with input and output voltages specified, fawk calculates value for R1 and R2 + - how to query attributes of existing things? + - how to guarantee the data sheet is compiled after the graphical sheets? + -> probably better to have this in a "target script" +- BUG: enable multiport_net_merge, then bug_files/multiconn0.rs; move TP2 1k or 2k to the left; more than one connection is created because the vertical ports are overlapping and when the horizontal port is connected, but it figures connections only one by one so it doesn't dare to extend existing connections [report: Igor2] +- BUG: {e t} over a non-dyntext, resize window larger: entry remains small [report: aron] +- FEATURE: view window: open once, single perview widget, copy current zoom+pan, close when parent sheet closed; consider the same for pcb-rnd and camv-rnd [report: Vuokko] +- FEATURE: consider dangling wire end indication (see pool node) +- FEATURE: support for protel format? (.asc, differerent syntax and data model from io_altium) [report: Scott] +- FEATURE: tooltip on toolbar icons should also show the hotkey (librnd?) [report: rudolfii] +- TODO#38: rethink grp-ref-in-grp-ref with child xforms, maybe cache=1 is a bad idea + - problem: ref1 -> ref2 -> grp -> text; ref2 is floater; if whole ref2 is rotated, we won't update anything in ref1's central xform list +- BUG: wirenet in group should work: load symnet.rs. select terminal and adjacent vertical line using negative selection box; convert selection to symbol. connect test point 1 to wire net. export netlist. do not assume wirenet is directly under the &direct in the tree [report: Erich] +- BUG: back annotation: abstract model: abstract model UUIDs are not implemented, annotation doesn't use them; either figure persistent uuids or use CMRs [report: Igor2] +- BUG: rewrite get_prjname() in dytext render + - figure the path of the project file + - project name change runtime (save-as); inalidate text objects (->rtext = NULL using csch_text_dyntext_inval()) to re-render the new name +- OPTIMIZE: do not re-create views multiple times in sch_rnd_prj_conf2prj(): start 'sch-rnd A.rs B.rs' from the same dir [report: Igor2] +- CLEANUP: code dups with pcb-rnd, consider moving some code to src_3rd/rnd_inclib: + - query + - propedit + - undodialog + - rename csch_ symbols to sch_rnd_ in plugins/ + - act_read +- librnd4.0.0: + - remove the whole project loading plug io: project files will be handled by librnd + - once multi is moved over: + - extend oidpath to generate and accept sheet prefix with $uuid/ + - act_draw should be able to use it as scope + - act_draw should be able to return oidpath with $uuid/ + - query() should be able to return/convert lists like that for scripting + +6. TODO() tags ========================================================== + - bitmap: needed for bitmap objects + - fungw: may need fungw API change + - multi: multiple sheet support + - hierarchic: needed for hierarchic projects Index: tags/1.0.5/doc/TODO.roadmap =================================================================== --- tags/1.0.5/doc/TODO.roadmap (nonexistent) +++ tags/1.0.5/doc/TODO.roadmap (revision 10414) @@ -0,0 +1,49 @@ +Long term roadmap (circa 2020) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +0. immediate/inconvenience + +1. single page schematics -> PCB flow + + attribute editor + + draw decoration + + draw nets + + save in lht + + autocompile + + draw symbols + + symbol editor mode + + draw pin + + floaters + + devmap editing? + +2. better lib handling + + lib window + - symbol "version" checks, update symbol + + save symbol from sheet to disk (through buffer) + +3. flat multi-page schematics -> PCB flow + + tabs + + load project file with multiple pages + + tab switch (decide what to do with the global var) + + compile multiple sheets + + save by project + + GUI to create new page (and manage project in general) + +4. hierarchical multi-page schematics -> PCB flow + + symbol->sheet references + + descend into symbol + + compilation + + hierarhical terminals up + + hierarhical terminals down + +5. hubs & buses + - hubs + - buses + +6. simulation target + + raw spice + + higher level abstraction + + GUI support + +7. extras + + non-graphical sheets + + back annotation Index: tags/1.0.5/doc/contact.html =================================================================== --- tags/1.0.5/doc/contact.html (nonexistent) +++ tags/1.0.5/doc/contact.html (revision 10414) @@ -0,0 +1,56 @@ + + + + + sch-rnd - contact + + + + + + + + + +
Main + Doc &  Knowledge pool  &  Tutorial + Current state + Events & timeline + sch-rnd [sch-rnd logo] +
+ + +

sch-rnd - contact

+ +

Contact the project

+

+Please subscribe to the pcb-rnd mailing list by sending "subscribe" to +pcb-rnd list.repo.hu (does not work with gmail) +or join IRC for + live chat (CET daytime) with other users +and developers. (This project is supported on the pcb-rnd mailing list/irc channel.) + +

Contact the lead developer

+

+Join IRC for live chat (CET daytime) and +look for Igor2. +

+Via email: schrnd igor2.repo.hu (does not work with gmail). + + +
+

+PRIVACY NOTICE: +

+This email address is provided only for personal use, exclusively for +topics directly related to the sch-rnd project. +

+Do NOT copy this email address to +software packages, documentation, etc. Permission is NOT granted +for collecting this email address in any list of email addresses. +Since this email address is a personal address, the + +GDPR applies while you are handling it. +

+ + Index: tags/1.0.5/doc/contrib.html =================================================================== --- tags/1.0.5/doc/contrib.html (nonexistent) +++ tags/1.0.5/doc/contrib.html (revision 10414) @@ -0,0 +1,70 @@ + + + + + sch-rnd - contribution + + + + + + + + + +
Main + Doc &  Knowledge pool  &  Tutorial + Current state + Events & timeline + sch-rnd [sch-rnd logo] +
+ + +

sch-rnd - contribution

+ +If you are interested to help out, please +contact the lead developer. + + +

Contributing as a user

+Using sch-rnd in production and just reporting bugs is already a huge contribution. +

+We also have a list of tasks that can be contributed by users. +

+More dedicated users can join in scheduled, systematic testing. Such testing +is split up into independent chunks that each can be done in an hour. +

+Even more dedicated users can join developing the documentation. +

+None of the above requires or assumes any programming skill. + +

Contributing as a developer

+

+The project is lead in an autocratic way by Igor2. +

+Developer freedom taken away: +

    +
  • the basic concept of sch-rnd is set and won't change +
  • the toolchain is chosen, and won't change; the usual hot topics: svn, scconfig, C. +
  • don't add code that restricts usability for others; add code that increases usability for some; thus prefer to add code in plugins! +
+

+Developer freedom promptly granted: +

    +
  • svn commit access from day 0 +
  • work together in trunk/, not alone in a branch +
  • sch-rnd has a strong plugin support; want to implement a strange/controversial feature? In a plugin, almost anything goes +
  • especially in plugins, work on whatever you want, even if noone else needs that feature +
+

+Coding style/indentation: there's an unified style +in core and core plugins. If you work on those parts, try to stick to it. If you +are working on a new plugin, it's still the preferred style but you can use +a different style. However, the rule is that if someone else starts hacking +that part too, he is allowed to convert the code to the unified format; but +unified format can not be converted to anything else. So it's a one way +process which long term grants unified style while not demotivates a plugin +developer by forcing a style on him in the early, "when the bulk of the code +is written" phase. + + Index: tags/1.0.5/doc/design/01_comp.svg =================================================================== --- tags/1.0.5/doc/design/01_comp.svg (nonexistent) +++ tags/1.0.5/doc/design/01_comp.svg (revision 10414) @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + cschem + + Engine + + Frontend + + plugins + + 3rd party software packages + + project repository + + libraries + + symbol + + plugin-specificdata + + schematicssnippet + + data model + + othersoftware + + generatortool + + PCBeditor + + dataeditor + + symbol editorsymbol generator + + userformat + + Circuitsimulator + + schematicseditor + + generatortool + + formatconverter + + I/O module + + devicemapper + + slottingmechanism + + userscript 1 + + userscript 2 + + libraryaccess + + formatconverter + + formatconverter + + DRC + + plugin-specificdata + + schematicssheet + + data sourcee.g. text + + data sourcee.g. text + + data output + + convertertool + + locallib + + projectfile + + fileor API + + fileor API + + file + + e.g. fileAPI, net + + e.g. file + + fileor API + + file + + file + + API + + API + + e.g. file + + API + + API + + + e.g. file + + + fileor API + + Index: tags/1.0.5/doc/design/01_system.html =================================================================== --- tags/1.0.5/doc/design/01_system.html (nonexistent) +++ tags/1.0.5/doc/design/01_system.html (revision 10414) @@ -0,0 +1,160 @@ + + +

1. The system

+ +

1.1. What is cschem

+ +

{des1:0} +The purpose of this chapter is to define what cschem is, what major components +it contains and how these components are interacting with the user and 3rd +party software. This chapter provides a low resolution system map. + +

1.1.1. Cschem as a concept

+ +

{des1:1} +Cschem is a system for storing, displaying, editing, transforming +(importing, exporting, filtering, generating, etc.) schematics data. + +

{des1:2} +Schematics data is the logical schematics of a system, describing a +system on an abstract level, optionally with directives, hints, suggestions +or recommendations on the physical implementations/properties. + +

{des1:3} +More specifically, cschem operates on projects. A project is either +a single schematics page or cosists of a project file and multiple +schematic pages and/or data files. + +

{des1:4} +A typical example is an electric schematics. While cschem +is not limited to electronics, this design document will use electronics +in most of the examples. + +

{des1:5} +Example: when used with electronics, cschem's role is to handle the schematics +drawing, which specifies the components and their logical connections. +The schematics is typically the main source for other processes, such as +simulation, PCB layout, part purchase, etc. + +

{des1:6} This flexibility is achieved by +attaching attributes to every object type in the data model. +Attributes are simple, typically user defined key=value fields. Various +tools in the toolchain may read and write different set of attributes. +The meaning of most attributes is defined only by conventions. More +about attributes can be found in chapter 4. + + +

1.1.2. Cschem as a software package: sch-rnd

+ +

{des1:7} +When the above concepts are implemented as a software package, called +"a cschem implementation" or "a cschem package". The official implementation +of the cschem concept is sch-rnd. Alternative implementations of the same +concepts may exist. These implementations must be compatible on the +conceptual level but might be incompatible in implementation details +(including file formats). + +

{des1:8} +The official implementation is a small, flexible, portable, modular, +extensible set of tools. This chapter describes some of the implementation +details of the official package. These implementation details should not affect other +implementations. + + +

1.2. Components and modules

+

1.2.1. Main components

+ +

+ +

{des1:9} +sch-rnd consists of two major components: frontend and engine. +Both components are defined as a group of smaller modules. + +

{des1:22} +(Note: the above diagram does not contain every single subcomponent and +plugin, it rather illustrates the main groups. Later chapters will enumerate +subcomponents and describe them in detail.) + +

The job of the engine is to: +

    +
  • {des1:10} run the data model: store, retrieve, execute simple operations on it +
  • {des1:11} run an infrastructure for plugins to access the data model in a controlled way +
  • {des1:12} load, unload, select and run the actual plugins for the given project +
+ +

The job of the frontend is to: +

    +
  • {des1:13} provide user interfaces to let the user interactively manipulate project data +
  • {des1:14} provide user interfaces to let the user manipulate project data in batch mode (automated and semi-automated processing) +
+ +

1.2.2. Engine modules

+ +

{des1:15} +Majority of the functionality the engine provides is implemented in modules, +which are replaceable plugins. There are typical ways a module behaves: + +

+ +

{des1:20} +The current project loaded will determine which modules should be active. +For example there might be multiple implementations of DRC or slotting; each +implementation would have an unique name and API version; the project would +contain requirements and recommendations as of what modules are needed for +proper operation, including which slotting plugin (if any). This is +called the project's module dependency list. + +

{des1:21} +A project can have multiple different module dependency lists (views). For example +a different slotting mechanism can be used when data is sent to the simulator and +when it is sent to the pcb layout tool. The frontend should let the user to +specify or select which module dependency list should be used. On an interactive +UI it shall be easy to switch between the dependency lists. + +

{des1:25} +How the frontend presents (displays, edits, navigates) the schematics data +usually depends on the view selected. (Some details that direct the +frontend in the presentation may be plugin-calculated.) + +

{des1:26} +A view contains an ordered list of engines and optionally attributes +for each engine, that configures the engine for the view in an engine-specific +way. The same engine may be present on the list multiple times (with or +without different attributes). + +

{des1:22} +The user can extend cschem by loading user script into the Engine. User +scripts can serve in any role listed above. + +

{des1:23} +The project may include arbitrary, plugin-specific data that will be used by +a plugin the project depends on (e.g. by an user script; it is the user's +responsibility to make sure the formatting of the data matches the +expectation of the plugin and the plugin is loaded). + +

{des1:24} +Another source of data is libraries. There are plugins that access local +or remote libraries for data that then can be copied into project repositories +or can be referenced from project repositories. Index: tags/1.0.5/doc/design/01_system_imp.html =================================================================== --- tags/1.0.5/doc/design/01_system_imp.html (nonexistent) +++ tags/1.0.5/doc/design/01_system_imp.html (revision 10414) @@ -0,0 +1,73 @@ + + +

cschem implementation - 1. The system

+ +Implementation detail notes for chapter 1. Please also refer to +the manifesto. This document +affects only how the official cschem implementation (sch-rnd) is done, not how +other implementations of the cschem concept should be done. + +

{imp1:1} +The engine is to be implemented as a plain C89 lib with an optional, low +level CLI frontend tool. + +

{imp1:2} +Dependencies of the engine should be limited to libs reasonably small +(e.g. no glib). + +

{imp1:3} +The engine needs to provide an API for user scripting; this API +will be fungw. + +

{imp1:4} +The engine must implement all the essential plugins in C89. These are +called the core plugins. Scripting is for users; the official core +must not depend on any particular scripting language. Rationale: this +helps lowering the compilation/installation barriers by avoiding largish +external dependencies. This also means it is possible to create a sch-rnd +project that can be loaded by any other sch-rnd user - the only +requirement is that such a project may depend only on core plugins. + +

{imp1:5} +The frontend, especially GUI editors will be implemented in a similar +modular approach. Plugins and user scripting included. Just like pcb-rnd, +the GUI editor shall have an API so that the actual GUI implementation +is provided by a replaceable plugin. The reason the design document is not +verbose about this is that the design document needs to concentrate on +the concept, not on the actual implementation. Modularity of the engine +is very important for the concept to work properly, while similar +implementation details on the UI side won't affect the concept too much. + +

{imp1:6} +The design document calls the central building block engine. +Speaking in geda terms, this component is similar to both gnetlist and to +libgeda. I wanted to avoid calling it lib because it will also provide a +CLI. I wanted to avoid calling it netlist because I believe netlist is +only a subset of transport formats/concepts it needs to do between the +components. + +

{imp1:7} +The usual "technology" section. For developing the official implementation +of sch-rnd I will use the technology already proven useful in pcb-rnd: +

    +
  • C89 +
  • svn +
  • scconfig and "plain old make" +
  • fungw for scripting (it's a gpmi descendant minilib) +
  • puplug for plugin system (it's a gpmi descendant minilib) +
+ +

{imp1:8} +Ripple annotation: as the arrows on the data flow drawing shows, +I imagine there would be a lot more flows in a lot more directions. I would +like to make these flows natural, not making difference between "forward" and +"backward" annotation. This also means the role of the schematics within a +project needs to be reconsidered: it's not always the Final Source of All Data. +Sometimes parts of the schematics is generated. Sometimes the schematics is +the slave, the output to connector pin swapping happening during PCB layout +or parameter tuning happening in simulation and the source of data is somewhere +else. In a typical use case in the first phase of the project most data would +obviously flow from schematics to somewhere-else. But in later phases of the +project this bias could change. The only important thing is that by the end +of the process, all data (schematics, simulation, pcb, etc.) must be consistent. + Index: tags/1.0.5/doc/design/02_abstract.svg =================================================================== --- tags/1.0.5/doc/design/02_abstract.svg (nonexistent) +++ tags/1.0.5/doc/design/02_abstract.svg (revision 10414) @@ -0,0 +1,108 @@ + + + + + + +objects + + +project + +project-view + + +bus + +bus +(bundled +nets) + + +project->bus + + + + +hub + +hub + + +project->hub + + + + +component + +component + + +project->component + + + + +network + +network + + +project->network + + + + +bus_port + +bus-port +(bundled +ports) + + +chan2 +channel + + +bus_port->chan2 + + + +chan1 +channel + + +bus->chan1 + + + +chan1->network + + + + +port + +port + + +chan2->port + + + + +component->bus_port + + + + +component->port + + + + + Index: tags/1.0.5/doc/design/02_data.html =================================================================== --- tags/1.0.5/doc/design/02_data.html (nonexistent) +++ tags/1.0.5/doc/design/02_data.html (revision 10414) @@ -0,0 +1,600 @@ + + +

2. schematics data

+ +

{des2:0} +This chapter is an overview of the data model cschem uses. Some details, e.g. +attributes, drawing primitives or +hierarchic design will be discussed in later +chapters. + +

2.1. Projects

+ +

{des2:1} +A project is a collection of schematics sheets, data files, configuration, +pcb-files, local libraries, logs, etc. What content belongs to a project +shall be decided by the user. + +

{des2:2} +The tool-agnostic project file describes the project by having tool-specific +sections. + +

{des2:3} +The cschem-specific section of the project file consists of a list of files +that are relevant to cschem: +

    +
  • view configuration +
  • plugin configuration, per view +
  • local lib configuration +
  • references to the schematic sheet(s) +
  • per-tool configuration, e.g. GUI-related settings for the graphical + schematics editor (optionally per view) +
+ +

{des2:4} +A schematics sheet consists of concrete elements (e.g. drawing +primitives, attributes, data) that indirectly describe abstract schematics objects. +The user is able to manipulate the concrete elements only, but can also +see the abstract objects. Much of cschem deals with the abstract +objects. + +

{des2:5} +Each schematics sheet has a cschem generated unique ID and user specified +attributes. Both the unique ID and attributes of the graphical sheet +are stored in the direct subtree of +the sheet. + +

{des2:68} +The following diagram shows how concrete graphical schematics sheet +elements can affect objects in the abstract model: + +

+ +

{des2:69} Note 1: concrete object attributes can affect the abstract model +by making connections and creating new networks. + +

{des2:73} Note 2: a connection drawing primitive contributes to the +"list of terminals" of wire-nets and bus-nets. + +

{des2:74} Note 3: groups also donate the attributes on their outgoing arrow; +these then become the attribute of concrete objects and as a side effect +(blue lines) may affect networks. + + + +

2.2. Abstract: schematics objects

+ +

{des2:6} +On an abstract logical level, a schematic consist of components +that have ports, and named networks that connect those +ports. Networks can be bundled into buses and buses +can be connected to bus-ports. Networks can be split and +connected by hubs. + +

{des2:7} +In an electronic example a component is a NAND gate, a +port is a pin or pad or terminal of the gate and network is +the electrical connection between the port of the gate and other +ports in the circuit. + +

{des2:56} +Each view has its own abstract +object model, generated by different set of plugins with different +configuration from the same concrete model. Since views are +independent, the per view abstract models are independent too. +The abstract models are generated on the fly and are not saved. + +

{des2:75} +An abstract schematics object always contains a list of concrete-object +(or concrete-object:key) +pairs referring to any concrete object (or an attribute of a concrete +object in the latter case) that contributed to the abstract object. This +cross-reference lets the user track back the sources of an abstract object, +which is important because the final output (e.g. netlist) is generated +from the abstract objects while the user can make changes to the +concrete objects only. + + +

2.3. Concrete: graphical schematics sheets

+ +

{des2:8} +A graphical schematics sheet is a two dimensional drawing, consisting of: +

    +
  • symbols - explicit (graphical) +
  • network connections - explicit (graphical) and implicit (attribute) +
  • decoration +
+ +

{des2:9} +Symbols and networks connections are objects that contribute to the +abstract, logical meaning of the sheet (components and networks). A +decoration is a graphical element that is displayed and edited and +exported on graphical output formats, but does not contribute to the +logical meaning on a computer-readable level. + +

{des2:12} +On graphical schematic sheets, many non-decoration objects are realized +using graphical drawing primitives: +

    +
  • in-sheet networks can be specified by drawing lines/arcs/etc. that form a wire-net +
  • hubs splitting and connecting different networks +
  • in-sheet bundled networks, by drawing lines/arcs/etc. that form a bus-net +
  • inter-sheet networks or buses, by drawing ports or bus-ports +
  • components, by placing the graphical representation of symbols +
  • in-sheet network connection to an in-sheet component by connecting a wire-net to a port of the symbol +
+ +

2.3.1. graphical representation of wires

+ +

{des2:13} +A wire-net is a group of drawing +primitives (e.g lines). In this chapter these drawing primitives are called wire-segments. The +group is tagged to be a wire-net by its role attribute. The graphical +representation of a wire-net does not need to be a straight line, but +can be a graph that even includes cycles. In other words, a wire-net can +be drawn as many lines with junctions and loops. + +

{des2:81} +A junction is graphics within a wire-net that represents connected crossings +of wires between wire objects of the same wire-nt. The simplest junction is +a zero-length line drawn with a pen thicker than wires. Any other junction +graphic is drawn packing atoms in a group or group_ref with role=junction +within the wirenet. + +

{des2:14} +A wire-net can be connected to zero or more ports or bus-ports. A +wire-net can not leave the current sheet - there are no inter-sheet wire-segments. + +

{des2:15} +A wire-net always represents (a part of) a network. In the simplest case a wire-net +is a network. In more complex cases multiple wire-nets (potentially on multiple +schematics sheets) and/or non-graphical data (e.g. connection dictated by +attributes or non-graphical schematics data) build a single network. + + +

{des2:16} +A wire-segment has no attributes of its own, only a wire-net has. The attributes +of a wire-net contributes to the attributes of the network it is part of. (The +details of this will be discussed in a later chapter; TODO: link). Therefore +there are always two things to consider, present or edit: +

    +
  • the attributes of a given wire-net (the concrete model's attributes) +
  • the cumulative attributes of the network the given wire-net is part of (the abstract model's attributes) +
+ +

{des2:17} +The set of possible attributes of a wire-net is the same as the attributes of a network +(see below). + +

2.3.2. graphical representation of hubs

+ +

{des2:57} +A hub-point is a concrete object (sometimes graphically represented as a +largish dot or polygon). One or more different wire-nets can be connected to a +hub-point; these wire-nets will be kept as separate networks, the +hub-point won't merge them. + +

{des2:58} +A hub-point also has attributes. + +

{des2:59} +The concrete hub-point is translated into an abstract hub for the abstract +model. + +

{des2:60} +Hub-points can connect bus-nets too. + +

{des2:61} +A hub-point differs from a normal wire-net branching in that: +

+ +

2.3.3. graphical representation of components and ports

+ +

{des2:18} +The graphical representation of (a part of) a component is called symbol. + +

{des2:19} +A symbol is a group or group_ref with symbol-related +attributes. It typically contains furhter groups for terminals, +bus-terminals, other symbols and decoration. When a symbol is placed on +a schematic sheet (either by copy or by reference), it is +instantiated. A symbol has a creation-time cschem generated +unique ID (which is the uuid field of the symbol group). + +

{des2:82} +Groups also have an src_uuid field, which is used to track original sources. +A newly created group has NIL (empty) src_uuid. Any copy of the group +(e.g. an instance of the a library symbol on a sheet) will have src_uuid +filled in with the src_uuid value of the source group, or if that was NIL, +with the "instance uuid" (the group's uuid field) of the source group. + +

{des2:53} +When an existing instance is moved within the sheet, renamed, its +attributes changed, it retrains instance UID (uuid field). When the instance is +copied, the new copy is a new instantiaton and gets a new instance UID. In +both cases it retains its src_uuid field. + +

{des2:20} +A symbol is usually part of a component, donating ports and attributes to +the abstract (logical) component. The simplest component is created by a single +symbol. More complex components are created by a combination of multiple +symbols placed on graphical schematics sheets (and potentially be generated by +non-graphical schematics sheets). Attribute collisions are resolved +the standard way. + +

{des2:21} +Among the attributes of symbols instance is one called name, which is +the project-unique identifier of the component the symbol instance contributes +to. The refdes can be calculated from this name, +see also: hierarchy. + +

{des2:22} +A symbol can be marked being decoration, in which case it does not contribute +to any component. + +

{des2:23} +A symbol can be used to describe a connection between different schematics +sheets, to represent (and reference to) a whole schematics sheet in a +hierarchy, +to represent a data file or other resource meaningful to specific plugins +(TODO: THIS CHAPTER). + + +

{des2:24} +The graphical representation of an abstract port is called terminal. A +(concrete) terminal is modelled as a line. A terminal hosts a list of attributes. + +

{des2:25} +Similar to port, the bus-port's representation is called bus-terminal, +it is also modeled as a line and hosts a list of attributes. + + +

{des2:76} +Terminals and bus-terminals are most often part of symbols, but for +hierarchical designs they are also placed directly on sheets to serve as +an interface to the parent. + +

2.4. Concrete: data/programmed schematics sheets

+ +

{des2:26} A data/programmed schematics sheet is a non-graphical sheet. +The purpose of the data/programmed schematics sheet is the same as +the purpose of a graphical schematics sheet: to donate concrete source objects +for the abstract objects. + +

{des2:71} The data/programmed schematics sheet contains data in a +format understood by one of the plugins in the current view. That plugin +is a "compiler" that interprets sheet data and emits abstract objects for +cschem to use. The compilation process can be as simple as parsing the +data or as complex as interpreting a high level programming language to +generate the abstract objects. Cschem doesn't impose any restriction on +the data format. + +

{des2:72} For the GUI a data/programmed schematics sheet is usually +opaque data which can not be displayed or edited. Most often the data is +edited by external applications. Alternatively the plugin handling the +format may provide custom GUI. + +

2.5. Abstract: details of schematics objects

+ +

{des2:27} The abstract schematics consists only of a few object types. Their +parent-children relations are illustrated by the tree below: +

+ +

{des2:28} +The attributes of a symbol, terminal and bus-terminal are the same as the +attributes of a component, port or bus-port, respectively (see below). + +

2.5.1. components and ports

+ +

{des2:29} +A component is a project-global object that has: +

    +
  • an unique ID (cschem generated) +
  • a list of attributes +
  • zero or more ports +
  • zero or more bus-ports +
+ +

{des2:30} +A port is a point of connect owned by a component. A port can connect a +component to a network. + +

{des2:31} +A port is a component-local object that is created by a graphical symbol +(from a graphical sheet) or from data/program (from a data sheet). + +

{des2:32} +A port has: +

    +
  • a cschem generated unique ID +
  • a list of attributes +
  • on that list, an attribute called name which is an unique ID of the port within the component +
+ +

{des2:33} +If there are multiple terminals with the same name within the same +component (within one or multiple symbols; specified graphically or via +data), they are combined into a single port with their attributes also +combined, with the usual +attribute collision rules. + +

{des2:77} +The terminal->port name translation can be done by plugins; when +available, core will call plugins for this job. This allows slotting +implemented in plugins: the same terminal name in different slots may +mean different ports within the same component. + +

{des2:34} +A bus-port is a port with multiple "parallel" channels, each channel +modelled as a separate port, called channel-port. A channel-port has a +chan attribute that specifies which network the given chan +will try to connect to when a bus-net or wire-net is connected to the +bus-port. + +

{des2:35} + +Note: details on addressing networks by name is in a later chapter + +

{des2:55} +Abstract network name attributes are donated directly by the +concrete wire-nets contributing name attributes. (In case of +hierarchy the name might be +translated/calculated by a plugin). + +

+
{des2:36} core attributes of a component +
attribute value description +
uuid unique ID cschem-generated UID (not persistent) +
connect PORT:NET list non-graphical connection; PORT is an existing port's name within the component; NET is the name of a network +
source list of refs reference list to the concrete objects that contributed to this component; when saved: each item is an UID or an UID:key pair +
+ +

+
{des2:37} core attributes of a port +
attribute value description +
uuid unique ID cschem-generated UID +
name name of the port user assigned port name +
connect name of a network the given port is also connected to a network (non-graphical connection) +
chan channel name connection affinity, in case port is part of a bus-port +
chan_rewrite rewrite list see at chan rewrite +
+ +

+
{des2:38} core attributes of a bus-port +
attribute value description +
uuid unique ID cschem-generated UID +
name name of the port user assigned port name +
connect name of a bus-net the given bus-port is also connected to a named bus (non-graphical connection) +
chan_rewrite rewrite list see at chan rewrite +
+ + +

2.5.2. networks

+ +

{des2:40} +A network is: +

    +
  • a list of ports connected (derived from contributors: explicit graphical wire-nets or implicit connections through attributes) +
  • a list of attributes (combined from the attributes of the same contributors) +
+ +

{des2:41} +A network has a project-wise unique name netname, which is derived +from the user specified name attribute and other factors (e.g. +hierarchy). A network also has a cschem generated unique ID. + +

{des2:42} +A network is combined from: +

    +
  • explicit graphical wiring: wire-nets and channels of bus-nets +
  • implicit connections: attributes specified in components or ports or bus channels +
  • connections dictated by data schematics sheets +
+ + +
{des2:43} core attributes of a network +
attribute value description +
uuid unique ID cschem-generated UID +
netname unique name cschem-specified project-unique network name +
name unique name user-specified sheet-unique network name +
chan bus-unique name when a connection is made, this name is used to look up and bind channel(s) +
source list of refs reference list to the concrete objects that contributed to this component; when saved: each item is an UID or an UID:key pair +
+ + +

2.5.3. bundled networks: buses and bus-ports

+ +

{des2:44} +A bus-net is a logical bundling of multiple networks. + +

{des2:45} +A bus-net consists of 1 or more bus-channels. Each bus-channel behaves as a network in +all regards. Each bus-channel has a chan attribute that specifies +what network or channel the given bus-channel will try to connect to when +the bus-net as a whole is connected. + +

{des2:46} +If a network is connected to the bus-net, either graphically or by attributes +or data schematics, the network is connected to the bus-channel that has the +chan attribute that matches the network's chan or name attribute. + +

{des2:47} +If a port is connected to a bus-net directly, the port must specify a chan +attribute. The port is connected to the bus-channel that has matching name +(chan attribute), considering the chan rewrite +attribute of the port. If there is no match, no connection is made. + +

{des2:48} +If a bus-port is connected to a bus-net directly, a matching is performed +between the bus-port's chan attributes and the +bus-channels' chan attributes, considering the +chan rewrite attribute of the bus-port. Whenever a match is found, a +connection is made. (Hint: the number of connection made should be +indicated by the UI so 0 connection is easy to detect) + +

{des2:49} +If a network is connected to a bus-port, the same rules apply as if +the network was connected to a bus-net, plus the bus-port's +chan rewrite attribute is considered. + +

{des2:50} +A bus-port accepts multiple bus-net connections and multiple network +connections. In case of multiple network connections, networks with +different net attributes are not connected together just because they are all +connected to the same bus-port. In other words, the channels of the +bus-port act as an independent port and each network will interact only +with the channel of the same net attribute, but channels are independent. +The connections are made on per-channel basis, considering +the chan rewrite attribute of the bus-port. + +

+
{des2:51} core attributes of a bus-net +
attribute value description +
uuid unique ID cschem-generated UID +
name unique name user-specified unique bus-net name +
source list of refs reference list to the concrete objects that contributed to this component; when saved: each item is an UID or an UID:key pair +
+ +

2.5.4. hubs

+ +

{des2:62} +A hub is an explicit object that forms a connection between multiple +different networks or buses (or in an extreme case is connected to +a single network or bus). + +

{des2:63} +On an output (e.g. netlist) that supports this feature, a hub is presented +as an explicit object. On output where this feature is not available, the +connected networks have to be merged. + +

{des2:64} +A hub can be regarded as a component with as many ports as many networks are +connected to it. It represents a physical galvanic connection among all +networks connected. + +

{des2:65} +A hub can be regarded as a component with as many bus-ports as many bus-nets are +connected to it. It represents a physical galvanic connection among all bus +channels with matching name, considering the chan rewrite +attribute of the hub. + +

{des2:66} +If a hub has at least one bus connection, it will do all bindings based on +chan matching, considering the chan rewrite +attribute of the hub. This applies to all channels of all buses connected +and to the chan attribute of all networks connected. If a network connected +to such a bus does not have a chan attribute even after the chan rewrite, +it is left unconnected. + + +

+
{des2:67} core attributes of a hub +
attribute value description +
uuid unique ID cschem-generated UID +
name unique name user-specified unique hub name (similar to a component's name) +
source list of refs reference list to the concrete objects that contributed to this component; when saved: each item is an UID or an UID:key pair +
chan_rewrite rewrite list see at chan rewrite +
+ +

2.5.5. connecting networks and ports

+ +

+
{des2:52} connectivity matrix +
  wire-net port hub bus-net bus-port +
wire-net direct direct direct 1chan 1chan +
port direct direct invalid 1chan 1chan +
hub direct invalid invalid match invalid +
bus-net 1chan 1chan match match match +
bus-port 1chan 1chan invalid match match + + +
 
 
+
connection types +
direct 1:1 connection ("knob", "node") +
1chan single port or network connected to one of the channels by the chan attribute, if the chan is found in the bus-net or bus-port +
match channel list matching; matching channels are connected, considering the chan rewrite attribute of the hub or port or bus-port. +
invalid connection can not be made +
+ +

2.5.6. chan rewrite

+ +

{des2:78} +The purpose of chan[nel] rewrite is to provide a mechanism that hubs and +ports can control how they connect bus channels. The normal mechanism +is full name match: e.g. if two buses are connected, the channels with +matching names are connected. This happens if the chan rewrite list of +the connection point is empty - in the simple, default case. + +

{des2:79} +To allow pseudo-bus-hierarchy, the chan_rewrite attribute +can rename chan attributes for the connection lookup. The rewrite affects +only the code that performs the chan name matching, it has no effect +outside of that domain. + +

{des2:80} +The chan_rewrite attribute is an unordered list of rules. A rule is +a name::pattern::subs triplet. Any incoming connection +(networks or buses) are searched. If their name attribute matches the +name field in the rule, the rule is executed: the +regex [TODO: link to appendix for the syntax] pattern is matched against +the chan attribute of the network or bus, and the matching portion is substituted +with the subs string of the rule. + + +

2.6. glossary

+ +

+
{des2:70} glossary +
term context meaning +
abstract model + project-view an in-memory model of the circuit as rendered by the plugins from the concrete objects; has no graphical representation; not edited by the user +
attribute + any a textual key=value pair attached to any object in cschem +
bus + abstract a construct that allows multiple channels (local nets) bundled +
bus-channel + abstract == channel (in the context of buses: shorthand for "a channel of a bus") +
bus-net + concrete graphical representation of multiple bus-segments connected (may have junctions) +
bus-segment + (drawing primitives) graphical representation of a segment of a bus (drawn using drawing primitives) +
bus-port + abstract a component port where a bus can be connected; behaves like a group of ports +
bus-terminal + concrete a terminal ("pin") of a symbol that accepts bus connection; allows multiple channels as if it was a bunch of bundled terminals +
channel + abstract a named "wire" of a bus or bus-port +
channel-port + abstract each channel of a bus-port behaves similar to a port; these are called channel-ports +
component + abstract an atomic device +
concrete model + project the data model edited by the user; used as a source for the abstract model +
hub + abstract an object that connects multiple networks without making them one network; can be used to split a (former) network into two (new) separate networks +
hub-point + concrete the graphical representation of a hub (drawing primitive) +
junction + concrete anonymous junction on a wire-net or bus-net, connecting two or more wire-segments or bus-segments +
network + abstract a named circuit network: a list of ports connected +
port + abstract a component's point-of-connect to a network (e.g. a pin or pad) +
project-view + top-level a specific view of a specific project +
symbol + concrete schematics symbol that represents (a part of) an element +
terminal + concrete a "pin" of a symbol that accepts a network connection +
uid,
uuid,
(universally/globally) unique ID +
any globally unique identifier - a series of random-looking bytes +
wire-net + concrete graphical representation of multiple wire-segments connected (may have junctions) +
wire-segment + (drawing primitives) graphical representation of a segment of a wire (drawn using drawing primitives) +
Index: tags/1.0.5/doc/design/02_data_imp.html =================================================================== --- tags/1.0.5/doc/design/02_data_imp.html (nonexistent) +++ tags/1.0.5/doc/design/02_data_imp.html (revision 10414) @@ -0,0 +1,300 @@ + + +

cschem implementation - 2. Schematics data

+ +

Goals

+ +

{imp2:0} +This chapter should try to define the "first-class" objects cschem +handles. The list of these objects should be as small as possible and +as orthogonal as possible. All extra features and mechanisms, like +slotting, hierarchy, name mangling, etc. should be implemented on top of +these features (usually by dealing with attributes). This is in accordance +with {pol:1}, {pol:2}, {pol:4}, {pol:9} + +

{imp2:1} +The model can be considered as a stack: +

+   +------------------------+
+   |  output, e.g. netlist  |
+   +--+------------------+--+
+      |  abstract model  |
+   +--+------------------+--+
+   |    concrete   model    |
++--+------------------------+--+
+|      drawing  primitives     |
+|      and data schematics     |
++------------------------------+
+
+ +

{imp2:2} +The main objective should be to keep the abstract model as simple as possible, +since most of the complex logics and methods and mechanisms will operate +on this model. + +

{imp2:3} +The concrete model can be more redundant, offering alternatives; the most +common example is that a network can be realized drawing wire-segments, +or drawing bus-segments or implying connections via attributes. + +

{imp2:4} +The input for the concrete model can be even more elaborate; most notably +the same concrete model elements can be created graphically or from data, +manually or programatically. + +

{imp2:5} +The final output is usually also a larger model that can be derived from +the abstract model. + + +

Abstract vs. concrete

+ +

{imp2:6} +At the end, all that matters is the abstract model. +Most plugins, export formats, checkers, etc. are interested in that. +That's what really describes the actual circuit. We have +concrete objects to provide an easier access for the user to manipulate +the abstract model. + +

{imp2:7} +Electronic example: in the abstract model the project needs a quad +NAND gate (7400). One of the possible implementations in the concrete +model: + +

    +
  • in the lib, there are two symbols, a generic NAND gate with 3 gates and a TTL power symbol +
  • the user places an instance of the power symbol and 4 instances of the NAND symbol +
  • the users sets the name attribute of all 5 symbols to the same, unique value, e.g. U15 +
  • cschem now knows that the abstract component called U15 depends on these five concrete symbols +
  • a slotting mechanism plugin and/or potentially other plugins affect (calculate) attributes of the five symbols and their ports (details to be discussed by later chapters) +
  • now that the final values are known, cschem attempts to combine the five concrete symbols into an abstract component (details to be discussed by later chapters) +
  • the rest of the code, e.g. netlist generator plugins, will often deal with abstract model only +
+ + +

{imp2:8} +A much simpler example is when a single symbol instance of the concrete model +becomes a single component in the abstract model. However, the above steps +are all the same, except the 4 or 5 symbols are reduced to 1. + +

{imp2:9} +The UI should present both the concrete and the abstract model. +The user should be able to edit the objects of the concrete model and +see the effect on the abstract model. + +

{imp2:10} +Letting the user directly edit the abstract model is probably not +practical: there are multiple ways the concrete model can be changed +to cause the desired change in the abstract model. It is like if +we wanted to fix a bug in the executable of a program and expect the +debugger or compiler to go and fix the source code accordingly. + +

{imp2:11} +Thus the UI should present the abstract model as read-only. But just like +debuggers can assist the user to navigate to the source line(s) that contributed +to a specific instruction or runtime situation, cschem UIs should be able to +navigate the user to the source(s) in the concrete model that caused +a specific effect in the abstract model. How the source references +are stored in memory is up to the implementation, but when the model is +saved/exported (e.g. to disk), it should use UIDs as specified. + +

{imp2:12} +A common example is (abstract) networks. The user, looking at a PCB or +simulation, wants to find the network named "Address6". This information is +clearly interpreted in the scope of the abstract model, where there +is a network with name "Address6" and a list of ports it connects (and +a list of attributes). A search can be made to find all graphical connections, +wire-nets, bus-nets, attribute connections and data that contributed to the final +list of ports (and attributes) of the network. + +

{imp2:13} +Note the terminology: the same terms are not reused in both the concrete +and the abstract models, e.g. a symbol in the concrete model +can become (or contribute to) a component in abstract model. + +

Core attributes

+ +

{imp2:14} +A very few aspects of the abstract model are implemented +through attributes. These attributes are used by the core implementation and +are relied upon by all plugins. These attributes are called the core +attributes. + +

{imp2:15} +The number of core attributes shall be as small as possible as per +{imp2:16}, {imp2:17}, {imp2:18} and {imp2:19}. + +

{imp2:20} +Currently the core attributes are restricted to deal with: +

    +
  • identification of objects in the abstract and concrete models +
  • realizing the simplest forms of attribute based network connections (not excluding other, more complex forms calculated by plugins; the result of those calculations will be translated to connections specified in this simple form; scope of later chapters) +
+ + +

Port implicit network vs. chan connection

+ +

{imp2:21} +A port (or a channel of a bus-port) can be non-graphically connected to a +network using the connect attribute. This always forms a connection +(even at the cost of creating the given network). + +

{imp2:22} +Another way is connecting the port graphically, using wire-nets in the +concrete model. + +

{imp2:23} +The two methods are orthogonal and can be used in parallel. If the same +port is connected to two differently named networks, the usual network collision +mechanism is used (will be discussed in a later chapter). If the port +is connected to a named network via attribute and an unnamed wire-net, the +wire-net automatically joins the named network (via the port). + +

{imp2:24} +The third orthogonal idea is channels of a bus. A channel is really a network, +which most often "stays within the scope of the bus", that is, won't have a +connect attribute that would make it a globally known network. If a port +is connected to a bus, the port's chan attribute determines which +channel of the bus is connected. + +

{imp2:25} +But this connection is again orthogonal to the above two. Which means +a port can be connected to a network in multiple different ways: +

    +
  • using the connect attribute of the port +
  • using the connect attribute of the parent component +
  • graphically, using a wire-net, assuming the wire-net is already associated with a network +
  • graphically, using a bus-net, assuming the bus-net channel is already connected to a network (via graphical connection to another port or wire-net or via the channel's connect attribute) +
+ + +

Avoid attribute overloading

+ +

{imp2:26} +A symbol has a name field for binding it to a component. This seems like +redundant to refdes (also, gschem uses refdes for this purpose). The reason for +this decision is that refdes is also the identifier printed on a PCB. In +a complex hierarchic setup it makes more sense to use a shorter refdes +generated from a longer name; the refdes can even be sequential. + +

{imp2:27} +If cschem tried to use refdes for both, it would be sort of overloading the +attribute with two different purposes: +

+ +

{imp2:28} +The alternative is to provide separate attributes for the two purposes: name +for the logical identification, refdes for the physical. Granting that: +

    +
  • in the simplest, flat cases the refdes will just match the name +
  • refdes can be calculated or derived from the name by a plugin +
+ +

{imp2:29} +The same considerations are followed when netname is derived from +name in case of networks. + + +

Proper bus support

+ +

{imp2:30} +Buses are not pure graphical objects; cschem does understand what +channels a bus has and does checks when anything is connected to a bus. + +

{imp2:31} +Buses and bus-ports are first-class objects, which means they can be used +the same way as networks: +

    +
  • a bus can be connected to anything that accepts connections +
  • a component can be connected to a whole bus in a single connection, using a bus-port +
  • a bus-port in a hierarchy means buses can cross schematics sheet boundaries as buses +
+ +

UIDs vs. names

+ +

{imp2:32} +While working on the back annotation for pcb-rnd -> gschem, I realized that +using refdes for element identification is not reliable. Looking at prior +art it turned out others struggled with the same problem (e.g. in the +renumber plugin). The problem is: it's easy to communicate pin swaps and +non-refdes-attribute changes, because we can address those by refdes:pinnum or +refdes:attribname. But changing refdes (which should be just a plain attribute) +is hard because it's also part of the addressing. + +

{imp2:33} +In a gschem -> pcb-rnd flow this means if only the refdes attribute +changes on the schematics e.g. from R15 to R21, pcb-rnd still preceives +this as if R15 was removed and R21 was added. Not an attrib change, not +a rename, but a full subcircuit removal and a new subcircuit added. The other way +around is not easy either: when an subcircuit is renamed in pcb-rnd and needs +to be back annotated: we have no other data to identify the subcircuits than its +refdes, and the rest of the back annotation data pack also may depend on the +refdes (e.g. for pin swaps in the same element). + +

{imp2:34} +To fix this, cschem will have UIDs right from the start. Wherever possible +in program-to-program communication, we will try to reference our objects +by UIDs instead of names. Of course at the end the names are presented to +the user, especially on the user interface, but the internal communication +should be UID based. This makes it hard to change the UID of an existing object +(which we don't want to do anyway) and makes it easy to change any other +attribute, including the name of the object. This is an option; flows +can decide to use any other identification from any other attribute specified +by the user and/or generated by plugins + +

{imp2:35} +Cschem will use the UIDs generated by libminuid. + +

{imp2:36} +An abstract object is identified by its project-unique name attribute. +The name attribute is (derived from) an attribute maintained by the user. +This name may not be the same as the visible name on the output; for example +in case of components the visible name on a PCB layout would be refdes +attribute, in +case of networks the PCB-visible name is the netname attribute +while the unique name by which all systems identify the component or network is +the name attribute. Refdes and netname can be derived automatically from +name by plugins - the simplest method is copy. + +

data/programmed schematics sheets

+

{imp2:37} Opaque data sheets gives cschem an extra level of flexibility: +later on in a hierarchic or multisheet design, parts of a bigger schematics +can be specified in: +

    +
  • plain text data +
  • CSV, TSV, xml, json, binary data +
  • an awk or perl or python script that simply prints abstract objects on its stdout +
  • vhdl/verilog +
+ +

{imp2:38} Any of these will need a plugin that handles the given format. +For plain text, CSV, TSV xml, json, binary data it's just a format parser that +then passes on the data to the same code that would handle the extracted concrete +objects of a graphical sheet. + +

{imp2:39} For any kind of script, including vhdl and verilog, the plugin +would need to run an external process or depend on a lib to actually execute +the source code (that is the data of the sheet) and convert the result into +concrete objects which then would be handled the same way as above. + +

{imp2:40} Since the sheet is opaque for the GUI, cschem is not forced +to reproduce hundreds of editors and compilers/interpreters. Since the +actual compiler is a plugin, the user can easily add support for a new +language/format. + +

{imp2:41} The difference between a data schematics sheet and an external +converter program that would compile the input into a graphical schematics +sheet is: +

    +
  • the data does not need to be converted to native cschem graphical sheets +
  • the data is handled from within cschem, by plugins; this makes the whole process feel more integrated +
  • the plugin has an option to provide a graphical representation, which doesn't need to look like cschem's GUI +
+ +

{imp2:42} The data/programmed schematics sheet is an alternative to +external conversions. Both methods can be used in parallel, even within the +same project, as long as the resulting abstract model is consistent. + Index: tags/1.0.5/doc/design/02_graphical.svg =================================================================== --- tags/1.0.5/doc/design/02_graphical.svg (nonexistent) +++ tags/1.0.5/doc/design/02_graphical.svg (revision 10414) @@ -0,0 +1,397 @@ + + + + + + +g + +cluster_0 + +graphical schematics sheet + +cluster_01 + +drawing primitives +(chapter 3) + +cluster_02 + +concrete model +(chapter2) + +cluster_1 + +abstract model +(chapter 2) + +cluster_2 + +real world +example: PCB + + +at1 + +"bus-segment": +atoms, e.g. lines + + +gr1 + +group +role=bus-net + + +at1->gr1 + + + + +at2 + +"wire-segment": +atoms, e.g. lines + + +gr2 + +group +role=wire-net + + +at2->gr2 + + + + +at3 + +atoms +and groups + + +gr3 + +group +role=symbol + + +at3->gr3 + + + + +at4 + +atoms +e.g. lines + + +gr4 + +group +role=bus_terminal + + +at4->gr4 + + + + +at5 + +atoms +e.g. lines + + +gr5 + +group +role=terminal + + +at5->gr5 + + + + +at6 + +atoms +e.g. arc, polygon + + +gr6 + +group +role=hub_point + + +at6->gr6 + + + + +at7 + +connection gfx +e.g. arc, polygon + + +connection + +connection + + +at7->connection + + + + +bus_net + +bus-net + + +gr1->bus_net + + + + +wire_net + +wire-net + + +gr2->wire_net + + + + +symbol + +symbol + + +gr3->symbol + + + + +bus_terminal + +bus-terminal + + +gr4->bus_terminal + + + + +terminal + +terminal + + +gr5->terminal + + + + +hub_point + +hub-point + + +gr6->hub_point + + + + +connection->wire_net + + +Note 2 + + +connection->bus_net + + +Note 2 + + +attribute + +attribute +of wire-nets, bus-nets, symbols, + hubs and terminals + + +symbol:e->attribute:se + + + + +component + +component + + +symbol->component + + + + +terminal:e->attribute:se + + + + +port + +port + + +terminal->port + + + + +bus_terminal:e->attribute:se + + + + +bus_port + +bus-port + + +bus_terminal->bus_port + + + + +wire_net:e->attribute:se + + + + +network + +network + + +wire_net->network + + + + +hub + +hub + + +hub_point->hub + + + + +bus_net:e->attribute:se + + + + +bus + +bus + + +bus_net->bus + + + + +attribute->network + + +Note 1 + + +pcb_net + +copper tracks +copper polygons + + +network->pcb_net + + + + +bus->pcb_net + + + + +pcb_pair + +copper tracks/polygons with +constraints (e.g. diff pair) + + +bus->pcb_pair + + + + +pcb_component + +component + + +component->pcb_component + + + + +pcb_pin + +pin or pad +of a +component + + +port->pcb_pin + + + + + +bus_port->pcb_pin + + + + +hub->pcb_net + + + + +pcb_hub + +specific point on copper +with geometry constraints +(e.g. star point gnd) + + +hub->pcb_hub + + + + + Index: tags/1.0.5/doc/design/03_coords.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/1.0.5/doc/design/03_coords.png =================================================================== --- tags/1.0.5/doc/design/03_coords.png (nonexistent) +++ tags/1.0.5/doc/design/03_coords.png (revision 10414) Property changes on: tags/1.0.5/doc/design/03_coords.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/1.0.5/doc/design/03_drawing.html =================================================================== --- tags/1.0.5/doc/design/03_drawing.html (nonexistent) +++ tags/1.0.5/doc/design/03_drawing.html (revision 10414) @@ -0,0 +1,561 @@ + + +

3. graphical schematics sheets - drawing primitives

+ +

{des3:0} +This chapter describes all drawing primitives that can be used on +a graphical schematics sheet as well as the data structure of the +graphical schematics sheet. + +

{des3:1} A drawing object is a drawing primitive, a group or a sheet. + +

{des3:2} A drawing object is fully specified by: +

    +
  • the drawing object type, which is one of the types defined in this document (e.g. line or arc or group) +
  • properties +
  • attributes +
+ +

{des3:3} Properties are fields that are typically not stored or +edited by the user in plain text form, and/or are produced and consumed +by the code and are not interesting for the user. Attributes are typically +textual data that are easy to edit as text. + +

{des3:4} All properties are present in the memory and file format. +When a property needs to be "turned off" (e.g. a group should not be +rotated), the property still has its slot in the file format and in the +memory, but the value is set to a special "unspecified" value. + +

{des3:5} A valid cschem implementation must implement the functionality +of all mandatory properties. If an implementation does not implement the +functionality of an optional property, the implementation must be able +to load, store and save the value of that property. Whether the +functionality of a property +must be implemented or not can be found in the mandatory column +of the property tables. + +

{des3:6} All attributes are optional. + +

{des3:7} Drawing objects are stored in a tree structure, with the top level +single root being the sheet and leaves being atoms. + +

{des3:8} The following figure demonstrates the tree structure +(parent -> child). Rectangular objects have attributes. + +

+ + +

+
{des3:9} drawing object types +
term type properties attributes children summary +
line atom yes no none straight line segment +
arc atom yes no none circular arc +
spline atom yes no none (spline) +
text atom yes no none multiline text +
polygon atom yes no none polygon with curved edges +
connection atom yes no none logical connection +
bitmap atom yes no none embedded bitmap +
group composite yes yes atoms, composites group of atoms and composites +
group_ref composite yes yes atoms, composites reference to another group +
sheet sheet yes yes atoms, composites root of the tree +
+ +

3.1. Common drawing object properties

+ +

3.1.1. Local identifier

+ +

{des3:10} An oid is a signed 32 bit integer. Any time a new +drawing object is placed on a sheet or within a group, the new drawing object's oid is set to +the group's or sheet's next_oid and the group's or sheet's next_oid is incremented. + +

{des3:11} The oid value 0 means "invalid" or "unused" or "unspecified". +Any non-zero oid is a valid drawing object ID. The same oid can not +be attached to two different drawing objects within a group or sheet. + +

{des3:71} Only positive oid values shall be used in files or +communication, negative values are reserved for application-internal use. + +

{des3:12} The oid is used for referencing drawing primitives +within the group or sheet. It is meant for internal references only: external objects, +such as other sheets, shall not use oid to reference into the sheet. + +

{des3:13} If next_oid overflows, oids are allocated using +a slower mechanism that still result in unique numbers. If there are 2^32-1 +drawing objects on the sheet, no more drawing objects shall be added. + +

{des3:72} An oid-path is a slash separated list of oids. +It is a top-down description of an object path: it contains zero or more +composite object oids then descending through groups until +reaching the final object that's being addressed. + +

{des3:73} An oid-path is always an absolute path, root +being the sheet. An oid-path is invalid if any prefix path of it +refers to a non-existing object. The leading slash is mandatory. + +

3.1.2. Common graphical features

+ +

{des3:14} color: 24 bit #rrggbb (2 digit numbers written as hex, +00 means darkest, ff means brightest). There is no alpha, there is no +drawing object level translucency. + +

{des3:15} Most drawing objects are drawn with a pen. + +

+
{des3:16} pen properties +
property mandatory description +
name yes string: name assigned by the user; used for addressing pens; unique within the group +
tip shape yes circle (also called round) or square; when square, an edge of the square is always aligned with the stroke direction +
tip size yes circle diameter or square edge length in coordinates +
color yes   +
font_height yes font height in coords for text objects (string) +
font_family no hint: font family name for text objects (string) +
font_style no hint: font style for text objects (string; e.g. bold, italic) +
dash no dash pattern +
dash_period no length in coords a full dash pattern cycle +
+ +

{des3:17} When using a pen, the base geomerty is specified as the single, 0 +wide centerline. For a round tip pen, this means the actual rendered pixels +extend to exactly ((tip size)/2) pixels in all directions from any point of +the base geometry. For example if the base geometry is a 10 units +long horizontal line and the tip size is 4, the total length of the rendered +line is 2+10+2=14 units. + +

{des3:18} Dash pattern: an unsigned 16 bit integer, a bit pattern, each +bit represents 1/16 dash_period long stroke, 1 means draw, 0 means invisible. +If dash value is 0x0000 or 0xFFFF or dash is not specified, solid stroke is drawn. +If dash_period is not specified or 0, it is (tip size)*128. + +

{des3:74} Pens are defined per group. When an object refers to a pen, +it uses the name of the pen. The pen is searched first in the group of +the object; if not found, in the parent group, then in the grandparent group, +etc. If no pen with the given oid (or name) is found when reaching the root, a +warning is issued and a safe (implementation-specific) default pen is used. + +

3.1.3. Coordinate system

+ +

{des3:19} Coordinates on the sheet are stored as unit-less integer x;y. +Negative coordinates are supported. The drawing has no special spot, the +user is free to use any coordinate values. The point at 0;0 is not +special either, but it is recommended that the first drawing object of a new +design is placed near to 0;0 to allow the design to expand in any +direction. + +

{des3:20} Cschem implementations are expected to handle at least 32 bit +wide, signed integer coordinates. When a drawing is presented in normal +orientation, the X axis is horizontal, increasing to the right, the Y +axis is vertical, increasing upward. + +

{des3:21} Angles are specified in degrees between [0 .. 360) for +absolute values and between [-360 .. +360] for relative values. Degree 0 +is at x>0;y=0; positive angle is toward CCW. Angles are stored as +floating point numbers, with precision at least matching the binary32 +(single precision) of IEEE 754. + +

{des3:22} The coordinate system is demonstrated by the following figure: +

+ +

3.1.4. Common properties

+

{des3:80} Every drawing and group object has these properties with the same +meanining. These common properties are not listed in each object type's +property list in the following sections. + +

+
{des3:81} common properties +
property value description +
lock boolean if true, the object is locked (should not be selected or edited individually); if not specified, defaults to false +
floater boolean if true, bypass the "group lock"; non-floater objects are group-locked by default (can't be selected or edited individually) if they are part of a group other than sheet's direct; if not specified, defaults to false +
+ + + +

3.2. Atoms

+ +

3.2.1. Line (segment)

+

{des3:23} A straight line segment represented by a single contour line and +no fill and no attributes and no children. + +

+
{des3:24} line properties +
property mandatory description +
oid yes   +
p1 yes x;y coords of the starting point +
p2 yes x;y coords of the ending point +
stroke yes pen to use for drawing the line +
+ +

{des3:25} Stroke may be unspecified if the line is part of a polygon +outline. + +

3.2.2. Arc (segment)

+

{des3:26} An arc segment represented by a single contour line and +no fill and no attributes and no children. + +

+
{des3:27} arc properties +
property mandatory description +
oid yes   +
cx, cy yes x;y coords of the center point +
r yes radius in coord units +
sang yes start angle [0..360) +
dang yes delta angle [+-360] +
svalid no boolean to indicate whether start-point coord is valid +
sx, sy no exact x;y coords of the start-point +
evalid no boolean to indicate whether end-point coord is valid +
ex, ey no exact x;y coords of the end-point +
stroke yes pen to use for drawing the line +
+ +

{des3:28} The exact endpoint x;y; coords are specified as an optional helper. In +case the endpoint may matter for visually connecting drawing objects, the +implementation may emit and load the endpoints. Either none of the endpoints +are specified or both endpoints are specified. + +

{des3:29} Optional: an implementation loading the drawing object may use the +endpoint to detect or even correct rounding errors either in the loader +implementation or in the emitter implementation. If the calculated +endpoint differs from the stored endpoint by more than 1/4 of the tip +size, the implementation shall recalculate other parameters of the arc to +match the endpoints. + +

{des3:30} If an implementation doesn't implement support for the endpoints, +it must invalidate the endpoint values upon any coordinate change to the arc, +but must preserve the endpoint properties upon other changes or no change. + + +

{des3:31} Stroke may be unspecified if the arc is part of a polygon +outline. + +

3.2.3. Spline

+

{des3:32} Not supported in the first version. + +

3.2.4. Text

+

{des3:33} The text object has properties and no attributes and no children. + +

{des3:34} It represents a multiline text block arranged in a bounding box. +When x2 and y2 are specified, pen font height is taken only as a hint: +the renderer may chose a different font and size but has to find the +closest possible match for fitting the unrotated text in the bounding box. +When x2;y2 are not specified, the lower left corner of the rendered text is +placed on x1,y1 and text size is chosen for the pen font_height property. +Rotation is performed after the above bounding box or pen font height rendering. + +

+
{des3:35} text properties +
property mandatory description +
oid yes   +
x1, y1 yes x;y coords of bounding box bottom-left (smaller coords) +
x2, y2 no x;y coords of unrotated bounding box top-right (larger coords) +
rot no rotation +
mirx no boolean; mirror X coords (mirror over y axis); default is false if not specified; affects origin vs. bbox relation, does not affect pixels fo rendered text +
miry no boolean; mirror Y coords (mirror over x axis); default is false if not specified; affects origin vs. bbox relation, does not affect pixels fo rendered text +
halign no horizontal alignment, per text line: start, center, end, word-justified, justified (default: start); affects only bbox specified text and multi-line text; start means toward the text object's origin +
text yes string +
stroke yes pen used to determine color and font properties +
dyntext yes boolean; when true, perform dyntext substitution +
+ +

{des3:79} Rotation is specified in degrees, taken as 0 if the field is not +specified. Zero means horizontal text, positive degree is CCW rotation around +x1, y1. + +

{des3:36} Horizontal alignment is considered only in two cases. First, +in singleline bbox-specified text that is narrower (horizontally) than the box; +second, in multiline text where +the width of the bounding box matches the width of the widest text line. This +property determines how to handle the narrower lines. Word-justified means +spacing should be applied in between words only; justified means the implementation +is free to use spacing between characters too. + +

{des3:37} The text field is plain 7 bit ASCII. The implementation may +optionally interpret "&hex;" and/or "&name;" Unicode sequences - users shall not +expect this to universally work across implementations; portable schematics +shall not use them. Line boundaries indicated by single \n characters. + +

{des3:75} If dyntext is true, any %pattern% is substituted in text +before rendering. The syntax of pattern is: +

+ +

{des3:76} Multiple ../ can be used to traverse the object tree up; the +root node's parent is itself. Addressing can be done only upward, it is +not possible to address sibling nodes. Non-existing properties or attributes +are substituted with empty string. + +

{des3:77} A typical example is the "refdes text" which is a text object +within a group role=symbol, with dyntext true, text field containing: +%../a.name%. + +

{des3:82} In case the addressed attribute is an array: if it has only +one element, it is substituted; else <array> is +printed. + +

3.2.5. Polygon

+ +

{des3:38} A polygon is represented by a complex outline, an optional +fill, and no attributes and no children. + +

+
{des3:39} polygon properties +
property mandatory description +
oid yes   +
outline yes list of atoms, see below; these atoms are the children of the polygon in the data tree +
stroke no pen or unspecified if no stroke is required +
fill no pen or unspecified if no fill is required +
+ +

{des3:40} The outline is an ordered list of lines, arcs and splines that specify the contour. The list is specified in CCW on both drawing object level and +endpoint level. If there's a gap between the endpoints of two +consecutive drawing objects, a straight line is assumed for the missing segment. + +

{des3:41} To avoid degenerate cases, the contour list has further +restrictions: +

    +
  • must consist at least 3 drawing objects +
  • must not contain lines or arcs that start and end in the same point +
  • arcs delta angles must be less than or equal to 180 degrees +
  • the final contour line, including the assumed missing line segments in gaps, must not intersect or touch itself +
+ +

{des3:42} Individual stroke of each outline object is ignored and the outline is +interpreted as a theoretical, 0 width contour. This theoretical contour +is drawn with the polygon object's stroke (when specified). + +

{des3:43} If the fill property is specified, the polygon is first filled +with the color of the fill pen. If the stroke property of the polygon is +specified, this pen is used to draw the outline contour of the polygon +(rendered after the fill). + +

3.2.6. Bitmap

+

{des3:69} A rectangular, scaled bitmap image. + +

+
{des3:70} line properties +
property mandatory description +
oid yes   +
p1 yes x;y coords of the top left corner of the bounding box +
p2 yes x;y coords of the bottom right corner of the bounding box +
transp yes if set, the value of the pixel that should be considered transparent; the value is in the same pixel format as the pnm +
pnm yes a Portable Anymap in P1, P2, P3, P4, P5 or P6 format +
+ + +

3.2.7. Connection

+

{des3:44} The graphical sheet does not imply connections based +on geometrical features, e.g. when the endpoint of a "wire" happens to +be on the endpoint of a "pin". Instead, all connections are created and +stored explicitly by connection objects. + +

{des3:45} The connection object is invisible and refers +to other objects. It has properties but no attributes and no children. + +

+
{des3:46} connection properties +
property mandatory description +
oid yes   +
conn yes list of connected drawing objects (see below) +
gfx yes oid-path if the drawing object that's the graphics of the connection, or invalid oid +
+ +

{des3:47} The connection always connects groups, because only groups +can represent abstract objects. The conn field is a list of oid-paths +of drawing objects (typically atoms) that are directly contributing to the +connection. The groups connected are the direct parent of the objects listed. +Such parent group is always a group or a group_ref with one of the following +roles: +

    +
  • a terminal (role=terminal or bus-terminal) +
  • a network (role=wire-net or bus-net) +
  • a hub (role=hub-point) +
+ +

{des3:48} The conn list must list drawing objects so that at least two +different (parent) groups are referred. + +

{des3:49} If the gfx oid-path is not invalid, it refers to a drawing object +(e.g. an atom or a group) that graphically represents the connection. + +

{des3:50} The most common use case is marking the graphically overlapping +parts of two or more groups a logical connection. The GUI detects the new +connection from user draw actions and creates (or extends an existing) +connection object. The typical gfx of a connection is a small dot drawn +as a zero length (round cap) line with pen size at least twice of the usual +wire style's. + +

{des3:51} Since the connection is a logical concept, it can +be realized between two groups that do not have graphically overlapping parts. +However, using connections that way is not intuitive for the user of a +graphical editor, and cschem implementations generally should refrain from +doing that. Overlapping objects (e.g. crossing wirenets) don't necessarily +connect (no connection object is made for disconnected crossings). + +

{des3:52} Conceptually a connection is similar to a junction within a +wirenet group but it is between two groups (but shall not connect two +wirenets - connected wirenet groups shall be simply merged). + +

3.3. Composite

+ +

3.3.1. The group object

+

{des3:53} +Group objects consist of properties, attributes and a list +of members (children). + +

+
{des3:54} group properties +
property mandatory description +
oid yes   +
next_oid yes signed 32 bit integer (see above at common drawing object properties) +
memb yes list of 1 or more member objects; these drawing objects are the children of the group node +
rot yes rotation angle around x;y; can be 0 for no rotation +
x, y yes x;y offset; can be 0;0 for no action +
mirx no boolean; mirror X coords (mirror over y axis); default is false if not specified +
miry no boolean; mirror Y coords (mirror over x axis); default is false if not specified +
purpose no arbitrary textual name generated for local lib root groups, first level of groups in the sheet's indirect group +
uuid no universally unique ID for referencing the group from external sources +
src_uuid no if the group was copied from an existing group, universally unique ID of the source group it was copied from +
+ +

+
{des3:55} group attributes +
attribute value description +
role one of 3.3.3. specify what concrete object the group represents +
+ +

{des3:56} The list of members consist of 1 or more atoms or composites. If +the rotation angle is specified, first the coordinates of members are +rotated around the rotation center. If any of the mir* fields are true, +mirroring is performed then. If the offset is specified, the +coordinates of members are shifted by the offset before the rendering. + +

3.3.2. The group_ref object

+ +

{des3:57} +A group reference is a group instance without locally defined +members, referencing a group that is stored elsewhere. A group_ref object +has properties and attributes but has no children. + +

+
{des3:58} group_ref properties +
property mandatory description +
oid yes   +
ref yes reference to an existing group +
rot yes rotation angle around x;y; can be 0 for no rotation +
x, y yes x;y offset; can be 0;0 for no action +
mirx no boolean; mirror X coords (mirror over y axis); default is false if not specified +
miry no boolean; mirror Y coords (mirror over x axis); default is false if not specified +
child_xform no see below +
+ +

{des3:59} The same attributes are available as for the group object. +The group_ref and referenced group attributes are merged only +while compiling the abstract model. + +

{des3:60} The ref field contains a reference oid-path. + +

{des3:83} The child_xform field is an unordered list of child +transformations. Each element of the list contains a oid-path of a child +object (relative to the referenced group) and one or more transformation +command. + +

{des3:84} +Each oid-path can be present only once on the list and each transformation +can be present only once in a given entry. + +

+
{des3:85} child_xform transformation commands +
name value type description +
movex coord child is moved (translated) in the X direction +
movey coord child is moved (translated) in the Y direction +
rot angle (deg) child is rotated +
mirx boolean if true, child is mirrored left/right +
miry boolean if true, child is mirrored up/down + +
+ +

{des3:86} +Order of transformations on each child object: +

    +
  • first the group reference's child object is instantiated (copied from the referee) +
  • then parent group transformations are applied (including the transformations of the group_ref) +
  • then the child_xform commands are executed (in the same order as group transformations are applied) +
+ +

3.3.3. The role attribute

+ +

{des3:61} A group or group_ref is a drawing object, that can be the +source of a concrete object. Each concrete object has only one source and +each group (or group_ref) can instantiate only one concrete object. (Any +multi-source merging, e.g. multiple symbols donating one element is done +in the concrete -> abstract step.) + +

{des3:62} If a group (or group_ref) does not define a concrete object, +it is a purely graphical feature that does not affect the concrete model, +the abstract model or any output derived from these models - but still +can affect graphical output. + +

{des3:63} Whether a group (or group_ref) is a source of a concrete object, +and if so, the actual type of the concrete object is determined by the +value of the "role" attribute of the group (or group_ref). The value +must be one of those listed in the table below. + +

+
{des3:64} role attribute values +
name documentation +
bus-net des2:45 +
bus-terminal des2:25 +
hub-point des2:57 +
symbol des2:18 +
terminal des2:24 +
wire-net des2:13 +
junction des2:81 +
+ +

{des3:78} An empty or missing role attribute means the group is a logical +grouping and does not directly create a concrete object. Such logical grouping +can be used by the user or the GUI to group objects together. For example +the user may draw arrows using lines and polygons to represent some logical +relation between areas of a sheet; to be able to easier move/copy/delete an +arrow, the user may use a custom group hosting the arrow. + +

{des3:65} Note: a junction connecting different groups can be created only by a connection object. + +

3.4. Sheet

+ +

{des3:66} A (graphical schematics) sheet has two child root +groups. The direct group lists +all objects directly visible on the sheet, while the indirect group +serves as a "local library", hosting invisible group objects that +can be referenced from group_ref's from direct or used by plugins (e.g. +devmap). + +

{des3:87} The first level under the indirect group is of "library" +groups. Each "library" group has a "purpose" +attribute that indentifies what kind of contents are collected there: +which type of library the group hosts, which plugin(s) can edit it. +For example the local symbol library is stored in the purpose=symbol group +and devmap uses the purpose=devmap group to store locally saved devmaps. +Library groups have no role attribute. + +

{des3:88} Furthermore a sheet has properties and attributes. The oid of the direct group +is 2 and the oid of the indirect group is 1. + +

+
{des3:67} sheet properties +
property mandatory description +
objects yes list of groups and atoms hosted on the sheet; these drawing objects are the children of the sheet +
next_oid yes signed 32 bit integer (see above at common drawing object properties) +
oid yes the sheet's own oid (to be used in parent references) +
indirect yes "local lib" group for invisible objects, oid=1 +
direct yes group for visible objects, oid=2 +
+ +

{des3:68} sheet uuid is the uuid of the direct group. Index: tags/1.0.5/doc/design/03_drawing_imp.html =================================================================== --- tags/1.0.5/doc/design/03_drawing_imp.html (nonexistent) +++ tags/1.0.5/doc/design/03_drawing_imp.html (revision 10414) @@ -0,0 +1,166 @@ + + +

3. cschem implementation - graphical schematics sheets - drawing primitives

+ +

Goals

+ +

{imp3:0} The graphical schematics sheet is a generic vector graphics +drawing canvas with enough metadata that cschem can translate them into +concrete objects. The goal is to find a balance between generic vector +drawing and "possible to implement in a consistent way in reasonable time". +A balance that svg for example failed to find. Finding the balance +requires temperance: the goal is not to provide a fully generic vector +graphics language but only to provide enough features for drawing +schematics. + +

Dualism #1: independent graphics and meaning

+ +

{imp3:1} A novel aspect is that instead of telling how concrete objects +look like in graphics, cschem rather separates looks and meanings. That is, +there is no single canonical graphical representation of a hub or a wire. The +user or an implementation (or plugins) can generate a group of random graphics +elements and mark it as being a terminal ("pin"). + +

{imp3:2} Likewise, connections are explicitly specified, without binding +it to any specific graphical representation. A typical examples are: +

    +
  • junction mark: can be a little dot or can be invisible (and the schematics + would indicate non-junction by little jumper arcs) +
  • bus graphics, especially on bus-bus or bus-wire junctions +
  • pin graphics +
+ +

{imp3:3} Gschem notes: this is very different from what gschem did: it +stored objects that were both concrete objects and drawing objects. This +means a pin or a junction dot will always look the same in gschem. Connections +were not marked explicitly but calculated on load, from line endings being +on other lines or pin ends. This made it hard to interpret the file by 3rd +party software, as such a software would need to reproduce the same geometric +calculations (potentially with the same rounding and/or tolerances!) to have +the same connection conclusions. + +

{imp3:4} Is allowing the user to use different drawing styles desirable? +On one hand, cschem won't enforce the One True Style, which could potentially +lead to different users or implementations using different graphics for +the same construct. On the other hand, this is already happening without cschem +too, and EEs don't seem to struggle understanding schematics of a different +style. Cschem won't struggle understanding them too, as the logical data is +not extracted from the graphical looks. + +

{imp3:5} An interesting question is how implementation A will handle +the graphics created by implementation B. For example a bus-wire junction: +implementation A may draw a 45 degree white line coming out from the bus, +wire connected to the end of this stub, and add a text with the channel name +next to the stub. The stub line and the text are put in a group and this group +is then used by the connection object's gfx. The data that actually makes +the logical connection is the conn property of the connection. When B +needs to edit this stub, it will not understand why the text is there, so +the graphics will not be properly updated. The user may need to do that manually +or use the bus connection graphics offer by B. + +

{imp3:6} The reference cschem implementation will set its own drawing +conventions; it's recommended, but not enforced that other implementation +follow these conventions. + +

Dualism #2: is that really that novel?

+ +

{imp3:7} In a sense it is not: a symbol is usually a custom set of +drawing primitives. The schematics capture software understands that it's +a symbol, it needs to be drawn as is. Orthogonal to that, the software +also has non-graphical metadata with the symbol (e.g. attributes) so it can +understand the symbol. + +

{imp3:8} In that sense, a symbol in many software (including gschem) +already shows this dualism. The novel aspect in cschem is that it extends +the same idea to all other object types, e.g. terminals ("pins"), junction +graphics, and even wires and buses. + +

{imp3:9} Revisiting the alternative styles question: a 4 slot digital +inverter gate is already drawn as 4 separate triangular symbols and as +a single box with 4 or 5 sections. Readers are not confused by the variants. +The same way buses and even junctions have alternative styles on existing +schematics. Cschem merely permits having such styles not by defining +and hardwiring each of them in code, but by separating the looks from the works. + +

text object and font

+

{imp3:20} There are two ways to specify font geometry of a text object: +

    +
  1. {imp3:21} bbox based: when x2;y2 are specified; this is useful for + fixed text objects placed on the sheet by the user; it's more important + that these text objects, especially when multiline, stay in place and + don't start to overlap with other objects than to have the exact font + size matched. +
  2. {imp3:22} pen height based: when the text object does not have + x2;y2, pen height property is used; this is useful when the + placement and approximate size of the text is important but + bbox matching is not. This is the typical case in symbols. +
+ + +

grouping

+ +

{imp3:10} Cschem has only one kind of group and allows group-in-group. +The typical use is that any concrete object is represented by a group. +For example a symbol is a group, a terminal ("pin") is a group within +the symbol group. What concrete object a group becomes is controlled +by the role attribute of the group. + +

{imp3:11} A group can be a reference (group_ref) to another group +specified elsewhere. This is how a symbol from a library can be instantiated. +Since groups and group references can do two basic transformation (shift and +rotate), they can place instances freely. This allows both by-reference +and by-copy instantiation. It's up to the user to decide which one to use. + +

{imp3:12} Only composites have attributes, atoms don't. This means placing +an atom directly on the sheet can not have attributes. Since groups +are cheap, this can be easily solved by putting the atom in its own group. + +

{imp3:13} Wire-nets are obviously represented by a group that usually +will contain lines representing wires. A connection objects can +connect two groups by referring to group member drawing objects, e.g. a +line (part of a wire-net group) and another line (part of a terminal group). + +

default pens

+ +

{imp3:14} The most trivial use of pens is that a group defines its own +set of pens, hardwiring how the drawing of the group works on the low level. +For example for a group that represents a symbol, it means hardwiring the +style of a "pin" (line thickness and color), thus the symbol always looks +the same, no matter in which schematics sheet it is placed. + +

{imp3:15} However, it's equally important that symbols from different +source can be combined in a sheet and they look the same. Plus the user should +be able to control, on sheet level the style of the symbols. This is achieved +by using the pen fallback mechanism: + +

    +
  • {imp3:17} there is a table about the conventional pen names all sheets expected to have +
  • {imp3:18} groups intended to be used on any sheet should mostly use conventional pens without defining them as pens for those purposes described below, falling back to the actual pen definitions in the direct root group; for other purposes groups should define local pens; using uppercase pen names avoids collision with future conventional names +
+ +

+
{imp3:19} the convention for centrally defined pens +
name usage +
sheet-decor default sheet decoration +
titlebox-frame used for lines of the box +
titlebox-fill background fill of the titlebox +
titlebox-big used for title text +
titlebox-small used for other fields listed above +
wire default wire-net (wiring) +
bus default bus (wiring) +
hub default hubs and connection graphics for wire-nets +
sym-decor default symbol decoration lines +
sym-primary default symbol primary data text (e.g. refdes, value) +
sym-secondary default symbol secondary data text (e.g. devmap, footprint) +
term-decor default terminal decoration lines +
term-primary default terminal primary data text (e.g. number, name) +
term-secondary default terminal secondary data text +
busterm-decor default terminal decoration lines +
busterm-primary default terminal primary data text (e.g. number, name) +
busterm-secondary default terminal secondary data text +
junction default wire-net junction mark +
+ + + + Index: tags/1.0.5/doc/design/03_stack.svg =================================================================== --- tags/1.0.5/doc/design/03_stack.svg (nonexistent) +++ tags/1.0.5/doc/design/03_stack.svg (revision 10414) @@ -0,0 +1,158 @@ + + + + + + +stack + +cluster1 + + +cluster2 + +composites + +cluster3 + +atoms + + +sheet + +sheet + + +group + +group + + +sheet->group + + + + +group_ref + +group_ref + + +sheet->group_ref + + + + +standalone + + + +sheet->standalone + + + +group->group + + + + +group->group_ref + + + + +line + +line + + +group->line + + + + +spline + +spline + + +group->spline + + + + +arc + +arc + + +group->arc + + + + +polygon + +polygon + + +group->polygon + + + + +text + +text + + +group->text + + + + +connection + +connection + + +group->connection + + + + + +standalone->line + + + + +standalone->spline + + + + +standalone->arc + + + + +standalone->polygon + + + + +standalone->text + + + + +standalone->connection + + + + + Index: tags/1.0.5/doc/design/04_attrib.html =================================================================== --- tags/1.0.5/doc/design/04_attrib.html (nonexistent) +++ tags/1.0.5/doc/design/04_attrib.html (revision 10414) @@ -0,0 +1,402 @@ + + +

4. Attributes

+ +

{des4:0} +An attribute is a tuple of: +

    +
  • key +
  • value +
  • priority +
  • source information +
+ +

{des4:1} +The "Attributes of an Object" (AoO) is a flat map (hash table) of zero or +more attributes. Attribute keys within the AoO are unique. There is no +particular limit on the size of the AoO. + +

4.1. Attribute keys

+ +

{des4:2} +Key is always a 7-bit ASCII string no longer than 510 characters, +containing only characters between decimal 33 and 126. + +

{des4:3} +As a convention the slash ('/') character can be used as a "path separator", +emulating semantic hierarchy in the flat AoO list, with the leading '/' for +root omitted. Cschem itself and most plugins will ignore such pseudo-hierarchy, +and will handle slash without side effects. Nevertheless GUI implementations +may present attributes as a tree and attribute conventions will use the +pseudo-hierarchy to group attributes. If the first character of the +key is with - or +, that alters attribute merging +during compilation.. This is called attribute prefixing (the prefix +is part of the key, e.g. when string comparing the key). + +

4.2. Attribute values

+ +

{des4:4} +Each attribute has only one atomic value. The value can be changed (replaced) and +interpreted as a whole. The value is one of: empty, scalar or array. + +

{des4:5} +An attribute with an empty value should behave the same way as if the +attribute was not present. The reason to have an explicit empty value +is to provide a way to keep track on the +compile-history of attributes. + + +

{des4:6} +A scalar value is a 7-bit ASCII string of arbitrary lengths, containing only +characters between decimal 32 and 126, tab (\t) and newline (\n). The +interpretation of the value should be detailed in the specification of +the given attribute. + +

{des4:7} +An array value is a one-dimensional, contiguous (free of holes or missing items), +ordered list of values. Array members are indexed with positive integers +starting from 0. Index values can be represented on at most 31 bits, which +also means the largest array may not have more than 231 values. + +

{des4:8} +The format and interpretation of array values are the same as of the scalar +values. The interpretation of array indices is also attribute-specific. + +

4.3. Attribute priority

+ +

{des4:9} +Each attribute has an unsigned 15 bit integer priority. Highest priority +is value 0, lowest priority is value 215-1. + +

{des4:10} +Whenever an attribute is going to be overwritten, the write action +should carry a priority. The write succeeds only if its priority value +is lower or equal to the the priority of the attribute in the target +AoO. When a write fails, the compile-history of the +attribute is still updated with the failed entry. + +

{des4:11} +For most code priority values are arbitrary integers to compare. However, +cschem as a whole have conventions on how priority values are allocated +and assigned: + + +
from to description +
0 0 Priority 0 shall be used for "hardwired" items the user shall not be able to change. +
1 100 user, high tier for group_ref instance +
101 200 user, high tier for group_ref original +
201 300 user, normal for group_ref instance +
301 400 user, normal for group_ref original +
401 500 user, low tier for group_ref instance +
501 600 user, low tier for group_ref original +
1001 10000 plugin, high tier +
11001 20000 plugin, normal +
21001 30000 plugin, low tier +
31001 31100 user, lowest tier +
+

+ +

{des4:12} +Default user priority shall be 250: middle of normal user priority for instances. + +

{des4:13} +Plugins that modify attributes shall use priority values between 1001 and +30000. These values should be assigned by the + view , as a range of priority values +for each plugin the view refers to. Each plugin should get three ranges, +each range should be of 10 values; one from the high tier, one from the normal +and one from the low tier section. E.g. a plugin may get the priority number +ranges 1041-1050, 11041-11050 and 21041-21050. + +

{des4:14} +Plugin ranges shall not overlap with other ranges. There should be an empty +10 value range between every two plugin ranges so that the user can use +priority values in between plugins. + + +

4.4. Attribute source

+ +

{des4:15} +After the concrete model is compiled +into the abstract model , each attributes of the abstract model +has a compilation-history that describes how the final value of that specific attribute +was affected by different sources of information. The complete +compilation-history is stored in the source field, as an array (as specified below). + + +

{des4:17} +Attributes of abstract objects start with an empty compilation-history. Each +successful write shall append and entry to the source array in the following +format: +

+	prio::type::source::description
+
+ +

{des4:18} +where prio is the new priority, source is the identifier +of the information source and description is a short, free form text +in which the source describes the reason for the change. + +

{des4:16}{des4:19} +Type and sources are specified in the following format: +

    +
  • an concrete attribute loaded from a file has "c" in type and + the source shall be in filename,line,col format (,col is optional); + description shall be empty +
  • an abstract attribute coming from the concrete model has "ac" in type and + the source shall be in filename,oid-path,attr-key format; + description shall be empty +
  • type is "pc" for an attribute generated by plugins from a concrete + attribute, source is filename,oid-path,attr-key,plugin-name +
  • type is "pa" for an attribute generated by plugins from an abstract + attribute, source is oid-path,attr-key,plugin-name +
  • an attribute generated by plugins without attribute source + has "p" in type and the source the plugin-name +
  • (if multiple sources were used by a plugin, it needs to pick one main + source and use one of the above three forms) +
  • if external tools modify the abstract model, the type shall be "e", + and source shall be the name of the tool +
  • if the write failed a dash ("-") is appended to the type. +
+ + +

4.5. Attribute compilation process

+ +

{des4:51} +First, all attributes of all concrete objects are copied into attributes +of the abstract objects they contribute to. There are three ways the copy +may happen depending on the first character of the concrete object attribute +key: +

    +
  • starting with minus (-) sign: attribute is not copied to the abstract object +
  • starting with a plus (+) sign: if attribute value is an array, values are appended on merge if there's an attribute collision (the plus prefix is removed from the key in the abstract object attribute) +
  • in any other case: user-user attribute collision is an error +
+ +

4.5.1. Plugin invocation

+ +

{des4:20} +Plugins are invoked in the order specified by the current view. The +view also specifies a range of priorities the invoked plugin may use. +Plugins that are invoked later shall have higher priority (lower +integer priority value). + +

{des4:21} +This means plugins invoked later can use, as input, attributes produced by +plugins invoked earlier. + +

{des4:22} +The same plugin can be present in the same view multiple times, but the +view is a linear list, there are no loops. This means attribute-overwrite-loops +can not form. (Such a loop would be two plugins A and B, A writing an attribute +that is then input of B which writes another attribute that is input for A +which then produces a new version of the attribute.) + +

{des4:23} +Because of the unique priorities mandated by the view, it is also impossible +that two plugins would attempt overwrite the same attribute with the same +priority. + +

4.5.2. Collision handling

+

{des4:24} +A collision is when the same attribute is written twice with the same priority. +There are only two ways attribute collision may happen: +

+ +

{des4:25} +The collision does not happen if the values are the same; in this case +the second write is silently ignored. + +

{des4:26} +An user-user collision is an error; the compilation fails and the +user shall be notified. Typical example is a "slotted" abstract component +that is built of two concrete symbols; if the user specifies e.g. +the "footprint" attribute in both symbols at the same priority but with +different value, cschem has no chance to decide which value to use in the +final "footprint" attribute of the abstract component. The user +should resolve it by: +

    +
  • removing attributes so that only one symbol of the component specifies the "footprint" +
  • raising the priority of the attribute in one of the related symbols +
  • editing attributes in all related symbols to have the same value +
+ +

{des4:27} +A plugin-plugin collision is not an error: the same plugin may decide +to overwrite the value of a specific attribute at the same priority. Since +both values are written by the same plugin in the same session, the value +written later will silently replace the value written earlier. The source +array is appended with the new write; examining the source field will +reveal the multiple writes. + +

4.6. User edits and UI presentation

+ +

{des4:28} +The empty value shall be displayed explicitly; it should be distinguishable +from a scalar value with an empty string, a scalar value with a string containing +white spaces only and an array value with zero elements. + +

{des4:29} +An array value shall be displayed explicitly; it should be distinguishable +from any valid text value. An empty array is a legal construct that needs +to be displayed in a way the user recognizes it and can add items in it. + +

{des4:30} +Setting an attribute to the empty value and removing the attribute from +the concrete object's AoO are two different operations that should both +be available. The first is used as a "strong remove", or "override-remove": +the user may specify the attribute with a high priority empty value to +make sure no plugin or group_ref "inheritance" can create it. The second, +attribute removal, is the "weak remove", which only removes the attribute from +the current AoO, leaving room for plugins to re-create it for the abstract model. + +

{des4:31} +The user should be able to specify arbitrary priority value for any +attribute the user may edit - the priority attribute may even be in a range +not marked as "user". Typical use cases with group_ref: +

    +
  • in group_ref: attribute priority in the "user low tier instance" range: "use this attribute if the library version doesn't have one" +
  • in group_ref: attribute priority in the "user lowest tier" range: "use this attribute if plugins did not set it" +
  • in group: "high tier original" attribute: "prefer this even if the group_ref had a different idea at normal priority" (should be used sparingly) +
  • in sheet, group_ref or atomic objects: knowing the plugin priorities set in the view config, a value higher than of a specific plugin's can be a fallback that says: "use this value if the first N plugins didn't fill in anything, but still don't let later plugins overwrite it" +
+ +

4.6.1. Concrete objects: atoms, groups and sheet

+ +

{des4:32} +Sheet, the drawing primitive group and drawing primitives of type atoms +have a singe AoO. The primary view of such an AoO should include the +attribute key, the attribute value and the user specified priority. It +may be useful to make the source field accessible. + +

4.6.2. Concrete objects: group_refs

+ +

{des4:33} +A group_ref has two sets of AoO: the original AoO as specified in +the referenced group and the instance AoO, that is specific to this +group_ref object. Attribute priority values on the original AoO are +increased by 100. + +

{des4:34} +When the group_ref object is made an input for an abstract object, the two +AoOs are merged and the resulting list is passed a single AoO. + +

{des4:35} +The user interface should present the two AoOs separately and let the user +edit the instance AoO. If the user interface permits edition of the +original AoO, it should make it clear that this will potentially affect +other group_ref objects as well ("editing the library"). + +

{des4:36} +The user interface should present the merge result of the two AoOs. A practical +way to achieve this is not to present 3 AoOs (original, instance, +merged) but to present the original and the merged; when the user +edits the merged AoO, that should affect the instance AoO. + +

4.6.3. Abstract objects

+ +

{des4:37} +When the user is editing the attributes of any concrete object, there is always +zero or one abstract object that is potentially affected. It may be useful +to compile the design and display the resulting abstract object and its AoO +after each attribute modification. The abstract object's AoO shall be read-only, +as the user can modify it only indirectly, by making modifications to an +attribute of a concrete object. + +

{des4:38} +If the abstract object's AoO is displayed, the full list of concrete objects +that contributed to the abstract object should also be listed, preferably +as a clickable cross-reference. + + +

4.7. Typical scalar attribute value formats

+ +

{des4:39} +The following conventions are documented to shorten plugin and +attribute specifications. Any attribute specification can chose one +of these value types/formats or can introduce its own. Formats +specified in this section have a "cschem-" prefix in their name +to make it easier to reference them from the plugin/attribute +specification. Only the most commonly used formats are specified here. + +

{des4:40} +Since the type/format shall be mandated by the attribute, there is no +explicit type/format indication stored with the attribute. + +

{des4:41} +All of these formats specify scalar values and can be used as +a member in an "array-of-" construct. + +

4.7.1. cschem-string

+

{des4:42} +Plain text string. Free form. May include &unicode; characters but +implementations may not have support for displaying unicode. There is no restriction +on the length of the value. May contain newlines. + +

4.7.2. cschem-integer

+

{des4:43} +Unitless integer value, specified in decimal or in hex with a 0x prefix. +The absolute value shall not be larger than 231-1. The value +string may start with a single '+' or '-' character to indicate the sign +or the value; the rest of the characters must be digits (between '0' and '9'). + +

4.7.2. cschem-number

+

{des4:44} +Unitless floating point value, specified in decimal format. Implementations +shall convert and store the value at least with ieee754 double precision. + +

{des4:45} +May have an optional sign, and can be specified in one of the following forms: +

    +
  • integer: -522, +522, 42., 001 +
  • decimal: -522.91, +522.31, 42.0000, 001.00700 +
  • exponent: -5.2291e+2, +5.2231E+02, 4.200000e+1 +
+ +

4.7.3. cschem-value

+

{des4:46} +A cschem-number followed by a unit. There may be zero or more whitepsace +between the two. The unit is a case sensitive series of letters +('a'..'z', 'A'..'Z', including '&unicode;') or a single dash ('-'). +If the unit is omitted or is a dash, the value is unitless. Unicode support +is optional. + +

4.7.4. cschem-uid

+

{des4:47} +An UID value stored as text. Useful for referencing other objects within +the design. + + +

4.7.5. cschem-symlink

+

{des4:48} +The value is a reference to the value of another attribute. By default +the symlink is followed, and the value of the attribute the symlink +points (the deref'd value) to is returned whenever the attribute value +is accessed by any code, unless the code explicit requests to avoid +dereferencing. (Typically a GUI will display both the symlink value and +the deref'd value and lets the symlink value be edited.) + +

{des4:49} +The syntax of the the symlink value is objectpath::key, where +objectpath is one of the following: + + +
syntax meaning +
. another attribute of the same object +
.. an attribute of the parent group +
role an attribute of the closest parent group with role attribute matching role, walking up the tree of group +
sheet an attribute of the current schematics sheet +
+ +

{des4:50} +.. and role can be combined to form a path (e.g. a full +reference could be symbol/..::pcb/footprint). + Index: tags/1.0.5/doc/design/04_attrib_imp.html =================================================================== --- tags/1.0.5/doc/design/04_attrib_imp.html (nonexistent) +++ tags/1.0.5/doc/design/04_attrib_imp.html (revision 10414) @@ -0,0 +1,261 @@ + + +

4. cschem implementation - attributes

+ +

4.1. Are priorities distractive?

+ +

{imp4:0} +Attribute priorities are designed with {pol:3} in mind: +

    +
  • in the most common, simple use cases, the user can ignore + attribute priorities +
  • for complex tasks priorities can be used to have full control over + what part of the system may overwrite a specific attribute +
+ +

{imp4:2} +The simple case has the following attribute modification precedence: +

    +
  • plugins may ovewrite attributes that are not explicitly specified by + the user (on the sheet or in the lib) +
  • if multiple plugins are going to write the same attribute, there is + an explicit, simple, clear order of plugin precedence mandated by the + view configuration +
  • attributes specified by the user in library (referenced groups) + are stronger than attributes calculated by plugins (i.e. an attribute + explicitly specified in a library symbol won't be overridden by a + plugin by default) +
  • attributes at the place of group_ref override attributes coming + from the referenced group or plugins (i.e. attributes of a symbol instance + override attributes from the lib or plugins) +
+ +

{imp4:3} +To achieve this, cschem needs only two conventions: +

+ +

{imp4:4} +In that simplest and most common case, the user ignores priorities so all +attributes the user creates will have the same priority. The user needs to +make sure not to enter contradictionary attributes. Library attributes +automatically get lower priority due to the +100 offset. Plugins +automatically get lower priority due to their priority range starting over 1000. +Every plugin uses only their "normal" priority range. The only priority-related +feature the UI needs to display is the order of plugins in the view. + +

{imp4:5} +This is pretty much how gschem worked implicitly, except a few corner cases +are handled better in cschem: +

    +
  • "lib attributes overriden by local attributes" works in both +
  • gschem silently accepted attribute collision and the user had no way to prioritize one attribute over the other; the outcome of the collision was hard to predict +
  • gschem backends/mechanisms could freely overwrite user attributes +
  • gschem could not run multiple backends in a modular/flexible way, only multiple mechanisms (such as slotting) plus one backend; the order of these were hardwired +
+ +

{imp4:6} +The next simple step is when the user manually bumps the priority of an +attribute. A common example is to raise the priority to resolve a collision. +Another trivial example is to lower the priority to make a locally specified +attribute a fallback but let specific (or all) plugins override it. + +

4.2. attribute key "paths"

+ +

{imp4:7} +Attribute keys within an AoO form a flat map - most of the code do not need +to care about the actual format of the key string. This works well as long +as there are only a few plugins and attributes defined. However, as the +number of attribute specifiers increase, there will be more and more collisions. + +

{imp4:8} +A typical example is the identifier of a pin: the same schematics may be the +source of simulation and the source of a pcb layout. In both cases a specific +pin of a component needs to be addressed, but the same pin may have a different +address ("pin number") for simulation and for PCB. The user needs to specify +both, thus the key must differ. A possible solution is to use "pinnumber" +and "pinseq", but that might be confusing - "number" and "seq" doesn't +really explain that one is for PCB or about the physical object the other is +for the SPICE syntax. However, it already has a common prefix: "pin". + +

{imp4:9} +The "path" syntax standrardizes the solution for this situation, recommending +to use "pcb/pinnum" and "spice/pinnum" instead of "pinnumber" and "pinseq". When +the convention is used consistently, attributes are groupped by their name. +The UI may offer very simple ways, such as alphabetic ordering, or more +complex ways, such as tree view, for helping the user navigate among the +attribute groups. Still, the non-UI code does not need to explicitly know +about these groups, these are just naming conventions. + +

{imp4:10} +Similar method is used by the OpenStreetMap project, where tag naming +conventions use ":" separators,such as building:levels or name:en, name:de. + +

{imp4:11} +This may sound painful to use in practice, e.g. user would need to set +the "pcb/footprint" attribute instead of simply setting the "footprint". +The practical solution for this would be a plugin that can convert short +named attributes to long named attributes. For example the + device mapper plugin +will look for a device specification (short named); when that's found, +it will consult the database and render pcb/footprint and the pinout; if +it is not found, it will look for "footprint" and copies that to +"pcb/footprint". If the user wants to override the final footprint, the +user can enter "pcb/footprint", with the default user priority this will +easily override the value the device mapper would emit. + +

{imp4:12} +At the end, as {imp4:13} suggests, trivail cases are easy: the good old +"footprint" attribute works; it is just not a hardwired behaviour but +the result of an opitonal plugin. + + +

4.3. hash vs. list vs. array vs. scalar

+ +

{imp4:14} +Vast majority of attributes will be a simple text string that is +interpreted in an attribute-specific way, usually following one +of the "cschem-" formats. This setup is flexible and easy for both +users and programmers. + +

{imp4:15} +However it's also common that the value is a list of, or array of +scalars. To avoid each attribute and plugin inventing its own syntax +for listing multiple values, cschem specifies attribute values to +be either scalar or array. + +

{imp4:16} +Furthermore attribute keys can be regarded as "paths" within their AoO, +using the "path separator" slash. This is only an UI convention, the +code does not need to care about it. + +

{imp4:17} +This means from the UI perspective the attribute subtree has a hash root, +using the "paths" may have "hash children". The last level can be an +array (if the attribute value is an array), but the leaves, the actual +values are always scalar. + + +

4.4. examples

+ +

4.4.1. compilation history of a pin number

+ +

{imp4:18} +Assume the following view: +

    +
  • gschem_slot (compatibility plugin): normal pirority 15081..15090 +
  • devmap plugin (device mapper): normal pirority 15041..15050 +
  • export_pcb: normal pirority 12011..12020 +
+ +

{imp4:19} +A typical attribute source for the pin's pcb/pinnum would be: +

+15085::p::gschem_slot::slotting
+15045::p::devmap::derived from devmap
+
+The final value is the one from 15045 + +

{imp4:20} +And for the display/number attribute (that would tell the GUI what +pin number to display): +

+12015::p::export_pcb::derived from pcb/pinnum
+
+ +

{imp4:21} +If the user has a manual override on the pin number, the +history of pcb/pinnum would look like this: +

+350::u::my_symbol.lht:32.11::
+250::u::foo.lth:182.4::
+15085::p-::gschem_slot::slotting
+15045::p-::devmap::derived from devmap
+
+First the value was set by the library (350), then got ovrridden by the +instance-value specified by the user in the group_ref (250). The slotting +plugin an the device mapper failed to modify the user specified value. +The final value is the one from 250. + +

{imp4:22} +If the user has a weak manual falback on the pin number, the +history of pcb/pinnum would look like this: +

+31050::u::foo.lth:182.4::
+15085::p::gschem_slot::slotting
+15045::p::devmap::derived from devmap
+
+First the value was set by the instance-value specified by the user in +the group_ref (31050). The slotting plugin an the device mapper can then +modify the user specified value. The final value is the one from 15045. If +the slotting or the devmap plugin did not modify the attribute, the user's +weak value from 31050 would be the final value. + + +

4.4.2. example on attribute symlinks

+ +

{imp4:23} The +symbol/..::pcb/footprint means "find the closest symbol we are in, +go one group up and use the pcb/footprint attribute from there". + +

{imp4:24} +A more typical use is referencing a parameter attribute in a hierarchical +design. For example in the child sheet implementing an amplifier will contain +6 opamps. The footprint attribute (attribute key called "pcb/footprint") should +not be hardwired in the child sheet but should be provided by the parent. This +is realized by: +

    +
  • the opamp symbols used in the child sheet has its pcb/footprint + attribute as a chscem-symlink pointing to "sheet::cschem/param/omamp-footprint" +
  • there is a default value specified in the child sheet attributes: + cschem/param/omamp-footprint = so8 +
  • the parent sheet symbol that instantiates the child sheet contains + an attribute cschem/param/omamp-footprint = dip8 +
+ +

{imp4:25} +When the instantiation happens, the parent symbol's atribute will override +the sheet's original cschem/param/omamp-footprint attribute, so the final +value of that attribute for this instance is "dip8". When the abstract model +is compiled, the final value of the component's pcb/footprint will be copied +from the sheet instance's cschem/param/omamp-footprint attribute because of +the symlink dereference, thus will end up as dip8. + + +

4.4.3. example on attribute key prefixes

+

{imp4:26} +In slotting, multiple (concrete) symbols have the same name and will be merged +into the same (abstract) component. Most attributes, like footprint, are +either specified only once, or if they are specified in multiple symbols +they have same value so there's no collision. + +

{imp4:27} +However, when using devmap, the user also needs to specify the slot +number, per symbol. Normally this would be slot=1, slot=2, slot=3, ... +attributes, but these would collide during merge. The solution is to +prefix keys with a minus sign, so symbol attributes are -slot=1, -slot=2, +-slot=3. Minus prefixed conrete attributes are ignored during compilation, +the resulting component does not have a slot attribute and there's no collision. + + +

4.4.4. safe keys for user attributes

+

{imp4:28} +Users would store their own attributes in groups, especially in symbols +and wirenets. They would choose arbitrary attribute keys that do not +clash with current attribute keys used by the code of a given +implementation (e.g. sch-rnd) at the given time. However, future +versions of the same implementation or a different implementation could +use that same attribute key for other purposes, causing a clash, making +the user's sheet non-portable. + +

{imp4:29} +To avoid this problem, the convention is that attribute key prefix usr/ +is reserved for user attributes: no code shall depend on such attributes. +Such attributes shall be used exclusively by the user, e.g. on the GUI +or exported to netlists and BOMs. + + + Index: tags/1.0.5/doc/design/05_netlist.html =================================================================== --- tags/1.0.5/doc/design/05_netlist.html (nonexistent) +++ tags/1.0.5/doc/design/05_netlist.html (revision 10414) @@ -0,0 +1,105 @@ + + +

5. Netlist

+ +

{des5:0} +In cschem terminology a netlist is a custom, 3rd-party application specific +file format that is derived (typically by a +plugin) from the abstract model. + +

{des5:1} +The type of information that ends up in a netlist depends on the +application. The export plugin will +

    +
  • filter the abstract model and include only the relevant subset of the model +
  • process the objects of the abstract model to generate summaries, indices, metadata for the netlist +
+ +

{des5:2} +Thus the term netlist used in cschem doesn't necessarily mean an +actual list of networks, but a more generic package of information intended +for annotation (data exchange between different software), that +may or may not include a list of networks, or a list of components or ports. + +

{des5:3} +Independently of the details of the netlist file format, it mainly consists +of netlist objects, each derived from the objects of the abstract model. +In a netlist file format specific way, each netlist object can be +uniquely identified (netlist ID) and referred to: +

    +
  • some formats support a netlist-unique name or ID +
  • structured formats often support a path within the document tree of the netlist +
  • as an ultimate fallback the generator can refer to the line.column location of the object within the generated text file or the binary byte offset within the generated binary file +
+ + +

5.1. Netlist map: format

+ +

{des5:4} +It is strongly recommended that any netlist export plugin should generate +a netlist map as a side effect. The map can be part of the netlist emitted +(in case the netlist file format supports arbitrary attachments, comments, +text blocks, etc.) or a separate file. + +

{des5:5} +The map file is a flat list of netlist ID, netlist object type, +concrete model references tuples. + +

{des5:6} +A netlist ID is netlist +file format specific, the concrete model references is a list of +concrete model references. The netlist object type is a netlist +format specific string that refers to the type of the ID, e.g. "component" +or "pin" or "net". + +

{des5:7} +A concrete model reference (CMR) is either an UID of a concrete +object (when the whole object is referenced) or the UID:key pair when +an attribute of the object is referenced. + +

{des5:8} +In practice this means if a cschem network ends up as network identified +as "pgnd" on the netlist, the map file will have an entry identified as +"pgnd" of type "net" containing a list of CMRs to every concrete object that +contributed to the network. This typically includes a few network UIDs +and a few by-attribute-connections, e.g. a connect attribute of a symbol +(in the form of UID:connect where UID is the UID of the symbol). + +

{des5:9} +Similar to that, if the netlist has a component +called "C2", the map will have a UID list pointing +to concrete symbols that built up C2 in the netlist. Again +similar, if the netlist refers to pin C2-1, the map for pin "C2-1" +will contain the UID of the concrete terminal that got derived into C2-1 +in the export. + +

{des5:10} +(Note: it is possible to build the CMR list because each abstract model +object contains a list of the concrete model +objects that created the given abstract object) + + +

5.2. Netlist map: purpose

+ +

{des5:11} +The purpose of the netlist map is to provide a mechanism through which +an object identified in a 3rd party software can be tracked back to +concrete objects on the corresponding schematics sheets. + +

{des5:12} +A cschem GUI is required to implement an UI that displays a list of netlist map +items: the netlist ID and type as a header and the list of CMRs. The UI shall +assist the user to navigate to the concrete objects listed as a CMR; e.g. +if the user clicks a CMR, the relevant schematic page is displayed with +the referred object centered and/or highlighted. In case of an attribute +reference optionally the attribute edition prepared/presented. + +

{des5:13} +This should create a tool-agnostic bridge between arbitrary 3rd-party +software and cschem: +

    +
  • the user selects an item in the 3rd party software (e.g. clicks on a pin in a PCB editor or names a pin in a spice simulation) +
  • the information of the selection is transferred to a map-lookup-tool, an external program or a plugin/addon running within the 3rd party software +
  • the map-lookup-tool looks up the map item in the netlist or map file and sends it back to a running instance of cschem (e.g. through a project manager) +
  • cschem presents the map item helping, effectively displaying the concrete objects of the schematics that eventually created the object which the user selected in the 3rd party software +
Index: tags/1.0.5/doc/design/06_example1.svg =================================================================== --- tags/1.0.5/doc/design/06_example1.svg (nonexistent) +++ tags/1.0.5/doc/design/06_example1.svg (revision 10414) @@ -0,0 +1,82 @@ + + + + + + +hierarchy + +cluster_1 + +top level + + +top + +top sheet + + +an + +an + + +top->an + + + + +dig + +dig + + +top->dig + + + + +amp1 + +amp + + +an->amp1 + + + + +amp2 + +amp + + +an->amp2 + + + + +amp3 + +amp + + +an->amp3 + + + + +amp4 + +amp + + +an->amp4 + + + + + Index: tags/1.0.5/doc/design/06_example2.svg =================================================================== --- tags/1.0.5/doc/design/06_example2.svg (nonexistent) +++ tags/1.0.5/doc/design/06_example2.svg (revision 10414) @@ -0,0 +1,306 @@ + + + + + + +hierarchy + +cluster_1 + +future user: a parent sheet + +cluster_2 + + + +ext_gnd + +ext_gnd + + +gnd + +./gnd + + +ext_gnd->gnd + + + + +ext_vcc + +ext_vcc + + +vcc + +./vcc + + +ext_vcc->vcc + + + + +ext_ctrl + +ext_ctrl + + +ctrl + +./ctrl + + +ext_ctrl->ctrl + + + + +ext_enable + +ext_enable + + +enable + +v/enable + + +ext_enable->enable + + + + +ext + + +top +top sheet + + +ext->top + + + + +chgnd + +chgnd + + +top->chgnd + + + + +an + +an + + +top->an + + + + +dig + +dig + + +top->dig + + + + +agnd + +./agnd + + +gnd->agnd + + + + +dgnd + +./dgnd + + +gnd->dgnd + + + + +avcc + +./avcc + + +vcc->avcc + + + + +dvcc + +./dvcc + + +vcc->dvcc + + + + +agnd->an + + + + +dgnd->dig + + + + +avcc->an + + + + +dvcc->dig + + + + +ctrl->an + + + + +ctrl->dig + + + + +amp1 + +amp + + +an->amp1 + + + + +an->amp1 + + + + +amp2 + +amp + + +an->amp2 + + + + +an->amp2 + + + + +amp3 + +amp + + +an->amp3 + + + + +an->amp3 + + + + +amp4 + +amp + + +an->amp4 + + + + +an->amp4 + + + + +dig->chgnd + + + + +dig->enable + + + + +amp1->enable + + + + +chgnd1 + + +amp1->chgnd1 + + + +amp2->enable + + + + +amp2->chgnd1 + + + +amp3->enable + + + + +amp3->chgnd1 + + + +amp4->enable + + + + +amp4->chgnd1 + + + +chgnd1:n->chgnd + + + + + Index: tags/1.0.5/doc/design/06_hierarchy.html =================================================================== --- tags/1.0.5/doc/design/06_hierarchy.html (nonexistent) +++ tags/1.0.5/doc/design/06_hierarchy.html (revision 10414) @@ -0,0 +1,254 @@ + + +

6. Hierarchy

+ +

{des6:0} +The abstract model is flat, but the source (the concrete model) from which +the abstract model is generated may be hierarchic. Since each object of the +flat abstract model remembers which concrete model object(s) it was derived +from, the output can again be hierarchical. + +

{des6:1} +In that flat abstract model, there is only one namespace for components +and one namespace for networks. The component namespace consists of +component names (and uuids), and the network namespace consists of network +names (and uids). + +

{des6:2} +Since networks are often referenced by name from the schematics, an auxiliary +global namespace is provided for networks that are used in the concrete model, +where they are identified by their netname and scope. + +

6.1. Topology

+ +

{des6:3} +A multi page project is called hierarchical if at least one sheet references to another sheet. The system of references +forms one or more loop-free trees, each with a single root sheet. The +list of root sheets is considered the "top level list of root sheets" or in +short, "root sheets" (or "top level sheets") for the project. + +

{des6:4} +Hierarchy affects how networks are created and referenced. +When a network is referenced by netname, the reference is either: +

    +
  • without a prefix, in which case an auto search + is performed within the hierarchy to find the closest network of + matching netname +
  • or with a prefix, in which case a controlled search + is performed + within the hierarchy to find the closest network of that name +
+ +

6.1.1. multi-page flat project

+ +

{des6:5} +If a project contains multiple schematics pages without hierarchical +cross-references, its topology is called a multi-page flat project. In +other words the top level consists of multiple root sheets but no sheet has +references to other sheets. It is possible to connect networks between +the pages using global nets. + +

6.1.2. single-tree hierarchy

+ +

{des6:6} +There is a single root sheet and all other sheets are accessible through +sheet references. In other words, the top level consists of only one +sheet and that sheet has references to other sheets. This setup can +exploit the subtree based netname references. The root sheet is very often +a map of the first level sheets and the connections between them. + + +

6.1.3. mixed: multi-tree hierarchy

+

{des6:7} +There are multiple root sheets, some of them with sheet references. In +other words, the top level consists of a list of trees. This setup can +exploit the subtree based netname references and global nets. The root +sheets are often a map of the first level sheets and the connections +between them, but there's no explicit map of the root sheet +interconnects, only the implicit binding of global networks. +Sheets are typically listed in the project file and marked whether they +are root sheets or not. + + +

6.2. Netname scoping

+ +

{des6:8} +Network names (netnames) determine the scope (visibility) of the network +within the tree of sheets in the concrete model. The scope of a network +is always one of the scopes from the table below. + + +
scope syntax description +
global /netname visible from anywhere in the hierarchy +
subtree-local v/netname visible only from within a subtree of the hierarchy +
sheet-local ./netname visible only from within the same sheet +
auto netname bind to an existing sheet-local net if available, else to a subtree-local net, else to a global net, else create a new global net +
subtree-auto ^/netname similar to auto, but is looking only for subtree-local (v/) networks - no locals and no globals; when subtree-local net is not found, an error is generated +
+ + +

{des6:9} +Global nets are accessible from any point from the hierarchy. If a subtree-local +or sheet-local network has the same name as a global net, it is shadowing the +global net: the auto references will prefer those local networks. However, +the global network can always be referenced using the / prefix, which overrides +the auto search. + +

{des6:10} +Global networks are created when first referenced (with the explicit / +prefix syntax or with the auto or subtree-auto syntax). + +

{des6:11} +A subtree local net can be regarded as a "group local" network, is +visible under a subtree. It is intended to provide a mechanism for creating +a "global net" locked into a local tree of sheets, allowing the tree to +be reused as part of a larger project without introducing interfering global +networks. + +

{des6:12} +Defining a new subtree-local network is done by using the netname prefix +v/; this anchors the netname to the current sheet. Auto netnames from +this sheet and sheets below this sheet will find this network if looking +for a sheet-local network failed. To prefer the nearest subtree-local +network over local networks, the subtree-auto ^/ prefix can be +used: this will start walking up in the hierarchy to find the closest +subtree-local net of matching netname. If that fails and the root sheet +is reached, the compilation fails (no abstract model is produced). + +

{des6:13} +A sheet local net is visible only within the same sheet. It is +intended to provide a mechanism for creating a local network in a sheet +that is going to be reused as a part of a hierarchy, without the local +netname interfering with global netnames. + +

{des6:14} +The most common netname is the auto netname, without prefix. This +reference will do an upward tree search for the closest suitable netname: +

+ +

6.3. Hierarchical reference

+ +

{des6:15} +A concrete schematics sheet may reference another sheet via a symbol +(called the sheet reference symbol). +The symbol represents a new instance of the referenced sheet. + +

{des6:16} +The current sheet with the symbol is called the parent sheet and the +referenced sheet "behind the symbol" is called the child sheet. The +parent-child relation is the one represented by the hierarchical tree of +the schematics sheets. + +

{des6:17} +The referenced sheet is addressed by one of the following attributes +(only one of these shall be specified in a symbol): + + +
attribute key value syntax meaning +
cschem/child/uuid uuid first the project then the hlibrary is searched for a sheet with matching uuid +
cschem/child/name string first the project then the the hlibrary is searched for a sheet with matching file name; if contains any slash character, it's a path within the hlibrary relative to the current sheet's path within the hlibrary +
cschem/child/path string path relative to the directory the current sheet is last saved in +
+ +

{des6:18} +Configuration setting hlibrary is a list of paths where schematics +sheets for use in hierarchy are stored on the file system. It is similar, but +orthogonal to the symbol library paths (but upon the user's decision there +might be overlap between the two). + +

{des6:29} +An implementation that supports project files typically keeps a list of all +root sheets in the project file and another (auxiliary, aux) list of all +other referenced from the root sheets. When a new reference is made (new +symbol is placed with cschem/child/* attribute), the aux list of the project +file is extended with the new file. Thus the project file always contains a +full list of sheet files needed for reproducing the hierarchy. + + +

6.3.1. Network connections - network parameters

+ +

{des6:19} +Networks between the current schematics and the referenced schematics are +connected in explicit and implicit ways. Implicit (non-graphical) connections +are done by referencing a netname, +using the "connect=" attribute. + +

{des6:20} +The explicit way of connecting networks is using the terminals +of the symbol. On the parent sheet, symbol terminals and bus-terminals +can be connected to local or global networks. On the child sheet, these +connections are realized by terminals and bus-terminals placed +directly on the sheet, outside of symbols. + +

{des6:21} +Explicit passing of a network using terminals helps keeping the namespaces +clean: the short, virtual "network segment" between the parent and the +child has no global name, only sheet-local representations as terminals on +both sides of the relation. It can also be regarded as a "network parameter" +for the subcircuit instance. + +

{des6:22} +The number, the type (terminal vs. bus-terminal) and the name attribute +of the ports of the symbol and the child sheet must match. Any mismatch results +in a compilation error (no abstract model is created). + +

6.3.2. Attributes - attribute parameters

+ +

{des6:23} +If the parent symbol contains attributes whose key start with the +cschem/param/ prefix, those attributes are copied into the child sheet +instance, with the same key and value, as sheet attributes. + +

{des6:24} +This mechanism is provided as a safe, explicit way for passing attributes +as arguments. Because of the key prefix limit, the parent can not +accidentally overwrite child sheet attributes. The API (the list +of cschem/param/* keys the child sheet will understand) can be specified +by the user and made known for both the implementor of the child sheet +and the parent sheet. + +

{des6:25} +In a typical application, on a child sheet, symbol, terminal and other +object attributes will symlink to "sheet::cschem/param/" keys to access +the parameters specified by the parent. + +

6.4. Other considerations

+ +

{des6:26} +Unnamed wire-nets are always treated as being local (as if they had a +./ prefix in their netname) as they shall never connect to a global network +by name. + +

{des6:27} +Abstract model netname generation: since the netname in the abstract model +must be project-wise unique, it can not be the same name used in a hierarchical +schematics. The exact details of the name translation is up to the plugin +that implements the translation. A typical example would be: +"refdes/refdes/refdes/netname" where refdes is the hierarchy down-reference +symbol's refdes attribute and netname is the netname attribute of the network +with the scope prefix removed. If the user doesn't chose a plugin, the default +behavior is to use the network's uuid as abstract netname. Normally the +renaming does not affect global nets, only subtree-local and sheet-local nets. + +

{des6:28} +Similar to netnames, abstract component names may be required to be unique +by the exporter plugin. In this case either the exporter plugin or an +intermediate plugin is used to attach human readable unique names deduced +from the hierarchy (e.g. "refdes/refdes/refdes"). Just like with the netnames, +this name translation is optional. The same name prefixes +can be used +(global, sheet-local, auto, subtree-local, subtree-auto) +on symbol names to control how they are merged into components. + + + Index: tags/1.0.5/doc/design/06_hierarchy_imp.html =================================================================== --- tags/1.0.5/doc/design/06_hierarchy_imp.html (nonexistent) +++ tags/1.0.5/doc/design/06_hierarchy_imp.html (revision 10414) @@ -0,0 +1,180 @@ + + +

6. cschem implementation - hierarchy

+ +

{imp6:0} +Hierarchical design is implemented in a way that keeps non-hierarchical +design simple while does not complicate hierarchical design too much either. +Carefully designed non-hierarchical sheets can be easily reused in hierarchical +designs - the most important thing to note is how global networks are used. + +

6.1. Topologies

+

{imp6:1} +The following table demonstrates all 3 topologies mentioned in the specification: +
+ + + +
flat + single-tree + multi-tree +
+ + +
+ +

{imp6:2} +Notable special cases: +

    +
  • A single-sheet schematics is considered flat +
  • A multi-page schematics with a single train of reference is considered hierarchical +
  • as the above multi-tree example shows, a single root page with no children is also considered a subtree in such a setup +
+ + +

{imp6:3} +The multi-tree setup could have a new top sheet that just references all the roots +and it's then a single-tree setup. So how does the multi-tree setup differs from +the single-tree setup? Only that it does not have such a single top-level sheet +that references all others. The reason to keep this possibility open is the +project file. A project file can list all the top level sheets (roots), having to have +a redundant or extra top level file just for this list would be annoying. On +the other hand, the project file can describe non-cschem-aspects of the project, +which a schematics sheet can't, so it's not possible to omit the project file +as an optional feature. + + +

6.2. Hierarchical example for all network parameter types

+ +

{imp6:4} +Assume there is a project with two sections: a sensitive analog circuitry +(called "an") and a high frequency logical control circuitry (called +"dig"). The analog circuit contains 4 copies of the same subcircuit +("amp") and some glue. The whole design is a module that could be used in +a bigger circuit. + +

{imp6:5} +This section gives one of the many possible ways to implement this with cschem, +described in a top-down way. + +

{imp6:6} +Because of its simplicity, the single-tree topology is chosen. A top sheet +(root sheet) is created with two symbols: one for "an" and one for "dig", with +symbol attribute cschem/child/name set to "an" and "dig" respectively. +

+ + +

{imp6:7} +There will be a few control signals that need to travel between the two; +these are added as terminals to both symbols and they are connected with +wires-nets on the top sheet. an and dig also need to take power, +"Vcc" and "GND" terminals are added on both. The top sheet is a good place to +connect the Vcc of the two worlds with ferrite beads and capacitors added +to avoid digital noise ending up in "an", separating the networks to +avcc/dvcc and agnd/dgnd. + +

{imp6:8} +We will have a subtree-local "enable" signal that should be used by both +"an" and "dig" to enable the circuitry. Instead of passing this through terminals, +we will define it as a subtree-local circuit, "netname=v/enable" on the top +sheet. + +

{imp6:9} +Since the whole project would be a reusable part within a bigger project, the +top page should have terminals to get networks from a parent later. These +terminals shall be named, placed on the sheet and connected to the a network. +Our network "v/enable" will be connected to a sheet terminal called "enable". + +

{imp6:10} +For "dig" we create a single sheet. It should have sheet-level terminals +matching the ones we used on the top sheet for the "dig" symbol. We do +not have a terminal for the enable signal, tho: whenever we need to connect +a symbol terminal to it, we can just add a "connect=^enable", which means +"connect to our parent's enable signal". The rest of the signals and +connections can be realized normally, as if this was the only sheet; named +networks should have the "./" prefix in their netname to avoid binding to global +nets. + +

{imp6:11} +For "an", we follow the same procedure, except it won't have much of its own +circuitry will be 4 copies of the same symbol referencing to "amp". Most probably +"an" will never need to use the "enable" signal. + +

{imp6:12} +We create the "amp" sheet, the same way as we did create the digital +sheet. We again can use the "connect=^enable" trick to connect terminals to +the enable signal defined on our top sheet. + +

{imp6:13} +Finally, there should be a global chassis ground. Every module that has +any electronics in it shall be connected to the chassis ground. This is +realized by a global network chgnd, assumed to "just exist". It would be +normally created by the user of our subtree. Connection to the chassis +ground is done by "connect=chgnd" (which does not enforce "chgnd" +to be global, but allows that). + +

{imp6:14} +The final "flow of nets" is as shown on the figure below. Blue objects are +sheet-local; red arrows represent a connection through terminals on both ends; +green lines are subtree-local network bindings, without the use of terminals. +Purple lines are global network bindings. +

+ + +

6.2. Considerations for the example

+ +

{imp6:15} +We did not enforce "chgnd" to be global, but referenced it without a +prefix: lookup scope is "auto". This means a search is started from +bottom up, and the first subtree-local "chgnd" can be used, or as a +fallback, the global one will be used (or even created if nobody else did yet). +It's a good practice to do this: we can not be sure what hierarchy we'd have +above us, and it may be that the user will want to quarantine us chgnd-wise, +by creating a "v/chgnd" a few levels up. This way the "chgnd" network can be +split up by subtree. + +

{imp6:16} +Referencing the enable network from amp as "^/enable" is safe: even if +the hierarchy above us have "v/enable" defined, the search will always +stop at the innermost hit, so "amp" will always bind to the "v/enable" of +"an". + +

{imp6:17} +This is a typical use of subtree-local networks: instead of complicating the +API of both "an" and "amp" by more ports for networks that will be shared +by all instances anyway. It's sort of a global network, without "infecting" +other parts of the hierarchy. The actual way it's bound to ext_enable can +be a simple "connect=v/enable" on the sheet level (input) terminal for +the "enable" network on the top sheet. This would both create "v/enable" +and connect it to the input. + +

{imp6:18} +Reusing "amp" in another project without "an" is easy. The API of +"an" is defined as: +

    +
  • the symbol that references "an" must have 3 ports (agnd, avcc, ctrl) +
  • one of the parents of "an" in the new hierarchy must provide a "v/enable" network +
  • there should be a global "chgnd" network, created anywhere (but it's not fatal if there is none) +
+ +

{imp6:19} +In a hierarchical setup global nets like chgnd is dangerous and probably +better to avoid. For example if no other sheet creates a chgnd, multiple instances +of "an" will still create one and get connected through it in a way that this +network is then never really grounded. The obvious reason chgnd is included +in the above example is to demonstrate how global nets work. The reason +the concept of global nets exists in cschem is to support the flat topology. + +

6.3. How the netlist would be generated

+ +

{imp6:20} +In case of flat netlist syntax: the hierarchy exists only in the concrete +model - once the project is compiled into an abstract model, that model is flat. +Generating the flat netlist from the flat abstract model should be trivial, +especially that names are already unique and flat in the abstract model. + +

{imp6:21} +In case of hierarchic netlist: there are strong cross-referencing between +the flat abstract model and the hierarchic concrete model. The exporter +plugin would start working from the abstract model and by looking at +the cross references it would be able to understand the original hierarchy. Index: tags/1.0.5/doc/design/06_topo1.svg =================================================================== --- tags/1.0.5/doc/design/06_topo1.svg (nonexistent) +++ tags/1.0.5/doc/design/06_topo1.svg (revision 10414) @@ -0,0 +1,28 @@ + + + + + + +flat + + +sheet1 + +sheet1 + + +sheet2 + +sheet2 + + +sheet3 + +sheet3 + + + Index: tags/1.0.5/doc/design/06_topo2.svg =================================================================== --- tags/1.0.5/doc/design/06_topo2.svg (nonexistent) +++ tags/1.0.5/doc/design/06_topo2.svg (revision 10414) @@ -0,0 +1,38 @@ + + + + + + +flat + + +sheet1 + +sheet1 + + +sheet2 + +sheet2 + + +sheet1->sheet2 + + + + +sheet3 + +sheet3 + + +sheet1->sheet3 + + + + + Index: tags/1.0.5/doc/design/06_topo3.svg =================================================================== --- tags/1.0.5/doc/design/06_topo3.svg (nonexistent) +++ tags/1.0.5/doc/design/06_topo3.svg (revision 10414) @@ -0,0 +1,58 @@ + + + + + + +flat + + +sheet1 + +sheet1 + + +sheet2 + +sheet2 + + +sheet1->sheet2 + + + + +sheet3 + +sheet3 + + +sheet1->sheet3 + + + + +sheet4 + +sheet4 + + +sheet5 + +sheet5 + + +sheet4->sheet5 + + + + +sheet6 + +sheet6 + + + Index: tags/1.0.5/doc/design/07_devmap.html =================================================================== --- tags/1.0.5/doc/design/07_devmap.html (nonexistent) +++ tags/1.0.5/doc/design/07_devmap.html (revision 10414) @@ -0,0 +1,167 @@ + + +

7. Device mapping

+ +

{des7:0} +Device mapping is a generic mechanism for detaching schematics +symbols from footprints and simulation models. It allows: +

    +
  • interchangeable symbols and interchangeable footprints/models for + the same generic device (e.g. transistor) by decoupling + their pin numbers from pin names (problem known as the "transistor problem") +
  • multiple symbols to represent different parts of one physical + footprint or simulation model (problem known as "slotting") +
+ +

{des7:1} +These goals are achieved by using symbolic terminal names (instead +of "pin numbers") in the schematic symbols and using auxiliary data to translate +the terminal names into port numbers. The following diagram demonstrates +the process: + +

+ +

{des7:2} +The default implementation of the device mapper is a plugin called std_devmap. +std_devmap has three major features: slotting name translation +(red), device mapping (green) and port mapping (blue). The slotting translation +makes sure the resulting abstract component has the right amount of ports; +the device mapper loads the device-specific port mapping and other +attributes from a database; the port mapper applies pin numbers from +a table (the table typically set up by the device mapper). + +

{des7:3} +The standard device mapper is an optional mechanism implemented in a plugin. The +user may choose to use it or to: +

    +
  • not include the device mapper in the view at all +
  • not using the slotting mechanism described here, on per symbol basis, + by not having a slot attribute +
  • not using the device mapping mechanism described here, on per symbol basis, + by not having a devmap attribute +
  • not using the port mapping mechanism described here, on per symbol basis, + by not having a portmap attribute and not using a device map + that would introduce a portmap attribute +
+ +

{des7:4} +It is possible to use features of this plugin selectively and/or replace +some or all features using another plugin. + +

{des7:5} +std_devmap registers for: +

+ +

7.1. Slot prefixing

+ +

{des7:6} +If the "slot" attribute presents in a symbol, and the terminal does +not have the "noslot" attribute, the translation is activated. The slot +name is taken directly from the concrete symbol's "slot" attribute. +All ports are then named as "slot/terminal-name" and the slot +attribute is then removed from the abstract component to avoid +collisions. + +

{des7:7} +Typical example: common opamp symbol: + +

+
{des7:9} example opamp terminal attributes +
name noslot terminal description +
in_plus (not present) positive input pin +
in_minus (not present) negative input pin +
out (not present) output pin +
v_plus "yes" positive power rail +
v_minus "yes" negative power rail +
+ +

{des7:10} +In the above example "v_plus" and "v_minus" are never prefixed with "slot/" because +of their "noslot" attribute. In case the symbol is used with the "slot" attribute +set, this means: +

+ +

{des7:11} +Note: when the same symbol is used in a non-slotted use case, the symbol will +not have the "slot" attribute; in this case no terminal name translation +applied and the resulting abstract component will have the same port names +as the terminal names of the symbol. + + +

7.2. Port mapping

+ +

{des7:12} +Port mapping takes a map between the symbolic description and the +physical description (port numbers for a footprint or sim model) and changes +port attributes accordingly. There +shall be one such mapping per abstract component. If multiple symbols +contribute a mapping, the attribute +priority mechanism will keep only one of the arrays. + + +

{des7:13} +The input array is an unordered list of (terminal name + slot name) +-> (attribute_name + value) pairs, each specified in the following syntax: +

+slot/termname -> attribkey=value
+or
+termname -> attribkey=value
+
+ +

{des7:14} E.g. "A/out -> pcb/pinnum=1" means "terminal with +name=out in symbol tagged as slot=A shall get attribute +pcb/pinnum set to 1". Equivalent non-slotted example is +"out -> pcb/pinnum=1" + + +

{des7:15} +If a slot/terminal pair referenced in the map is not found in the concrete +symbol, no error message is emitted. +A typical example when this happens is when a logic circuit +has 4 identical slots but the schematics uses only 3. +If this is considered an error, a DRC plugin shall check for it. + +

{des7:16} +If an existing port of the abstract component is not listed in the mapping, +that is the mapping doesn't reference the port in any way, a warning +is generated. (This happens e.g. on the PCB flow when the schematics +symbol uses a terminal that has no physical pin with the given device.). + + +

+
{des7:18} port mapping related symbol attributes +
attribute value description +
portmap array of map entries the actual map, as described above +
slot slot name textual name of the slot the symbol provides +
+ +

7.3. Device mapping

+ +

{des7:19} +The device mapper takes the "devmap" attribute of a symbol and looks it up +in a database for finding a device map file. If the "devmap" attribute is an +array, each devmap file is looked up and applied, in order of appearance. + +

{des7:20} +A device map file is a simple list of cschem attributes. The device mapper +takes each attribute from the device map file and apply it on the symbol that +had the "devmap" attribute. + +

{des7:21} +A common device map file will usually have a "portmap" attribute that will +set at least one attributes on each terminal. + +

+
{des7:22} device mapping related symbol attributes +
attribute value description +
devmap name name of the devmap file to use +
+ Index: tags/1.0.5/doc/design/07_devmap_imp.html =================================================================== --- tags/1.0.5/doc/design/07_devmap_imp.html (nonexistent) +++ tags/1.0.5/doc/design/07_devmap_imp.html (revision 10414) @@ -0,0 +1,199 @@ + + +

7. cschem implementation - device mapping

+ +

7.1. The transistor problem; heavy vs. light symbols

+ +

7.1.1 PCB example

+ +

{imp7:0} +The transistor problem is that a transistor symbol containing pin +numbers will not always match the PCB footprint's pin numbering. This +is especially annoying when the same symbol is to be used with signal +(sot23) and power (to220) transistors. + +

{imp7:1} +Classic solution 'A' is simply having different, heavy symbols for each +footprint. This approach has the obvious problem that replacing the +footprint means replacing the symbol as well and that symbol needs +to be copied for each footprint variant. + +

{imp7:2} +A less obvious problem is that the symbol->pcb-footprint mapping is +only one aspect, for one workflow (f1). If there's another flow (f2) that +may also have different mappings for the same symbol, it results in multiple +combinations of f1+f2 mappings. This easily leads to an explosion of heavy +symbols even for the very same device. + +

{imp7:3} +Classic solution 'B' is to craft the footprint to match the symbol. This +means there's no sot23 footprint, but a sot23-2n7002 footprint. In other +words, the same sot23 footprint is copied over and over with only pin numbering +changes, forming "heavy footprints". Just like with heavy symbols, this easily +gets out of hand as well: what if different board densities or soldering methods +are to be supported? Instead of having 3 or 4 different sot23 footprints for +the different requirements, this method requires (3 or 4 processes) * (number +of different devices) clones of the sot23 footprints. + +

{imp7:4} +While both of the above solutions would work with cschem, it is recommended +to use the devmap mechanism instead. For the 2n7002-in-sot23 example, the devmap +would mean: +

    +
  • the schematics symbol is a generic MOSFET symbol; it does not have + pinseq, pinnumber or anything alike, only a name attribute on + each port, set to G, D or S +
  • the symbol has no footprint attribute either +
  • the symbol has a devmap=2n7002_sot23 attribute +
  • there is a file called 2n7002_sot23 in the devmap database or library +
  • the devmap file specifies that pcb/footprint attribute should be set to + sot23 and the portmap attribute should be set to: +
    +G->pcb/pinnum=1
    +S->pcb/pinnum=2
    +D->pcb/pinnum=3
    +
    +
  • the sot23 footprint is generic and has numbered pins, 1, 2 and 3 +
+ +

7.1.2 SPICE example

+ +

{imp7:5} +The same example for SPICE simulation works the same way, except the devmap +file would set spice/model=M and a different portmap array: +

+G->spice/pinnum=2
+S->spice/pinnum=3
+D->spice/pinnum=1
+
+ +

7.3. Combining the two

+ +

{imp7:6} +A schematic can be the source of multiple workflows, e.g. both simulation +and PCB layout. An easy way to specify the device mapping for multiple flows is to +include them all in the same devmap file. The resulting file would set all +pcb/ and spice/ attributes and the portmap array would look like this: +

+G->pcb/pinnum=1
+G->spice/pinnum=2
+S->pcb/pinnum=2
+S->spice/pinnum=3
+D->pcb/pinnum=3
+D->spice/pinnum=1
+
+ +

{imp7:7} +However, this again creates bad coupling: for PCB, the devmap file name +includes the footprint, because that makes the actual binding between the +generic symbol and generic footprint. This mean there would be a different +devmap file for the same MOSFET part coming in a to92 package. Yet, the spice +model attribute and port mapping would be copied into both. + +

{imp7:8} +A better way is to have a pcb-only devmap file called "2n7002_sot23" and a +SPICE specific devmap file called "2n7002_spice". The devmap attribute of +the generic MOSFET symbol placed for the device can be an array, listing both +devmap files. This keeps them decoupled, a footprint change does not affect +the simulation mapping. + +

7.2. Slotting

+ +

{imp7:9} +Slotting works by the slot attribute. Each entry of the portmap +attribute may contain a slot reference on the left side. When present, it +limits the use of the entry to symbols with matching slot name. This allows +assignment of the same terminal names multiple times, to different physical +pin numbers, depending on the slot attribute. + +

{imp7:10} +For example the PCB devmap for common dual +opamp in a 8 pin package, using slots 'A' and 'B': +

+A/out -> pcb/pinnum=1
+A/in_minus -> pcb/pinnum=2
+A/in_plus -> pcb/pinnum=3
+B/out -> pcb/pinnum=7
+B/in_minus -> pcb/pinnum=6
+B/in_plus -> pcb/pinnum=5
+v_plus -> pcb/pinnum=8
+v_minus -> pcb/pinnum=4
+
+ +

{imp7:11} +When both slots are present, using this portmap will produce the following +port names in the resulting abstract model component: A/out, A/in_minus, +A/in_plus, B/out, B/in_minus, B/in_plus, v_plus, v_minus. If slot A is +missing from the schematics, only B/out, B/in_minus, B/in_plus, v_plus, +v_minus are added in the abstract model. + +

{imp7:12} +Note how v_plus and v_minus are specified to match universally, regardless +of the slot. This allows a symbol where both instances have v_plus and v_minus +terminals, but also allows a separate "opamp power" symbol with an arbitrary +slot name (e.g. slot=power) that contains only the power terminals. They are +not prefixed with A/ or B/ because they had the noslot attribute (in the +terminal). + +

{imp7:13} +The resulting devmap file could be called "lm358_dip8", "lm358_so8" (and +can set attribute device=lm358 on the resulting component). But +this pinout is a de-facto standard for dual ompamps in 8 pin packages, so +it could also be called "opamp2_dip8", "opamp2_so8" or even just +"opamp2_any8" - but in this case the device=lm358 can not be part +of the devmap file. + +

{imp7:14} +Note that this leads to the same heavy vs. light symbol consideration, +applied to devmap files now. Cschem supports both approaches, it is up +to the user to decide whether heavy or light devmap files should be used +in the user's own library of devmap files. + +

7.3. How does this differ from gschem for the user?

+ +

7.3.1. Device map

+ +

{imp7:15} +Option A: do the same as in gschem: manually set "pin numbers" and all +attributes specific to footprints and simulation. This obviously reproduces +the transistor problem, easily resulting in mismatched footprints. It also +reproduces the heavy vs. light symbol problem. + +

{imp7:16} +Option B: instead of filling in the footprint attribute, fill in the +devmap attribute. Instead of saying it is a "footprint=sot23" (and maybe +adding a device=2n7002 or value=2n7002), say it is a "devmap=2n7002_sot23". +Instead of filling in the physical pinout in a heavy symbol, write it into +a devmap file. + + +

7.3.2. Slotting

+ +

{imp7:17} +Instead of the slotdef attribute, use the devmap attribute that is +pointing to a slotted devmap file. Using the slot attribute is the same, +except the value of the slot attribute doesn't have to be an integer +but can be text, e.g. "power", "gpio", "i2c". + +

{imp7:18} +Instead of the somewhat cryptic slotdef attribute, the devmap file contains +a more readable table of pin assignment. + +

7.4. How it is displayed on the UI?

+ +

{imp7:19} +After devmap or portmap runs, the resulting attributes are available in the +abstract model. Cschem can trace the connection between the concrete +model's schematics symbol/terminal and the abstract model's component/port. + +

{imp7:20} +Using this connection, a plugin in turn can take the resulting pcb/pinnum or +spice/pinnum attribute from the abstract model and display it at any terminal +on the schematics that contributed to it. Whether pcb/pinnum or spice/pinnum is +displayed that way, depends on the plugin (or plugin parameters), which is +configured in the view. + +

{imp7:21} +In short: a view can be set up to display PCB pin numbers and another view +can be set up to display SPICE pin numbers and the user can switch between +views any time. Index: tags/1.0.5/doc/design/07_diag.svg =================================================================== --- tags/1.0.5/doc/design/07_diag.svg (nonexistent) +++ tags/1.0.5/doc/design/07_diag.svg (revision 10414) @@ -0,0 +1,176 @@ + + + + + + +devmap + +cluster_1 + +concrete schematics symbol + +cluster_2 + +terminal + +cluster_3 + +devmap plugin + +cluster_4 + +abstract component + +cluster_5 + +port + + +a_devmap + +devmap +attribute + + +a_devmap2 + +devmap +attribute + + +a_devmap->a_devmap2 + + + + +a_slot + +slot +attribute + + +slot_prefix + +slot prefixing +mechanism + + +a_slot->slot_prefix + + + + +a_name + +name +attribute + + +a_name->slot_prefix + + + + +a_noslot + +noslot +attribute + + +a_noslot->slot_prefix + + + + +a_pname + +name attribute +(often slot-prefixed) + + +slot_prefix->a_pname + + + + +devmap + +devmap +mechanism + + +a_footprint + +pcb/footprint attribute, +spice/model attribute + + +devmap:se->a_footprint + + + + +a_pinmap + +pinmap +attribute + + +devmap:s->a_pinmap + + + + +pinmap + +pinmap +mechanism + + +a_pinname + +pcb/pin attribute, +spice/pin attribute + + +pinmap->a_pinname + + + + +output +output: +footprint & pin number, +spice model & node position + + +a_footprint->output + + + + +a_pinmap->pinmap + + + + +a_devmap2->devmap + + + + +a_pname:s->devmap:e + + + + +a_pinname->output + + + + + Index: tags/1.0.5/doc/design/08_ripple.html =================================================================== --- tags/1.0.5/doc/design/08_ripple.html (nonexistent) +++ tags/1.0.5/doc/design/08_ripple.html (revision 10414) @@ -0,0 +1,154 @@ + + +

8. Ripple annotation

+ +

8.1. Forward vs. backward annotation

+

{des8:0} +A very common workflow is that the schematics is the only one true source of +information; if anything needs to be changed in a later stage of the design +process, e.g. during PCB layout or part ordering, the engineer doing the +later stage has to go back to ask the schematics designer to change the +schematics and do a new forward annotation. In turn the new annotation +will change the input for all later stages and brings the project in sync +with the requester's intentions. + +

{des8:1} +Cschem also supports "back annotation", which means the engineer of a +later phase of the project may change the design there and send back the +changes to the abstract model, which in turn has to be used to update +the schematics. This is still the same process as described above, just +instead of a "paper and pen" (or natural language email) interaction, +the back annotation can take place as a data pack. + +

{des8:2} +Below is a simplified flowchart of how the different parts of the design +process are connected. The red mark means the schematics is regarded as +source of information, the current state of the project. + +

+ +

8.2. Back annotation

+ + +

{des8:3} +The forward annotation process, when (TODO: link) a netlist +is generated from the concrete model, is described in + chapter 5 . + +

{des8:4} +Back annotation: when a change request appears in a later phase of the +project, in a 3rd party software (e.g. PCB editor), it can be saved as +a computer-readable data pack, called netpatch. Just like a +netlist, a netpatch has a wider scope than just describing +changes to network connections: it can also describe changes to +attributes of components or networks, removal requests for components or +networks. + +

{des8:5} +Just like netlist format, netpatch format is also specific +to the 3rd-party software that produces it. In a later chapter (TODO: link) +a standard cschem netpatch format is described - 3rd party software +may chose to use that format for easier access to the back annotation mechanism. + +

{des8:6} +A netpatch is an ordered list of entries; entries +are one of the following concepts: +

+
{des8:7} netpatch entries +
concept arguments description +
add_conn port, network the port needs to have a connection to the network +
del_conn port, network the port must not be connected to the network +
add_attrib object, key, newvalue change the attribute of an object (e.g. port, component or network); if the attribute did not exist, create it +
del_attrib object, key remove the attribute of an object +
del object, type delete the object; type specifies the type of the object so that ports can be distinguished from components or networks; the actual syntax of the object argument depends on type +
add object, type create a new object; type specifies the type of the object so that ports can be distinguished from components or networks; the actual syntax of the object argument depends on type +
+ + +

8.3. Ripple annotation

+

{des8:8} +Cschem fully supports the above development model, based on forward +and back annotations. However, with a minor shift in how the whole process +is regarded, but without any change to the code, the model easily becomes +the ripple annotation: + +

    +
  • {des8:9} + 1. The real source of information everybody works from is the abstract model. + +
  • {des8:10} + 2. In the first phase of the project, a lot of schematics -> abstract + model annotations happen, but in the late phase of the project it is more + likely that other tools will do more annotation. In other words, in the + early phase of the project the schematics drive changes, in later phases + simulation, pcb layout, or even part availability will drive changes. + +
  • {des8:11} + 3. Anything connected to the abstract model gets updates from the abstract + model, and should be sending back change requests to the abstract model. + +
  • {des8:12} + 4. The schematics is not necessarily an exception from rule 3. +
+ +

{des8:13} +The following diagram demonstrates this approach: + +

+ +

{des8:14} +This diagram is very similar to the previous one; the difference is that +the schematics is not in a special place anymore and the focus has been moved +to the abstract model. Annotation is not "forward" or "back" anymore, because +all participants are equal in working on the abstract model. Annotation +originated in one part of the toolchain can hit the other parts without +first having to go through the schematics. Thus annotation is called ripple +annotation. + +

{des8:15} +After such a ripple annotation, eventually the schematics, just +like the pcb or simulation will be updated. The design is fully in sync +only if all participants worked from the latest abstract model, there are +no outstanding netpatches and no local differences or deviations +at any tool in the toolchain. + +

8.3. Implementation of the ripple annotation

+ +

{des8:16} +The similarity of the two diagrams also suggests this is only a shift in +how the user relate to cschem and the schematics, not an actual change +in code or specification. + +

{des8:17} +The only difficulty of fully implementing the ideal ripple annotation is that +the abstract model does not exist as persistent data, never saved to the disk. +Instead, it's a temporary image stored in memory. + +

{des8:18} +The environment in which the ripple annotation is to be implemented is: +

    +
  • cschem core can be ran without a GUI, as an automated/batch/CLI process +
  • thus the abstract model can be generated from the concrete model (schematics) + any time, automatically +
  • back annotation works by other software sending back netpatches (TODO: link 8.2) +
  • because of netlist maps (TODO: link), a netpatch can be easily + interpreted in both the abstract and the concrete models. +
+ +

{des8:19} +The implementation of ripple annotation thus assumes that both the +schematics and the outstanding netpatches are accessible (as an +ordered list of patches). It compiles the vanilla abstract model, then +applies the netpatches before generating the (TODO: link) +netlists. The annotation happens in the abstract model -> schematics +direction too: the schematics editor gets back the patches and the GUI +assists the user to make the necessary changes to the schematics. + +

{des8:20} +If a netpatch is fully implemented in the schematics, the resulting +abstract complies with the netpatch: that is, if the netpatch +is applied onto the abstract model, no change happens and the resulting abstract +model matches to the abstract model used as an input for the patch. This is +very easy to detect, and the compliant patch can be removed. When all +netpatches are removed, the schematics is fully in sync with the +current state of the design. Index: tags/1.0.5/doc/design/08_ripple1.svg =================================================================== --- tags/1.0.5/doc/design/08_ripple1.svg (nonexistent) +++ tags/1.0.5/doc/design/08_ripple1.svg (revision 10414) @@ -0,0 +1,97 @@ + + + + + + +ripple_annot + + +sch + +concrete model +(schematics) + + +abs + +abstract model + + +sch->abs + + + + +abs->sch + + + + +pcb + +pcb layout, +silicon, etc + + +abs->pcb + + + + +sim + +simulation + + +abs->sim + + + + +bom + +purchase management +(BoM, parts, vendors) + + +abs->bom + + + + +doc + +documentation +e.g. user manual + + +abs->doc + + + + +pcb->abs + + + + +sim->abs + + + + +bom->abs + + + + +doc->abs + + + + + Index: tags/1.0.5/doc/design/08_ripple2.svg =================================================================== --- tags/1.0.5/doc/design/08_ripple2.svg (nonexistent) +++ tags/1.0.5/doc/design/08_ripple2.svg (revision 10414) @@ -0,0 +1,97 @@ + + + + + + +ripple_annot + + +abs + +abstract model + + +sch + +concrete model +(schematics) + + +abs->sch + + + + +pcb + +pcb layout, +silicon, etc + + +abs->pcb + + + + +sim + +simulation + + +abs->sim + + + + +bom + +purchase management +(BoM, parts, vendors) + + +abs->bom + + + + +doc + +documentation +e.g. user manual + + +abs->doc + + + + +sch->abs + + + + +pcb->abs + + + + +sim->abs + + + + +bom->abs + + + + +doc->abs + + + + + Index: tags/1.0.5/doc/design/08_ripple_imp.html =================================================================== --- tags/1.0.5/doc/design/08_ripple_imp.html (nonexistent) +++ tags/1.0.5/doc/design/08_ripple_imp.html (revision 10414) @@ -0,0 +1,54 @@ + + +

8. cschem implementation - ripple annotation

+ +

{imp8:0} +The back annotation is an optional feature. Cschem supports it, some +of the 3rd party software support it and the user may choose to use it. +The user is also free to choose the traditional, "tell me what I need +to change on the schematics, then I'll forward annotate" method. + +

{imp8:1} +The ripple annotation is just clever use of the back annotation plus some +netpatch management. It is probably a good idea to put the schematics, +the project file and all patches in the same version control system. + +

{imp8:2} +With such a setup a current snapshot of the VCS and a run of cschem +core on it, e.g. as a simple 'make' or 'make pcb' or 'make spice' will +produce up-to-date forward annotation packs at any member of the team. + +

{imp8:3} +The advantages of ripple annotations are: +

    +
  • It lets a non-schematics-editor team member to update the project and + the changes may reach other team members without first having to wait + for a schematics update +
  • Provided sufficient 3rd party tool support, every member of the team + can make changes to the project, using their tools, from their point + of view, without having to learn the cschem GUI or even cschem concepts. + For example a PCB designer may agree with the schematics designer that + pins can be swapped arbitrarily on a connector; the PCB designer can + do this using e.g. pcb-rnd, the wiring diagrams, docs and simulation + can be updated even if the schematics editor is on holiday. +
  • Since changes are collected as an ordered netpatch set, it is always + clear if there are outstanding changes. This may make project management + easier, there won't be forgotten change requests. +
  • The netpatch is computer readable - this minimizes the chance + of misunderstanding a change request. +
  • For special projects, like a footprint converter board, it is possible + that the PCB happens first, and it is back-annotated against an empty + abstract model, then the schematics is created using the netpatch. +
+ +

{imp8:4} +In theory, as an extreme example, one may even use the system without +schematics: build a smallish simulation by hand, add the right footprint +and pinout attributes, back annotate it against an empty abstract model then +forward annotate to PCB layout. This setup bypasses 90% of cschem and (ab)uses +cschem core as a tool for collecting netpatches and converting them to +different netlist formats. + + + + Index: tags/1.0.5/doc/design/09_buses.html =================================================================== --- tags/1.0.5/doc/design/09_buses.html (nonexistent) +++ tags/1.0.5/doc/design/09_buses.html (revision 10414) @@ -0,0 +1,57 @@ + + +

9. Buses

+ +

{des9:0} +As described in chapter 2, bus-nets +are bundled networks, called channels within the bus. Channels +are identified by their chan attribute. + +

{des9:1} +When a connection is to be made at a hub or port or bus-port, each +channel is considered separately, by its chan attribute, applying +the chan rewrite rules (of the hub or +port or bus-port). + +

{des9:2} +Channel names are arbitrary. To exploit the chan rewrite rules, +a convention for hierarchic naming is introduced in this chapter. Users and +implementations shall respect this convention when creating new channel names. + +

9.1. pseudo-hierarchy

+ +

{des9:3} +A bus-net is a flat collection of channels. That is, there is no bus-in-bus +support. As per convention, a pseudo-hierarchy is encoded in channel names, +using the slash ("/") character. + +

{des9:4} +For example channels "bar" and "baz", are plain channels in the bus; +channel names "foo/bar" and "foo/baz", are considered to be "channels +bar and baz within the virtual sub-bus of foo". + +

{des9:5} +Technically all four +channels are equal bus channels, but it's particularly easy to use the +chan rewrite rules to connect networks or buses to a specific "sub-bus". + +

{des9:6} +There is no limit on how many slashes a channel name may contain, thus +how many levels of sub-buses a bus may contain - for example +"foo/bar/baz/ch1" is a valid channel name assuming a hierarchy +of 3 sub-buses within the main bus. However, if a given prefix is used +as a virtual "sub-bus", it can not be used as a channel name; this if +"foo/bar/baz/ch1" is a channel in the bus, "foo", "foo/bar" and "foo/bar/baz" +are all considered "names of virtual sub-buses" and shall not be used as +channel names. + +

{des9:7} +(Note: cschem, on the abstract level, does not understand sub-buses, +and handles all channel names equally. The above convention is only meaningful +for the user and to some GUI code.) + + + + + + Index: tags/1.0.5/doc/design/09_buses_imp.html =================================================================== --- tags/1.0.5/doc/design/09_buses_imp.html (nonexistent) +++ tags/1.0.5/doc/design/09_buses_imp.html (revision 10414) @@ -0,0 +1,91 @@ + + +

9. cschem implementation - Buses

+ +

{imp9:0} +Legend: for this rationale, the examples will use buses, networks and hubs, +as shown below: +

+

+Each object is annotated by its type and key=value pairs of a few, selected +attributes. + +

{imp9:1} +The simplest channel based connection is when a network is connected to a bus +using a hub: +

+

+The network is hooked up onto one of the bus channels. If the + chan_rewrite +attribute of the hub is empty or does not modify the participants (the +bus and the network), the connection is made using pure channel attributes. +That is, the network has chan=G so it connects to the channel of the bus +that also has attribute chan=G. + +

{imp9:2} +If the network names a channel that does not exist in any of the buses +that are connected to the hub, the network remains unconnected (the GUI +should warn for this): +

+ + +

{imp9:3} +Similar things happen when two buses are connected via a hub; the connection +is made channel by channel: +

+ + +

{imp9:4} +When the hub's chan_rewrite attribute is set to B2::B::G, that means +any chan name in B2 is transformed, replacing regex B with string G. In +practice, this means the channel that was originally B in bus B2 is now called +G and connected accordingly. Because the second field uses regex, a safer +description of the pattern would be: B2::^B$::G, so the chan name +is modified only if it is "B", not if it "contains B". Note that the real +chan name in B2 remains "B", the rewrite rule affects only the binding +within the hub: +

+ + +

{imp9:5} +The same mechanism can be used to disconnect one of the channels; for +example the chan_rewrite entry in the hub B2::^B$:: would replace +"chan=B" to "chan=", making the channel association to empty, which will not +cause a connection. This way B2's channel 'B' is left unconnected: +

+ +

{imp9:6} +In the following example we will define two R,G,B buses B2 and B3, and +a more complex, "hierarchical" bus B1 that includes two full sets of +R,G,B "sub-buses", called the "left sub-bus" and the "right sub-bus". + +

{imp9:7} +Using the conventions of hierarchy, it is possible to design a bus B1 so that +it has two full copies of the R,G,B channels, one prefixed "left/", the other +prefixed "right/". By convention, the user calls "left/" and "right/" sub-buses. +When two "plain" R,G,B buses B2 and B3 are connected, the user shall decide which +sub-bus they should connect to. For this, we are going to modify all three chan +names in both B2 and B3, using the following two chan_rewrite rules at hub H1: +

+B2::^::left/
+
+

and this chan_rewrite at hub H2: +

+B3::^::right/
+
+

+

+The regex part in the above rule, "^", means: "match the beginning of the string". +This effectively means we replace the beginning of the string, or in other words, +insert before the original string. What we insert is "left/" in case of B2 +and "right/" in case of B3. + +

{imp9:8} +At the end of the day, this simple trick means the hubs could prefix the +channel names of incoming buses locally, without affecting the bus or +other connections of the bus, effectively changing where the channels of this +bus would connect to within the other bus. Using this mechanism together +with the bus-hierarchy-channel-naming convention, hierarchical buses can be +emulated. + + Index: tags/1.0.5/doc/design/10_forge.html =================================================================== --- tags/1.0.5/doc/design/10_forge.html (nonexistent) +++ tags/1.0.5/doc/design/10_forge.html (revision 10414) @@ -0,0 +1,143 @@ + + +

10. cschem - forge

+ +

{des10:0} +The purpose of the forge plugin is to provide an easy to implement yet generic +way for describing attribute transformations in attributes (e.g. in a +library symbol) during compilation. + +

10.1. Unconditinal forge

+ +

{des10:1} +The forge plugin works from the array attribute forge, which is +taken as an ordered list of atomic steps to execute on attributes. For +portability of data, the forge plugin needs to implement exactly the +operations described below. + +

{des10:2} +Each entry of the array is one operation. An operation is split into tokens +separated by the separator character, which is a non-alphanumeric character +following the operator (first token). For example sub,^dip,DIP,footprint is a valid +operation that uses regexp to replace leading "dip" to DIP in the footprint +attribute. Since sub is followed by a comma, the token separator is comma. + +

{des10:3} +Operations work with the current values of attributes at the time +of plugin execution during compilation of the abstract model. If destination +attribute doesn't exist, it is created. + +

{des10:4} +If referenced source attribute of an operation does not exist, the operation +is silently skipped. + +

+
{des10:5} Operation summary +
operations and arguments in-place array? short description +
sub,pat,str,attr yes map substitutes one match of regex pattern pat with str in attr +
gsub,pat,str,attr yes map substitutes all matches of regex pattern pat with str in attr +
suba,pat,ref,attr yes map substitutes one match of regex pattern pat with the value of the ref attribute in attr +
gsuba,pat,ref,attr yes map substitutes all matches of regex pattern pat with the value of the ref attribute in attr +
delete,attr yes atomic deletes (removes) the attribute +
scalar,attr yes* atomic create attr as scalar if it does not exist; throw an error if it exists as an array +
array,attr yes* atomic create attr as array if it does not exist; throw an error if it exists as a scalar +
copy,dstattr,srcattr no atomic copies the value of srcattr to the destination attribute dstattr (overwriting or creating it) +
append,dstattr,srcattr no darr appends the value of the source attribute srcattr to the value of the destination attribute dstattr +
prepend,dstattr,srcattr no darr prepends the value of the source attribute srcattr to the value of the destination attribute dstattr +
+ +

{des10:6} +In-place operations modify existing attributes in place. They are no-op for +non-existing attributes. + +

{des10:7} +If addressed attribute of the operation is an array, the operation will +behave according to the "array?" column: +

    +
  • map: on copy, an array is mapped into an array; on edit-in-place each array element is edited individually +
  • atomic: if array, the whole array is dealt with at once, as an atomic object; if scalar, result is a scalar too +
  • darr: if destination is an array, the source (or each element of the source, if it's an array) is combined into the destination array. Fails if source is array and destination is scalar. +
+ +

10.1. Conditinal forge

+

{des10:8} +Attributes whose key start with forge-if/ are used for conditional +execution of forge. The remainder of the attribute key is an arbitrary +identifier, for example forge-if/dnp is commonly used for setting a DNP +(do-not-populate) attribute depending on the current view and/or stances. + +

{des10:9} The attribute is an array; the first entry contains +the condition; the rest of the entries contain the same forge operations +as the unconditional forge attribute. However, the operations are +performed only if the expression in the first entry evaluates to true. + +

{des10:10} The condition is an expression in the usual infix form. +There are three data types supported: +

    +
  • integer: a sequence of digits (decimal number, not larger than 2^31-1) +
  • string literal: a sequence of characters enclosed in double quotes; a double quote can be added using the usual \" form, and \\ is taken as a single backslash +
  • constant: an id or id.id that is going to be substituted with the value of the named constant; the value is always a string +
+ +

{des10:11} The following binary operators are defined for strings (where each +oparand is a string literal or a constant): +

    +
  • str == str is 1 if the two strings match (case sensitive), 0 otherwise; the result is an integer +
  • str != str is 0 if the two strings match (case sensitive), 1 otherwise; the result is an integer +
+ + +

{des10:12} The following binary operators are defined for integers, with +their usual meaning and precedence: +

    +
  • == means equal +
  • != means not-equal +
  • < +
  • > +
  • <= +
  • >= +
  • && means logic "and" +
  • || means logic "or" +
  • -, +, *, / are the usual subtract, add, multiply, divide +
  • % is the remainder of an integer division +
+ +

{des10:13} The following non-binary operators are defined for integers, with +their usual meaning and precedence: +

    +
  • ! is the unary "not" operator +
  • - is the unary minus +
+ +

{des10:14} Parenthesis affects the precedence the usual way. + + +

10.2. Stances for conditinal forge

+

{des10:15} One of the factors that can be used in conditional forge is +project stance, which is a collection of project build options: when +the same project can be used to produce differently configured boards/circuits, +stance values determine which option is currently displayed or exported. + +

{des10:16} Each stance has a name and an arbitrary textual value. Optionally +the implementation may provide a list of possible values. All values are +invented by the user. + +

{des10:17} The implementation is free to define stance names but the +following three must be supported: +

+
standard stances +
name usage provisions +
model for the simplest cases, this single stance selects which one of the build configurations is used (e.g. which model or variant of the board is made) +
sub_major major subtype; if there's a build option that is orthogonal to the model, this stance should be used +
sub_minor minor subtype; if there's a build option that is orthogonal to both the model and the sub_major stances, this stance should be used +
+ +

10.3. Standard id.id substitution

+

{des10:18} The implementation must support at least the following id.id +substitutions: +

    +
  • view.name is the name of the current view +
  • stance.model is the current value of the project stance called model +
  • stance.sub_major is the current value of the project stance called sub_major +
  • stance.sub_minor is the current value of the project stance called sub_minor +
Index: tags/1.0.5/doc/design/10_forge_imp.html =================================================================== --- tags/1.0.5/doc/design/10_forge_imp.html (nonexistent) +++ tags/1.0.5/doc/design/10_forge_imp.html (revision 10414) @@ -0,0 +1,100 @@ + + +

10. cschem implementation - forge

+ +

{imp10:0} +The most common example of for forge is the generic power (rail) symbol. +The power symbol has a single terminal, usually named 1. This terminal +should be connected to the rail network named, within the symbol, e.g. to VDDQ. +This can be done using the connect attribute with value 1:VDDQ. + +

{imp10:1} +But VDDQ also needs to be printed as a dyntext. Dyntext can not address the +first element of an array and especially can not remove the "1:" section. +If the text object contains simply "VDDQ" without dyntext, it means this +information is stored twice, once in the connect attribute, once +in the text object. Such setup is prone to errors in case of a generic power +symbol where the user needs to change the rail text. (It is okay to hardwire +things like that in a Vcc-like symbol where the user can not change rail +value.) + +

{imp10:2} +An easy solution with the forge plugin is to store "VDDQ" in an custom +attribute, which is printed using dyntext and not specify the connect +attribute at all. Instead specify forge that creates connect +from the custom attribute. + +

{imp10:3} +Example forge script for the above, assuming the custom attribute is called +rail and terminal name is 1: +

+delete,forge/tmp
+scalar,forge/tmp
+sub,^,1:,forge/tmp
+suba,$,rail,forge/tmp
+array,connect
+append,connect,forge/tmp
+
+ +

{imp10:4} +The first two operations ensures an empty scalar attribute called forge/tmp. +The next two use regex to build 1:rail in forge/tmp (rail is substituted with +the value of attribute rail, because of suba). The last two operations +ensure connect exists as an array type attribute and appends the new +connection to it. + +

10.1. cschem implementation - stances and build options

+

{imp10:5} +Suppose the current project of 3 sheets is of an MCU controlled board with +various sensors. The MCU, the interface circuity and some of the +sensors are mandatory, but some of the more expensive sensors are optional. +A design decision is made so that there are models standard, +advanced and professinal. There is only one PCB is made +for all options, but different components are DNP'd for the different options. + +

{imp10:6} +The implementation in cschem is: +

    +
  • set up the possible values for the model stance to a list of: standard, advanced and professinal +
  • set the value of the model stance to one of them, e.g. advanced +
  • for each abstract component that is not present on all three models, visit the symbol(s) contributing to that component and add a conditional forge attribute that creates a pcb/dnp attribute if the component should not be populated on the pcb for a given stance +
+ +

{imp10:7} +For example take a sensor that should be on advanced and professinal +but not on standard. Create the array type attribute +forge-if/model-dnp (the model-dnp part is arbitrary) with this +content (each line is an array element): +

+(stance.model != "advanced") && (stance.model != "professinal")
+scalar,pcb/dnp
+sub,^.*$,DNP,pcb/dnp
+
+ +

{imp10:8} +The condition specifies when the component is DNP. Alternatively +it could be written as (stance.model == "standard"). + +

{imp10:9} +The rest of the forge is setting the pcb/dnp attribute to DNP. The value +could be anything, as long as the attribute exists and is non-empty, the +export mechanism should take it as true. Using DNP is practical for +dyntext printing the attribute value on the sheet. + +

{imp10:10} +Note: stances and lists of possible stance values shall be stored in the +project file (e.g. project role configuration) and not on sheet level +because it affects the abstract model, which uses all sheets of the project. + +

{imp10:11} +Now suppose there's an orthogonal property, whether the device is going to +ha a battery option, which affects whether the board has a battery charger +circuit. All three models can be shipped with or without the battery option. +One way to handle this is to double the stance.model values, from 3 to 6, +so each has a battery and a no-battery variant. But a more elegant solution is +to keep the original 3 models and use the sub_major stance with two values, +with-battery or no-battery. The process of creating the stance +values and creating the DNP forge for the battery charger is the same as above, +using stance.sub_major instead of stance.model. + + Index: tags/1.0.5/doc/design/11_appendix.html =================================================================== --- tags/1.0.5/doc/design/11_appendix.html (nonexistent) +++ tags/1.0.5/doc/design/11_appendix.html (revision 10414) @@ -0,0 +1,29 @@ + + +

11. Appendix

+ +

11.1. List of engine hooks

+

{des11:0} +The table below lists all engine hooks currently implemented in libcschem. +An engine hook is a call where the core calls view engines (plugins/scripts) +while performing operations on the data. Each title is a hook name +and the list of arguments in parenthesis. + +

11.1.1. terminal_name_to_port_name(current_name, component, terminal)

+

{des11:1} +Compile a terminal name to a port name, operating on component. Current_name +is a string that represents the currently proposed port name. The hook may +change this by returning a different string. Returning anything else (or +simply not setting the return value) will keep current_name. +

+Example: std_devmap uses this hook to calculate a port name that matches +the physical package, including slotting. + +

11.1.2. symbol_joins_component(symbol, component)

+

{des11:2} +Called when a symbol is merged into a component, whether the component +is newly created or already existed. The call is made after each +symbol-to-component join, after the attributes of the symbol got merged +into the component (whether this merge changed any component attribute +or not). + Index: tags/1.0.5/doc/design/Makefile =================================================================== --- tags/1.0.5/doc/design/Makefile (nonexistent) +++ tags/1.0.5/doc/design/Makefile (revision 10414) @@ -0,0 +1,59 @@ +ROOT =../.. + +DESDIR=$(DOCDIR)/design + +DES = \ + front_des.html \ + 01_system.html \ + 02_data.html \ + 03_drawing.html \ + 04_attrib.html \ + 05_netlist.html \ + 06_hierarchy.html \ + 07_devmap.html \ + 08_ripple.html + +IMP = \ + front_imp.html \ + 01_system_imp.html \ + 02_data_imp.html \ + 03_drawing_imp.html \ + 04_attrib_imp.html \ + 06_hierarchy_imp.html \ + 07_devmap_imp.html \ + 08_ripple_imp.html + +pdf: des.pdf imp.pdf + +.images.stamp: src/* + cd src && make + echo "done" > .images.stamp + +des.pdf: des.ps + ps2pdf des.ps + +des.ps: $(DES) .images.stamp + (for n in $(DES); do echo ""; cat $$n; done) | sed "s/\.svg/.png/g" | html2ps --colour > des.ps + +imp.pdf: imp.ps + ps2pdf imp.ps + +imp.ps: $(IMP) .images.stamp + (for n in $(IMP); do echo ""; cat $$n; done) | sed "s/\.svg/.png/g" | html2ps --colour > imp.ps + + +install_all: + $(SCCBOX) mkdir -p "$(DESDIR)" + $(SCCBOX) $(HOW) -d $(DES) "$(DESDIR)" + $(SCCBOX) $(HOW) -d $(IMP) "$(DESDIR)" + +install: + $(MAKE) install_all HOW="install -f" + +linstall: + $(MAKE) install_all HOW="linstall -f" + +uninstall: + $(MAKE) install_all HOW="uninstall" + +include $(ROOT)/Makefile.conf Index: tags/1.0.5/doc/design/chknum =================================================================== --- tags/1.0.5/doc/design/chknum (nonexistent) +++ tags/1.0.5/doc/design/chknum (revision 10414) @@ -0,0 +1,39 @@ +#!/bin/sh + +# Check if paragraph IDs are unique, print next available ID + +fn=$1 +if test ! -f "$fn" +then + echo file not found + exit 1 +fi + +awk ' + +{ + rest = $0 + out = "" + while(match(rest, "[{][a-z]*[0-9]*:[^}]*[}]")) { + id = substr(rest, RSTART+1, RLENGTH-2) + split(id, A, ":") + curr = int(A[2]) + if (curr > last) + last = curr + if (doc == "") + doc = A[1] + else if (doc != A[1]) + print "Error: invalid doc id:", id, "in line", NR, "(should be", doc, ")" + + if (id in SEEN) + print "Error: invalid doc id:", id, "in line", NR, "reused (first used in line", SEEN[id], ")" + else + SEEN[id] = NR + rest = substr(rest, RSTART+RLENGTH, length(rest)) + } +} + +END { + print "Info: next available ID is: {" doc ":" last+1 "}" +} +' < $fn Property changes on: tags/1.0.5/doc/design/chknum ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/1.0.5/doc/design/front_des.html =================================================================== --- tags/1.0.5/doc/design/front_des.html (nonexistent) +++ tags/1.0.5/doc/design/front_des.html (revision 10414) @@ -0,0 +1,14 @@ + + +
 
 
 
 
 
 
 
  +

+Cschem +
 
 
 
  + + + + +
 
 
 
  +Design document +
+ Index: tags/1.0.5/doc/design/front_imp.html =================================================================== --- tags/1.0.5/doc/design/front_imp.html (nonexistent) +++ tags/1.0.5/doc/design/front_imp.html (revision 10414) @@ -0,0 +1,13 @@ + + +
 
 
 
 
 
 
 
  +
+Cschem +
 
 
 
  + + + + +
 
 
 
  +Implementation rationale +
Index: tags/1.0.5/doc/design/index.html =================================================================== --- tags/1.0.5/doc/design/index.html (nonexistent) +++ tags/1.0.5/doc/design/index.html (revision 10414) @@ -0,0 +1,20 @@ + + +

cschem - design document

+ +

Table of Contents

+
    +
  1. The system
    (rationale) +
  2. Schematics data
    (rationale) +
  3. Drawing primitives (graphical schematics sheet)
    (rationale) +
  4. Attributes
    (rationale) +
  5. Netlists
    (no rationale) +
  6. Hierarchal projects
    (rationale) +
  7. Device mapping
    (rationale) +
  8. Ripple annotation
    (rationale) +
  9. Buses
    (rationale) +
  10. Attribute forge
    (rationale) +
  11. Appendix +
+ + Index: tags/1.0.5/doc/design/renum =================================================================== --- tags/1.0.5/doc/design/renum (nonexistent) +++ tags/1.0.5/doc/design/renum (revision 10414) @@ -0,0 +1,42 @@ +#!/bin/sh + +### +### WARNING: DO NOT RUN THIS SCRIPT ON DOCUMENTS ALREADY PUBLISHED! +### +### This script shall be run right before the publication of a new chapter. +### + + +fn=$1 +if test ! -f "$fn" +then + echo file not found + exit 1 +fi + +awk ' +BEGIN { + next_id=0 +} + +function gen_next_id() +{ + return "{" doc ":" next_id++ "}" +} + +{ + rest = $0 + out = "" + while(match(rest, "[{][a-z]*[0-9]*:[^}]*[}]")) { + if (doc == "") { + doc = substr(rest, RSTART+1, RLENGTH-2) + sub(":.*", "", doc) + } + out = out substr(rest, 1, RSTART-1) gen_next_id() + rest = substr(rest, RSTART+RLENGTH, length(rest)) + } + print out rest +} +' < $fn > $fn.tmp + +mv $fn.tmp $fn Property changes on: tags/1.0.5/doc/design/renum ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/1.0.5/doc/design/src/01_comp.aag =================================================================== --- tags/1.0.5/doc/design/src/01_comp.aag (nonexistent) +++ tags/1.0.5/doc/design/src/01_comp.aag (revision 10414) @@ -0,0 +1,222 @@ + *cschem------------------------+ + |*front------+ *engine------+| + || | | [datm ] || + || | | *plugins-+ || + || [schedit] | | |[drc ]| || + || | | |[slot ]| || + || [symedit] | | |[devmap]| || *3rd-------+ + || | | |[fmt1 ]| || | [pcb ]| +[dat1] || [gen1 ] | | |[fmt2 ]| || | [sim ]| + || | | |[fmt3 ]| || | [wut ]| + || [datedit] | | |[scr1 ]| || | [bar ]| + || | | |[scr2 ]| || +----------+ + || | | |[elib ]| || *library---+ + || | | |[io ]| || |[libsym ]| + || | | +--------+ || |[libsch ]| + |+-----------+ +------------+| |[libdata ]| + +------------------------------+ +----------+ + *project-------+ + |[prj] [ sch ]| +[dat2] [gen2 ] |[lib] [plgd ]| [conv] [dat3] + +--------------+ + +%% +[cschem] + label cschem + valign top + bgcolor #bbbbbb + linecolor #bbbbbb + +[front] + label Frontend + valign top + bgcolor #9999ee + linecolor #9999ee + +[3rd] + label 3rd party software packages + valign top + bgcolor #bbbbbb + linecolor #bbbbbb + +[library] + label libraries + valign top + bgcolor #ee9999 + + +[engine] + label Engine + valign top + bgcolor #99cc99 + +[project] + label project repository + valign top + bgcolor #ee9999 + + +[pcb] + label PCB\neditor + +[sim] + label Circuit\nsimulator + +[wut] + label other\nsoftware + +[dat1] + label data source\ne.g. text + +[dat2] + label data source\ne.g. text + linecolor #999999 + textcolor #999999 + +[dat3] + label data output + linecolor #999999 + textcolor #999999 + + +[schedit] + label schematics\neditor + +[symedit] + label symbol editor\nsymbol generator + +[datedit] + label data\neditor + +[gen1] + label generator\ntool + +[gen2] + label generator\ntool + linecolor #999999 + textcolor #999999 + +[conv] + label converter\ntool + linecolor #999999 + textcolor #999999 + +[drc] + label DRC + +[slot] + label slotting\nmechanism + +[devmap] + label device\nmapper + +[fmt1] + label format\nconverter + +[fmt2] + label format\nconverter + +[fmt3] + label format\nconverter + +[datm] + label data model + bgcolor #99ee99 + linecolor #99ee99 + +[plugins] + label plugins + valign top + bgcolor #99ee99 + linecolor #99ee99 + + +[io] + label I/O module + +[elib] + label library\naccess + +[prj] + label project\nfile + +[sch] + label schematics\nsheet + +[lib] + label local\nlib + +[plgd] + label plugin-specific\ndata + +[scr1] + label user\nscript 1 + +[scr2] + label user\nscript 2 + +[bar] + label user\nformat + + +[libsym] + label symbol + +[libsch] + label schematics\nsnippet + +[libdata] + label plugin-specific\ndata + +-> dat1.e gen1 + label file + +-> dat2.e gen2 + label file + linecolor #999999 + textcolor #999999 + +-> gen2.e project + label e.g. file + linecolor #999999 + textcolor #999999 + +-> gen1.e engine + label API + +<-> schedit.e engine + label API + +<-> symedit.e engine + label API + +<-> datedit.e engine + label API + +<-> project.n io + label e.g. file + +<-> fmt1.e pcb + label file\nor API + +<-> fmt2.e sim + label file\nor API + +<-> fmt3.e wut + label file\nor API + +-> project conv.w + label e.g. file + linecolor #999999 + textcolor #999999 + +-> conv.e dat3 + label file + linecolor #999999 + textcolor #999999 + +-> scr1.e bar + label file\nor API + +<-> elib.e library + label e.g. file\nAPI, net Index: tags/1.0.5/doc/design/src/02_abstract.dot =================================================================== --- tags/1.0.5/doc/design/src/02_abstract.dot (nonexistent) +++ tags/1.0.5/doc/design/src/02_abstract.dot (revision 10414) @@ -0,0 +1,23 @@ +digraph objects { + project [label = "project-view"] + bus_port [label = "bus-port\n(bundled\nports)"] + bus [label = "bus\n(bundled\nnets)"] + hub [label = "hub"] + + chan1 [label = "channel" shape=none] + chan2 [label = "channel" shape=none] + + project -> component + project -> network + project -> bus + project -> hub + + bus -> chan1 [arrowhead="none"] + chan1 -> network + + component -> port + component -> bus_port + + bus_port -> chan2 [arrowhead="none"] + chan2 -> port +} Index: tags/1.0.5/doc/design/src/02_graphical.dot =================================================================== --- tags/1.0.5/doc/design/src/02_graphical.dot (nonexistent) +++ tags/1.0.5/doc/design/src/02_graphical.dot (revision 10414) @@ -0,0 +1,103 @@ +digraph g { + rankdir=LR + subgraph cluster_0 { + label="graphical schematics sheet" + + subgraph cluster_01 { + label="drawing primitives\n(chapter 3)" + + at1 [label="\"bus-segment\":\natoms, e.g. lines"] + at2 [label="\"wire-segment\":\natoms, e.g. lines"] + at3 [label="atoms\nand groups"] + at4 [label="atoms\ne.g. lines"] + at5 [label="atoms\ne.g. lines"] + at6 [label="atoms\ne.g. arc, polygon"] + at7 [label="connection gfx\ne.g. arc, polygon"] + + gr1 [label="group\nrole=bus-net"] + gr2 [label="group\nrole=wire-net"] + gr3 [label="group\nrole=symbol"] + gr4 [label="group\nrole=bus_terminal"] + gr5 [label="group\nrole=terminal"] + gr6 [label="group\nrole=hub_point"] + + connection + } + + subgraph cluster_02 { + label="concrete model\n(chapter2)" + symbol + terminal + bus_terminal [label="bus-terminal"] + wire_net [label="wire-net"] + hub_point [label="hub-point"] + bus_net [label="bus-net"] + attribute [label="attribute\nof wire-nets, bus-nets, symbols,\n hubs and terminals" shape=octagon] + } + } + + subgraph cluster_1 { + label="abstract model\n(chapter 2)" + + network [shape=box height=1.875] + bus [shape=box] + component [shape=box] + port [shape=box] + bus_port [label="bus-port" shape=box] + hub [shape=box] + } + + subgraph cluster_2 { + label="real world\nexample: PCB" + bgcolor="#cccccc" + pcb_component [label="component"] + pcb_pin [label="pin or pad\nof a\ncomponent"] + pcb_net [label="copper tracks\ncopper polygons"] + pcb_pair [label="copper tracks/polygons with\nconstraints (e.g. diff pair)"] + pcb_hub [label="specific point on copper\nwith geometry constraints\n(e.g. star point gnd)"] + } + + at1 -> gr1 + at2 -> gr2 + at3 -> gr3 + at4 -> gr4 + at5 -> gr5 + at6 -> gr6 + at7 -> connection [dir=back] + + connection -> wire_net [label="Note 2" weight=20] + connection -> bus_net [label="Note 2" weight=20] + + gr1 -> bus_net + gr2 -> wire_net + gr3 -> symbol + gr4 -> bus_terminal + gr5 -> terminal + gr6 -> hub_point + + symbol -> component + terminal -> port + bus_terminal -> bus_port + wire_net -> network + bus_net -> bus + hub_point -> hub + attribute -> network [label="Note 1" color=blue] + + symbol:e -> attribute:se [constraint=0 color=blue] + wire_net:e -> attribute:se [constraint=0 color=blue] + bus_net:e -> attribute:se [constraint=0 color=blue] + terminal:e -> attribute:se [constraint=0 color=blue] + bus_terminal:e -> attribute:se [constraint=0 color=blue] + + component -> pcb_component + port -> pcb_pin + bus_port -> pcb_pin + network -> pcb_net + bus -> pcb_net + bus -> pcb_pair + hub -> pcb_net + hub -> pcb_hub + + bus_port-> pcb_component [style=invis] + +} Index: tags/1.0.5/doc/design/src/03_coords.lht =================================================================== --- tags/1.0.5/doc/design/src/03_coords.lht (nonexistent) +++ tags/1.0.5/doc/design/src/03_coords.lht (revision 10414) @@ -0,0 +1,347 @@ +ha:pcb-rnd-board-v2 { + + ha:attributes { + {PCB::grid::unit}=mil + } + + li:styles { + ha:Signal { + diameter = 1.999996mm + thickness = 10.0mil + hole = 31.5mil + clearance = 20.0mil + } + ha:Power { + diameter = 2.199894mm + thickness = 20.0mil + hole = 0.999998mm + clearance = 20.0mil + } + ha:Fat { + diameter = 137.8mil + thickness = 80.0mil + hole = 47.24mil + clearance = 25.0mil + } + ha:Sig-tight { + diameter = 64.0mil + thickness = 10.0mil + hole = 31.5mil + clearance = 12.0mil + } + } + + ha:meta { + ha:size { + thermal_scale = 0.500000 + x = 1000.0mil + y = 1000.0mil + isle_area_nm2 = 199999999.999200 + } + ha:cursor { + zoom = 0.000000 + x = 25.0mil + y = 625.0mil + } + ha:drc { + min_drill = 15.0mil + min_ring = 10.0mil + bloat = 12.0mil + shrink = 9.0mil + min_width = 10.0mil + min_silk = 7.0mil + } + ha:grid { + spacing = 25.0mil + offs_x = 0.0 + offs_y = 0.0 + } + } + + ha:data { + + li:objects { + } + li:layers { + + ha:component { + lid=0 + group=3 + ha:combining { } + visible=1 + + li:objects { + ha:arc.26 { + x=500.0mil; y=550.0mil; width=6.750142mm; height=6.750142mm; astart=180; adelta=41; thickness=10.0mil; clearance=40.0mil; + } + ha:polygon.39 { + li:geometry { + ta:contour { + { 646.9669685mil; 321.9669685mil } + { 17.779999mm; 10.423025mm } + { 18.678025mm; 375.0mil } + } + } + + ha:flags { + clearpoly=1 + } + } + ha:text.43 { + string=+Delta; x=775.0mil; y=350.0mil; scale=100; fid=0; direction=0; + ha:flags { + clearline=1 + } + } + ha:text.44 { + string=0 deg; x=700.0mil; y=550.0mil; scale=100; fid=0; direction=0; + ha:flags { + clearline=1 + } + } + ha:text.47 { + string=90 deg; x=525.0mil; y=125.0mil; scale=100; fid=0; direction=0; + ha:flags { + clearline=1 + } + } + ha:text.49 { + string=180 deg; x=25.0mil; y=575.0mil; scale=100; fid=0; direction=0; + ha:flags { + clearline=1 + } + } + ha:text.51 { + string=270 deg; x=525.0mil; y=900.0mil; scale=100; fid=0; direction=0; + ha:flags { + clearline=1 + } + } + } + } + + ha:solder { + lid=1 + group=8 + ha:combining { } + visible=1 + } + + ha:comp-GND { + lid=2 + group=3 + ha:combining { } + visible=1 + } + + ha:comp-power { + lid=3 + group=3 + ha:combining { } + visible=1 + } + + ha:sold-GND { + lid=4 + group=8 + ha:combining { } + visible=1 + } + + ha:sold-power { + lid=5 + group=8 + ha:combining { } + visible=1 + } + + ha:signal3 { + lid=6 + group=5 + ha:combining { } + visible=1 + } + + ha:outline { + lid=7 + group=7 + ha:combining { } + visible=1 + } + + ha:silk { + lid=8 + group=10 + ha:combining { auto=1; } + visible=1 + } + + ha:silk { + lid=9 + group=1 + ha:combining { auto=1; } + visible=1 + + li:objects { + ha:line.4 { + x1=75.0mil; y1=550.0mil; x2=850.0mil; y2=550.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.7 { + x1=500.0mil; y1=200.0mil; x2=500.0mil; y2=975.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:polygon.13 { + li:geometry { + ta:contour { + { 925.0mil; 550.0mil } + { 825.0mil; 525.0mil } + { 825.0mil; 575.0mil } + } + } + + ha:flags { + clearpoly=1 + } + } + ha:polygon.18 { + li:geometry { + ta:contour { + { 500.0mil; 125.0mil } + { 475.0mil; 225.0mil } + { 525.0mil; 225.0mil } + } + } + + ha:flags { + clearpoly=1 + } + } + ha:text.22 { + string=+X; x=900.0mil; y=550.0mil; scale=100; fid=0; direction=0; + ha:flags { + clearline=1 + } + } + ha:text.23 { + string=+Y; x=425.0mil; y=100.0mil; scale=100; fid=0; direction=0; + ha:flags { + clearline=1 + } + } + ha:text.24 { + string=-X; x=75.0mil; y=475.0mil; scale=100; fid=0; direction=0; + ha:flags { + clearline=1 + } + } + ha:text.25 { + string=-Y; x=425.0mil; y=900.0mil; scale=100; fid=0; direction=0; + ha:flags { + clearline=1 + } + } + ha:text.45 { + string={0;0}; x=400.0mil; y=475.0mil; scale=100; fid=0; direction=0; + ha:flags { + clearline=1 + } + } + } + } + } + } + + ha:netlists { + li:input { + } + } + ha:layer_stack { + li:groups { + ha:0 { + name = top_paste + ha:type { top=1; paste=1; } + li:layers { } + } + ha:1 { + name = top_silk + ha:type { silk=1; top=1; } + li:layers { 9; } + } + ha:2 { + name = top_mask + ha:type { top=1; mask=1; } + li:layers { } + } + ha:3 { + name = top_copper + ha:type { copper=1; top=1; } + li:layers { 0; 2; 3; } + } + ha:4 { + ha:type { substrate=1; intern=1; } + li:layers { } + } + ha:5 { + name = Intern + ha:type { copper=1; intern=1; } + li:layers { 6; } + } + ha:6 { + ha:type { substrate=1; intern=1; } + li:layers { } + } + ha:7 { + name = global outline + ha:type { outline=1; intern=1; } + li:layers { 7; } + } + ha:8 { + name = bottom_copper + ha:type { bottom=1; copper=1; } + li:layers { 1; 4; 5; } + } + ha:9 { + name = bottom_mask + ha:type { bottom=1; mask=1; } + li:layers { } + } + ha:10 { + name = bottom_silk + ha:type { silk=1; bottom=1; } + li:layers { 8; } + } + ha:11 { + name = bottom_paste + ha:type { bottom=1; paste=1; } + li:layers { } + } + } + } + li:pcb-rnd-conf-v1 { + ha:overwrite { + ha:design { + min_ring = 10.00 mil + clearance = 20.00 mil + via_thickness = 2000.00 um + via_drilling_hole = 31.50 mil + min_slk = 7.00 mil + max_height = 1000.00 mil + line_thickness = 10.00 mil + shrink = 9.00 mil + poly_isle_area = 199999999.999200 + max_width = 1000.00 mil + min_wid = 10.00 mil + bloat = 12.00 mil + min_drill = 15.00 mil + } + ha:editor { + all_direction_lines = true + } + } + } +} Index: tags/1.0.5/doc/design/src/03_stack.dot =================================================================== --- tags/1.0.5/doc/design/src/03_stack.dot (nonexistent) +++ tags/1.0.5/doc/design/src/03_stack.dot (revision 10414) @@ -0,0 +1,58 @@ +digraph stack { + ranksep=1; + + subgraph cluster1 { + color=none + sheet [width=4; shape=rect] + } + + subgraph cluster2 { + color=none + label="composites" + labeljust="r"; + bgcolor="#BBBBBB"; + + group [shape=rect] + group_ref [shape=rect] + + standalone [shape=point; label=""; width=0] + } + + subgraph cluster3 { + color=none + label="atoms" + labeljust="r"; + bgcolor="#BBBBBB"; + + line + spline + arc + polygon + text + connection + } + + sheet -> group + sheet -> group_ref + sheet -> standalone [arrowhead=none] + + group -> group + group -> group_ref [constraint = false] + + group -> line + group -> spline + group -> arc + group -> polygon + group -> text + group -> connection + + group_ref -> line [style=invis] + + + standalone -> line [constraint = false] + standalone -> spline [constraint = false] + standalone -> arc [constraint = false] + standalone -> polygon [constraint = false] + standalone -> text [constraint = false] + standalone -> connection [constraint = false] +} Index: tags/1.0.5/doc/design/src/06_example1.dot =================================================================== --- tags/1.0.5/doc/design/src/06_example1.dot (nonexistent) +++ tags/1.0.5/doc/design/src/06_example1.dot (revision 10414) @@ -0,0 +1,21 @@ +digraph hierarchy { + subgraph cluster_1 { + label="top level" + top [label="top sheet" shape=box] + } + + an [shape=box] + dig [shape=box] + + top -> dig + top -> an + an -> amp1 + an -> amp2 + an -> amp3 + an -> amp4 + + amp1 [label="amp" shape=box] + amp2 [label="amp" shape=box] + amp3 [label="amp" shape=box] + amp4 [label="amp" shape=box] +} Index: tags/1.0.5/doc/design/src/06_example2.dot =================================================================== --- tags/1.0.5/doc/design/src/06_example2.dot (nonexistent) +++ tags/1.0.5/doc/design/src/06_example2.dot (revision 10414) @@ -0,0 +1,93 @@ +digraph hierarchy { + + ranksep=1; + + subgraph cluster_1 { + label="future user: a parent sheet" + ext_gnd [shape=diamond] + ext_vcc [shape=diamond] + ext_ctrl [shape=diamond] + ext_enable [shape=diamond] + ext [style=invisible] + chgnd [shape=diamond] + } + + subgraph cluster_2 { + label="" + top [label="top sheet" shape=plaintext] + + enable [label="v/enable" shape=diamond color=green] + + gnd [label="./gnd" shape=diamond color=blue] + vcc [label="./vcc" shape=diamond color=blue] + + agnd [label="./agnd" shape=diamond color=blue] + dgnd [label="./dgnd" shape=diamond color=blue] + avcc [label="./avcc" shape=diamond color=blue] + dvcc [label="./dvcc" shape=diamond color=blue] + ctrl [label="./ctrl" shape=diamond color=blue] + + {rank=same; agnd, dgnd, avcc, dvcc, ctrl, enable, top} + + gnd -> agnd [color=blue] + gnd -> dgnd [color=blue] + vcc -> avcc [color=blue] + vcc -> dvcc [color=blue] + } + + an [shape=box] + dig [shape=box] + amp1 [shape=box] + amp2 [shape=box] + amp3 [shape=box] + amp4 [shape=box] + + ext -> top [color="#dddddd" constaint=0] + ext_gnd -> gnd [color=red] + ext_vcc -> vcc [color=red] + ext_ctrl -> ctrl [color=red] + ext_enable -> enable [color=red] + + + top -> dig [color="#dddddd" weight=100] + top -> an [color="#dddddd" weight=100] + an -> amp1 [color="#dddddd" weight=100] + an -> amp2 [color="#dddddd" weight=100] + an -> amp3 [color="#dddddd" weight=100] + an -> amp4 [color="#dddddd" weight=100] + + amp1 [label="amp"] + amp2 [label="amp"] + amp3 [label="amp"] + amp4 [label="amp"] + + agnd -> an [color=red] + dgnd -> dig [color=red] + avcc -> an [color=red] + dvcc -> dig [color=red] + ctrl -> an [color=red] + ctrl -> dig [color=red] + + dig -> enable [color=green constraint=1] + amp1 -> enable [color=green constraint=1] + amp2 -> enable [color=green constraint=1] + amp3 -> enable [color=green constraint=1] + amp4 -> enable [color=green constraint=1] + + an -> amp1 [color="red" constraint=0] + an -> amp2 [color="red" constraint=0] + an -> amp3 [color="red" constraint=0] + an -> amp4 [color="red" constraint=0] + + amp1 -> chgnd1 [color="purple" constraint=0 arrowhead=none] + amp2 -> chgnd1 [color="purple" constraint=0 arrowhead=none] + amp3 -> chgnd1 [color="purple" constraint=0 arrowhead=none] + amp4 -> chgnd1 [color="purple" constraint=0 arrowhead=none] + dig -> chgnd [color="purple" constraint=1] + top -> chgnd [color="purple" constraint=0] + + chgnd1:n -> chgnd [color="purple" constraint=0] + chgnd1 [shape=none width=0 height=0 label=""] + + {rank=same; dig, chgnd1} +} Index: tags/1.0.5/doc/design/src/06_topo1.dot =================================================================== --- tags/1.0.5/doc/design/src/06_topo1.dot (nonexistent) +++ tags/1.0.5/doc/design/src/06_topo1.dot (revision 10414) @@ -0,0 +1,6 @@ +digraph flat { + shape=box; + sheet1 + sheet2 + sheet3 +} \ No newline at end of file Index: tags/1.0.5/doc/design/src/06_topo2.dot =================================================================== --- tags/1.0.5/doc/design/src/06_topo2.dot (nonexistent) +++ tags/1.0.5/doc/design/src/06_topo2.dot (revision 10414) @@ -0,0 +1,8 @@ +digraph flat { + shape=box; + sheet1 + sheet2 + sheet3 + sheet1 -> sheet2 + sheet1 -> sheet3 +} \ No newline at end of file Index: tags/1.0.5/doc/design/src/06_topo3.dot =================================================================== --- tags/1.0.5/doc/design/src/06_topo3.dot (nonexistent) +++ tags/1.0.5/doc/design/src/06_topo3.dot (revision 10414) @@ -0,0 +1,7 @@ +digraph flat { + shape=box; + sheet1 -> sheet2 + sheet1 -> sheet3 + sheet4 -> sheet5 + sheet6 +} \ No newline at end of file Index: tags/1.0.5/doc/design/src/07_diag.dot =================================================================== --- tags/1.0.5/doc/design/src/07_diag.dot (nonexistent) +++ tags/1.0.5/doc/design/src/07_diag.dot (revision 10414) @@ -0,0 +1,58 @@ +digraph devmap { + rankdir=LR; + ranksep=1 + + subgraph cluster_1 { + label="concrete schematics symbol" + a_devmap [label="devmap\nattribute"] + a_slot [label="slot\nattribute"] + subgraph cluster_2 { + label="terminal" + bgcolor=lightgrey + a_name [label="name\nattribute"] + a_noslot [label="noslot\nattribute"] + } + } + + subgraph cluster_3 { + label="devmap plugin" + + slot_prefix [label="slot prefixing\nmechanism"; color=red] + + devmap [label="devmap\nmechanism"; color=green] + pinmap [label="pinmap\nmechanism"; color=blue] + } + + subgraph cluster_4 { + label="abstract component" + a_footprint [label="pcb/footprint attribute,\nspice/model attribute"] + a_pinmap [label="pinmap\nattribute"] + a_devmap2 [label="devmap\nattribute"] + subgraph cluster_5 { + label="port" + bgcolor=lightgrey + a_pname [label="name attribute\n(often slot-prefixed)"] + a_pinname [label="pcb/pin attribute,\nspice/pin attribute"] + } + } + + output [label="output:\nfootprint & pin number,\nspice model & node position"; shape=plaintext] + + a_slot -> slot_prefix [color=red] + a_noslot -> slot_prefix [color=red] + a_name -> slot_prefix [color=red] + slot_prefix -> a_pname [color=red] + + a_devmap -> a_devmap2 + + a_devmap2 -> devmap [color=green; weight=0] + a_pname:s -> devmap:e [color=green; weight=0] + devmap:s -> a_pinmap [color=green] + devmap:se -> a_footprint [color=green] + + a_pinmap -> pinmap [color=blue; weight=0] + pinmap -> a_pinname [color=blue] + + a_pinname -> output + a_footprint -> output +} \ No newline at end of file Index: tags/1.0.5/doc/design/src/08_ripple1.dot =================================================================== --- tags/1.0.5/doc/design/src/08_ripple1.dot (nonexistent) +++ tags/1.0.5/doc/design/src/08_ripple1.dot (revision 10414) @@ -0,0 +1,25 @@ +digraph ripple_annot { + rankdir=LR + sch [label="concrete model\n(schematics)" color=red] + abs [label="abstract model" shape=box height=2] + pcb [label="pcb layout,\nsilicon, etc"] + sim [label="simulation"] + bom [label="purchase management\n(BoM, parts, vendors)"] + doc [label="documentation\ne.g. user manual"] + + sch->abs + abs->sch [weight=0] + + abs->pcb + pcb->abs [weight=0] + + abs->sim + sim->abs [weight=0] + + abs->bom + bom->abs [weight=0] + + abs->doc + doc->abs [weight=0] + +} \ No newline at end of file Index: tags/1.0.5/doc/design/src/08_ripple2.dot =================================================================== --- tags/1.0.5/doc/design/src/08_ripple2.dot (nonexistent) +++ tags/1.0.5/doc/design/src/08_ripple2.dot (revision 10414) @@ -0,0 +1,25 @@ +digraph ripple_annot { + rankdir=LR + abs [label="abstract model" shape=box height=2 color=red] + sch [label="concrete model\n(schematics)"] + pcb [label="pcb layout,\nsilicon, etc"] + sim [label="simulation"] + bom [label="purchase management\n(BoM, parts, vendors)"] + doc [label="documentation\ne.g. user manual"] + + abs->sch + sch->abs [weight=0] + + abs->pcb + pcb->abs [weight=0] + + abs->sim + sim->abs [weight=0] + + abs->bom + bom->abs [weight=0] + + abs->doc + doc->abs [weight=0] + +} \ No newline at end of file Index: tags/1.0.5/doc/design/src/09_bus_bus.svg =================================================================== --- tags/1.0.5/doc/design/src/09_bus_bus.svg (nonexistent) +++ tags/1.0.5/doc/design/src/09_bus_bus.svg (revision 10414) @@ -0,0 +1,277 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + chan=R + + chan=G + + chan=B + bus, name=B1 + + + Hub, name=h1 + + chan=R + + chan=G + + chan=B + bus, name=B2 + + + + + + + + Index: tags/1.0.5/doc/design/src/09_bus_bus_rw.svg =================================================================== --- tags/1.0.5/doc/design/src/09_bus_bus_rw.svg (nonexistent) +++ tags/1.0.5/doc/design/src/09_bus_bus_rw.svg (revision 10414) @@ -0,0 +1,277 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + chan=R + + chan=G + + chan=B + bus, name=B1 + + + Hub, name=h1 + + chan=R + + chan=G + + chan=B + bus, name=B2 + + + + + + + + Index: tags/1.0.5/doc/design/src/09_bus_bus_rw2.svg =================================================================== --- tags/1.0.5/doc/design/src/09_bus_bus_rw2.svg (nonexistent) +++ tags/1.0.5/doc/design/src/09_bus_bus_rw2.svg (revision 10414) @@ -0,0 +1,271 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + chan=R + + chan=G + + chan=B + bus, name=B1 + + + Hub, name=h1 + + chan=R + + chan=G + + chan=B + bus, name=B2 + + + + + + + + Index: tags/1.0.5/doc/design/src/09_bus_net.svg =================================================================== --- tags/1.0.5/doc/design/src/09_bus_net.svg (nonexistent) +++ tags/1.0.5/doc/design/src/09_bus_net.svg (revision 10414) @@ -0,0 +1,193 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + chan=R + + chan=G + + chan=B + bus, name=B1 + + net, name=n1, chan=G + + Hub, name=h1 + + + + + Index: tags/1.0.5/doc/design/src/09_bus_net2.svg =================================================================== --- tags/1.0.5/doc/design/src/09_bus_net2.svg (nonexistent) +++ tags/1.0.5/doc/design/src/09_bus_net2.svg (revision 10414) @@ -0,0 +1,187 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + chan=R + + chan=G + + chan=B + bus, name=B1 + + net, name=n1, chan=Z + + Hub, name=h1 + + + + + Index: tags/1.0.5/doc/design/src/09_hbus_bus_rw.svg =================================================================== --- tags/1.0.5/doc/design/src/09_hbus_bus_rw.svg (nonexistent) +++ tags/1.0.5/doc/design/src/09_hbus_bus_rw.svg (revision 10414) @@ -0,0 +1,475 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + chan=left/R + + chan=left/G + + chan=left/B + bus, name=B1 + + + Hub, name=h1 + + chan=R + + chan=G + + chan=B + bus, name=B2 + + + + + + + + chan=right/R + + chan=right/G + + chan=right/B + + + Hub, name=h2 + + chan=R + + chan=G + + chan=B + bus, name=B3 + + + + + + + + Index: tags/1.0.5/doc/design/src/09_legend.svg =================================================================== --- tags/1.0.5/doc/design/src/09_legend.svg (nonexistent) +++ tags/1.0.5/doc/design/src/09_legend.svg (revision 10414) @@ -0,0 +1,171 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + chan=R + + chan=G + + chan=B + bus, name=B1 + + net, name=n1, chan=G + + Hub, name=h1 + + Index: tags/1.0.5/doc/design/src/Makefile =================================================================== --- tags/1.0.5/doc/design/src/Makefile (nonexistent) +++ tags/1.0.5/doc/design/src/Makefile (revision 10414) @@ -0,0 +1,56 @@ +all: ../01_comp.svg ../02_abstract.svg ../02_graphical.svg ../03_stack.svg \ + ../03_coords.png ../06_example1.svg ../06_example2.svg ../06_topo1.svg \ + ../06_topo2.svg ../06_topo3.svg ../07_diag.svg ../08_ripple1.svg \ + ../08_ripple2.svg + +../01_comp.svg ../01_comp.png: 01_comp.aag + aagraph -Tsvg 01_comp.aag > ../01_comp.svg + aagraph -Tpng 01_comp.aag > ../01_comp.png + +../02_abstract.svg ../02_abstract.png: 02_abstract.dot + dot -Tsvg 02_abstract.dot > ../02_abstract.svg + dot -Tpng 02_abstract.dot > ../02_abstract.png + +../02_graphical.svg ../02_graphical.png: 02_graphical.dot + dot -Tsvg 02_graphical.dot > ../02_graphical.svg + dot -Tpng 02_graphical.dot > ../02_graphical.png + +../03_stack.svg ../03_stack.png: 03_stack.dot + dot -Tsvg 03_stack.dot > ../03_stack.svg + dot -Tpng 03_stack.dot > ../03_stack.png + +../03_coords.png: 03_coords.lht + pcb-rnd -x png --dpi 300 --outfile ../03_coords.png 03_coords.lht + +../06_example1.svg ../06_example1.png: 06_example1.dot + dot -Tsvg 06_example1.dot > ../06_example1.svg + dot -Tpng 06_example1.dot > ../06_example1.png + +../06_example2.svg ../06_example2.png: 06_example2.dot + dot -Tsvg 06_example2.dot > ../06_example2.svg + dot -Tpng 06_example2.dot > ../06_example2.png + +../06_topo1.svg ../06_topo1.png: 06_topo1.dot + dot -Tsvg 06_topo1.dot > ../06_topo1.svg + dot -Tpng 06_topo1.dot > ../06_topo1.png + +../06_topo2.svg ../06_topo2.png: 06_topo2.dot + dot -Tsvg 06_topo2.dot > ../06_topo2.svg + dot -Tpng 06_topo2.dot > ../06_topo2.png + +../06_topo3.svg ../06_topo3.png: 06_topo3.dot + dot -Tsvg 06_topo3.dot > ../06_topo3.svg + dot -Tpng 06_topo3.dot > ../06_topo3.png + +../07_diag.svg ../07_diag.png: 07_diag.dot + dot -Tsvg 07_diag.dot > ../07_diag.svg + dot -Tpng 07_diag.dot > ../07_diag.png + +../08_ripple1.svg ../08_ripple1.png: 08_ripple1.dot + dot -Tsvg 08_ripple1.dot > ../08_ripple1.svg + dot -Tpng 08_ripple1.dot > ../08_ripple1.png + +../08_ripple2.svg ../08_ripple2.png: 08_ripple2.dot + dot -Tsvg 08_ripple2.dot > ../08_ripple2.svg + dot -Tpng 08_ripple2.dot > ../08_ripple2.png + Index: tags/1.0.5/doc/developer/Makefile =================================================================== --- tags/1.0.5/doc/developer/Makefile (nonexistent) +++ tags/1.0.5/doc/developer/Makefile (revision 10414) @@ -0,0 +1,28 @@ +ROOT=../.. +DEVDIR=$(DOCDIR)/developer + +all: + +install_all: + $(SCCBOX) mkdir -p $(DEVDIR)/lihata_format $(DEVDIR)/lihata_format/examples + $(SCCBOX) $(HOW) -d lihata_format/*.html $(DEVDIR)/lihata_format + $(SCCBOX) $(HOW) -d lihata_format/*.svg $(DEVDIR)/lihata_format + $(SCCBOX) $(HOW) -d lihata_format/*.txt $(DEVDIR)/lihata_format + $(SCCBOX) $(HOW) -d lihata_format/examples/* $(DEVDIR)/lihata_format/examples + $(SCCBOX) $(HOW) -d *.html *.txt $(DEVDIR) + +install: + $(MAKE) install_all HOW="install -f -d" + +linstall: + $(MAKE) install_all HOW="install -f -l -d" + +uninstall: + $(MAKE) install_all HOW="install -u" + +clean: + +distclean: + + +include $(ROOT)/Makefile.conf Index: tags/1.0.5/doc/developer/alien/orcad/page.txt =================================================================== --- tags/1.0.5/doc/developer/alien/orcad/page.txt (nonexistent) +++ tags/1.0.5/doc/developer/alien/orcad/page.txt (revision 10414) @@ -0,0 +1,54 @@ +(little endian) + +The page file is a tree. The root of the tree is a page object. + +Page file structure: ++--------+----------------------------------------+ +|pri hdr | +----------+ +-----------+ +---------+ | +| | |aux hdr #1| |closing hdr| | payload | | +|9 bytes | |type=0xa | |type=0xa | | | | +| | | | |(MAGIC) | | | | +|type=0xa| +----------+ +-----------+ +---------+ | ++--------+----------------------------------------+ + + +Object structure: + Primary header is 9 bytes long: + - type: 1 byte + - len: 4 bytes + - unknown: 4 byte (usually all-zero) + Payload: len number of bytes + +Payload may start with aux headers: + - this is recognised by the first byte matching the main header's type byte + - these subsequent headers do not allocate or address further data blocks + - the last header is the closing header and has a different structure: + - the length of this header is the length field of the previous header + - structure: + - type: 1 byte (matching the main header) + - the length of this header is known + - the last 8 bytes of this header is a magic number + 0xFF 0xE4 0x5C 0x39 0x00 0x00 0x00 0x00 + +Payload: + - payload is probably a C struct saved as is + - the structure of payload depends on primary header type + + +---- + +string: + - 2 byte length + - string characters (as many as length said) + - \0 (not part of length!) + +---- + +Page struct: + - page name (string) + - page size (string): standard sizes (hardwired dimensions) 'A'..'E' + - page settings: + - TODO + - a fixed sequence of payload segments: + - 2 bytes number-of-object counter (how many objects make up this segment) + - a sequence of the same objects packed (as many as the number-of-object counter) said Index: tags/1.0.5/doc/developer/archive/20160101_cschem.html =================================================================== --- tags/1.0.5/doc/developer/archive/20160101_cschem.html (nonexistent) +++ tags/1.0.5/doc/developer/archive/20160101_cschem.html (revision 10414) @@ -0,0 +1,68 @@ + + +

pcb-rnd devlog

+ +

cschem

+ +Cschem is a project I plan to start within the next few years. It's goals +and some design concepts are similar to gschem's and geda's, while it +also breaks some traditions in order to fix shortcomings in the design of geda. It's +named after gschem, not after geda, to emphasize that the editor needs to +be connected more to the rest of the system (see details later). +

+Some concepts cschem will try to follow (marking with * where there's major +difference to geda): +

    +
  • 1. design +
      +
    • 1.1. modularity, aka. toolkit approach +
    • 1.2. flexibility (through attributes) +
    • 1.3. one schematics file is one sheet +
    • 1.4. multi page projects (hierarchic, flat) +
    • 1.5. data is in structured text files (no builtin sql support in core) +
    • 1.6. * the concept of a "project"; it's optional, tools can work on a set of schematics files _or_ on a complete project +
    • 1.7. * nets and components are uniquely identifiable using the same identifiers by all projects +
    • 1.8. * no excess "smartness" in the GUI editor: no slotting, no pin numbering, no auto renumbering, etc; these all should be done in the netlist layer and results fed back to the editor +
    • 1.9. * direct, bidirectional communication between the editor (GUI) and the netlist layer without any integration of the two, through simple and clean API, keeping both parts replaceable; attributes cschem got back from the netlister are "volatile": not saved, do not override attributes provided by the user +
    • 1.10. * less format-specific tricks built into the GUI code, more generic approaches (e.g. a search is a search, not a search-for-text-attribute and results on the result lists are any object of the design) +
    • 1.11. * slotting, pin mapping, device mapping are in backends +
    • 1.12. * back annotation should not be any harder than forward annotation +
    • 1.13. * since a lot of info is invented in backends, not in the GUI (e.g. pin numbers, when slotting), the GUI needs to be able to switch between "views": what (combination of) backend(s) to get these info from; Note: this would also provide an interactive DRC on the GUI with the DRC still implemented in the netlister! +
    • 1.14. * the scriptable plugin system is based on GPMI from the start to guarantee the tool is not tied to any one specific scripting engine or scripting language +
    +
  • 2. implementation +
      +
    • 2.1. a core library that does common things like figuring what objects are connected with net lines +
    • 2.2. the simple GUI editor should provide the frame; exotic functions should come from user plugins +
    • 2.3. a simple netlister that provides only generic (* absolutely no backend specific) queries; actual backends are implemented as plugins +
    • 2.4. * the core library and the netlister and the GUI core are all implemented in plain C: +
        +
      • 2.4.1. * no dependency on any specific scripting engine or scripting language; no core functionality implemented in anything else but C +
      • 2.4.2. * no dependency on big "solves-everything" libraries (e.g. no glib or cairo dependency) +
      • 2.4.3. * the actual GUI is behind the plugin system (like PCB's HIDs) +
      • 2.4.4. * the first gui, in accordance with the no big libraries, will not be gtk or qt but sdl2 based; this would guarantee to have a front end that doesn't need to be rewritten every 5 years just for the sake of the rewrite +
      • 2.4.5. * scconfig instead of autotools: smaller, easier to maintain, works better outside of the gnu-win32 world +
      +
    +
  • 3. project management +
      +
    • 3.1. automatic tests wherever possible, as early as possible +
    • 3.2. * VCS: simple, centralized svn with straight linear development, actively trying to avoid branching +
    • 3.3. * near-zero-administration releases with svn commits +
    • 3.4. * users should be able to submit bug reports anonymously, without having to register, without having to run javascript, java applet, flash, etc. +
    +
+ + +

+There are a lot of open questions: +

    +
  • q1. how buses should work +
  • q2. how slotting should work (but at least we can have alternatives here) +
  • q3. how hierarchical design should work +
  • q4. * how the GUI should display large amount of attributes without making the whole page an unreadable mess +
  • q5. flat vs. non-flat netlists - if turns out it's not just an implementation detail in a netlister backend +
  • q6. * whether project file format is a custom format or just a top sch page referencing other sch pages - pcb-rnd is leading here, there is an optional project file format already defined, so this is more or less decided +
  • q7. attribute conventions +
+ Index: tags/1.0.5/doc/developer/archive/design_proc.html =================================================================== --- tags/1.0.5/doc/developer/archive/design_proc.html (nonexistent) +++ tags/1.0.5/doc/developer/archive/design_proc.html (revision 10414) @@ -0,0 +1,132 @@ + + +

sch-rnd - design process

+ +

Terminology

+
    +
  • use case: a specific example that shows what the user would + like to use cschem for. An use case focuses on the task, the abstract + problem that is to be solved and not on how the given problem is + actually solved. + +
  • implementation: a mechanism in the design/code or a property + of design/code that focuses on how something works (and not on + what it would be used for) + +
  • item: a section, typically a paragraph of one of our + design document with an unique identifier. Identifiers are wrapped + in braces and contain two fields separated by a colon, e.g. + {pol:15}. The first field is the name of the category + (e.g. pol is for policy and des is for design), the second field is + an integer. If an item is removed, it's identifier is retired and + never used again for another item. This helps us referencing sections + of the documents. +
+ + +

Design document edition process

+
    + +
  • 1. Igor2 writes a section of the design document, marked as + proposal, accessible both in svn and on the project web page + +
  • 2. Igor2 announces it on the mailing list with a deadline (probably + a week or two) + +
  • 3. contributors read the proposal, make comments, make public + debates about the details + +
  • 4. Igor2 collects and edits all the feedback and updates the proposal + +
  • 5. it either results in a coherent, complete section or we go back + to step 2 and do another cycle of refining. + +
  • 6. when a section is finished, it is semi-closed: later sections + shouldn't make significant changes to it unless it is unavoidable +
+ +

+The process is public and is done on the cschem mailing list and in cschem svn. + +

+A graphical representation from a contributor's point of view: +

+ +

+A succesful contribution moves along the green lines, first from top down +then fed back to the design proc and moves from left to right reaching +the implementation. Actions among the red lines won't affect or change cschem. + +

The debate

+The debate must be constructive and limited to the scope of the current +section as much as possible. Users should: +
    +
  • collect use cases from their practice +
  • make up use cases +
  • share the use cases (on the mailing list) - they will be collected and + documented in svn +
  • try to apply the proposed design on these use cases and determine + if the proposed implementation can reasonably handle the the + use cases +
+

+In other words, the debate should first focus more on what needs to +be solved than how exactly it is solved. If a contributor doesn't +like an implementation proposal, (s)he should provide use cases +to prove the implementation proposal is weak. An alternative +implementation proposal should try to handle all (or at least most) +use cases. +

+Cschem is a complex system - suggestions and demands will contradict each other +or the availabel programmer resources or project goals. In such situations +a decision has to be made, which inevitably leads to valuing some ideas, +suggestions or demands higher than others or even ignoring some requests. +Although the sheer crowd behind a given suggestion matters, the decision +process is not democtratic: the final word is Igor2's. + + +

Policies

+ +

+In case of contradiction (e.g. between use cases), we need to +differentiate between the priority of use cases. There are +abstract, generic policies that may help in that. + +

    +
  • {pol:1} keep the implementation simple: easy to understand, easy to track, + easy to (re)implement + +
  • {pol:2} don't expect only one implementation to exist + +
  • {pol:3} simple, common tasks should have a simple solution; if anything + needs to have a complex/inconvenient solution, that needs to be the complex, + rare task + +
  • {pol:4} provide tools and building blocks, not hardwired solutions; + elements of the system should make up a toolchain that can be + combined in unexpected way; let the user easily recombine the elemetns + +
  • {pol:5} do not assume the user is dumb; the tool does have a + learning curve; the learning curve shouldn't be unnecessarily steep + but the tool doesn't need to include "user friendly" hacks for "dummies". + +
  • {pol:6} cschem is not gschem nor gnetlist; it is not kicad or + whichever-$$$-EDA package either; we do not need to adhere to + or be compatible with any old custom only because "they do that" ... + +
  • {pol:7} ... but we should obey the Principle of Least Surprise if + it doesn't result in an implementation that's too incoherent + with the rest of the system. + +
  • {pol:8} No premature optimizations. Get everything working first + and then optimize. + +
  • {pol:9} modularity: separate tasks into independent, replacable + layers with clear boundaries and clean APIs between the layers. Keep + layers fucused; one layer preferrably does only one thing. + +
  • {pol:10} in the design phase, concentrate on the concepts, (what + problems need to be solved and what the solution is), not on the + implementation details (how exactly it is coded). + +
Index: tags/1.0.5/doc/developer/archive/howto_contrib.html =================================================================== --- tags/1.0.5/doc/developer/archive/howto_contrib.html (nonexistent) +++ tags/1.0.5/doc/developer/archive/howto_contrib.html (revision 10414) @@ -0,0 +1,48 @@ + + +

sch-rnd - howto contribute

+ +Any contribution is valuable. However, any contribution costs too, not +just for the contributor but for the community: the time to read it, test +it, maintain it, etc. In the best contribution the cost/benefit ratio is +strongly biased toward the benefit. This howto gives a few pointers how +this cost/benefit ratio could be improved. + + + +

Do's

Dont's

+ +
+
    +
  • focus: if the current design process is about aspect foo, please don't + write long essays on how aspect bar is affected unless it's absolutely + necessary to understand how foo is affected. +
  • split things up; if there are 4 sections of a design doc you have + comments about, please start 4 separate thread for them. +
  • proper referencing; if your comment is about a specific section, use + the section label (e.g. "{des1:4}") for reference. If the whole mail + or thread is about such a section, best put the reference in the subsect. +
  • concentrate on what problem we need to solve, not on which + technology is used in the solution; e.g. "we want this part to + be user scriptable" is a good consideration; "we want this part + to be written in lua" is a bad one. +
  • Generally speaking: distinguish between design and implementation details. + Focus on the design. +
+ + +
+
    +
  • Avoid sending a single huge mail commenting every second line of a + chapter: that will be very hard to handle for everyone else. + Avoid writing verbose, especially about "background information"; + please try to keep text as short as possible. +
  • Please don't get stuck on an implementation detail; it's impossible + to design cschem to 100% match everybody's preference on every little + detail. If it matches only 70%, please live with it for now, if the + design is strong, it will be easy to provide alternatives later. +
  • Do not hijack threads; if you want to steer the discussion in another + direction, it's okay to reply to a mail in a thread, but please do + change the topic so people know it's a new (sub)thread. +
+
Index: tags/1.0.5/doc/developer/archive/proc.svg =================================================================== --- tags/1.0.5/doc/developer/archive/proc.svg (nonexistent) +++ tags/1.0.5/doc/developer/archive/proc.svg (revision 10414) @@ -0,0 +1,154 @@ + + + + + + +process + + +design + +design document + + +code + +code + + +design->code + + +implementation + + +contrib + +YOUR +contribution: +suggestions +ideas + + +design->contrib + + +read the spec; +run the model +in your head + + +happy + +(happy) +end + + +code->happy + + + + +start + +start + + +start->design + + +download +the spec + + +diff + +sieve +change- +suggestions +ideas + + +contrib->diff + + +send mail +to list + + +edit + +translate the +change suggestion into +an svn commit + + +diff:w->edit + + +explicit +suggestions + + +devnull + +thank you, +was a nice reading + + +diff:e->devnull + + +anything else + + +invis1 + + +diff:s->invis1 + + +edit:w->design:w + + +svn +commit + + +notify + +change notification +on the mailing list +within 24 hours + + +edit->notify + + + + +nonot + +(no notification) + + +devnull->nonot + + + + +end + +end + + +nonot->end + + + + + Index: tags/1.0.5/doc/developer/archive/roadmap.html =================================================================== --- tags/1.0.5/doc/developer/archive/roadmap.html (nonexistent) +++ tags/1.0.5/doc/developer/archive/roadmap.html (revision 10414) @@ -0,0 +1,82 @@ + + + + +

1. GUI: Drawing objects (done) +

Provide tools for placing and editing drawing objects on a sheet +

Milestones:

    +
  • wirenet draw/merge +
  • wirenet del +
  • wirenet undo +
  • rectangle (filled/unfilled), polygon +
  • text (basic implementation) +
  • arcs and circles +
+ +

2. Object attribute access (done) +

Provide CLI tools and dialog boxes for accessign drawing object attributes +

Milestones:

    +
  • object-specific property dialog boxe for wirenets +
  • object-specific property dialog boxe for symbols/components +
  • generic propedit() +
  • generic query() +
  • finish the basic menu system + +
+ +

3. Symbol support (done) +

Implement basic support for symbols and build the initial symbol lib +

Milestones:

    +
  • symbol lib support (backing code) +
  • symbol lib dialog +
  • parametric symbols +
  • placement GUI, rotate +
  • symbol lib: basic passives, diodes and leds +
  • symbol lib: transistors, slotted opamps and comparators +
  • symbol lib: misc (titlebox, mounting holes, etc) +
  • symbol lib: basic connectors + +
+ +

4. File formats (done) +

Finish I/O plugins for the two most important file formats +

Milestones:

    +
  • lihata sheet (native file format) +
  • lihata symbol (native file format) +
  • tEDAx netlist export (portable interface to PCB editors) + +
+ + +

5. Internal mechanisms, part 1 (done) +

Abstract model compiler and device mapper +

Milestones:

    +
  • compiler for nets and components +
  • implement and test filter-like plugin mechanisms +
  • implement devmap as a filter-like plugin +
  • develop a minimal devmap database for testing + +
+ +

6. Internal mechanisms, part 2 (done) +

Data model generalism and reuse +

Milestones:

    +
  • support multiple sheets (flat multi-page designs) +
  • buffer operations: copy and paste +
  • buffer operations: import, export, serialization +
  • buffer operations: transformations (rotate, mirror) + +
+ + +

7. Automation (back annotation done) +

Features used in workflow automation +

Milestones:

    +
  • back annotation +
  • minimal user scripting + +
+ + + + Index: tags/1.0.5/doc/developer/archive/src/Makefile =================================================================== --- tags/1.0.5/doc/developer/archive/src/Makefile (nonexistent) +++ tags/1.0.5/doc/developer/archive/src/Makefile (revision 10414) @@ -0,0 +1,4 @@ +all: ../proc.svg + +../proc.svg: proc.dot + dot -Tsvg proc.dot > ../proc.svg Index: tags/1.0.5/doc/developer/archive/src/proc.dot =================================================================== --- tags/1.0.5/doc/developer/archive/src/proc.dot (nonexistent) +++ tags/1.0.5/doc/developer/archive/src/proc.dot (revision 10414) @@ -0,0 +1,33 @@ +digraph process { + + { + rank=same + design [shape=box label="design document"] + code [shape=box label="code"] + happy [label="(happy)\nend" style=rounded shape=box] + } + + start [label="start" style=rounded shape=box] + contrib [label="YOUR\ncontribution:\nsuggestions\nideas" color=lightgreen style=filled] + diff [shape=diamond label="sieve\nchange-\nsuggestions\nideas"] + edit [shape=box label="translate the\nchange suggestion into\nan svn commit"] + notify [shape=box label="change notification\non the mailing list\nwithin 24 hours"] + devnull [shape=box label="thank you,\nwas a nice reading"] + nonot [shape=box label="(no notification)"] + end [label="end" style=rounded shape=box] + invis1 [width=2 style=invisible] + + start -> design [label="download\nthe spec" weight=100 color=green] + design -> contrib [label="read the spec;\nrun the model\nin your head" weight=100 color=green] + design -> code [label="implementation" color=green] + code -> happy [color=green] + contrib -> diff [label="send mail\nto list" weight=100 color=green] + diff -> edit [weight=20 label="explicit\nsuggestions" tailport=w color=green] + diff -> devnull [weight=20 label="anything else" tailport=e color=red] + edit -> design [label="svn\ncommit" headport=w tailport=w color=green] + edit -> notify + devnull -> nonot [color=red] + nonot -> end [color=red] + diff -> invis1 [weight=1000 tailport=s style=invisible arrowhead=none] + +} Index: tags/1.0.5/doc/developer/archive/use_cases/backannot.html =================================================================== --- tags/1.0.5/doc/developer/archive/use_cases/backannot.html (nonexistent) +++ tags/1.0.5/doc/developer/archive/use_cases/backannot.html (revision 10414) @@ -0,0 +1,20 @@ + + + +

sch-rnd - use cases

+ +

The "back annotation"

+ +

Setup

+
    +
  • any <-> sch flow +
  • in a later phase of the project, in a 3rd party software (e.g. PCB layout tool, simulation software) some change is made that has to be carried back to the schematics +
+ +

Problems

+
    +
  • net change: multiple ways a network connection can be specified +
  • net change: hierarchy; what if a schematics is used in 4 instances and there's a change only in one instance? +
  • attribute change: attributes may be calculated by plugins (source shall be changed) +
+ Index: tags/1.0.5/doc/developer/archive/use_cases/blockdiag.html =================================================================== --- tags/1.0.5/doc/developer/archive/use_cases/blockdiag.html (nonexistent) +++ tags/1.0.5/doc/developer/archive/use_cases/blockdiag.html (revision 10414) @@ -0,0 +1,19 @@ + + + +

sch-rnd - use cases

+ +

Block diagram

+ +Simulink style block diagrams, circuit boards, circuits +with cables, hydraulics and maybe also VHDL. Features +required: +
    +
  • Graphical symbols with pins. +
  • Possibility to connect pins or more abstract connection points. +
  • Buses to bunch together like wires in a cable. +
  • Possibility to assign values to objects. +
  • The connections will form nets. +
+ + Index: tags/1.0.5/doc/developer/archive/use_cases/package.html =================================================================== --- tags/1.0.5/doc/developer/archive/use_cases/package.html (nonexistent) +++ tags/1.0.5/doc/developer/archive/use_cases/package.html (revision 10414) @@ -0,0 +1,24 @@ + + + +

sch-rnd - use cases

+ +

The Packaging problem

+ +

Setup

+
    +
  • sch -> pcb flow +
  • generic (light) symbol in the schematics (e.g. a generic IC) +
  • footprint attribute set to a generic package (e.g. a generic BGA256) +
+ +

Problems

+
    +
  • the pin numbering of the IC is arbitrary +
  • the pin numbering of the Package is arbitrary +
  • a Package+IC doesn't determine the pinout: there are various IC devices with different pinouts with the same footprint +
  • number of logical pins may not match number of physical pins; unused pins, multiple pins connected, power and ground rings,passive componnents +
  • Package designers will also use cschem to design the package +
  • IC designers will also use cschem to design the bonding diagram +
+ Index: tags/1.0.5/doc/developer/archive/use_cases/plugin_gui.html =================================================================== --- tags/1.0.5/doc/developer/archive/use_cases/plugin_gui.html (nonexistent) +++ tags/1.0.5/doc/developer/archive/use_cases/plugin_gui.html (revision 10414) @@ -0,0 +1,14 @@ + + + +

sch-rnd - use cases

+ +

plugin highlight

+ +A plugin may want to: +
    +
  • modify attributes +
  • higlight/selection of symbols (and nets) +
  • drive the GUI (dialog boxes, "go there" on the schamtics) +
+ Index: tags/1.0.5/doc/developer/archive/use_cases/transistor.html =================================================================== --- tags/1.0.5/doc/developer/archive/use_cases/transistor.html (nonexistent) +++ tags/1.0.5/doc/developer/archive/use_cases/transistor.html (revision 10414) @@ -0,0 +1,22 @@ + + + +

sch-rnd - use cases

+ +

The "transistor" problem

+ +

Setup

+
    +
  • sch -> pcb flow +
  • generic (light) symbol in the schematics (e.g. a generic NPN) +
  • footprint attribute set to a generic footprint (e.g. a generic sot23) +
+ +

Problems

+
    +
  • the pin numbering of the symbol is arbitrary +
  • the pin numbering of the footprint is arbitrary +
  • a footprint+NPN doesn't determine the pinout: there are various NPN devices with different pinouts with the same footprint +
  • number of logical pins may not match number of physical pins; unused pins, mutliple pins connected +
+ Index: tags/1.0.5/doc/developer/io_lihata_ver.html =================================================================== --- tags/1.0.5/doc/developer/io_lihata_ver.html (nonexistent) +++ tags/1.0.5/doc/developer/io_lihata_ver.html (revision 10414) @@ -0,0 +1,41 @@ + + + + sch-rnd - io_lihata versions + + + + + +

sch-rnd - io_lihata versions

+

+History of io_lihata, per format version. + +

lihata sheet (cschem-sheet-v)

+

v1

+

+ Initial stable version at sch-rnd 0.9.0. + + +

lihata group (cschem-group-v), e.g. symbol

+

v1

+

+ Initial stable version at sch-rnd 0.9.0. + +

lihata buffer (cschem-buffer-v)

+

v1

+

+ Initial stable version at sch-rnd 0.9.0. + +

sch-rnd - misc plugin lihata versions

+

+History of file, per format version. + +

lihata devmap (std_devmap.v)

+

v1

+

+ Initial stable version at sch-rnd 0.9.0. + + + + Index: tags/1.0.5/doc/developer/libcschem/undo_and_ptrs.txt =================================================================== --- tags/1.0.5/doc/developer/libcschem/undo_and_ptrs.txt (nonexistent) +++ tags/1.0.5/doc/developer/libcschem/undo_and_ptrs.txt (revision 10414) @@ -0,0 +1,32 @@ +In libcschem, it is safe to reference concrete objects by pointers, because +of the undo system. + +Every concrete object is also part of a doubly linked list. This list is +one of the sheet's 'active' or 'deleted' lists. This is true for all +objects in both the direct and the indirect subtrees. + +Existing objects are part of the 'active' list. Once they are deleted, they +are moved to the 'deleted' list by the 'redo' operation of the deletion and +if it is undone, the 'undo' operation will move the object back from the +'deleted' list to the 'active' list. + +Order of objects on these two lists does not matter. The lists are there +for only one purpose: to make sure no object is lost. + +This also means that once an object is created, it is never freed until +the whole sheet is freed. It may change its state from active to deleted +or back, but the address of the object is preserved. + +Furthermore each concrete object is part of exactly one sheet. A paste buffer +is a sheet too. When an object travels between sheets, the object needs to +be copied. The 'deleted' list of a sheet used as a paste buffer is always +empty: buffers are not edited, they are created and destroyed and re-created +from real sheets. + + +Conclusion: this makes referencing by pointer safe, even without having +to use a reference counter: + +- a concret object is always within a sheet +- it is created once, and will never be deleted until the whole sheet is deleted +- the address of the object is immutable Index: tags/1.0.5/doc/developer/libcschem/xorcache.txt =================================================================== --- tags/1.0.5/doc/developer/libcschem/xorcache.txt (nonexistent) +++ tags/1.0.5/doc/developer/libcschem/xorcache.txt (revision 10414) @@ -0,0 +1,11 @@ +For concrete molde objects there are fields, typically holding +oid-paths, that have a textual description on input but should be +tracked by object pointers after load. + +These fields are stored in a pair of struct fields marked xorcache: +either the text version or the object-pointer version is NULL. After +load, the text is valid, the pointer is NULL. Upon the first access, +the reference is resolved and the code uses the pointer. Whenever +this happens, the text field is free'd and set to NULL. + +Export code rebuilds the textual reference from the pointer. Index: tags/1.0.5/doc/developer/lihata_format/Makefile =================================================================== --- tags/1.0.5/doc/developer/lihata_format/Makefile (nonexistent) +++ tags/1.0.5/doc/developer/lihata_format/Makefile (revision 10414) @@ -0,0 +1,17 @@ +DOTS = \ + cschem-sheet-v.dot \ + +all: tree.html tree.txt $(DOTS) + +%.dot: render/render.sh render/*.awk *.lht + cd render && ./render.sh dot + for n in *.dot; do dot -Tsvg $$n > $${n%%.dot}.svg; done + +tree.html: render/render.sh render/*.awk *.lht + cd render && ./render.sh html > ../tree.html + +tree.txt: tree.html + w3m -cols 256 tree.html > tree.txt + +comm_flags.lht: ../../../src/pcb-rnd render/gen_flags.sh + cd render && ./gen_flags.sh > ../comm_flags.lht Index: tags/1.0.5/doc/developer/lihata_format/arc.ID.svg =================================================================== --- tags/1.0.5/doc/developer/lihata_format/arc.ID.svg (nonexistent) +++ tags/1.0.5/doc/developer/lihata_format/arc.ID.svg (revision 10414) @@ -0,0 +1,214 @@ + + + + + + +ha:arc.ID + + + +/lht_tree_doc/comm/arc.ID + + +ha:arc.ID + + + + + +/lht_tree_doc/comm/arc.ID/children/cx + + +cx +coord + + + + + +/lht_tree_doc/comm/arc.ID->/lht_tree_doc/comm/arc.ID/children/cx + + + + + +/lht_tree_doc/comm/arc.ID/children/cy + + +cy +coord + + + + + +/lht_tree_doc/comm/arc.ID->/lht_tree_doc/comm/arc.ID/children/cy + + + + + +/lht_tree_doc/comm/arc.ID/children/r + + +r +coord + + + + + +/lht_tree_doc/comm/arc.ID->/lht_tree_doc/comm/arc.ID/children/r + + + + + +/lht_tree_doc/comm/arc.ID/children/sang + + +sang +angle + + + + + +/lht_tree_doc/comm/arc.ID->/lht_tree_doc/comm/arc.ID/children/sang + + + + + +/lht_tree_doc/comm/arc.ID/children/dang + + +dang +angle + + + + + +/lht_tree_doc/comm/arc.ID->/lht_tree_doc/comm/arc.ID/children/dang + + + + + +/lht_tree_doc/comm/arc.ID/children/sx + + +sx +coord + + + + + +/lht_tree_doc/comm/arc.ID->/lht_tree_doc/comm/arc.ID/children/sx + + + + + +/lht_tree_doc/comm/arc.ID/children/sy + + +sy +coord + + + + + +/lht_tree_doc/comm/arc.ID->/lht_tree_doc/comm/arc.ID/children/sy + + + + + +/lht_tree_doc/comm/arc.ID/children/ex + + +ex +coord + + + + + +/lht_tree_doc/comm/arc.ID->/lht_tree_doc/comm/arc.ID/children/ex + + + + + +/lht_tree_doc/comm/arc.ID/children/ey + + +ey +coord + + + + + +/lht_tree_doc/comm/arc.ID->/lht_tree_doc/comm/arc.ID/children/ey + + + + + +/lht_tree_doc/comm/arc.ID/children/stroke + + +stroke +pen + + + + + +/lht_tree_doc/comm/arc.ID->/lht_tree_doc/comm/arc.ID/children/stroke + + + + + +/lht_tree_doc/comm/arc.ID/children/lock + + +lock +bool + + + + + +/lht_tree_doc/comm/arc.ID->/lht_tree_doc/comm/arc.ID/children/lock + + + + + +/lht_tree_doc/comm/arc.ID/children/floater + + +floater +bool + + + + + +/lht_tree_doc/comm/arc.ID->/lht_tree_doc/comm/arc.ID/children/floater + + + + + Index: tags/1.0.5/doc/developer/lihata_format/attrib.svg =================================================================== --- tags/1.0.5/doc/developer/lihata_format/attrib.svg (nonexistent) +++ tags/1.0.5/doc/developer/lihata_format/attrib.svg (revision 10414) @@ -0,0 +1,85 @@ + + + + + + +ha:attrib + + + +/lht_tree_doc/comm/attrib + + +ha:attrib + + + + + +/lht_tree_doc/comm/attrib/children/simple-attrib-key + + +simple-attrib-key +string + + + + + +/lht_tree_doc/comm/attrib->/lht_tree_doc/comm/attrib/children/simple-attrib-key + + + + + +/lht_tree_doc/comm/attrib/children/detailed-attrib + + +ha:detailed-attrib + + + + + +/lht_tree_doc/comm/attrib->/lht_tree_doc/comm/attrib/children/detailed-attrib + + + + + +/lht_tree_doc/comm/attrib/children/detailed-attrib/children/value + + +value +string + + + + + +/lht_tree_doc/comm/attrib/children/detailed-attrib->/lht_tree_doc/comm/attrib/children/detailed-attrib/children/value + + + + + +/lht_tree_doc/comm/attrib/children/detailed-attrib/children/prio + + +prio +integer + + + + + +/lht_tree_doc/comm/attrib/children/detailed-attrib->/lht_tree_doc/comm/attrib/children/detailed-attrib/children/prio + + + + + Index: tags/1.0.5/doc/developer/lihata_format/attribs.svg =================================================================== --- tags/1.0.5/doc/developer/lihata_format/attribs.svg (nonexistent) +++ tags/1.0.5/doc/developer/lihata_format/attribs.svg (revision 10414) @@ -0,0 +1,85 @@ + + + + + + +ha:attribs + + + +/lht_tree_doc/comm/attribs + + +ha:attribs + + + + + +/lht_tree_doc/comm/attribs/children/simple-attrib-key + + +simple-attrib-key +string + + + + + +/lht_tree_doc/comm/attribs->/lht_tree_doc/comm/attribs/children/simple-attrib-key + + + + + +/lht_tree_doc/comm/attribs/children/detailed-attrib + + +ha:detailed-attrib + + + + + +/lht_tree_doc/comm/attribs->/lht_tree_doc/comm/attribs/children/detailed-attrib + + + + + +/lht_tree_doc/comm/attribs/children/detailed-attrib/children/value + + +value +string + + + + + +/lht_tree_doc/comm/attribs/children/detailed-attrib->/lht_tree_doc/comm/attribs/children/detailed-attrib/children/value + + + + + +/lht_tree_doc/comm/attribs/children/detailed-attrib/children/prio + + +prio +integer + + + + + +/lht_tree_doc/comm/attribs/children/detailed-attrib->/lht_tree_doc/comm/attribs/children/detailed-attrib/children/prio + + + + + Index: tags/1.0.5/doc/developer/lihata_format/comm_attribs.lht =================================================================== --- tags/1.0.5/doc/developer/lihata_format/comm_attribs.lht (nonexistent) +++ tags/1.0.5/doc/developer/lihata_format/comm_attribs.lht (revision 10414) @@ -0,0 +1,20 @@ +ha:lht_tree_doc { ha:comm { + + ha:attrib { + type=ha + hide=1 + desc { a hash of attributes } + li:children { + ha:simple-attrib-key { valtype=string; desc={attribute value without metadata (text node)} } + ha:detailed-attrib { + type=ha + desc { attribute with metadata (hash node) } + li:children { + ha:value { valtype=string; desc={attribute value} } + ha:prio { valtype=integer; desc={priority value} } + } + } + } + } + +}} Index: tags/1.0.5/doc/developer/lihata_format/comm_concrete.lht =================================================================== --- tags/1.0.5/doc/developer/lihata_format/comm_concrete.lht (nonexistent) +++ tags/1.0.5/doc/developer/lihata_format/comm_concrete.lht (revision 10414) @@ -0,0 +1,158 @@ +ha:lht_tree_doc { ha:comm { + + ha:group.ID { + type=ha + desc { Group of concrete objects } + li:children { + ha:uuid = { valtype=minuid; desc={instance UID }} + ha:src_uuid = { valtype=minuid; desc={source UID }} + ha:x = { valtype=coord; desc={xform: translate placement in x (horizontal) direction }} + ha:y = { valtype=coord; desc={xform: translate placement in y (vertical) direction }} + ha:rot = { valtype=angle; desc={xform: rotate placement }} + ha:mirx = { valtype=bool; desc={xform: mirror placement left/right }} + ha:miry = { valtype=bool; desc={xform: mirror placement child up/down }} + ha:loclib_name = { valtype=string; desc={name in the local library (optional)}} + ha:objects { + type=li + desc { List of child objects } + li:children { + sy:line.ID = {/lht_tree_doc/comm/line.ID} + sy:arc.ID = {/lht_tree_doc/comm/arc.ID} + sy:polygon.ID = {/lht_tree_doc/comm/polygon.ID} + sy:text.ID = {/lht_tree_doc/comm/text.ID} + sy:connection.ID = {/lht_tree_doc/comm/connection.ID} + sy:pen.NAME = {/lht_tree_doc/comm/pen.NAME} + } + } + sy:attrib@dup = {/lht_tree_doc/comm/attrib} + } + } + + ha:group_ref.ID { + type=ha + desc { Group reference to a concrete object within the same sheet or buffer } + li:children { + ha:ref = { valtype=oidpath; desc={path relative to sheet root, to the referee (should be a group) }} + ha:child_xform { + type=li + desc { List of child object transformation to be performed after placement } + li:children { + ha:OIDPATH { + desc={list of transformations to be performed on referee children objects after placement; OIDPATH is relative to the referee group } + li:children { + ha:movex = { valtype=coord; desc={xform: move child in x (horizontal) direction }} + ha:movey = { valtype=coord; desc={xform: move child in y (vertical) direction }} + ha:rot = { valtype=angle; desc={xform: rotate child }} + ha:mirx = { valtype=bool; desc={xform: mirror child left/right }} + ha:miry = { valtype=bool; desc={xform: mirror child up/down }} + ha:remove = { valtype=bool; desc={xform: mirror child up/down }} + } + } + } + } + sy:attrib@dup = {/lht_tree_doc/comm/attrib} + } + } + + ha:line.ID { + type=ha + desc { Drawing object: straight line } + li:children { + ha:x1 = { valtype=coord; desc={start point, x coord }} + ha:y1 = { valtype=coord; desc={start point, y coord }} + ha:x2 = { valtype=coord; desc={end point, x coord }} + ha:y2 = { valtype=coord; desc={end point, y coord }} + ha:stroke = { valtype=pen; desc={pen to use }} + ha:lock = { valtype=bool; desc={object is locked }} + ha:floater = { valtype=bool; desc={"group lock" doesn't apply }} + } + } + + ha:arc.ID { + type=ha + desc { Drawing object: circular arc } + li:children { + ha:cx = { valtype=coord; desc={center point, x coord }} + ha:cy = { valtype=coord; desc={center point, y coord }} + ha:r = { valtype=coord; desc={radius }} + ha:sang = { valtype=angle; desc={start angle }} + ha:dang = { valtype=angle; desc={delta angle }} + ha:sx = { valtype=coord; desc={start point, x coord }} + ha:sy = { valtype=coord; desc={start point, y coord }} + ha:ex = { valtype=coord; desc={end point, x coord }} + ha:ey = { valtype=coord; desc={end point, y coord }} + ha:stroke = { valtype=pen; desc={pen to use }} + ha:lock = { valtype=bool; desc={object is locked }} + ha:floater = { valtype=bool; desc={"group lock" doesn't apply }} + } + } + + ha:polygon.ID { + type=ha + desc { Drawing object: polygon } + li:children { + ha:outline { + type=li + desc { ordered list of contour objects (no gaps allowed) } + li:children { + sy:line.ID = {/lht_tree_doc/comm/line.ID} + sy:arc.ID = {/lht_tree_doc/comm/arc.ID} + } + } + ha:stroke = { valtype=pen; desc={pen used for outline objects }} + ha:fill = { valtype=pen; desc={pen used for fill (no fill if not present)}} + ha:lock = { valtype=bool; desc={object is locked }} + ha:floater = { valtype=bool; desc={"group lock" doesn't apply }} + } + } + + ha:connection.ID { + type=ha + desc { Logical object: connection between different groups } + li:children { + ha:conn { + type=li + desc { list of objects participating in the connection (at least 2)} + li:children { + ha:OIDPATH = { valtype=oidpath; desc={drawing object making the connection )}} + } + } + } + } + + ha:text.ID { + type=ha + desc { Drawing object: straight line } + li:children { + ha:text = { valtype=string; desc={text string (or dyntext template)}} + ha:x1 = { valtype=coord; desc={lower left x coord of text box }} + ha:y1 = { valtype=coord; desc={lower left y coord of text box }} + ha:x2 = { valtype=coord; desc={upper right corner of untrasformed box; present only if text size is bbox-specified }} + ha:y2 = { valtype=coord; desc={upper right corner of untrasformed box; present only if text size is bbox-specified }} + ha:rot = { valtype=angle; desc={rotaition around x1;y1 }} + ha:mirx = { valtype=bool; desc={mirror origin/bbox left/right}} + ha:miry = { valtype=bool; desc={mirror origin/bbox up/down}} + ha:halign = { valtype=halign; desc={horizontal alignment }} + ha:dyntext = { valtype=bool; desc={if text string is a dyntext template }} + ha:stroke = { valtype=pen; desc={pen to use }} + ha:lock = { valtype=bool; desc={object is locked }} + ha:floater = { valtype=bool; desc={"group lock" doesn't apply }} + } + } + + ha:pen.NAME { + type=ha + desc { Logical object: a named pen used for drawing; names are unique within a group } + li:children { + ha:shape = { valtype=shape; desc={pen tip shape)}} + ha:size = { valtype=coord; desc={diameter or side length}} + ha:color = { valtype=color; desc={ink color }} + ha:font_height = { valtype=coord; desc={height of text font for non-bbox-defined text}} + ha:font_family = { valtype=string; desc={family hint for the font selector}} + ha:font_style = { valtype=string; desc={style hint for the font selector}} + ha:dash = { valtype=hex4; desc={dash pattern }} + ha:dash_period = { valtype=coord; desc={dash pattern length}} + } + } + +}} Index: tags/1.0.5/doc/developer/lihata_format/connection.ID.svg =================================================================== --- tags/1.0.5/doc/developer/lihata_format/connection.ID.svg (nonexistent) +++ tags/1.0.5/doc/developer/lihata_format/connection.ID.svg (revision 10414) @@ -0,0 +1,53 @@ + + + + + + +ha:connection.ID + + + +/lht_tree_doc/comm/connection.ID + + +ha:connection.ID + + + + + +/lht_tree_doc/comm/connection.ID/children/conn + + +li:conn + + + + + +/lht_tree_doc/comm/connection.ID->/lht_tree_doc/comm/connection.ID/children/conn + + + + + +/lht_tree_doc/comm/connection.ID/children/conn/children/OIDPATH + + +OIDPATH +oidpath + + + + + +/lht_tree_doc/comm/connection.ID/children/conn->/lht_tree_doc/comm/connection.ID/children/conn/children/OIDPATH + + + + + Index: tags/1.0.5/doc/developer/lihata_format/cschem-buffer-v.svg =================================================================== --- tags/1.0.5/doc/developer/lihata_format/cschem-buffer-v.svg (nonexistent) +++ tags/1.0.5/doc/developer/lihata_format/cschem-buffer-v.svg (revision 10414) @@ -0,0 +1,50 @@ + + + + + + +li:cschem-buffer-v* + + + +/lht_tree_doc/roots/cschem-buffer-v* + + +li:cschem-buffer-v* + + + + + +dup1_/lht_tree_doc/roots/cschem-buffer-v*/children/obj_indirect.1 + +obj_indirect.1 -> + + + + + +/lht_tree_doc/roots/cschem-buffer-v*->dup1_/lht_tree_doc/roots/cschem-buffer-v*/children/obj_indirect.1 + + + + + +dup2_/lht_tree_doc/roots/cschem-buffer-v*/children/obj_direct.2 + +obj_direct.2 -> + + + + + +/lht_tree_doc/roots/cschem-buffer-v*->dup2_/lht_tree_doc/roots/cschem-buffer-v*/children/obj_direct.2 + + + + + Index: tags/1.0.5/doc/developer/lihata_format/cschem-group-v.svg =================================================================== --- tags/1.0.5/doc/developer/lihata_format/cschem-group-v.svg (nonexistent) +++ tags/1.0.5/doc/developer/lihata_format/cschem-group-v.svg (revision 10414) @@ -0,0 +1,36 @@ + + + + + + +li:cschem-group-v* + + + +/lht_tree_doc/roots/cschem-group-v* + + +li:cschem-group-v* + + + + + +dup4_/lht_tree_doc/roots/cschem-group-v*/children/group.1 + +group.1 -> + + + + + +/lht_tree_doc/roots/cschem-group-v*->dup4_/lht_tree_doc/roots/cschem-group-v*/children/group.1 + + + + + Index: tags/1.0.5/doc/developer/lihata_format/cschem-sheet-v.svg =================================================================== --- tags/1.0.5/doc/developer/lihata_format/cschem-sheet-v.svg (nonexistent) +++ tags/1.0.5/doc/developer/lihata_format/cschem-sheet-v.svg (revision 10414) @@ -0,0 +1,64 @@ + + + + + + +ha:cschem-sheet-v* + + + +/lht_tree_doc/roots/cschem-sheet-v* + + +ha:cschem-sheet-v* + + + + + +dup5_/lht_tree_doc/roots/cschem-sheet-v*/children/obj_indirect.1 + +obj_indirect.1 -> + + + + + +/lht_tree_doc/roots/cschem-sheet-v*->dup5_/lht_tree_doc/roots/cschem-sheet-v*/children/obj_indirect.1 + + + + + +dup6_/lht_tree_doc/roots/cschem-sheet-v*/children/obj_direct.2 + +obj_direct.2 -> + + + + + +/lht_tree_doc/roots/cschem-sheet-v*->dup6_/lht_tree_doc/roots/cschem-sheet-v*/children/obj_direct.2 + + + + + +dup7_/lht_tree_doc/roots/cschem-sheet-v*/children/conf + +conf -> + + + + + +/lht_tree_doc/roots/cschem-sheet-v*->dup7_/lht_tree_doc/roots/cschem-sheet-v*/children/conf + + + + + Index: tags/1.0.5/doc/developer/lihata_format/examples/example.buff =================================================================== --- tags/1.0.5/doc/developer/lihata_format/examples/example.buff (nonexistent) +++ tags/1.0.5/doc/developer/lihata_format/examples/example.buff (revision 10414) @@ -0,0 +1,78 @@ +ha:cschem-buffer-v1 { + ha:obj_indirect.1 { + li:objects { + ha:group.1 { + li:objects { + ha:group.8 { + li:objects { + ha:group.1 { + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; floater=1; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; floater=1; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + name=R?? + role=symbol + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + sym-license-dist=GPLv2+ + sym-license-use=Public Domain + sym-source=sch-rnd default symbol lib + value=4k7 + } + } + } + ha:attrib { + ha:purpose = { value=symbol; prio=0; } + } + } + } + } + ha:obj_direct.2 { + li:objects { + ha:group_ref.1 { + x=10000; y=0; + ref=/1/1/8 + li:child_xform { + } + ha:attrib { + footprint=1206 + name=R2 + uid=xxxxx2 + value=2k + } + } + ha:line.2 { x1=0; y1=-4000; x2=-4000; y2=-4000; stroke=wire; } + ha:line.3 { x1=-4000; y1=-4000; x2=-4000; y2=0; stroke=wire; } + ha:arc.4 { cx=-8000; cy=4000; r=4000; sang=0.000000; dang=360.000000; stroke=sheet-decor; } + } + } +} Index: tags/1.0.5/doc/developer/lihata_format/examples/example.devmap =================================================================== --- tags/1.0.5/doc/developer/lihata_format/examples/example.devmap (nonexistent) +++ tags/1.0.5/doc/developer/lihata_format/examples/example.devmap (revision 10414) @@ -0,0 +1,10 @@ +ha:std_devmap.v1 { + ha:comp_attribs { + footprint=sot23 + li:portmap={ + {B->pcb/pinnum=1} + {E->pcb/pinnum=2} + {C->pcb/pinnum=3} + } + } +} Index: tags/1.0.5/doc/developer/lihata_format/examples/example.sch =================================================================== --- tags/1.0.5/doc/developer/lihata_format/examples/example.sch (nonexistent) +++ tags/1.0.5/doc/developer/lihata_format/examples/example.sch (revision 10414) @@ -0,0 +1,213 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + ha:group.1 { + li:objects { + ha:group.2 { + loclib_name=library/symbol/passive/resistor-1.sym + li:objects { + ha:group.1 { + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; floater=1; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; floater=1; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=R?? + role=symbol + value=4k7 + } + } + } + ha:attrib { + ha:purpose = { value=symbol; prio=0; } + } + } + } + } + ha:obj_direct.2 { + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.1 { + li:objects { + ha:polygon.11 { + li:outline { + ha:line { x1=0; y1=0; x2=80000; y2=0; } + ha:line { x1=80000; y1=0; x2=80000; y2=20000; } + ha:line { x1=80000; y1=20000; x2=0; y2=20000; } + ha:line { x1=0; y1=20000; x2=0; y2=0; } + } + stroke=titlebox-frame; + fill=titlebox-fill; + } + ha:line.12 { x1=0; y1=10000; x2=80000; y2=10000; stroke=titlebox-frame; } + ha:line.13 { x1=40000; y1=10000; x2=40000; y2=0; stroke=titlebox-frame; } + ha:text.20 { x1=1000; y1=16500; dyntext=0; stroke=titlebox-big; text=TITLE; } + ha:text.21 { x1=1000; y1=10500; x2=79000; y2=16000; dyntext=1; stroke=titlebox-big; text=%../../A.title%; } + ha:text.22 { x1=1000; y1=5500; dyntext=0; stroke=titlebox-small; text={PROJECT:}; } + ha:text.23 { x1=13000; y1=5500; x2=39000; y2=9500; dyntext=1; stroke=titlebox-big; text=%project.name%; } + ha:text.24 { x1=1000; y1=500; dyntext=0; stroke=titlebox-small; text={PAGE:}; } + ha:text.25 { x1=10000; y1=500; x2=39000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.page%; } + ha:text.26 { x1=41000; y1=5500; dyntext=0; stroke=titlebox-small; text={FILE:}; } + ha:text.27 { x1=48000; y1=5500; x2=79000; y2=9500; dyntext=1; stroke=titlebox-big; text=%filename%; } + ha:text.28 { x1=41000; y1=500; dyntext=0; stroke=titlebox-small; text={MAINTAINER:}; } + ha:text.29 { x1=55000; y1=500; x2=79000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.maintainer%; } + } + ha:attrib { + purpose=titlebox + } + } + ha:group.2 { + x=72000; y=100000; + li:objects { + ha:group.1 { + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; floater=1; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; floater=1; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.value%; floater=1; } + ha:text.4 { x1=8000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.5 { x1=9000; y1=5000; x2=9000; y2=-5000; stroke=sym-decor; } + ha:line.6 { x1=11000; y1=5000; x2=11000; y2=-5000; stroke=sym-decor; } + ha:line.7 { x1=4000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.8 { x1=11000; y1=0; x2=16000; y2=0; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=C1 + role=symbol + value=100n + } + } + ha:group_ref.3 { + x=100000; y=100000; + ref=/1/1/2 + li:child_xform { + } + ha:attrib { + name=R1 + value=4k7 + } + } + ha:group.4 { + li:objects { + ha:line.1 { x1=92000; y1=100000; x2=100000; y2=100000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.5 { + li:conn { + /2/4/1 + /2/2/1/1 + } + } + ha:connection.6 { + li:conn { + /2/4/1 + /2/3/2/1 + } + } + ha:arc.7 { cx=96000; cy=52000; r=8000; sang=45.000000; dang=180.000000; stroke=sheet-decor; } + ha:line.8 { x1=104000; y1=56000; x2=104000; y2=52000; stroke=sheet-decor; } + ha:line.9 { x1=104000; y1=52000; x2=108000; y2=52000; stroke=sheet-decor; } + ha:polygon.10 { + li:outline { + ha:line { x1=116000; y1=64000; x2=116000; y2=56000; } + ha:line { x1=116000; y1=56000; x2=124000; y2=56000; } + ha:line { x1=124000; y1=56000; x2=124000; y2=64000; } + ha:line { x1=124000; y1=64000; x2=116000; y2=64000; } + } + stroke=sheet-decor; + fill=hub; + } + ha:text.11 { x1=92000; y1=76000; dyntext=0; stroke=sheet-decor; text=Hello World!; } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer=Tibor 'Igor2' Palinkas + page=1 of 1 + print_page=A/4 + title=file format example + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 2 + grid = 4.0960 mm + } + } + } +} Index: tags/1.0.5/doc/developer/lihata_format/examples/example.sym =================================================================== --- tags/1.0.5/doc/developer/lihata_format/examples/example.sym (nonexistent) +++ tags/1.0.5/doc/developer/lihata_format/examples/example.sym (revision 10414) @@ -0,0 +1,64 @@ +ha:cschem-group-v1 { + ha:group.1 { + li:objects { + ha:polygon.1 { + li:outline { + ha:line { x1=10266; y1=-1780; x2=9224; y2=-3517; } + ha:line { x1=9224; y1=-3517; x2=10935; y2=-3368; } + ha:line { x1=10935; y1=-3368; x2=10266; y2=-1780; } + } + stroke=sym-decor; + fill=sym-decor; + } + ha:group.2 { + x=12000; y=8000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=-4000; dyntext=1; stroke=term-primary; text=%../a.display/name%; floater=1; } + } + ha:attrib { + name=C + role=terminal + } + } + ha:group.3 { + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; floater=1; } + } + ha:attrib { + name=B + role=terminal + } + } + ha:group.4 { + x=12000; y=-4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=-4000; dyntext=1; stroke=term-primary; text=%../a.display/name%; floater=1; } + } + ha:attrib { + name=E + role=terminal + } + } + ha:text.5 { x1=8000; y1=8000; rot=90.000000; dyntext=1; stroke=sym-secondary; text=%../A.devmap%; floater=1; } + ha:text.6 { x1=4000; y1=8000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:arc.7 { cx=9000; cy=0; r=5500; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:line.8 { x1=7000; y1=4000; x2=7000; y2=-4000; stroke=sym-decor; } + ha:line.9 { x1=4000; y1=0; x2=7000; y2=0; stroke=sym-decor; } + ha:line.10 { x1=7000; y1=-1000; x2=12000; y2=-4000; stroke=sym-decor; } + ha:line.11 { x1=7000; y1=1000; x2=12000; y2=4000; stroke=sym-decor; } + } + ha:attrib { + name=Q?? + role=symbol + devmap=bc817_sot23 + -sym-source = {sch-rnd default symbol lib} + -sym-copyright = {(C) 2022 Tibor 'Igor2' Palinkas} + -sym-license-dist = {GPLv2+} + -sym-license-use = {Public Domain} + } + } +} Index: tags/1.0.5/doc/developer/lihata_format/group.ID.svg =================================================================== --- tags/1.0.5/doc/developer/lihata_format/group.ID.svg (nonexistent) +++ tags/1.0.5/doc/developer/lihata_format/group.ID.svg (revision 10414) @@ -0,0 +1,327 @@ + + + + + + +ha:group.ID + + + +/lht_tree_doc/comm/group.ID + + +ha:group.ID + + + + + +/lht_tree_doc/comm/group.ID/children/uuid + + +uuid +minuid + + + + + +/lht_tree_doc/comm/group.ID->/lht_tree_doc/comm/group.ID/children/uuid + + + + + +/lht_tree_doc/comm/group.ID/children/src_uuid + + +src_uuid +minuid + + + + + +/lht_tree_doc/comm/group.ID->/lht_tree_doc/comm/group.ID/children/src_uuid + + + + + +/lht_tree_doc/comm/group.ID/children/x + + +x +coord + + + + + +/lht_tree_doc/comm/group.ID->/lht_tree_doc/comm/group.ID/children/x + + + + + +/lht_tree_doc/comm/group.ID/children/y + + +y +coord + + + + + +/lht_tree_doc/comm/group.ID->/lht_tree_doc/comm/group.ID/children/y + + + + + +/lht_tree_doc/comm/group.ID/children/rot + + +rot +angle + + + + + +/lht_tree_doc/comm/group.ID->/lht_tree_doc/comm/group.ID/children/rot + + + + + +/lht_tree_doc/comm/group.ID/children/mirx + + +mirx +bool + + + + + +/lht_tree_doc/comm/group.ID->/lht_tree_doc/comm/group.ID/children/mirx + + + + + +/lht_tree_doc/comm/group.ID/children/miry + + +miry +bool + + + + + +/lht_tree_doc/comm/group.ID->/lht_tree_doc/comm/group.ID/children/miry + + + + + +/lht_tree_doc/comm/group.ID/children/loclib_name + + +loclib_name +string + + + + + +/lht_tree_doc/comm/group.ID->/lht_tree_doc/comm/group.ID/children/loclib_name + + + + + +/lht_tree_doc/comm/group.ID/children/objects + + +li:objects + + + + + +/lht_tree_doc/comm/group.ID->/lht_tree_doc/comm/group.ID/children/objects + + + + + +dup14_/lht_tree_doc/comm/attrib + + +ha:attrib + + + + + +/lht_tree_doc/comm/group.ID->dup14_/lht_tree_doc/comm/attrib + + + + + +dup8_/lht_tree_doc/comm/group.ID/children/objects/children/line.ID + +line.ID -> + + + + + +/lht_tree_doc/comm/group.ID/children/objects->dup8_/lht_tree_doc/comm/group.ID/children/objects/children/line.ID + + + + + +dup9_/lht_tree_doc/comm/group.ID/children/objects/children/arc.ID + +arc.ID -> + + + + + +/lht_tree_doc/comm/group.ID/children/objects->dup9_/lht_tree_doc/comm/group.ID/children/objects/children/arc.ID + + + + + +dup10_/lht_tree_doc/comm/group.ID/children/objects/children/polygon.ID + +polygon.ID -> + + + + + +/lht_tree_doc/comm/group.ID/children/objects->dup10_/lht_tree_doc/comm/group.ID/children/objects/children/polygon.ID + + + + + +dup11_/lht_tree_doc/comm/group.ID/children/objects/children/text.ID + +text.ID -> + + + + + +/lht_tree_doc/comm/group.ID/children/objects->dup11_/lht_tree_doc/comm/group.ID/children/objects/children/text.ID + + + + + +dup12_/lht_tree_doc/comm/group.ID/children/objects/children/connection.ID + +connection.ID -> + + + + + +/lht_tree_doc/comm/group.ID/children/objects->dup12_/lht_tree_doc/comm/group.ID/children/objects/children/connection.ID + + + + + +dup13_/lht_tree_doc/comm/group.ID/children/objects/children/pen.NAME + +pen.NAME -> + + + + + +/lht_tree_doc/comm/group.ID/children/objects->dup13_/lht_tree_doc/comm/group.ID/children/objects/children/pen.NAME + + + + + +dup14_/lht_tree_doc/comm/attrib/children/simple-attrib-key + + +simple-attrib-key +string + + + + + +dup14_/lht_tree_doc/comm/attrib->dup14_/lht_tree_doc/comm/attrib/children/simple-attrib-key + + + + + +dup14_/lht_tree_doc/comm/attrib/children/detailed-attrib + + +ha:detailed-attrib + + + + + +dup14_/lht_tree_doc/comm/attrib->dup14_/lht_tree_doc/comm/attrib/children/detailed-attrib + + + + + +dup14_/lht_tree_doc/comm/attrib/children/detailed-attrib/children/value + + +value +string + + + + + +dup14_/lht_tree_doc/comm/attrib/children/detailed-attrib->dup14_/lht_tree_doc/comm/attrib/children/detailed-attrib/children/value + + + + + +dup14_/lht_tree_doc/comm/attrib/children/detailed-attrib/children/prio + + +prio +integer + + + + + +dup14_/lht_tree_doc/comm/attrib/children/detailed-attrib->dup14_/lht_tree_doc/comm/attrib/children/detailed-attrib/children/prio + + + + + Index: tags/1.0.5/doc/developer/lihata_format/group_ref.ID.svg =================================================================== --- tags/1.0.5/doc/developer/lihata_format/group_ref.ID.svg (nonexistent) +++ tags/1.0.5/doc/developer/lihata_format/group_ref.ID.svg (revision 10414) @@ -0,0 +1,242 @@ + + + + + + +ha:group_ref.ID + + + +/lht_tree_doc/comm/group_ref.ID + + +ha:group_ref.ID + + + + + +/lht_tree_doc/comm/group_ref.ID/children/ref + + +ref +oidpath + + + + + +/lht_tree_doc/comm/group_ref.ID->/lht_tree_doc/comm/group_ref.ID/children/ref + + + + + +/lht_tree_doc/comm/group_ref.ID/children/child_xform + + +li:child_xform + + + + + +/lht_tree_doc/comm/group_ref.ID->/lht_tree_doc/comm/group_ref.ID/children/child_xform + + + + + +dup15_/lht_tree_doc/comm/attrib + + +ha:attrib + + + + + +/lht_tree_doc/comm/group_ref.ID->dup15_/lht_tree_doc/comm/attrib + + + + + +/lht_tree_doc/comm/group_ref.ID/children/child_xform/children/OIDPATH + + +OIDPATH + + + + + +/lht_tree_doc/comm/group_ref.ID/children/child_xform->/lht_tree_doc/comm/group_ref.ID/children/child_xform/children/OIDPATH + + + + + +/lht_tree_doc/comm/group_ref.ID/children/child_xform/children/OIDPATH/children/movex + + +movex +coord + + + + + +/lht_tree_doc/comm/group_ref.ID/children/child_xform/children/OIDPATH->/lht_tree_doc/comm/group_ref.ID/children/child_xform/children/OIDPATH/children/movex + + + + + +/lht_tree_doc/comm/group_ref.ID/children/child_xform/children/OIDPATH/children/movey + + +movey +coord + + + + + +/lht_tree_doc/comm/group_ref.ID/children/child_xform/children/OIDPATH->/lht_tree_doc/comm/group_ref.ID/children/child_xform/children/OIDPATH/children/movey + + + + + +/lht_tree_doc/comm/group_ref.ID/children/child_xform/children/OIDPATH/children/rot + + +rot +angle + + + + + +/lht_tree_doc/comm/group_ref.ID/children/child_xform/children/OIDPATH->/lht_tree_doc/comm/group_ref.ID/children/child_xform/children/OIDPATH/children/rot + + + + + +/lht_tree_doc/comm/group_ref.ID/children/child_xform/children/OIDPATH/children/mirx + + +mirx +bool + + + + + +/lht_tree_doc/comm/group_ref.ID/children/child_xform/children/OIDPATH->/lht_tree_doc/comm/group_ref.ID/children/child_xform/children/OIDPATH/children/mirx + + + + + +/lht_tree_doc/comm/group_ref.ID/children/child_xform/children/OIDPATH/children/miry + + +miry +bool + + + + + +/lht_tree_doc/comm/group_ref.ID/children/child_xform/children/OIDPATH->/lht_tree_doc/comm/group_ref.ID/children/child_xform/children/OIDPATH/children/miry + + + + + +/lht_tree_doc/comm/group_ref.ID/children/child_xform/children/OIDPATH/children/remove + + +remove +bool + + + + + +/lht_tree_doc/comm/group_ref.ID/children/child_xform/children/OIDPATH->/lht_tree_doc/comm/group_ref.ID/children/child_xform/children/OIDPATH/children/remove + + + + + +dup15_/lht_tree_doc/comm/attrib/children/simple-attrib-key + + +simple-attrib-key +string + + + + + +dup15_/lht_tree_doc/comm/attrib->dup15_/lht_tree_doc/comm/attrib/children/simple-attrib-key + + + + + +dup15_/lht_tree_doc/comm/attrib/children/detailed-attrib + + +ha:detailed-attrib + + + + + +dup15_/lht_tree_doc/comm/attrib->dup15_/lht_tree_doc/comm/attrib/children/detailed-attrib + + + + + +dup15_/lht_tree_doc/comm/attrib/children/detailed-attrib/children/value + + +value +string + + + + + +dup15_/lht_tree_doc/comm/attrib/children/detailed-attrib->dup15_/lht_tree_doc/comm/attrib/children/detailed-attrib/children/value + + + + + +dup15_/lht_tree_doc/comm/attrib/children/detailed-attrib/children/prio + + +prio +integer + + + + + +dup15_/lht_tree_doc/comm/attrib/children/detailed-attrib->dup15_/lht_tree_doc/comm/attrib/children/detailed-attrib/children/prio + + + + + Index: tags/1.0.5/doc/developer/lihata_format/index.html =================================================================== --- tags/1.0.5/doc/developer/lihata_format/index.html (nonexistent) +++ tags/1.0.5/doc/developer/lihata_format/index.html (revision 10414) @@ -0,0 +1,64 @@ + + + + sch-rnd developer manual - lihata file formats + + + +

sch-rnd native file formats

+

+The native file format of sch-rnd is +lihata based. Lihata is a generic markup language that describes how +a tree can be serialized into a file format. What the tree contains and +what each node means is up to the user (sch-rnd in this case). This document +describes how the lihata trees are interpreted by sch-rnd. +

+This document is halfway in between the low level lihata document and the +high level data model +specification. It is assumed that the reader is familiar with both: the +lihata interface plugin doesn't do anything on its own, it only takes +the data model from the memory and the lihata document on disk and +converts the syntax between the two. +

+The following table is a summary of the native file formats sch-rnd core +plugins use. Note: +sch-rnd does not try to recognize the purpose of the file by the file name, +but by the root node name - files can be named anything, there's no +"extension"; there are some files that are found by name (typically config +files) - these are marked with bold. +

+ + +
typical filename root node + purpose (and documentation) + +
foo.sch ha:cschem-sheet-v* + Schematics sheet, self-contained +
(struct drawing) +
(sample file) + +
bar.sym li:cschem-group-v* + A group, usually a symbol, self-contained +
(struct drawing) +
(sample file) + +
baz.devmap li:std_devmap.v + A devmap file, self-contained +
(struct drawing) +
(sample file) + +
buffer.lht li:cschem-buffer-v + buffer content save; aside from the header, it's the same as a sheet (ha:cschem-sheet-v*) +
(struct drawing) +
(sample file) + +
project.lht ha:geda-project-v1 or ha:coraleda-project-v1 + A project file (documented in pcb-rnd; sch-rnd specific tutorial) + +
menu-default.lht ha: + The main menu system, including popup menus, all key and mouse bindings (documented in pcb-rnd) + +
+ + + Index: tags/1.0.5/doc/developer/lihata_format/line.ID.svg =================================================================== --- tags/1.0.5/doc/developer/lihata_format/line.ID.svg (nonexistent) +++ tags/1.0.5/doc/developer/lihata_format/line.ID.svg (revision 10414) @@ -0,0 +1,134 @@ + + + + + + +ha:line.ID + + + +/lht_tree_doc/comm/line.ID + + +ha:line.ID + + + + + +/lht_tree_doc/comm/line.ID/children/x1 + + +x1 +coord + + + + + +/lht_tree_doc/comm/line.ID->/lht_tree_doc/comm/line.ID/children/x1 + + + + + +/lht_tree_doc/comm/line.ID/children/y1 + + +y1 +coord + + + + + +/lht_tree_doc/comm/line.ID->/lht_tree_doc/comm/line.ID/children/y1 + + + + + +/lht_tree_doc/comm/line.ID/children/x2 + + +x2 +coord + + + + + +/lht_tree_doc/comm/line.ID->/lht_tree_doc/comm/line.ID/children/x2 + + + + + +/lht_tree_doc/comm/line.ID/children/y2 + + +y2 +coord + + + + + +/lht_tree_doc/comm/line.ID->/lht_tree_doc/comm/line.ID/children/y2 + + + + + +/lht_tree_doc/comm/line.ID/children/stroke + + +stroke +pen + + + + + +/lht_tree_doc/comm/line.ID->/lht_tree_doc/comm/line.ID/children/stroke + + + + + +/lht_tree_doc/comm/line.ID/children/lock + + +lock +bool + + + + + +/lht_tree_doc/comm/line.ID->/lht_tree_doc/comm/line.ID/children/lock + + + + + +/lht_tree_doc/comm/line.ID/children/floater + + +floater +bool + + + + + +/lht_tree_doc/comm/line.ID->/lht_tree_doc/comm/line.ID/children/floater + + + + + Index: tags/1.0.5/doc/developer/lihata_format/pen.NAME.svg =================================================================== --- tags/1.0.5/doc/developer/lihata_format/pen.NAME.svg (nonexistent) +++ tags/1.0.5/doc/developer/lihata_format/pen.NAME.svg (revision 10414) @@ -0,0 +1,150 @@ + + + + + + +ha:pen.NAME + + + +/lht_tree_doc/comm/pen.NAME + + +ha:pen.NAME + + + + + +/lht_tree_doc/comm/pen.NAME/children/shape + + +shape +shape + + + + + +/lht_tree_doc/comm/pen.NAME->/lht_tree_doc/comm/pen.NAME/children/shape + + + + + +/lht_tree_doc/comm/pen.NAME/children/size + + +size +coord + + + + + +/lht_tree_doc/comm/pen.NAME->/lht_tree_doc/comm/pen.NAME/children/size + + + + + +/lht_tree_doc/comm/pen.NAME/children/color + + +color +color + + + + + +/lht_tree_doc/comm/pen.NAME->/lht_tree_doc/comm/pen.NAME/children/color + + + + + +/lht_tree_doc/comm/pen.NAME/children/font_height + + +font_height +coord + + + + + +/lht_tree_doc/comm/pen.NAME->/lht_tree_doc/comm/pen.NAME/children/font_height + + + + + +/lht_tree_doc/comm/pen.NAME/children/font_family + + +font_family +string + + + + + +/lht_tree_doc/comm/pen.NAME->/lht_tree_doc/comm/pen.NAME/children/font_family + + + + + +/lht_tree_doc/comm/pen.NAME/children/font_style + + +font_style +string + + + + + +/lht_tree_doc/comm/pen.NAME->/lht_tree_doc/comm/pen.NAME/children/font_style + + + + + +/lht_tree_doc/comm/pen.NAME/children/dash + + +dash +hex4 + + + + + +/lht_tree_doc/comm/pen.NAME->/lht_tree_doc/comm/pen.NAME/children/dash + + + + + +/lht_tree_doc/comm/pen.NAME/children/dash_period + + +dash_period +coord + + + + + +/lht_tree_doc/comm/pen.NAME->/lht_tree_doc/comm/pen.NAME/children/dash_period + + + + + Index: tags/1.0.5/doc/developer/lihata_format/polygon.ID.svg =================================================================== --- tags/1.0.5/doc/developer/lihata_format/polygon.ID.svg (nonexistent) +++ tags/1.0.5/doc/developer/lihata_format/polygon.ID.svg (revision 10414) @@ -0,0 +1,129 @@ + + + + + + +ha:polygon.ID + + + +/lht_tree_doc/comm/polygon.ID + + +ha:polygon.ID + + + + + +/lht_tree_doc/comm/polygon.ID/children/outline + + +li:outline + + + + + +/lht_tree_doc/comm/polygon.ID->/lht_tree_doc/comm/polygon.ID/children/outline + + + + + +/lht_tree_doc/comm/polygon.ID/children/stroke + + +stroke +pen + + + + + +/lht_tree_doc/comm/polygon.ID->/lht_tree_doc/comm/polygon.ID/children/stroke + + + + + +/lht_tree_doc/comm/polygon.ID/children/fill + + +fill +pen + + + + + +/lht_tree_doc/comm/polygon.ID->/lht_tree_doc/comm/polygon.ID/children/fill + + + + + +/lht_tree_doc/comm/polygon.ID/children/lock + + +lock +bool + + + + + +/lht_tree_doc/comm/polygon.ID->/lht_tree_doc/comm/polygon.ID/children/lock + + + + + +/lht_tree_doc/comm/polygon.ID/children/floater + + +floater +bool + + + + + +/lht_tree_doc/comm/polygon.ID->/lht_tree_doc/comm/polygon.ID/children/floater + + + + + +dup16_/lht_tree_doc/comm/polygon.ID/children/outline/children/line.ID + +line.ID -> + + + + + +/lht_tree_doc/comm/polygon.ID/children/outline->dup16_/lht_tree_doc/comm/polygon.ID/children/outline/children/line.ID + + + + + +dup17_/lht_tree_doc/comm/polygon.ID/children/outline/children/arc.ID + +arc.ID -> + + + + + +/lht_tree_doc/comm/polygon.ID/children/outline->dup17_/lht_tree_doc/comm/polygon.ID/children/outline/children/arc.ID + + + + + Index: tags/1.0.5/doc/developer/lihata_format/render/common.awk =================================================================== --- tags/1.0.5/doc/developer/lihata_format/render/common.awk (nonexistent) +++ tags/1.0.5/doc/developer/lihata_format/render/common.awk (revision 10414) @@ -0,0 +1,69 @@ +function get_name(node, ty, level) +{ + if (node "/name" in DATA) + nm = DATA[node "/name"] + else + nm = qstrip(NAME[node]) + if (ty != "") + nm = ty ":" nm + while(level > 0) { + nm = " " nm + level-- + } + return nm +} + +function dup_begin(DUPSAV) +{ + DUPSAV[1] = dupd_prefix + if (DUPSAV[1] == "") + dupd_prefix = "dup" ++uniq_node_name "_" +} + +function dup_end(DUPSAV) +{ + dupd_prefix = DUPSAV[1] +} + +function gen_sub(root, level, parent, v, n, N, node, dst_children, DUPSAV) +{ + if (!(root in NAME)) { + print "Error: path not found: " root > "/dev/stderr" + return + } + if (parent == "") + parent = root + v = children(N, root "/children") + for(n = 1; n <= v; n++) { + node = N[n] + if (TYPE[node] == "symlink") { + # normal node symlink: generate a link +# print "SY:" node " " DATA[node] "^^^" sy_is_recursive(node) > "/dev/stderr" + dup_begin(DUPSAV) + if (NAME[node] ~ "@dup") { + tbl_entry(DATA[node], level, parent) + gen_sub(DATA[node], level+1) + } + else + tbl_entry_link(node, DATA[node], level, parent) + dup_end(DUPSAV) + } + else if ((node "/children") in NAME) { + tbl_entry(node, level, parent) + if (TYPE[node "/children"] == "symlink") { + dup_begin(DUPSAV) + dst_children = DATA[node "/children"] + sub("/children$", "", dst_children) + gen_sub(dst_children, level+1, node) + dup_end(DUPSAV) + } + else { + gen_sub(node, level+1) + } + } + else if (TYPE[node] == "hash") + tbl_entry(node, level, parent) + else + print "Unhandled child (unknown type): " node > "/dev/stderr" + } +} Index: tags/1.0.5/doc/developer/lihata_format/render/dot.awk =================================================================== --- tags/1.0.5/doc/developer/lihata_format/render/dot.awk (nonexistent) +++ tags/1.0.5/doc/developer/lihata_format/render/dot.awk (revision 10414) @@ -0,0 +1,99 @@ +BEGIN { + nl = "\\n" +} + +function tbl_entry(node, level, nparent ,nm,vt,dsc,ty,vr, url, tip,duppar,grp,grp_parent) +{ + ty = DATA[node "/type"] + nm = get_name(node, ty, 0) + vt = DATA[node "/valtype"] + vr = DATA[node "/ver"] + grp_parent = parent(parent(node)) + grp = DATA[grp_parent "/dot_group"] + dsc = qstrip(DATA[node "/desc"]) + gsub("\"", "\\\"", dsc) + tip=" tooltip=" q dsc q + url=" URL=" q "tree.html#" node q + + if (dupd_prefix != "") { + node = dupd_prefix node + DUPD[node] ++ + + if (nparent != "") { + duppar = dupd_prefix nparent + if (duppar in DUPD) + nparent = duppar + } + } + + print " " q node q " [label=" q nm nl vt nl vr q url tip "]" >fn + if (nparent != "") + print " " q nparent q " -> " q node q > fn + if (grp != "") { + if (LAST_GRP_SIBL[nparent] != "") { + print " " q LAST_GRP_SIBL[nparent] q " -> " q node q "[style=invis]" > fn + } + LAST_GRP_SIBL[nparent] = node + } +} + +function tbl_entry_link(node, dst, level, parent ,nm,vt,dsc,ty,vr,contid,url,tip,dr) +{ + ty = DATA[node "/type"] + nm = get_name(node, ty, 0) + vt = DATA[node "/valtype"] + vr = DATA[node "/ver"] + dsc = qstrip(DATA[node "/desc"]) + gsub("\"", "\\\"", dsc) + dr = dst + sub("^.*/", "", dr) + url=" URL=" q dr ".svg" q + tip=" tooltip=" q dsc q + + + if (dupd_prefix != "") { + node = dupd_prefix node + DUPD[node] ++ + + if (parent != "") { + duppar = dupd_prefix parent + if (duppar in DUPD) + parent = duppar + } + } + + + print " " q node q " [label=" q nm " ->" nl vt nl vr nl q url tip " shape=plaintext]" >fn + if (parent != "") + print " " q parent q " -> " q node q > fn +} + +function gen_graph(rpath, v, n, N, name) +{ + name = get_name(rpath, DATA[rpath "/type"]) + fn=name + sub(".*[:/]", "", fn) + gsub("[*]", "", fn) + fn = "../" fn ".dot" + + print "digraph " q name q " {" > fn + tbl_entry(rpath, 0) + gen_sub(rpath, 1) + print "}" > fn + close(fn) +} + +function gen_graphs(rpath, v, n, N, name) +{ + v = children(N, rpath) + for(n = 1; n <= v; n++) { + if (N[n] "/hide" in NAME) + continue + gen_graph(N[n]) + } +} + +END { + gen_graphs("/lht_tree_doc/roots") + gen_graphs("/lht_tree_doc/comm") +} Index: tags/1.0.5/doc/developer/lihata_format/render/html.awk =================================================================== --- tags/1.0.5/doc/developer/lihata_format/render/html.awk (nonexistent) +++ tags/1.0.5/doc/developer/lihata_format/render/html.awk (revision 10414) @@ -0,0 +1,117 @@ +BEGIN { + print "" + print "" + print "" + print " sch-rnd developer manual - lihata file formats" + print "" + print "" + print "" +} + +function tbl_hdr(node, level) +{ + print " type:name value ver description" +} + +function get_valtype(node, vt) +{ + vt = DATA[node "/valtype"] + if (vt != "") + vt = "" vt "" + else + vt = " " + return vt +} + +function tbl_entry(node, level, parent ,nm,vt,dsc,ty,vr) +{ + if (!(node in NAME)) { + print "Error: path not found: " node > "/dev/stderr" + return + } + ty = DATA[node "/type"] + nm = get_name(node, ty, level) + vt = get_valtype(node) + vr = DATA[node "/ver"] + if (vr == "") vr = " " + dsc = qstrip(DATA[node "/desc"]) + print " " nm " " vt " " vr " " dsc +} + +function tbl_entry_link(node, dst, level, parent ,nm,vt,dsc,ty,vr) +{ + if (!(node in NAME)) { + print "Error: path not found: " node > "/dev/stderr" + return + } + if (!(dst in NAME)) { + print "Error: path not found: " dst > "/dev/stderr" + return + } + + ty = DATA[dst "/type"] + nm = get_name(node, ty, level) + vt = get_valtype(dst) + vr = DATA[dst "/ver"] + if (vr == "") vr = " " + dsc = qstrip(DATA[dst "/desc"]) + print " " nm " " vt " " vr " " dsc " -> " +} + +function gen_main(path, v, n, N) +{ + print "

" DATA[path "/type"] ":" NAME[path] "

" +# print "

" +# print qstrip(DATA[path "/desc"]) + print "

" + print "" + tbl_hdr() + tbl_entry(path, 0) + gen_sub(path, 1) + print "
" +} + +function gen_roots(rpath, v, n, N) +{ + v = children(N, rpath) + for(n = 1; n <= v; n++) { + if (N[n] "/hide" in NAME) + continue + gen_main(N[n]) + } +} + +function gen_types(path, v, n, N, node) +{ + print "" + print "" + print "
type description" + + v = children(N, path) + for(n = 1; n <= v; n++) { + node = N[n] + print "
" NAME[node] + print " " qstripnl(DATA[node]) + } + print "
" +} + + +END { + print "

File format root nodes

" + print "

Each table below describes the full tree of one of the sch-rnd file formats, from the root." + gen_roots("/lht_tree_doc/roots") + + print "

Common subtrees

" + print "

Each table below describes a subtree that usually does not specify a whole tree (thus they are usually not a valid file on their own). These subtrees are described in a separate table because they are used from multiple other trees." + gen_roots("/lht_tree_doc/comm") + + print "

Types

" + print "

" + gen_types("/lht_tree_doc/types") + + print "

Comments

" + print "

ver column: Format version range the subtree may appear in." + print "" + print "" +} Index: tags/1.0.5/doc/developer/lihata_format/render/lht.awk =================================================================== --- tags/1.0.5/doc/developer/lihata_format/render/lht.awk (nonexistent) +++ tags/1.0.5/doc/developer/lihata_format/render/lht.awk (revision 10414) @@ -0,0 +1,62 @@ +BEGIN { + q="\"" +} + +function parent(path) +{ + sub("/[^/]*$", "", path) + return path +} + +function children(DST, path) +{ + return split(CHILDREN[path], DST, "[|]") +} + +function sy_is_recursive(path, dp) +{ + dp = DATA[path] + gsub("/[0-9]::", "/", path) + if (path ~ dp) + rturn 1 + return 0 +} + +function sy_href(path) +{ + return "#" path +} + +(($1 == "open") || ($1 == "data")) { + path=$3 + gsub("[0-9]+::", "", path) + TYPE[path] = $2 + p = parent(path) + if (CHILDREN[p] == "") + CHILDREN[p] = path + else + CHILDREN[p] = CHILDREN[p] "|" path + data=$4 + gsub("\\\\057", "/", data) + DATA[path] = data + + name=$3 + sub("^.*/", "", name) + sub(".*::", "", name) + NAME[path] = name +} + +function qstrip(s) +{ + gsub("[\\\\]+164", " ", s) + gsub("[\\\\]n", " ", s) + return s +} + +function qstripnl(s) +{ + gsub("[\\\\]+164", " ", s) + gsub("[\\\\]n", "\n", s) + return s +} + Index: tags/1.0.5/doc/developer/lihata_format/render/render.sh =================================================================== --- tags/1.0.5/doc/developer/lihata_format/render/render.sh (nonexistent) +++ tags/1.0.5/doc/developer/lihata_format/render/render.sh (revision 10414) @@ -0,0 +1,6 @@ +#!/bin/sh + +for n in ../*.lht +do + lhtflat < $n +done | tee Flat | awk -F "[\t]" -f lht.awk -f common.awk -f $1.awk Property changes on: tags/1.0.5/doc/developer/lihata_format/render/render.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/1.0.5/doc/developer/lihata_format/root_buffer.lht =================================================================== --- tags/1.0.5/doc/developer/lihata_format/root_buffer.lht (nonexistent) +++ tags/1.0.5/doc/developer/lihata_format/root_buffer.lht (revision 10414) @@ -0,0 +1,11 @@ +ha:lht_tree_doc { ha:roots { + + ha:cschem-buffer-v* { + type=li + desc={Buffer content (direct/indirect: same meaning as schematic sheet)} + li:children { + sy:obj_indirect.1 = {/lht_tree_doc/comm/group.ID} + sy:obj_direct.2 = {/lht_tree_doc/comm/group.ID} + } + } +}} Index: tags/1.0.5/doc/developer/lihata_format/root_conf.lht =================================================================== --- tags/1.0.5/doc/developer/lihata_format/root_conf.lht (nonexistent) +++ tags/1.0.5/doc/developer/lihata_format/root_conf.lht (revision 10414) @@ -0,0 +1,22 @@ +ha:lht_tree_doc { ha:roots { + + ha:sch-rnd-conf-v1 { + type=li + desc=complete sch-rnd configuration tree + li:children { + ha:overwrite { + type=ha + desc={overwrite values while merging; children: a full or partial config tree} + } + ha:prepend { + type=ha + desc={prepend values while merging; children: a full or partial config tree} + } + ha:append { + type=ha + desc={append values while merging; children: a full or partial config tree} + } + } + } + +}} Index: tags/1.0.5/doc/developer/lihata_format/root_devmap.lht =================================================================== --- tags/1.0.5/doc/developer/lihata_format/root_devmap.lht (nonexistent) +++ tags/1.0.5/doc/developer/lihata_format/root_devmap.lht (revision 10414) @@ -0,0 +1,16 @@ +ha:lht_tree_doc { ha:roots { + + ha:std_devmap.v* { + type=ha + desc={Device map for plugin std_devmap} + li:children { + ha:comp_attribs { + type=ha + desc={Attributes to be set in the abstract component} + li:children { + sy:attrib@dup = {/lht_tree_doc/comm/attrib} + } + } + } + } +}} Index: tags/1.0.5/doc/developer/lihata_format/root_group.lht =================================================================== --- tags/1.0.5/doc/developer/lihata_format/root_group.lht (nonexistent) +++ tags/1.0.5/doc/developer/lihata_format/root_group.lht (revision 10414) @@ -0,0 +1,10 @@ +ha:lht_tree_doc { ha:roots { + + ha:cschem-group-v* { + type=li + desc={concrete group (e.g. symbol) } + li:children { + sy:group.1 = {/lht_tree_doc/comm/group.ID} + } + } +}} Index: tags/1.0.5/doc/developer/lihata_format/root_sheet.lht =================================================================== --- tags/1.0.5/doc/developer/lihata_format/root_sheet.lht (nonexistent) +++ tags/1.0.5/doc/developer/lihata_format/root_sheet.lht (revision 10414) @@ -0,0 +1,12 @@ +ha:lht_tree_doc { ha:roots { + + ha:cschem-sheet-v* { + type=ha + desc={schematic sheet} + li:children { + sy:obj_indirect.1 = {/lht_tree_doc/comm/group.ID} + sy:obj_direct.2 = {/lht_tree_doc/comm/group.ID} + sy:conf = {/lht_tree_doc/roots/sch-rnd-conf-v1} + } + } +}} Index: tags/1.0.5/doc/developer/lihata_format/std_devmap.v.svg =================================================================== --- tags/1.0.5/doc/developer/lihata_format/std_devmap.v.svg (nonexistent) +++ tags/1.0.5/doc/developer/lihata_format/std_devmap.v.svg (revision 10414) @@ -0,0 +1,115 @@ + + + + + + +ha:std_devmap.v* + + + +/lht_tree_doc/roots/std_devmap.v* + + +ha:std_devmap.v* + + + + + +/lht_tree_doc/roots/std_devmap.v*/children/comp_attribs + + +ha:comp_attribs + + + + + +/lht_tree_doc/roots/std_devmap.v*->/lht_tree_doc/roots/std_devmap.v*/children/comp_attribs + + + + + +dup3_/lht_tree_doc/comm/attrib + + +ha:attrib + + + + + +/lht_tree_doc/roots/std_devmap.v*/children/comp_attribs->dup3_/lht_tree_doc/comm/attrib + + + + + +dup3_/lht_tree_doc/comm/attrib/children/simple-attrib-key + + +simple-attrib-key +string + + + + + +dup3_/lht_tree_doc/comm/attrib->dup3_/lht_tree_doc/comm/attrib/children/simple-attrib-key + + + + + +dup3_/lht_tree_doc/comm/attrib/children/detailed-attrib + + +ha:detailed-attrib + + + + + +dup3_/lht_tree_doc/comm/attrib->dup3_/lht_tree_doc/comm/attrib/children/detailed-attrib + + + + + +dup3_/lht_tree_doc/comm/attrib/children/detailed-attrib/children/value + + +value +string + + + + + +dup3_/lht_tree_doc/comm/attrib/children/detailed-attrib->dup3_/lht_tree_doc/comm/attrib/children/detailed-attrib/children/value + + + + + +dup3_/lht_tree_doc/comm/attrib/children/detailed-attrib/children/prio + + +prio +integer + + + + + +dup3_/lht_tree_doc/comm/attrib/children/detailed-attrib->dup3_/lht_tree_doc/comm/attrib/children/detailed-attrib/children/prio + + + + + Index: tags/1.0.5/doc/developer/lihata_format/text.ID.svg =================================================================== --- tags/1.0.5/doc/developer/lihata_format/text.ID.svg (nonexistent) +++ tags/1.0.5/doc/developer/lihata_format/text.ID.svg (revision 10414) @@ -0,0 +1,230 @@ + + + + + + +ha:text.ID + + + +/lht_tree_doc/comm/text.ID + + +ha:text.ID + + + + + +/lht_tree_doc/comm/text.ID/children/text + + +text +string + + + + + +/lht_tree_doc/comm/text.ID->/lht_tree_doc/comm/text.ID/children/text + + + + + +/lht_tree_doc/comm/text.ID/children/x1 + + +x1 +coord + + + + + +/lht_tree_doc/comm/text.ID->/lht_tree_doc/comm/text.ID/children/x1 + + + + + +/lht_tree_doc/comm/text.ID/children/y1 + + +y1 +coord + + + + + +/lht_tree_doc/comm/text.ID->/lht_tree_doc/comm/text.ID/children/y1 + + + + + +/lht_tree_doc/comm/text.ID/children/x2 + + +x2 +coord + + + + + +/lht_tree_doc/comm/text.ID->/lht_tree_doc/comm/text.ID/children/x2 + + + + + +/lht_tree_doc/comm/text.ID/children/y2 + + +y2 +coord + + + + + +/lht_tree_doc/comm/text.ID->/lht_tree_doc/comm/text.ID/children/y2 + + + + + +/lht_tree_doc/comm/text.ID/children/rot + + +rot +angle + + + + + +/lht_tree_doc/comm/text.ID->/lht_tree_doc/comm/text.ID/children/rot + + + + + +/lht_tree_doc/comm/text.ID/children/mirx + + +mirx +bool + + + + + +/lht_tree_doc/comm/text.ID->/lht_tree_doc/comm/text.ID/children/mirx + + + + + +/lht_tree_doc/comm/text.ID/children/miry + + +miry +bool + + + + + +/lht_tree_doc/comm/text.ID->/lht_tree_doc/comm/text.ID/children/miry + + + + + +/lht_tree_doc/comm/text.ID/children/halign + + +halign +halign + + + + + +/lht_tree_doc/comm/text.ID->/lht_tree_doc/comm/text.ID/children/halign + + + + + +/lht_tree_doc/comm/text.ID/children/dyntext + + +dyntext +bool + + + + + +/lht_tree_doc/comm/text.ID->/lht_tree_doc/comm/text.ID/children/dyntext + + + + + +/lht_tree_doc/comm/text.ID/children/stroke + + +stroke +pen + + + + + +/lht_tree_doc/comm/text.ID->/lht_tree_doc/comm/text.ID/children/stroke + + + + + +/lht_tree_doc/comm/text.ID/children/lock + + +lock +bool + + + + + +/lht_tree_doc/comm/text.ID->/lht_tree_doc/comm/text.ID/children/lock + + + + + +/lht_tree_doc/comm/text.ID/children/floater + + +floater +bool + + + + + +/lht_tree_doc/comm/text.ID->/lht_tree_doc/comm/text.ID/children/floater + + + + + Index: tags/1.0.5/doc/developer/lihata_format/tree.html =================================================================== --- tags/1.0.5/doc/developer/lihata_format/tree.html (nonexistent) +++ tags/1.0.5/doc/developer/lihata_format/tree.html (revision 10414) @@ -0,0 +1,269 @@ + + + + sch-rnd developer manual - lihata file formats + + + +

File format root nodes

+

Each table below describes the full tree of one of the sch-rnd file formats, from the root. +

li:cschem-buffer-v*

+

+ +
type:name value ver description +
li:cschem-buffer-v*     Buffer content (direct/indirect: same meaning as schematic sheet) +
 ha:obj_indirect.1     Group of concrete objects -> +
 ha:obj_direct.2     Group of concrete objects -> +
+

li:sch-rnd-conf-v1

+

+ +
type:name value ver description +
li:sch-rnd-conf-v1     complete sch-rnd configuration tree +
 ha:overwrite     overwrite values while merging; children: a full or partial config tree +
 ha:prepend     prepend values while merging; children: a full or partial config tree +
 ha:append     append values while merging; children: a full or partial config tree +
+

ha:std_devmap.v*

+

+ +
type:name value ver description +
ha:std_devmap.v*     Device map for plugin std_devmap +
 ha:comp_attribs     Attributes to be set in the abstract component +
  ha:attrib     a hash of attributes +
   simple-attrib-key string   attribute value without metadata (text node) +
   ha:detailed-attrib     attribute with metadata (hash node) +
    value string   attribute value +
    prio integer   priority value +
+

li:cschem-group-v*

+

+ +
type:name value ver description +
li:cschem-group-v*     concrete group (e.g. symbol) +
 ha:group.1     Group of concrete objects -> +
+

ha:cschem-sheet-v*

+

+ +
type:name value ver description +
ha:cschem-sheet-v*     schematic sheet +
 ha:obj_indirect.1     Group of concrete objects -> +
 ha:obj_direct.2     Group of concrete objects -> +
 li:conf     complete sch-rnd configuration tree -> +
+

Common subtrees

+

Each table below describes a subtree that usually does not specify a whole tree (thus they are usually not a valid file on their own). These subtrees are described in a separate table because they are used from multiple other trees. +

ha:group.ID

+

+ +
type:name value ver description +
ha:group.ID     Group of concrete objects +
 uuid minuid   instance UID +
 src_uuid minuid   source UID +
 x coord   xform: translate placement in x (horizontal) direction +
 y coord   xform: translate placement in y (vertical) direction +
 rot angle   xform: rotate placement +
 mirx bool   xform: mirror placement left/right +
 miry bool   xform: mirror placement child up/down +
 loclib_name string   name in the local library (optional) +
 li:objects     List of child objects +
  ha:line.ID     Drawing object: straight line -> +
  ha:arc.ID     Drawing object: circular arc -> +
  ha:polygon.ID     Drawing object: polygon -> +
  ha:text.ID     Drawing object: straight line -> +
  ha:connection.ID     Logical object: connection between different groups -> +
  ha:pen.NAME     Logical object: a named pen used for drawing; names are unique within a group -> +
 ha:attrib     a hash of attributes +
  simple-attrib-key string   attribute value without metadata (text node) +
  ha:detailed-attrib     attribute with metadata (hash node) +
   value string   attribute value +
   prio integer   priority value +
+

ha:group_ref.ID

+

+ +
type:name value ver description +
ha:group_ref.ID     Group reference to a concrete object within the same sheet or buffer +
 ref oidpath   path relative to sheet root, to the referee (should be a group) +
 li:child_xform     List of child object transformation to be performed after placement +
  OIDPATH     list of transformations to be performed on referee children objects after placement; OIDPATH is relative to the referee group +
   movex coord   xform: move child in x (horizontal) direction +
   movey coord   xform: move child in y (vertical) direction +
   rot angle   xform: rotate child +
   mirx bool   xform: mirror child left/right +
   miry bool   xform: mirror child up/down +
   remove bool   xform: mirror child up/down +
 ha:attrib     a hash of attributes +
  simple-attrib-key string   attribute value without metadata (text node) +
  ha:detailed-attrib     attribute with metadata (hash node) +
   value string   attribute value +
   prio integer   priority value +
+

ha:line.ID

+

+ +
type:name value ver description +
ha:line.ID     Drawing object: straight line +
 x1 coord   start point, x coord +
 y1 coord   start point, y coord +
 x2 coord   end point, x coord +
 y2 coord   end point, y coord +
 stroke pen   pen to use +
 lock bool   object is locked +
 floater bool   "group lock" doesn't apply +
+

ha:arc.ID

+

+ +
type:name value ver description +
ha:arc.ID     Drawing object: circular arc +
 cx coord   center point, x coord +
 cy coord   center point, y coord +
 r coord   radius +
 sang angle   start angle +
 dang angle   delta angle +
 sx coord   start point, x coord +
 sy coord   start point, y coord +
 ex coord   end point, x coord +
 ey coord   end point, y coord +
 stroke pen   pen to use +
 lock bool   object is locked +
 floater bool   "group lock" doesn't apply +
+

ha:polygon.ID

+

+ +
type:name value ver description +
ha:polygon.ID     Drawing object: polygon +
 li:outline     ordered list of contour objects (no gaps allowed) +
  ha:line.ID     Drawing object: straight line -> +
  ha:arc.ID     Drawing object: circular arc -> +
 stroke pen   pen used for outline objects +
 fill pen   pen used for fill (no fill if not present) +
 lock bool   object is locked +
 floater bool   "group lock" doesn't apply +
+

ha:connection.ID

+

+ +
type:name value ver description +
ha:connection.ID     Logical object: connection between different groups +
 li:conn     list of objects participating in the connection (at least 2) +
  OIDPATH oidpath   drawing object making the connection ) +
+

ha:text.ID

+

+ +
type:name value ver description +
ha:text.ID     Drawing object: straight line +
 text string   text string (or dyntext template) +
 x1 coord   lower left x coord of text box +
 y1 coord   lower left y coord of text box +
 x2 coord   upper right corner of untrasformed box; present only if text size is bbox-specified +
 y2 coord   upper right corner of untrasformed box; present only if text size is bbox-specified +
 rot angle   rotaition around x1;y1 +
 mirx bool   mirror origin/bbox left/right +
 miry bool   mirror origin/bbox up/down +
 halign halign   horizontal alignment +
 dyntext bool   if text string is a dyntext template +
 stroke pen   pen to use +
 lock bool   object is locked +
 floater bool   "group lock" doesn't apply +
+

ha:pen.NAME

+

+ +
type:name value ver description +
ha:pen.NAME     Logical object: a named pen used for drawing; names are unique within a group +
 shape shape   pen tip shape) +
 size coord   diameter or side length +
 color color   ink color +
 font_height coord   height of text font for non-bbox-defined text +
 font_family string   family hint for the font selector +
 font_style string   style hint for the font selector +
 dash hex4   dash pattern +
 dash_period coord   dash pattern length +
+

Types

+

+ + + + + + + + + + + + + + + +
type description +
angle + + A decimal number without unit, representing an angle in degree. Can + be positive or negative. + +
coord + + A decimal integer. + +
double + + Unitless numeric value in decimal format. Depending on context it is + sometimes signed. + +
integer + + Unitless integer value in decimal format. Depending on context it is + sometimes signed. + +
hex4 + + 4 digits of hexadecimal numbers (0-9, a-f, A-F) + +
bool + + Single digit boolean value: 0 means false, 1 means true. + +
pen + + Name of a pen defined in a parent group. + +
halign + + One of: left, center, right, word_justify, justify. + +
shape + + One of: round, square. + +
color + + #rrggbb + +
minuid + + An unique ID as generated by libminuid (24 ASCII characters). + +
none + + No value. + +
string + + Free form text data + +
oidpath + + A slash separated list of integer object IDs (oids). + +
+

Comments

+

ver column: Format version range the subtree may appear in. + + Index: tags/1.0.5/doc/developer/lihata_format/tree.txt =================================================================== --- tags/1.0.5/doc/developer/lihata_format/tree.txt (nonexistent) +++ tags/1.0.5/doc/developer/lihata_format/tree.txt (revision 10414) @@ -0,0 +1,209 @@ +File format root nodes + +Each table below describes the full tree of one of the sch-rnd file formats, from the root. + +li:cschem-buffer-v* + +type:name value ver description +li:cschem-buffer-v* Buffer content (direct/indirect: same meaning as schematic sheet) + ha:obj_indirect.1 Group of concrete objects -> + ha:obj_direct.2 Group of concrete objects -> + +li:sch-rnd-conf-v1 + +type:name value ver description +li:sch-rnd-conf-v1 complete sch-rnd configuration tree + ha:overwrite overwrite values while merging; children: a full or partial config tree + ha:prepend prepend values while merging; children: a full or partial config tree + ha:append append values while merging; children: a full or partial config tree + +ha:std_devmap.v* + +type:name value ver description +ha:std_devmap.v* Device map for plugin std_devmap + ha:comp_attribs Attributes to be set in the abstract component + ha:attrib a hash of attributes + simple-attrib-key string attribute value without metadata (text node) + ha:detailed-attrib attribute with metadata (hash node) + value string attribute value + prio integer priority value + +li:cschem-group-v* + +type:name value ver description +li:cschem-group-v* concrete group (e.g. symbol) + ha:group.1 Group of concrete objects -> + +ha:cschem-sheet-v* + +type:name value ver description +ha:cschem-sheet-v* schematic sheet + ha:obj_indirect.1 Group of concrete objects -> + ha:obj_direct.2 Group of concrete objects -> + li:conf complete sch-rnd configuration tree -> + +Common subtrees + +Each table below describes a subtree that usually does not specify a whole tree (thus they are usually not a valid file on their own). These subtrees are described in a separate table because they are used from multiple other trees. + +ha:group.ID + +type:name value ver description +ha:group.ID Group of concrete objects + uuid minuid instance UID + src_uuid minuid source UID + x coord xform: translate placement in x (horizontal) direction + y coord xform: translate placement in y (vertical) direction + rot angle xform: rotate placement + mirx bool xform: mirror placement left/right + miry bool xform: mirror placement child up/down + loclib_name string name in the local library (optional) + li:objects List of child objects + ha:line.ID Drawing object: straight line -> + ha:arc.ID Drawing object: circular arc -> + ha:polygon.ID Drawing object: polygon -> + ha:text.ID Drawing object: straight line -> + ha:connection.ID Logical object: connection between different groups -> + ha:pen.NAME Logical object: a named pen used for drawing; names are unique within a group -> + ha:attrib a hash of attributes + simple-attrib-key string attribute value without metadata (text node) + ha:detailed-attrib attribute with metadata (hash node) + value string attribute value + prio integer priority value + +ha:group_ref.ID + +type:name value ver description +ha:group_ref.ID Group reference to a concrete object within the same sheet or buffer + ref oidpath path relative to sheet root, to the referee (should be a group) + li:child_xform List of child object transformation to be performed after placement + OIDPATH list of transformations to be performed on referee children objects after placement; OIDPATH is relative to the referee group + movex coord xform: move child in x (horizontal) direction + movey coord xform: move child in y (vertical) direction + rot angle xform: rotate child + mirx bool xform: mirror child left/right + miry bool xform: mirror child up/down + remove bool xform: mirror child up/down + ha:attrib a hash of attributes + simple-attrib-key string attribute value without metadata (text node) + ha:detailed-attrib attribute with metadata (hash node) + value string attribute value + prio integer priority value + +ha:line.ID + +type:name value ver description +ha:line.ID Drawing object: straight line + x1 coord start point, x coord + y1 coord start point, y coord + x2 coord end point, x coord + y2 coord end point, y coord + stroke pen pen to use + lock bool object is locked + floater bool "group lock" doesn't apply + +ha:arc.ID + +type:name value ver description +ha:arc.ID Drawing object: circular arc + cx coord center point, x coord + cy coord center point, y coord + r coord radius + sang angle start angle + dang angle delta angle + sx coord start point, x coord + sy coord start point, y coord + ex coord end point, x coord + ey coord end point, y coord + stroke pen pen to use + lock bool object is locked + floater bool "group lock" doesn't apply + +ha:polygon.ID + +type:name value ver description +ha:polygon.ID Drawing object: polygon + li:outline ordered list of contour objects (no gaps allowed) + ha:line.ID Drawing object: straight line -> + ha:arc.ID Drawing object: circular arc -> + stroke pen pen used for outline objects + fill pen pen used for fill (no fill if not present) + lock bool object is locked + floater bool "group lock" doesn't apply + +ha:connection.ID + +type:name value ver description +ha:connection.ID Logical object: connection between different groups + li:conn list of objects participating in the connection (at least 2) + OIDPATH oidpath drawing object making the connection ) + +ha:text.ID + +type:name value ver description +ha:text.ID Drawing object: straight line + text string text string (or dyntext template) + x1 coord lower left x coord of text box + y1 coord lower left y coord of text box + x2 coord upper right corner of untrasformed box; present only if text size is bbox-specified + y2 coord upper right corner of untrasformed box; present only if text size is bbox-specified + rot angle rotaition around x1;y1 + mirx bool mirror origin/bbox left/right + miry bool mirror origin/bbox up/down + halign halign horizontal alignment + dyntext bool if text string is a dyntext template + stroke pen pen to use + lock bool object is locked + floater bool "group lock" doesn't apply + +ha:pen.NAME + +type:name value ver description +ha:pen.NAME Logical object: a named pen used for drawing; names are unique within a group + shape shape pen tip shape) + size coord diameter or side length + color color ink color + font_height coord height of text font for non-bbox-defined text + font_family string family hint for the font selector + font_style string style hint for the font selector + dash hex4 dash pattern + dash_period coord dash pattern length + +Types + ++--------------------------------------------------------------------------------------------------+ +| type | description | +|-------+------------------------------------------------------------------------------------------| +|angle |A decimal number without unit, representing an angle in degree. Can be positive or | +| |negative. | +|-------+------------------------------------------------------------------------------------------| +|coord |A decimal integer. | +|-------+------------------------------------------------------------------------------------------| +|double |Unitless numeric value in decimal format. Depending on context it is sometimes signed. | +|-------+------------------------------------------------------------------------------------------| +|integer|Unitless integer value in decimal format. Depending on context it is sometimes signed. | +|-------+------------------------------------------------------------------------------------------| +|hex4 |4 digits of hexadecimal numbers (0-9, a-f, A-F) | +|-------+------------------------------------------------------------------------------------------| +|bool |Single digit boolean value: 0 means false, 1 means true. | +|-------+------------------------------------------------------------------------------------------| +|pen |Name of a pen defined in a parent group. | +|-------+------------------------------------------------------------------------------------------| +|halign |One of: left, center, right, word_justify, justify. | +|-------+------------------------------------------------------------------------------------------| +|shape |One of: round, square. | +|-------+------------------------------------------------------------------------------------------| +|color |#rrggbb | +|-------+------------------------------------------------------------------------------------------| +|minuid |An unique ID as generated by libminuid (24 ASCII characters). | +|-------+------------------------------------------------------------------------------------------| +|none |No value. | +|-------+------------------------------------------------------------------------------------------| +|string |Free form text data | +|-------+------------------------------------------------------------------------------------------| +|oidpath|A slash separated list of integer object IDs (oids). | ++--------------------------------------------------------------------------------------------------+ + +Comments + +ver column: Format version range the subtree may appear in. Index: tags/1.0.5/doc/developer/lihata_format/types.lht =================================================================== --- tags/1.0.5/doc/developer/lihata_format/types.lht (nonexistent) +++ tags/1.0.5/doc/developer/lihata_format/types.lht (revision 10414) @@ -0,0 +1,63 @@ +ha:lht_tree_doc { ha:types { + +angle { + A decimal number without unit, representing an angle in degree. Can + be positive or negative. +} + +coord { + A decimal integer. +} + +double { + Unitless numeric value in decimal format. Depending on context it is + sometimes signed. +} + +integer { + Unitless integer value in decimal format. Depending on context it is + sometimes signed. +} + +hex4 { + 4 digits of hexadecimal numbers (0-9, a-f, A-F) +} + +bool { + Single digit boolean value: 0 means false, 1 means true. +} + +pen { + Name of a pen defined in a parent group. +} + +halign { + One of: left, center, right, word_justify, justify. +} + +shape { + One of: round, square. +} + +color { + #rrggbb +} + +minuid { + An unique ID as generated by libminuid (24 ASCII characters). +} + +none { + No value. +} + +string { + Free form text data +} + +oidpath { + A slash separated list of integer object IDs (oids). +} + +}} + Index: tags/1.0.5/doc/developer/mods3/after.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/1.0.5/doc/developer/mods3/after.png =================================================================== --- tags/1.0.5/doc/developer/mods3/after.png (nonexistent) +++ tags/1.0.5/doc/developer/mods3/after.png (revision 10414) Property changes on: tags/1.0.5/doc/developer/mods3/after.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/1.0.5/doc/developer/mods3/deps.svg =================================================================== --- tags/1.0.5/doc/developer/mods3/deps.svg (nonexistent) +++ tags/1.0.5/doc/developer/mods3/deps.svg (revision 10414) @@ -0,0 +1,685 @@ + + + + + + +plugin_deps + + + +user + +user + + + +act_draw + +act_draw + + + +user->act_draw + + + + + +act_read + +act_read + + + +user->act_read + + + + + +backann + +backann + + + +user->backann + + + + + +construct + +construct + + + +user->construct + + + + + +diag + +diag + + + +user->diag + + + + + +export_abst + +export_abst + + + +user->export_abst + + + + + +export_bom + +export_bom + + + +user->export_bom + + + + + +export_lpr + +export_lpr + + + +user->export_lpr + + + + + +export_ps + +export_ps + + + +user->export_ps + + + + + +export_png + +export_png + + + +user->export_png + + + + + +export_spice + +export_spice + + + +user->export_spice + + + + + +lib_netlist_exp + +lib_netlist_exp + + + +user->lib_netlist_exp + + + + + +export_svg + +export_svg + + + +user->export_svg + + + + + +export_tedax + +export_tedax + + + +user->export_tedax + + + + + +gui + +gui + + + +user->gui + + + + + +io_altium + +io_altium + + + +user->io_altium + + + + + +lib_alien + +lib_alien + + + +user->lib_alien + + + + + +io_geda + +io_geda + + + +user->io_geda + + + + + +io_lihata + +io_lihata + + + +user->io_lihata + + + + + +io_ngrp_fawk + +io_ngrp_fawk + + + +user->io_ngrp_fawk + + + + + +lib_ngrp + +lib_ngrp + + + +user->lib_ngrp + + + + + +io_ngrp_tedax + +io_ngrp_tedax + + + +user->io_ngrp_tedax + + + + + +io_tinycad + +io_tinycad + + + +user->io_tinycad + + + + + +query + +query + + + +user->query + + + + + +lib_plot + +lib_plot + + + +user->lib_plot + + + + + +lib_target + +lib_target + + + +user->lib_target + + + + + +place + +place + + + +user->place + + + + + +propedit + +propedit + + + +user->propedit + + + + + +renumber + +renumber + + + +user->renumber + + + + + +sch_dialogs + +sch_dialogs + + + +user->sch_dialogs + + + + + +sim + +sim + + + +user->sim + + + + + +sim_gui + +sim_gui + + + +user->sim_gui + + + + + +sim_ngspice + +sim_ngspice + + + +user->sim_ngspice + + + + + +target_spice + +target_spice + + + +user->target_spice + + + + + +std_cschem + +std_cschem + + + +user->std_cschem + + + + + +std_devmap + +std_devmap + + + +user->std_devmap + + + + + +std_forge + +std_forge + + + +user->std_forge + + + + + +std_tools + +std_tools + + + +user->std_tools + + + + + +symlib_fs + +symlib_fs + + + +user->symlib_fs + + + + + +symlib_local + +symlib_local + + + +user->symlib_local + + + + + +target_none + +target_none + + + +user->target_none + + + + + +target_pcb + +target_pcb + + + +user->target_pcb + + + + + +export_lpr->export_ps + + + + + +lib_exp_text + +lib_exp_text + + + +export_ps->lib_exp_text + + + + + +lib_exp_pixmap + +lib_exp_pixmap + + + +export_png->lib_exp_pixmap + + + + + +export_spice->lib_netlist_exp + + + + + +export_svg->lib_exp_text + + + + + +export_tedax->lib_netlist_exp + + + + + +lib_hid_common + +lib_hid_common + + + +gui->lib_hid_common + + + + + +io_altium->lib_alien + + + + + +lib_alien->query + + + + + +io_geda->lib_alien + + + + + +io_ngrp_fawk->lib_ngrp + + + + + +script + +script + + + +io_ngrp_fawk->script + + + + + +io_ngrp_tedax->lib_ngrp + + + + + +io_tinycad->lib_alien + + + + + +lib_plot->query + + + + + +sch_dialogs->lib_hid_common + + + + + +sim_gui->lib_plot + + + + + +sim_gui->sch_dialogs + + + + + +sim_gui->sim + + + + + +sim_ngspice->sim + + + + + +sim_ngspice->target_spice + + + + + +target_spice->lib_target + + + + + +target_pcb->lib_target + + + + + Index: tags/1.0.5/doc/developer/mods3/engine.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/1.0.5/doc/developer/mods3/engine.png =================================================================== --- tags/1.0.5/doc/developer/mods3/engine.png (nonexistent) +++ tags/1.0.5/doc/developer/mods3/engine.png (revision 10414) Property changes on: tags/1.0.5/doc/developer/mods3/engine.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/1.0.5/doc/developer/mods3/export.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/1.0.5/doc/developer/mods3/export.png =================================================================== --- tags/1.0.5/doc/developer/mods3/export.png (nonexistent) +++ tags/1.0.5/doc/developer/mods3/export.png (revision 10414) Property changes on: tags/1.0.5/doc/developer/mods3/export.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/1.0.5/doc/developer/mods3/feature.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/1.0.5/doc/developer/mods3/feature.png =================================================================== --- tags/1.0.5/doc/developer/mods3/feature.png (nonexistent) +++ tags/1.0.5/doc/developer/mods3/feature.png (revision 10414) Property changes on: tags/1.0.5/doc/developer/mods3/feature.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/1.0.5/doc/developer/mods3/gen.sh =================================================================== --- tags/1.0.5/doc/developer/mods3/gen.sh (nonexistent) +++ tags/1.0.5/doc/developer/mods3/gen.sh (revision 10414) @@ -0,0 +1,192 @@ +#!/bin/sh + +path=../../../src/plugins + +sloc() +{ + (cd "$1" && sloccount .) | awk '/^Total Phys/ { size=$9; sub(",", "", size); print size }' +} + +gen_pie() +{ + local bn="$1" code_size="$2" color="$3" + echo "" + echo "@slice" + echo "$code_size" + echo "@label" + echo "$bn ($code_size)" + if test ! -z "$color" + then + echo "@color" + echo "$color" + fi +} + +rm -f *.pie *.lines + +echo "#autogenerated by gen.sh" > mods.pie +echo "#autogenerated by gen.sh" > after.pie + +echo After... >&2 +#tmp=/tmp/sch-mods-stat +#mkdir $tmp +#cp -r ../../../src/sch-rnd/*.c ../../../src/sch-rnd/*.h ../../../src/sch-rnd/Makefile* $tmp +echo " sch-rnd..." >&2 +sch_rnd_size=`sloc ../../../src/sch-rnd/` +echo " lib..." >&2 +lib_size=`sloc ../../../src/libcschem/` +echo " 3rd..." >&2 +mini_size=`sloc ../../../src_3rd/` + +gen_pie "sch-rnd app" $sch_rnd_size "#00ff88" >> after.pie +gen_pie "libcschem" $lib_size "#88ff00" >> after.pie +gen_pie "3rd minilibs" $mini_size "#8800ff" >> after.pie + +echo "" > classes +echo ' +digraph plugin_deps { +overlap=scale +'> deps.dot + +( +cat pre.html +for n in $path/* +do + if test -d "$n" + then + echo $n >&2 + bn=`basename $n` + code_size=`sloc $n` + total=$(($total + $code_size)) + class=`cat $n/*.pup | sed ' + /^$class/ { + s/$class *// + s/[()]//g + p + } + { d } + ' ` + echo "$class" >> classes + + echo "$code_size" >> $class.lines + gen_pie $bn $code_size >> $class.pie + +# case $bn in +# gpmi) echo "@pull" >> mods.pie; echo "0.1" >> mods.pie;; +# esac + + echo "$bn$code_size" + cat $n/*.pup | awk -v "plugin=$n" ' + BEGIN { + q = "\"" + dep="/dev/fd/3" + sub(".*/", "", plugin) + } + /^[$]/ { + key=$1 + sub("[$]", "", key) + $1="" + DB[key]=$0 + next + } + + /^dep/ { + print q plugin q "->" q $2 q >> dep + } + + /^[A-Za-z]/ { + key=$1 + $1="" + DB[key]=$0 + next + } + + function strip(s) { + sub("^[ \t]*", "", s) + sub("[ \t]*$", "", s) + return s + } + + END { + st = DB["state"] + if (st ~ "partial") + clr = "bgcolor=\"yellow\"" + else if (st ~ "works") + clr = "bgcolor=\"lightgreen\"" + else if ((st ~ "fail") || (st ~ "disable")) + clr = "bgcolor=\"red\"" + else + clr="" + + clr2 = clr + if (clr2 != "") { + sub("bgcolor=\"", "", clr2) + sub("\"", "", clr2) + print "@color" >> "mods.pie" + print clr2 >> "mods.pie" + } + + print "" st + if (DB["lstate"] != "") + print "
(" strip(DB["lstate"]) ")" + + dfl = DB["default"] + if (dfl ~ "buildin") + clr = "bgcolor=\"lightgreen\"" + else if (dfl ~ "plugin") + clr = "bgcolor=\"yellow\"" + else if ((dfl ~ "disable-all") || (dfl ~ "disable")) + clr = "bgcolor=\"red\"" + else + clr="" + + print "" dfl + if (DB["ldefault"] != "") + print "
(" strip(DB["ldefault"]) ")" + print "" DB["class"] + print "" DB["long"] + if (int(DB["autoload"])) + print q "user" q "->" q plugin q " [color=\"#a0a0a0\"]" >> dep + + class = DB["class"] + if (class ~ "io") + clr = "fillcolor=\"#ffa0a0\"" + else if (class ~ "import") + clr = "fillcolor=\"#a0ffff\"" + else if (class ~ "export") + clr = "fillcolor=\"#a0ffff\"" + else if (class ~ "lib") + clr = "fillcolor=\"#a0a0a0\"" + else if (class ~ "hid") + clr = "fillcolor=\"#a0a0ff\"" + print q plugin q " [style=filled " clr "]" >> dep + } + ' + fi +done +cat post.html +gen_pie "plugins" "$total" "#0088ff" >> after.pie +) > index.html 3>>deps.dot +echo "}" >>deps.dot + +twopi -Tsvg deps.dot > deps.svg + +for n in *.lines +do + lines=`awk '{ sum += $1 } END { print sum }' < $n` + bn=${n%%.lines} + gen_pie $bn $lines >> mods.pie +done + + +classes=`sort < classes | uniq` + +for n in $classes after mods +do + animpie < $n.pie | animator -H -d $n + pngtopnm ${n}0000.png | pnmcrop | pnmtopng > $n.png + rm ${n}0000.png +done + + +rm classes Property changes on: tags/1.0.5/doc/developer/mods3/gen.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/1.0.5/doc/developer/mods3/gui.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/1.0.5/doc/developer/mods3/gui.png =================================================================== --- tags/1.0.5/doc/developer/mods3/gui.png (nonexistent) +++ tags/1.0.5/doc/developer/mods3/gui.png (revision 10414) Property changes on: tags/1.0.5/doc/developer/mods3/gui.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/1.0.5/doc/developer/mods3/index.html =================================================================== --- tags/1.0.5/doc/developer/mods3/index.html (nonexistent) +++ tags/1.0.5/doc/developer/mods3/index.html (revision 10414) @@ -0,0 +1,311 @@ + + + sch-rnd modularization + + +

sch-rnd modularization

+

Why bother...

+I believe good software should be modular. This is especially important in +the context of large software, such as CAD applications. There should be +a thin core that can model the world and provide the basic operations defined +on it but anything else should go in separate modules. +

+Sch-rnd is built up from scratch with modularity in mind. +

+I believe such modularization has benefits on multiple levels: +

    +
  • it is possible to compile smaller, potentially faster executables by omitting features the specific user would never use anyway +
  • in a distribution dynamic-link plugins can be distributed as separate packages providing the user with the option to decide what features to install +
  • such plugins have to have some sort of APIs if they want to reference each other or if the code needs to reference them; such an API may not (and often did not) exist when the code is part of the core +
+ +

Code size in charts

+ +

Overall distribution

+All numbers are in SLOC +and are acquired running sloccount on the given directory. While lines of +code alone is not a true measure of complexity, it's a good estimation. The +slices of pie charts are the major components of the sch-rnd executable. +

+
Main components
+

+The main components are: +

    +
  • libcschem: library that is operating the data model and the modular compiler +
  • sch-rnd app: application code: main() and the central infrastructure +
  • 3rd minilibs: 3rd-party minilibs shipped with sch-rnd; these minilibs are specialized in narrow tasks +
  • plugins: optional modules implementing the actual functionality (each can be disabled) +
+ +

Zooming on to the plugins

+

+ + + +
total size per class
+
IO plugins
+
+ + + + +
feature plugins
+
export plugins
+
+ + + +
GUI plugins
+
engine plugins
+
+ +

+(Red means the plugin doesn't really work). + +

Progress in numbers

+Below is a table with the summary of core plugins. + +
module size [sloc] status configure
default
class description + + +
act_draw278 + works + buildin + feature + Actions for drawing objects on a graphical sheet or symbol +
act_read333 + works + buildin + feature + Data access related API as actions +
backann1128 + works + buildin + feature + interactive back annotation +
construct465 + works + buildin + feature + construct complex objects from atoms, break up groups +
diag71 + works + buildin + feature + Actions for sch-rnd core diagnostics, intended for developers. These are not in core because end users normally don't need these. As a plugin, due to dynamic loading, it can be dropped on an existing sch-rnd installation with minimal risk of scaring away a reproducible bug. +
export_abst194 + works + buildin + export + export project's abstract model to text +
export_bom254 + works + buildin + export + export a BoM based on the components of the abstract model, using configurable templates +
export_lpr14 + works + buildin + export + Export to lpr (using export_ps to generate postscript) +
export_png267 + works + buildin + export + png, jpeg and gif render +
export_ps576 + works + buildin + export + PostScript, Encapsulated PostScript exporter +
export_spice474 + works + buildin + export + SPICE netlist exporter for circuit simulation +
export_svg219 + works + buildin + export + Scalable Vector Graphics exporter +
export_tedax259 + works + buildin + export + export netlist as a tEDAx netlist block +
gui1415 + works + buildin + gui + sch-rnd-specific GUI elements +
io_altium2444 + works + buildin + io + Load schematics from altium schdoc +
io_geda1236 + works + buildin + io + Load schematics and symbols from gEDA format. +
io_lihata1576 + works + buildin + io + Load and save the schematics and symbols in the native lihata format. +
io_ngrp_fawk259 + works + buildin + io + non-graphical schematic sheets in form of fawk scripts. +
io_ngrp_tedax393 + works + buildin + io + Load non-graphical schematic sheets in tEDAx format. +
io_tinycad1511 + works + buildin + io + Load schematics from TinyCAD .dsn xml format. +
lib_alien623 + works + buildin + io + Format-independent helper functions for reading alien files +
lib_netlist_exp62 + works + buildin + export + Helper functions for exporting netlists +
lib_ngrp241 + works + buildin + io + Helper functions for handling non-graphical sheets +
lib_plot639 + works + disable-all + gui + subdialog for plotting and navigating graphs +
lib_target133 + works + buildin + export + Helper functions for implementing target plugins +
place137 + works + buildin + feature + place complex objects such as terminals from template +
propedit2203 + works + buildin + feature + List and edit properties of a group of objects. +
query4245 + works + buildin + feature + sch-rnd query language: execute expressions on objects and rules for the programmed drc. +
renumber333 + works + buildin + feature + Systematically change the name of selected symbols +
sch_dialogs6545 + works + buildin + gui + Standard schematics editor dialog boxes +
sim1695 + works + buildin + feature + abstract differences of circuit simiulation implementations, provide an unified interface (infrastructure, CLI and actions) +
sim_gui2138 + works + buildin + feature + GUI for the the a unified high level simulation interface +
sim_ngspice438 + works + buildin + feature + ngspice specific execution glue (for the GUI) +
std_cschem342 + works + buildin + engine + Handles: component connect +
std_devmap1007 + works + buildin + engine + Handles slotting, device mapping and port mapping +
std_forge2088 + works + buildin + engine + Handles: attribute forging +
std_tools1461 + works + buildin + feature + Tools for drawing standard cschem concrete primitives +
symlib_fs119 + works + buildin + symlib + access symbol libraries stored on the local file system +
symlib_local696 + works + buildin + symlib + access symbol library stored within the sheet +
target_none46 + works + buildin + engine + Display original names +
target_pcb176 + works + buildin + engine + Attribute transformations for the PCB workflow +
target_spice1096 + works + buildin + engine + Attribute transformations for the SPICE workflow +
+ +

Classes

+

+Each plugin implements a class (rarely a set of classes). Classes are: + +
name description +
feature random features directly accessible for the user, usually actions +
lib support code library for other plugins (core doesn't depend on these); functionality not directly accessible for the user but other plugins may depend on it +
import load alien formats into the design space +
export save (parts of) the design space in alien formats +
io native file format (save & load) implementation +
+ +

Status

+

+Common status column values mean: + +
name description +
works production quality code - configures, compiles, tested +
WIP work in progress: the plugin may be avaialble for testing but is not yet production quality +
abandoned unmaintained plugin; may be in working condition but there is no developer supporting it +
deprecated legacy plugin scheduled for removal; may still work but will soon be removed; if your workflow depends on it, please report ASAP +
+ +

Plugin dependency map

+

+sch-rnd plugin dependency graph + + + Index: tags/1.0.5/doc/developer/mods3/io.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/1.0.5/doc/developer/mods3/io.png =================================================================== --- tags/1.0.5/doc/developer/mods3/io.png (nonexistent) +++ tags/1.0.5/doc/developer/mods3/io.png (revision 10414) Property changes on: tags/1.0.5/doc/developer/mods3/io.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/1.0.5/doc/developer/mods3/mods.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/1.0.5/doc/developer/mods3/mods.png =================================================================== --- tags/1.0.5/doc/developer/mods3/mods.png (nonexistent) +++ tags/1.0.5/doc/developer/mods3/mods.png (revision 10414) Property changes on: tags/1.0.5/doc/developer/mods3/mods.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/1.0.5/doc/developer/mods3/post.html =================================================================== --- tags/1.0.5/doc/developer/mods3/post.html (nonexistent) +++ tags/1.0.5/doc/developer/mods3/post.html (revision 10414) @@ -0,0 +1,31 @@ + + +

Classes

+

+Each plugin implements a class (rarely a set of classes). Classes are: + +
name description +
feature random features directly accessible for the user, usually actions +
lib support code library for other plugins (core doesn't depend on these); functionality not directly accessible for the user but other plugins may depend on it +
import load alien formats into the design space +
export save (parts of) the design space in alien formats +
io native file format (save & load) implementation +
+ +

Status

+

+Common status column values mean: + +
name description +
works production quality code - configures, compiles, tested +
WIP work in progress: the plugin may be avaialble for testing but is not yet production quality +
abandoned unmaintained plugin; may be in working condition but there is no developer supporting it +
deprecated legacy plugin scheduled for removal; may still work but will soon be removed; if your workflow depends on it, please report ASAP +
+ +

Plugin dependency map

+

+sch-rnd plugin dependency graph + + + Index: tags/1.0.5/doc/developer/mods3/pre.html =================================================================== --- tags/1.0.5/doc/developer/mods3/pre.html (nonexistent) +++ tags/1.0.5/doc/developer/mods3/pre.html (revision 10414) @@ -0,0 +1,70 @@ + + + sch-rnd modularization + + +

sch-rnd modularization

+

Why bother...

+I believe good software should be modular. This is especially important in +the context of large software, such as CAD applications. There should be +a thin core that can model the world and provide the basic operations defined +on it but anything else should go in separate modules. +

+Sch-rnd is built up from scratch with modularity in mind. +

+I believe such modularization has benefits on multiple levels: +

    +
  • it is possible to compile smaller, potentially faster executables by omitting features the specific user would never use anyway +
  • in a distribution dynamic-link plugins can be distributed as separate packages providing the user with the option to decide what features to install +
  • such plugins have to have some sort of APIs if they want to reference each other or if the code needs to reference them; such an API may not (and often did not) exist when the code is part of the core +
+ +

Code size in charts

+ +

Overall distribution

+All numbers are in SLOC +and are acquired running sloccount on the given directory. While lines of +code alone is not a true measure of complexity, it's a good estimation. The +slices of pie charts are the major components of the sch-rnd executable. +

+
Main components
+

+The main components are: +

    +
  • libcschem: library that is operating the data model and the modular compiler +
  • sch-rnd app: application code: main() and the central infrastructure +
  • 3rd minilibs: 3rd-party minilibs shipped with sch-rnd; these minilibs are specialized in narrow tasks +
  • plugins: optional modules implementing the actual functionality (each can be disabled) +
+ +

Zooming on to the plugins

+

+ + + +
total size per class
+
IO plugins
+
+ + + + +
feature plugins
+
export plugins
+
+ + + +
GUI plugins
+
engine plugins
+
+ +

+(Red means the plugin doesn't really work). + +

Progress in numbers

+Below is a table with the summary of core plugins. + +
module size [sloc] status configure
default
class description + + Index: tags/1.0.5/doc/developer/mods3/symlib.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/1.0.5/doc/developer/mods3/symlib.png =================================================================== --- tags/1.0.5/doc/developer/mods3/symlib.png (nonexistent) +++ tags/1.0.5/doc/developer/mods3/symlib.png (revision 10414) Property changes on: tags/1.0.5/doc/developer/mods3/symlib.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/1.0.5/doc/developer/packaging/Changelog =================================================================== --- tags/1.0.5/doc/developer/packaging/Changelog (nonexistent) +++ tags/1.0.5/doc/developer/packaging/Changelog (revision 10414) @@ -0,0 +1,149 @@ +How to get a release candidate tarball in /tmp: + + ver=1.0.5 + cd /tmp + svn export svn://repo.hu/sch-rnd/trunk sch-rnd-$ver + tar -cf sch-rnd-$ver.tar sch-rnd-$ver + +Packaging changes between 1.0.5 and 1.0.4 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +A. changes that probably don't need action + +(none) + +B. changes that probably DO need action + +1. new ./configure line (for hierarchic support, built-in) + +2. New plugin (in existing package) for exporting tedax footprint: + (- new ./configure line) + - new export_tedax_footprint* files in package sch-rnd-export-vector + + + +Packaging changes between 1.0.4 and 1.0.3 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +A. changes that probably don't need action + +(none) + +B. changes that probably DO need action + +1. Bumped dependency version: librnd version >= 4.1.0 is required + +2. New plugin for loading orcad schematics: + - new ./configure line + - new io_orcad* files in package sch-rnd-io-alien + + +Packaging changes between 1.0.3 and 1.0.2 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +A. changes that probably don't need action + +1. new plugin files in existing packages (static linked, no file changes but + ./configure argument changes): + - lib_anymap in sch-rnd-core + - lib_tedax in sch-rnd-core + + +B. changes that probably DO need action + +1. ./configure line changed for a few new plugins + +2. new plugin files in existing packages (dynamic loaded): + - lib_ucdf in sch-rnd-io-alien (.pup, .so) + +3. new plugin files in existing packages (static linked): + - funcmap in sch-rnd-core (.conf) + +Packaging changes between 1.0.2 and 1.0.1 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +A. changes that probably don't need action + +(none) + +B. changes that probably DO need action + +1. ./configure line changed for a few new plugins + +2. new package: sch-rnd-sim (circuit simulation) + +3. new plugin in sch-rnd-lib-gui: lib_plot + +4. new plugin in sch-rnd-export-extra: export_bom + +5. new conf file in package sch-rnd-core: + $C/target_pcb.conf + +Packaging changes between 1.0.1 and 1.0.0 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +A. changes that probably don't need action + +(none) + +B. changes that probably DO need action + +1. changes in the description (for new features) + +2. new plugin files in existing packages: + - io_altium in sch-rnd-io-alien (.pup, .so and .conf) + - the description of sch-rnd-io-alien contains Altium + +3. a bunch of new plugins compiled into the executable; + please update your ./configure line + +4. doc/resources is installed, please make sure those files are + included in the -doc package + +5. spice models in a minimal spice library are installed (at + $PREFIX/share/sch-rnd/spice/*) and should be part of the core package + +Packaging changes between 1.0.0 and 0.9.5 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +A. changes that probably don't need action + +(none) + +B. changes that probably DO need action + +(none) + +Packaging changes between 0.9.5 and 0.9.4 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +A. changes that probably don't need action + +(none) + +B. changes that probably DO need action + +1. new config file in package sch-rnd-io-alien: $C/io_tinycad.conf + +2. extended package descriptio (description.txt) with more file formats + +Packaging changes between 0.9.4 and 0.9.3 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +A. changes that probably don't need action + +(none) + +B. changes that probably DO need action + +1. Dependency: minimum required librnd version is 4.0.0 now. This affects + both the main librnd4 dependency and when pcb-rnd plugin packages depend + on librnd4 plugin packages, e.g. sch-rnd-export-gd used to depend on + librnd3-pixmap but now depends on librnd4-pixmap. Doing a + "s/librnd3/librnd4/g" in the packaging script should be safe. + + + +Packaging changes between 0.9.3 and 0.9.2 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +No change in packaging. + + +Packaging changes between 0.9.2 and 0.9.1 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Initial packaging. + Index: tags/1.0.5/doc/developer/packaging/desc =================================================================== --- tags/1.0.5/doc/developer/packaging/desc (nonexistent) +++ tags/1.0.5/doc/developer/packaging/desc (revision 10414) @@ -0,0 +1,57 @@ +@sch-rnd + Standard installation of sch-rnd + + Install sch-rnd core and the most commonly used plugins. + +@sch-rnd-doc + Documentation for sch-rnd + + User manual and developer doc (html). + +@sch-rnd-core + sch-rnd executable with the core functionality and boxsym-rnd + + Includes the data model, the most common action commands, the native file + format. Can be used in headless mode or batch/scripted mode for automated + processing or with GUI (if sch-rnd-lib-gui and librnd GUI HIDs are installed). + +@sch-rnd-debug + Debug and diagnostics. + + Extra action commands to help in debugging and diagnosing problems and bugs. + +@sch-rnd-export-extra + Export formats: special/extra + + Less commonly used export formats: abstract model text export, + direct printing with lpr. + +@sch-rnd-export-vector + Export formats: vector graphics + + Common vector graphic export formats: ps, eps, svg. + +@sch-rnd-export-gd + Export formats that require libgd. + + Bitmap export plugin (png, jpeg, etc.) + +@sch-rnd-io-alien + File format compatibility with other schematics capture tools. + + Load and/or save boards in file formats supported by other + EDA tools, geda/gschem, lepton-eda, TinyCAD, Altium. + +@sch-rnd-lib-gui + Support library for building the GUI. + + Provides sch-rnd specific dialog boxes and top window GUI elements. + +@sch-rnd-sim + High level circuit simulation + + Circuit simulation that can export and execute SPICE (ngspice) in + the background and save or present the results. Works both from the + GUI (with dialogs for configuring simulation setups, presenting + plots and data in the same dialog) and from CLI (with actions using + existing configuration, saving output data to a computer readable file). Index: tags/1.0.5/doc/developer/packaging/description.txt =================================================================== --- tags/1.0.5/doc/developer/packaging/description.txt (nonexistent) +++ tags/1.0.5/doc/developer/packaging/description.txt (revision 10414) @@ -0,0 +1,36 @@ +sch-rnd is a highly modular schematic capture software with a rich set of +plugins for communicating with various external design tools and other +EDA/CAD packages. + +Feature highlights: + - explicit abstract model + - back annotation support + - multiple sheets + +File formats and compatibility: + - text based, tree structured native file format (lihata) + - import netlist: + * altium schematics + * geda cschem schematics (v2) + * lihata cschem schematics (any version) + * cschem non-graphical schematic sheets in fawk format + * cschem non-graphical schematic sheets in tEDAx format + * orcad schematics + * TinyCAD schematics + - export netlist: + * tEDAx netlist + * lihata cschem schematics (any version) + - import misc: + * geda cschem symbol (v1) + * lihata cschem symbol (any version) + - export misc: + * abstract model text + * Bill of Materials + * printer (using ps) + * png + * ps + * eps + * spice + * svg + * tdx + * lihata cschem symbol (any version) Index: tags/1.0.5/doc/developer/packaging/extra.digest =================================================================== --- tags/1.0.5/doc/developer/packaging/extra.digest (nonexistent) +++ tags/1.0.5/doc/developer/packaging/extra.digest (revision 10414) @@ -0,0 +1,6 @@ +@appendfiles sch-rnd-core $PREFIX/bin/sch-rnd $PREFIX/share/man/man1/sch-rnd.1 +@appendfiles sch-rnd-core $PREFIX/bin/boxsym-rnd $PREFIX/share/man/man1/boxsym-rnd.1 $PREFIX/share/man/man5/boxsym-rnd.5 $PREFIX/lib/sch-rnd/boxsym-rnd/* $PREFIX/lib/sch-rnd/minuid +@appendfiles sch-rnd-core $C/sch-rnd-conf.lht $C/menu-default.lht +@appendfiles sch-rnd-core $PREFIX/share/sch-rnd/default-sheet.lht +@appendfiles sch-rnd-core $PREFIX/share/sch-rnd/devmap/* $PREFIX/share/sch-rnd/font/* $PREFIX/share/sch-rnd/symbol/* $PREFIX/share/sch-rnd/spice/* +@appendfiles sch-rnd-doc $PREFIX/share/doc/sch-rnd Index: tags/1.0.5/doc/developer/packaging/librnd_root.mk =================================================================== --- tags/1.0.5/doc/developer/packaging/librnd_root.mk (nonexistent) +++ tags/1.0.5/doc/developer/packaging/librnd_root.mk (revision 10414) @@ -0,0 +1,8 @@ +include ../../../Makefile.conf +include $(LIBRND_MAK) + +all: + @echo $(LIBRND_PREFIX) + +libdir: + @echo $(LIBRND_LIBDIR) Index: tags/1.0.5/doc/developer/packaging/packages.html =================================================================== --- tags/1.0.5/doc/developer/packaging/packages.html (nonexistent) +++ tags/1.0.5/doc/developer/packaging/packages.html (revision 10414) @@ -0,0 +1,111 @@ + + + + +

Librnd minimum version: 4.1.0

+

Package summary and dependencies

+

+ +
package depends on (packages) consists of (plugins) +
sch-rnd-doc  +
sch-rndsch-rnd-core sch-rnd-io-alien sch-rnd-lib-gui librnd4-hid-gtk2-gl librnd4-hid-gtk2-gdk sch-rnd-export-extra sch-rnd-doc<metapackage> +
sch-rnd-sim sch-rnd-core sch-rnd-lib-gui sim sim_gui sim_ngspice +
sch-rnd-io-alien sch-rnd-core io_altium io_geda io_orcad io_tinycad lib_alien lib_ucdf +
sch-rnd-export-gd sch-rnd-core librnd4-pixmap export_png +
sch-rnd-lib-gui sch-rnd-core librnd4-lib-gui gui lib_plot sch_dialogs +
sch-rnd-core librnd4(builtin: act_draw act_read backann construct export_spice export_tedax funcmap hlibrary_fs io_lihata io_ngrp_fawk io_ngrp_tedax lib_anymap lib_netlist_exp lib_ngrp lib_target lib_tedax place propedit query renumber std_cschem std_devmap std_forge std_tools symlib_fs symlib_local target_none target_pcb target_spice) +
sch-rnd-export-vector sch-rnd-core librnd4 export_ps export_svg export_tedax_footprint +
sch-rnd-export-extra sch-rnd-core sch-rnd-export-vector export_abst export_bom export_lpr +
sch-rnd-debug sch-rnd-core diag +
+

Package description and files

+ +
package files short long +
sch-rnd-doc/usr/share/doc/* Documentation for sch-rnd User manual and developer doc (html). +
sch-rnd Standard installation of sch-rnd Install sch-rnd core and the most commonly used plugins. +
sch-rnd-sim $P/sim.pup $P/sim.so $P/sim_gui.pup $P/sim_gui.so $P/sim_ngspice.pup $P/sim_ngspice.so $C/sim.conf $C/sim_gui.conf High level circuit simulation Circuit simulation that can export and execute SPICE (ngspice) in the background and save or present the results. Works both from the GUI (with dialogs for configuring simulation setups, presenting plots and data in the same dialog) and from CLI (with actions using existing configuration, saving output data to a computer readable file). +
sch-rnd-io-alien $P/io_altium.pup $P/io_altium.so $P/io_geda.pup $P/io_geda.so $P/io_orcad.pup $P/io_orcad.so $P/io_tinycad.pup $P/io_tinycad.so $P/lib_alien.pup $P/lib_alien.so $P/lib_ucdf.pup $P/lib_ucdf.so $C/io_altium.conf $C/io_geda.conf $C/io_orcad.conf $C/io_tinycad.conf File format compatibility with other schematics capture tools. Load and/or save boards in file formats supported by other EDA tools, geda/gschem, lepton-eda, TinyCAD, Altium. +
sch-rnd-export-gd $P/export_png.pup $P/export_png.so Export formats that require libgd. Bitmap export plugin (png, jpeg, etc.) +
sch-rnd-lib-gui $P/gui.pup $P/gui.so $P/lib_plot.pup $P/lib_plot.so $P/sch_dialogs.pup $P/sch_dialogs.so $C/adialogs.conf Support library for building the GUI. Provides sch-rnd specific dialog boxes and top window GUI elements. +
sch-rnd-core $PREFIX/bin/sch-rnd $PREFIX/share/man/man1/sch-rnd.1 $PREFIX/bin/boxsym-rnd $PREFIX/share/man/man1/boxsym-rnd.1 $PREFIX/share/man/man5/boxsym-rnd.5 $PREFIX/lib/sch-rnd/boxsym-rnd/* $PREFIX/lib/sch-rnd/minuid $C/sch-rnd-conf.lht $C/menu-default.lht $PREFIX/share/sch-rnd/default-sheet.lht $PREFIX/share/sch-rnd/devmap/* $PREFIX/share/sch-rnd/font/* $PREFIX/share/sch-rnd/symbol/* $PREFIX/share/sch-rnd/spice/* $C/funcmap.conf $C/renumber.conf $C/std_cschem.conf $C/std_devmap.conf $C/target_pcb.conf $C/target_spice.conf sch-rnd executable with the core functionality and boxsym-rnd Includes the data model, the most common action commands, the native file format. Can be used in headless mode or batch/scripted mode for automated processing or with GUI (if sch-rnd-lib-gui and librnd GUI HIDs are installed). +
sch-rnd-export-vector $P/export_ps.pup $P/export_ps.so $P/export_svg.pup $P/export_svg.so $P/export_tedax_footprint.pup $P/export_tedax_footprint.so Export formats: vector graphics Common vector graphic export formats: ps, eps, svg. +
sch-rnd-export-extra $P/export_abst.pup $P/export_abst.so $P/export_bom.pup $P/export_bom.so $P/export_lpr.pup $P/export_lpr.so $C/export_bom.conf Export formats: special/extra Less commonly used export formats: abstract model text export, direct printing with lpr. +
sch-rnd-debug $P/diag.pup $P/diag.so Debug and diagnostics. Extra action commands to help in debugging and diagnosing problems and bugs. +
+

External dependencies of Ppackages

+

Note: package names differ from distro to distro, this table only approximates the packahge names external dependencies have on your target. +

Note: every package that has .so files in it depends on librnd. +

+ +
package extneral dependencies +
sch-rnd-doc +
sch-rnd +
sch-rnd-sim +
sch-rnd-io-alienlibxml2 +
sch-rnd-export-gd +
sch-rnd-lib-gui +
sch-rnd-core +
sch-rnd-export-vector +
sch-rnd-export-extra +
sch-rnd-debug +
+

File prefixes:

    +
  • $P: plugin install dir (e.g. /usr/lib/sch-rnd/) +
  • $C: conf dir (e.g. /etc/sch-rnd/) +
  • $PREFIX: installation prefix (e.g. /usr) +
+

./configure arguments

+--all=disable +--buildin-funcmap +--buildin-act_read +--buildin-place +--buildin-symlib_local +--buildin-lib_netlist_exp +--buildin-std_tools +--buildin-renumber +--buildin-io_ngrp_tedax +--buildin-backann +--buildin-std_cschem +--buildin-export_tedax +--buildin-lib_tedax +--buildin-lib_anymap +--buildin-hlibrary_fs +--buildin-std_forge +--buildin-std_devmap +--buildin-propedit +--buildin-io_ngrp_fawk +--buildin-io_lihata +--buildin-target_spice +--buildin-target_pcb +--buildin-act_draw +--buildin-target_none +--buildin-symlib_fs +--buildin-query +--buildin-lib_target +--buildin-export_spice +--buildin-lib_ngrp +--buildin-construct +--plugin-lib_alien +--plugin-export_ps +--plugin-export_bom +--plugin-export_abst +--plugin-io_orcad +--plugin-io_altium +--plugin-sim_gui +--plugin-sch_dialogs +--plugin-lib_plot +--plugin-export_lpr +--plugin-export_tedax_footprint +--plugin-export_svg +--plugin-sim +--plugin-gui +--plugin-diag +--plugin-sim_ngspice +--plugin-io_tinycad +--plugin-io_geda +--plugin-export_png +--plugin-lib_ucdf + + + + Index: tags/1.0.5/doc/developer/packaging/packages.sh =================================================================== --- tags/1.0.5/doc/developer/packaging/packages.sh (nonexistent) +++ tags/1.0.5/doc/developer/packaging/packages.sh (revision 10414) @@ -0,0 +1,398 @@ +#!/bin/sh +ROOT=../../.. +proot=$ROOT/src/plugins + +# Get librnd requirement from INSTALL so it doesn't need to be maintained +# multiple locations +librnd_min_ver() +{ + awk -v "which=$1" ' + /librnd >=/ { + ver=$0 + sub("^.*>=[ \t]*", "", ver) + sub("[ \t].*$", "", ver) + split(ver, V, "[.]") + if (which == "major") + print V[1] + else if (which == "minor") + print V[2] + else if (which == "patch") + print V[3] + else + print ver + } + ' < $ROOT/INSTALL +} + + +# major version of librnd +RNDV=`librnd_min_ver major` +RNDVER=`librnd_min_ver` + +if test -f $ROOT/Makefile.conf +then + LIBRND_ROOT=`make -f librnd_root.mk` + LIBRND_LIBDIR=`make -f librnd_root.mk libdir` +fi + +if test -z "$LIBRND_ROOT" +then + if test -f /usr/local/share/librnd${RNDV}/librnd_packages.sh + then + LIBRND_ROOT=/usr/local + else + LIBRND_ROOT=/usr + fi + LIBRND_LIBDIR=$LIBRND_ROOT/lib/librnd${RNDV} +fi + +if test -f $LIBRND_ROOT/share/librnd${RNDV}/librnd_packages.sh +then + . $LIBRND_ROOT/share/librnd${RNDV}/librnd_packages.sh +else + echo "librnd installation not found - try to configure this checkout first or install librnd in /usr or /usr/local" >&2 + exit 1 +fi + +### generate description.txt (file formats) ### + +echo "$RNDV" > auto/ver_librnd_major + +. $LIBRND_LIBDIR/devhelpers/awk_on_formats.sh + +awk_on_formats ' +{ print $0 } + +function out(dir, type ,n,v,A,tmp) +{ + v = split(FMTS[dir, type], A, " *
*") + if (v < 1) return + print " -", dir, type ":" + for(n = 1; n <= v; n++) { + tmp = A[n] + sub("^ *", "", tmp) + print " * " tmp + } +} + +/(lihata)/ { + t = split(types, T, " ") + for(n = 1; n <= t; n++) { + out("import", T[n]); + out("export", T[n]); + } + exit +} +' < description.txt > description2.txt && mv description2.txt description.txt + +### generate packages.html and auto/ ### + +# TODO: io-standard +meta_deps="core io-alien lib-gui librnd${RNDV}-hid-gtk2-gl librnd${RNDV}-hid-gtk2-gdk export-extra doc" + +(echo ' + + +' + +( +for n in $proot/*/*.pup +do + pkg=`basename $n` + sed "s/^/$pkg /" < $n +done +for n in $proot/*/*.tmpasm +do + sed "s@^@$n @" < $n +done +cat extra.digest +) | awk -v "meta_deps=$meta_deps" -v "librnd_pkgs=$librnd_pkgs" -v "librnd_plugins=$librnd_plugins" -v "RNDV=$RNDV" -v "RNDVER=$RNDVER" ' + BEGIN { + v = split(meta_deps, A, "[ \t]") + meta_deps = "" + for(n = 1; n <= v; n++) { + if (A[n] == "") + continue + if ((!(A[n] ~ "^sch-rnd")) && (!(A[n] ~ "^librnd"))) + A[n] = "sch-rnd-" A[n] + if (meta_deps == "") + meta_deps = A[n] + else + meta_deps = meta_deps " " A[n] + } + + while((getline < "desc") == 1) { + if ($0 ~ "^@") { + pkg=$0 + sub("^@", "", pkg) + getline SHORT[pkg] < "desc" + continue + } + LONG[pkg] = LONG[pkg] $0 " " + } + + v = split(librnd_pkgs, A, "[ \t]+") + for(n = 1; n <= v; n++) + LIBRND_PKG[A[n]] = 1 + + v = split(librnd_plugins, A, "[ \t\r\n]+") + for(n = 1; n <= v; n++) + if (split(A[n], B, "=") == 2) + PLUGIN["sch-rnd-" B[1]] = B[2] + } + + function fix_dep(dep) + { + if ((dep == "") || (dep ~ "^librnd")) + return dep + sub("^sch-rnd-", "", dep) + if (dep in LIBRND_PKG) + return "librnd" RNDV "-" dep + return "sch-rnd-" dep + } + + function fix_deps(deps ,A,n,s,v) + { + v = split(deps, A, "[ \t]+") + s = "" + for(n = 1; n <= v; n++) + s = s " " fix_dep(A[n]) + sub("^ ", "", s) + return s; + } + + + { + if ($1 ~ "^[!]") { + in_librnd = 1 + sub("^[!]", "", $1) + } + else + in_librnd = 0 + } + + ($1 ~ "@files") { + pkg=$2 + files=$0 + sub("@files[ \t]*[^ \t]*[ \t]", "", files) + IFILES[pkg] = files + PKG[pkg] = "n/a" + } + + ($1 ~ "@appendfiles") { + pkg=$2 + files=$0 + sub("@appendfiles[ \t]*[^ \t]*[ \t]", "", files) + IFILES[pkg] = IFILES[pkg] " " files + } + + ($1 ~ "@appendextdeps") { + pkg=$2 + files=$0 + sub("@appendextdeps[ \t]*[^ \t]*[ \t]", "", files) + EXTDEPS[pkg] = EXTDEPS[pkg] " " files + } + + ($1 ~ "@appenddeps") { + pkg=$2 + deps=$0 + sub("@appenddeps[ \t]*[^ \t]*[ \t]", "", deps) + PKG_DEP[pkg] = PKG_DEP[pkg] " " deps + } + + ($1 ~ "[.]pup$") { + pkg = $1; + sub("[.]pup$", "", pkg) + if (pkg == "(core)") pkg="core" + } + + ($1 ~ "[.]tmpasm$") { + pkg = $1; + sub("/Plug.tmpasm$", "", pkg) + sub(".*/", "", pkg) + if (pkg == "(core)") pkg="core" + } + + ($1 ~ "[.]pup$") { + val=$3 + if (val == "(core)") val="core" + cfg = pkg + val = "sch-rnd-" val + } + + { + pkg = "sch-rnd-" pkg + } + + ($1 ~ "[.]pup$") && ($2 == "$package") { + PKG[val] = PKG[val] " " cfg; + PLUGIN[pkg] = val; + if (val == "sch-rnd-core") { + CFG_BUILDIN[cfg]++ + } + else { + CFG_PLUGIN[cfg]++ +print in_librnd, $1 > "L1" + if (in_librnd) + dir = "$LP" + else + dir="$P" + IFILES[val] = IFILES[val] " " dir "/" cfg ".pup " dir "/" cfg ".so" + } + } + + ($1 ~ "[.]pup$") && ($2 == "dep") { PLUGIN_DEP[pkg] = PLUGIN_DEP[pkg] " " val } + + ($1 ~ "[.]pup$") && ($2 == "$extdeps") { + tmp=$0 + sub("^[^ \t]*[ \t]*[$]extdeps[ \t]*", "", tmp) + PUPEXTDEPS[pkg] = PUPEXTDEPS[pkg] " " tmp + } + + ($1 ~ "[.]tmpasm$") && ($3 == "/local/rnd/mod/CONFFILE") { + fn=$4 + sub("[{][ \t]*", "", fn) + sub("[ \t]*[}]", "", fn) + if (in_librnd) + dir = "$LC" + else + dir="$C" + if (CONFFILE[PLUGIN[pkg]] == "") + CONFFILE[PLUGIN[pkg]] = dir "/" fn + else + CONFFILE[PLUGIN[pkg]] = CONFFILE[PLUGIN[pkg]] " " dir "/" fn + } + + function add_dep(pkg, depson, ds) + { + if (pkg != depson) { + ds = pkg "::" depson + if (!(ds in DEP_SEEN)) { + DEP_SEEN[ds] = 1 + PKG_DEP[pkg] = PKG_DEP[pkg] " " depson + } + } + } + + function strip(s) { + sub("^[ \t]*", "", s) + sub("[ \t]*$", "", s) + return s + } + + function uniq(str ,A,B,v,n,res) + { + v = split(str, A) + for(n = 1; n <= v; n++) + B[A[n]] = 1 + for(n in B) + if (res == "") + res = n + else + res = res " " n + return res + } + + END { + +# for(plg in PLUGIN_DEP) +# print "PLUGIN[" plg "] = " PLUGIN[plg] > "/dev/stderr" +# exit(1) + + + # everything depends on core + for(pkg in PKG) + add_dep(pkg, "sch-rnd-core") + + # calculate dependencies + for(plg in PLUGIN_DEP) { + v = split(PLUGIN_DEP[plg], A, " ") + pkg = PLUGIN[plg] + if (pkg == "") continue + for(n = 1; n <= v; n++) { + if (A[n] == "") continue + depson = PLUGIN[A[n]] + if (depson == "") + depson = A[n] + add_dep(pkg, depson) + } + } + + PKG_DEP["core"] = "" + PKG_DEP["doc"] = "" + PKG_DEP["sch-rnd"] = meta_deps + PKG["sch-rnd"] = "<metapackage>" + PKG["sch-rnd-doc"] = " " + IFILES["sch-rnd-doc"] = "/usr/share/doc/*" + + print "

Librnd minimum version: " RNDVER "

" + print RNDVER > "auto/librnd_min_ver" + + print "

Package summary and dependencies

" + print "

" + print "" + print "
package depends on (packages) consists of (plugins)" + + for(pkg in PKG) { + if (pkg == "sch-rnd-core") + print "
" pkg "" fix_deps(PKG_DEP[pkg]) "(builtin: " PKG[pkg] ")" + else + print "
" pkg "" fix_deps(PKG_DEP[pkg]) "" PKG[pkg] + print strip(PKG_DEP[pkg]) > "auto/" pkg ".deps" + print pkg > "auto/List" + } + print "
" + + print "

Package description and files

" + print "" + print "
package files short long" + for(pkg in PKG) { + if (SHORT[pkg] == "") SHORT[pkg] = " " + if (LONG[pkg] == "") LONG[pkg] = " " + print "
" pkg "" IFILES[pkg] " " CONFFILE[pkg] "" "" SHORT[pkg] "" LONG[pkg] + print strip(IFILES[pkg] " " CONFFILE[pkg]) > "auto/" pkg ".files" + print strip(SHORT[pkg]) > "auto/" pkg ".short" + print strip(LONG[pkg]) > "auto/" pkg ".long" + } + print "
" + + print "

External dependencies of Ppackages

" + print "

Note: package names differ from distro to distro, this table only approximates the packahge names external dependencies have on your target." + print "

Note: every package that has .so files in it depends on librnd." + print "

" + print "" + print "
package extneral dependencies" + for(plg in PLUGIN) + EXTDEPS[PLUGIN[plg]] = EXTDEPS[PLUGIN[plg]] " " PUPEXTDEPS[plg] + for(pkg in PKG) + print "
" pkg "" uniq(EXTDEPS[pkg]) + print "
" + + + print "

File prefixes:

    " + print "
  • $P: plugin install dir (e.g. /usr/lib/sch-rnd/)" + print "
  • $C: conf dir (e.g. /etc/sch-rnd/)" + print "
  • $PREFIX: installation prefix (e.g. /usr)" + print "
" + + + print "

./configure arguments

" + print "--all=disable" + print "--all=disable" > "auto/Configure.args" + + for(p in CFG_BUILDIN) { + print "--buildin-" p + print "--buildin-" p > "auto/Configure.args" + } + for(p in CFG_PLUGIN) { + print "--plugin-" p + print "--plugin-" p > "auto/Configure.args" + } + } +' + +echo ' + + +') > packages.html + Property changes on: tags/1.0.5/doc/developer/packaging/packages.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/1.0.5/doc/developer/packaging.txt =================================================================== --- tags/1.0.5/doc/developer/packaging.txt (nonexistent) +++ tags/1.0.5/doc/developer/packaging.txt (revision 10414) @@ -0,0 +1,94 @@ +Packaging sch-rnd for a distribution +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +1. program, libs, desktop integration + +Sch-rnd is an interactive schematics capture (editor) program. A typical +user is an electric engineer. This sort of programs are often called EDA, +Electronics Design Automation. + +Sch-rnd has different frontends: graphical and stdio/text based batch +processing. There are different graphical frontends - sch-rnd does not +depend on gtk or motif, the specific frontend modules may depend on them. + +Sch-rnd is scriptable if system installed libfungw is available. Since +libfungw is not a mainstream library, it is most probably not already +present in your distro and it should also be packaged. + +Sch-rnd is intended for UNIX-fans. It is heavily keyboard-oriented and it +doesn't assume its users don't want to understand or learn how it works. +Many typical user workflows include Makefiles and it's a common thing to +start sch-rnd from a shell. Thus desktop integration is not in focus +at the moment. If you fixed things for this while packaging, please let +us know, we may merge your patches (see below). + +2. options, plugins, dependencies + +Sch-rnd is a modular software with a lot of options. Majority of these options +are selected by the state of a module. A module has three states: + - disable: (not compiled at all) + - buildin: enabled and static linked + - plugin: enabled and dynamic loaded (from a .so) + +The configure script takes --disable-*, --building-* and --plugin-* +arguments with * substituted with the name of the module. The configure +script also determines the dependencies according to the selection. Special +arguments --all=plugin and --all=buildin are provided in configure to select +all working modules to be plugins or buildins. + +For binary distributions it's strongly recommended to have most of the +modules compiled as plugins and have them in separate packages. This +would let the user to install a core sch-rnd package and then optional +extras on demand, reducing dependencies. + +The preferred package splitup is documented in packaging/, +please follow that as closely as possible so different systems can +deliver similar sch-rnd packages. + +This is less relevant for source distributions, if the user has full control +over the configuration. + +If non-critical dependencies are not met, modules are automatically disabled +by ./configure. + +3. typical ./configure options - scconfig vs. auto* + +./configure --prefix works as expected. DESTDIR works as expected. + +Typical commands for configuring sch-rnd for packaging would be: + + ./configure --all=plugin --prefix=/usr + make all + DESTDIR=/tmp/pkg_tmp make install + +We are happy with scconfig. Please don't write about how much better +autoconf or cmake would be, we won't switch. + +4. release cycles, tarballs, svn trunk - what to package + +Development happens in svn trunk/, there are usually no branches. While +we try to keep trunk/ compilable any time, it's not guaranteed that it +would work out-of-the-box between releases. It is not recommended to +package trunk/ - please package stable releases instead. + +We follow the "release early, release often" rule. Source release tarballs +are always considered stable. Beside the project web page, releases are +also accessible as svn tags: svn://www.repo.hu/sch-rnd/tags . + +Sometimes we have minor releases with 2..3 month period, sometimes a +longer period passes between releases. + +There's no automated release notification at the moment; if you want to +get notified about new releases, please contact me +(http://www.repo.hu/projects/sch-rnd/contact.html) + +5. bug reporting and fixes for packaging + +There's no special method for reporting packaging related bugs and +feature requests, please follow the normal bug report instructions or just +drop me a mail. Please mention that the issue is related to packaging, this +usually gives it a higher priority. + +We are willing to make minor changes to make packaging easier - if you bump +into something you'd need to work around while packaging, please let us know, +we may just fix it "upstream". + Index: tags/1.0.5/doc/developer/popup.txt =================================================================== --- tags/1.0.5/doc/developer/popup.txt (nonexistent) +++ tags/1.0.5/doc/developer/popup.txt (revision 10414) @@ -0,0 +1,37 @@ +Popup naming conventions +~~~~~~~~~~~~~~~~~~~~~~~~ + +Right click context popup on drawing area: + - /popups/popup-obj-TYPE + floating object (nor part of any atomic group); TYPE is substituted + with object type, e.g. polygon + + - /popups/popup-obj-misc + called if popup-obj-TYPE failed + + - /popups/popup-user-grp-PURPOSE + on a group with no role; PURPOSE is substituted with the purpose + attribute of the group + + - /popups/popup-user-grp-unknown + Same, but if the purpose attribute is empty or does not exist, it is + substituted with "unknown". + + - /popups/popup-ROLE + Group with role=ROLE, ROLE must be one of the cschem-defined group roles, + e.g. symbol, terminal, etc. + + - /popups/sheet + Clicked on an empty part of the drawing area of a sheet + + - /popups/symbol-as-sheet + Clicked on an empty part of the drawing area of a sheet when in symbol + editing mode + + - popups/none + None of the above (e.g. clicked outside of drawing area) + + + + + Index: tags/1.0.5/doc/developer/releasing.txt =================================================================== --- tags/1.0.5/doc/developer/releasing.txt (nonexistent) +++ tags/1.0.5/doc/developer/releasing.txt (revision 10414) @@ -0,0 +1,15 @@ +release check list + +(0. test compile and test run a clean checkout on a clean system + configure with --debug --all=buildin, then without + not required anymore: autotest does it now) +1. check next version number and previous revision in tags/ +2. update the changelog +3. rewrite the release notes +4. modify version number in scconfig +5. commit trunk +6. svn tag using URLs (use svn copy --pin-externals) +7. update state.html (timeline, events and doc/news.html) +(8. update locally built binaries: windows) +9. modify scconfig version to -dev + Index: tags/1.0.5/doc/developer/symbol_as_sheet.txt =================================================================== --- tags/1.0.5/doc/developer/symbol_as_sheet.txt (nonexistent) +++ tags/1.0.5/doc/developer/symbol_as_sheet.txt (revision 10414) @@ -0,0 +1,18 @@ +Symbol loaded as a sheet +~~~~~~~~~~~~~~~~~~~~~~~~ + +Also known as: symbol edit mode or symedit. + +When this happens, sheet->is_symbol is set to 1 which triggers a bunch of +special cases here and there. The general structure is this: + +- a symbol file is a single group (stored under a csch group in lihata) +- when the loader detects this root, this group is loaded as sheet->direct +- in sch-rnd sheet postproc some extra steps are done to load pens from the + default sheet, else all pens would be invalid; these pens are marked + ->copied_from_default=1 +- on save sheet->is_symbol decides only the direct group needs to be saved, + using the csch group root node instead of a sheet root +- on save pens that are marked ->copied_from_default==1 are not saved + (undoable pen modify always resets this bit so any pen modification forces + saving the pen) Index: tags/1.0.5/doc/developer/symbol_loclib_paste.txt =================================================================== --- tags/1.0.5/doc/developer/symbol_loclib_paste.txt (nonexistent) +++ tags/1.0.5/doc/developer/symbol_loclib_paste.txt (revision 10414) @@ -0,0 +1,18 @@ +Load two sheets, first with grp_refs to loclib; use the buffer to copy these +grp_refs to the second sheet: + -> broken ref on the target buffer; three possible solutions: + +Possible solutions: + +1. on copy: convert group ref to group on copy and mark loclib-enable + -> BAD: this will break for non-loclib grp_refs + +2. on paste: remember group ref sheet on copy and if on paste there's a + mismatch, do a full copy + -> BAD: this will break if the source sheet is closed while grp_refs + are in buffer already! + +3. buffer could have an indirect subtree too, copy would fill it in + - on copy create indirect symlib in buffer and copy the loclib entry + - on paste compare indirects to the sheet's indirect hash, insert if needed + - all this done by loclib code; non-loclib grp_refs should be refused Index: tags/1.0.5/doc/doc.html =================================================================== --- tags/1.0.5/doc/doc.html (nonexistent) +++ tags/1.0.5/doc/doc.html (revision 10414) @@ -0,0 +1,36 @@ + + + + sch-rnd - documentation + + + + + + + + + + +
Main + Doc &  Knowledge pool  &  Tutorial + Current state + Events & timeline + sch-rnd [sch-rnd logo] +
+ + +
+ +

sch-rnd documentation

+ + + + + Index: tags/1.0.5/doc/examples/Makefile =================================================================== --- tags/1.0.5/doc/examples/Makefile (nonexistent) +++ tags/1.0.5/doc/examples/Makefile (revision 10414) @@ -0,0 +1,26 @@ +ROOT=../.. +EXADIR=$(DOCDIR)/examples + +all: + +install_all: + $(SCCBOX) mkdir -p $(EXADIR)/backann $(EXADIR)/devmaps + $(SCCBOX) $(HOW) -d backann/div* $(EXADIR)/backann + $(SCCBOX) $(HOW) -d devmaps/*.devmap $(EXADIR)/devmaps + $(SCCBOX) $(HOW) -d *.rs $(EXADIR) + +install: + $(MAKE) install_all HOW="install -f -d" + +linstall: + $(MAKE) install_all HOW="install -f -l -d" + +uninstall: + $(MAKE) install_all HOW="install -u" + +clean: + +distclean: + + +include $(ROOT)/Makefile.conf Index: tags/1.0.5/doc/examples/backann/div.bap =================================================================== --- tags/1.0.5/doc/examples/backann/div.bap (nonexistent) +++ tags/1.0.5/doc/examples/backann/div.bap (revision 10414) @@ -0,0 +1,8 @@ +net_info div CN1-2 R1-2 R2-1 +net_info Vcc R1-1 CN1-3 +change_attrib R2 footprint 0805 +change_attrib R1 footprint 0805 +del_conn CN1-2 div +del_conn CN1-3 Vcc +add_conn CN1-2 Vcc +add_conn CN1-3 div Index: tags/1.0.5/doc/examples/backann/div.rp =================================================================== --- tags/1.0.5/doc/examples/backann/div.rp (nonexistent) +++ tags/1.0.5/doc/examples/backann/div.rp (revision 10414) @@ -0,0 +1,1272 @@ +ha:pcb-rnd-board-v8 { + + li:styles { + ha:Signal { + via_proto = 0 + thickness = 10.0mil + text_thick = 0.0 + text_scale = 100 + clearance = 20.0mil + } + ha:Power { + via_proto = 1 + thickness = 20.0mil + text_thick = 0.0 + text_scale = 100 + clearance = 20.0mil + } + ha:Fat { + via_proto = 2 + thickness = 80.0mil + text_thick = 0.0 + text_scale = 100 + clearance = 25.0mil + } + ha:Sig-tight { + via_proto = 3 + thickness = 10.0mil + text_thick = 0.0 + text_scale = 100 + clearance = 12.0mil + } + } + + ha:meta { + ha:size { + thermal_scale = 0.500000 + x = 400.0mil + y = 350.0mil + } + ha:grid { + spacing = 25.0mil + offs_x = 0.0 + offs_y = 0.0 + } + } + + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=0.8mm; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + } + } + + ha:ps_proto_v6.1 { + hdia=1.0mm; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.2mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.2mm; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.2mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + } + } + + ha:ps_proto_v6.2 { + hdia=1.2mm; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=3.5mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=3.5mm; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=3.5mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + } + } + + ha:ps_proto_v6.3 { + hdia=0.8mm; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=64.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=64.0mil; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=64.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:subc.603 { + ha:attributes { + value= + footprint=connector(3,1) + refdes=CN1 + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=1.000001mm; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + } + } + } + + ha:ps_proto_v6.1 { + hdia=1.000001mm; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=86.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=86.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:padstack_ref.632 { + proto=0; x=100.0mil; y=150.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=25.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + } + } + ha:padstack_ref.633 { + proto=1; x=200.0mil; y=150.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=25.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=2 + } + } + ha:padstack_ref.634 { + proto=1; x=300.0mil; y=150.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=25.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=3 + } + } + } + li:layers { + + ha:subc-aux { + lid=0 + ha:combining { } + + li:objects { + ha:line.604 { + x1=100.0mil; y1=150.0mil; x2=3.540001mm; y2=150.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=x + } + } + ha:line.607 { + x1=100.0mil; y1=150.0mil; x2=100.0mil; y2=4.810001mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=y + } + } + ha:line.610 { + x1=100.0mil; y1=150.0mil; x2=100.0mil; y2=150.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=origin + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + + ha:top-silk { + lid=1 + ha:combining { } + + li:objects { + ha:line.613 { + x1=50.0mil; y1=100.0mil; x2=50.0mil; y2=200.0mil; thickness=10.0mil; clearance=0.0; + } + ha:line.616 { + x1=50.0mil; y1=100.0mil; x2=350.0mil; y2=100.0mil; thickness=10.0mil; clearance=0.0; + } + ha:line.619 { + x1=350.0mil; y1=200.0mil; x2=50.0mil; y2=200.0mil; thickness=10.0mil; clearance=0.0; + } + ha:line.622 { + x1=350.0mil; y1=200.0mil; x2=350.0mil; y2=100.0mil; thickness=10.0mil; clearance=0.0; + } + ha:line.625 { + x1=50.0mil; y1=200.0mil; x2=150.0mil; y2=200.0mil; thickness=10.0mil; clearance=0.0; + } + ha:line.628 { + x1=150.0mil; y1=100.0mil; x2=150.0mil; y2=200.0mil; thickness=10.0mil; clearance=0.0; + } + ha:text.631 { + string=%a.parent.refdes%; x=100.0mil; y=50.0mil; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 0.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + } + } + uid = Prm/3TkY34Vrzi8ZOx1APAAA + } + ha:subc.636 { + ha:attributes { + refdes=R2 + value=4k7 + footprint=0805 Standard SMT resistor, capacitor etc + openscad=1206.scad + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=0.0; hplated=0; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + li:ps_poly { + 0.649986mm + -0.749808mm + -0.649986mm + -0.749808mm + -0.649986mm + 0.749808mm + 0.649986mm + 0.749808mm + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + 0.726186mm + -32.52mil + -0.726186mm + -32.52mil + -0.726186mm + 32.52mil + 0.726186mm + 32.52mil + } + } + + ha:ps_shape_v4 { + ha:combining { auto=1; } + ha:layer_mask { + top = 1 + paste = 1 + } + clearance=0.0 + li:ps_poly { + 0.649986mm + -0.749808mm + -0.649986mm + -0.749808mm + -0.649986mm + 0.749808mm + 0.649986mm + 0.749808mm + } + } + } + } + } + + li:objects { + ha:padstack_ref.656 { + proto=0; x=3.762496mm; y=6.807201mm; rot=-180.000000; xmirror=0; smirror=0; clearance=10.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + name=1 + } + } + ha:padstack_ref.657 { + proto=0; x=1.962652mm; y=6.807201mm; rot=-180.000000; xmirror=0; smirror=0; clearance=10.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=2 + name=2 + } + } + } + li:layers { + + ha:top-silk { + lid=0 + ha:combining { } + + li:objects { + ha:line.637 { + x1=2.962396mm; y1=7.506971mm; x2=2.762752mm; y2=7.506971mm; thickness=8.0mil; clearance=0.0; + } + ha:line.640 { + x1=2.962396mm; y1=6.107431mm; x2=2.762752mm; y2=6.107431mm; thickness=8.0mil; clearance=0.0; + } + ha:text.643 { + string=%a.parent.refdes%; x=3.662674mm; y=7.607301mm; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 180.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + + ha:subc-aux { + lid=1 + ha:combining { } + + li:objects { + ha:line.644 { + x1=2.862574mm; y1=6.807201mm; x2=2.862574mm; y2=6.807201mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=pnp-origin + } + } + ha:line.647 { + x1=2.862574mm; y1=6.807201mm; x2=2.862574mm; y2=6.807201mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=origin + } + } + ha:line.650 { + x1=2.862574mm; y1=6.807201mm; x2=1.862574mm; y2=6.807201mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=x + } + } + ha:line.653 { + x1=2.862574mm; y1=6.807201mm; x2=2.862574mm; y2=5.807201mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + } + } + uid = Gb4CEJNqF8FflGx6irgAAAAB + } + ha:subc.659 { + ha:attributes { + refdes=R1 + value=1k + footprint=0805 Standard SMT resistor, capacitor etc + openscad=1206.scad + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=0.0; hplated=0; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + li:ps_poly { + 0.649986mm + -0.749808mm + -0.649986mm + -0.749808mm + -0.649986mm + 0.749808mm + 0.649986mm + 0.749808mm + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + 0.726186mm + -32.52mil + -0.726186mm + -32.52mil + -0.726186mm + 32.52mil + 0.726186mm + 32.52mil + } + } + + ha:ps_shape_v4 { + ha:combining { auto=1; } + ha:layer_mask { + top = 1 + paste = 1 + } + clearance=0.0 + li:ps_poly { + 0.649986mm + -0.749808mm + -0.649986mm + -0.749808mm + -0.649986mm + 0.749808mm + 0.649986mm + 0.749808mm + } + } + } + } + } + + li:objects { + ha:padstack_ref.679 { + proto=0; x=7.572496mm; y=6.807201mm; rot=-180.000000; xmirror=0; smirror=0; clearance=10.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + name=1 + } + } + ha:padstack_ref.680 { + proto=0; x=5.772652mm; y=6.807201mm; rot=-180.000000; xmirror=0; smirror=0; clearance=10.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=2 + name=2 + } + } + } + li:layers { + + ha:top-silk { + lid=0 + ha:combining { } + + li:objects { + ha:line.660 { + x1=6.772396mm; y1=7.506971mm; x2=6.572752mm; y2=7.506971mm; thickness=8.0mil; clearance=0.0; + } + ha:line.663 { + x1=6.772396mm; y1=6.107431mm; x2=6.572752mm; y2=6.107431mm; thickness=8.0mil; clearance=0.0; + } + ha:text.666 { + string=%a.parent.refdes%; x=7.472674mm; y=7.607301mm; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 180.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + + ha:subc-aux { + lid=1 + ha:combining { } + + li:objects { + ha:line.667 { + x1=6.672574mm; y1=6.807201mm; x2=6.672574mm; y2=6.807201mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=pnp-origin + } + } + ha:line.670 { + x1=6.672574mm; y1=6.807201mm; x2=6.672574mm; y2=6.807201mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=origin + } + } + ha:line.673 { + x1=6.672574mm; y1=6.807201mm; x2=5.672574mm; y2=6.807201mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=x + } + } + ha:line.676 { + x1=6.672574mm; y1=6.807201mm; x2=6.672574mm; y2=5.807201mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + } + } + uid = Gb4CEJNqF8FflGx6irgAAAAB + } + } + li:layers { + + ha:top-sig { + lid=0 + group=3 + ha:combining { } + + ha:attributes { + {pcb-rnd::key::vis}={l; Shiftt} + {pcb-rnd::key::select}={l; t} + } + + li:objects { + ha:line.681 { + x1=100.0mil; y1=150.0mil; x2=100.0mil; y2=200.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.684 { + x1=100.0mil; y1=200.0mil; x2=75.0mil; y2=225.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.693 { + x1=75.0mil; y1=225.0mil; x2=75.0mil; y2=6.807201mm; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.705 { + x1=3.762496mm; y1=6.807201mm; x2=5.772652mm; y2=6.807201mm; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.714 { + x1=150.0mil; y1=100.0mil; x2=150.0mil; y2=6.807201mm; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.717 { + x1=150.0mil; y1=100.0mil; x2=175.0mil; y2=75.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.720 { + x1=175.0mil; y1=75.0mil; x2=275.0mil; y2=75.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.723 { + x1=275.0mil; y1=75.0mil; x2=300.0mil; y2=100.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.726 { + x1=300.0mil; y1=100.0mil; x2=300.0mil; y2=150.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.732 { + x1=7.572496mm; y1=6.807201mm; x2=7.572496mm; y2=6.302496mm; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.744 { + x1=7.572496mm; y1=6.302496mm; x2=200.0mil; y2=150.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + } + color = {#8b2323} + } + + ha:bottom-sig { + lid=1 + group=10 + ha:combining { } + + ha:attributes { + {pcb-rnd::key::vis}={l; Shiftb} + {pcb-rnd::key::select}={l; b} + } + + li:objects { + } + color = {#3a5fcd} + } + + ha:top-gnd { + lid=2 + group=3 + ha:combining { } + + li:objects { + } + color = {#104e8b} + } + + ha:bottom-gnd { + lid=3 + group=10 + ha:combining { } + + li:objects { + } + color = {#cd3700} + } + + ha:int-sig2 { + lid=4 + group=7 + ha:combining { } + + ha:attributes { + {pcb-rnd::key::vis}={l; Shifti} + {pcb-rnd::key::select}={l; i} + } + + li:objects { + } + color = {#548b54} + } + + ha:int-sig1 { + lid=5 + group=5 + ha:combining { } + + ha:attributes { + {pcb-rnd::key::vis}={l; Shifto} + {pcb-rnd::key::select}={l; o} + } + + li:objects { + } + color = {#8b7355} + } + + ha:outline { + lid=6 + group=9 + ha:combining { } + + li:objects { + } + color = {#00868b} + } + + ha:bottom-silk { + lid=7 + group=12 + ha:combining { auto=1; } + + ha:attributes { + {pcb-rnd::key::vis}={l; Shiftx} + {pcb-rnd::key::select}={l; x} + } + + li:objects { + } + color = {#000000} + } + + ha:top-silk { + lid=8 + group=1 + ha:combining { auto=1; } + + ha:attributes { + {pcb-rnd::key::vis}={l; Shifts} + {pcb-rnd::key::select}={l; s} + } + + li:objects { + } + color = {#000000} + } + + ha:top-paste { + lid=9 + group=0 + ha:combining { auto=1; } + + li:objects { + } + color = {#cd00cd} + } + + ha:top-mask { + lid=10 + group=2 + ha:combining { sub=1; auto=1; } + + li:objects { + } + color = {#ff0000} + } + + ha:bottom-mask { + lid=11 + group=11 + ha:combining { sub=1; auto=1; } + + li:objects { + } + color = {#ff0000} + } + + ha:bottom-paste { + lid=12 + group=13 + ha:combining { auto=1; } + + li:objects { + } + color = {#cd00cd} + } + + ha:slot-plated { + lid=13 + group=14 + ha:combining { auto=1; } + + li:objects { + } + color = {#8b7355} + } + + ha:slot-unplated { + lid=14 + group=15 + ha:combining { auto=1; } + + li:objects { + } + color = {#00868b} + } + + ha:top-assy { + lid=15 + group=16 + ha:combining { } + + li:objects { + } + color = {#444444} + } + + ha:bot-assy { + lid=16 + group=17 + ha:combining { } + + li:objects { + } + color = {#444444} + } + + ha:fab { + lid=17 + group=18 + ha:combining { auto=1; } + + li:objects { + } + color = {#222222} + } + } + } + + ha:netlists { + li:input { + ha:div { + li:conn { CN1-2; R1-2; R2-1; } + } + ha:Vcc { + li:conn { R1-1; CN1-3; } + } + ha:GND { + li:conn { R2-2; CN1-1; } + } + } + li:netlist_patch { + ha:change_attrib { net=R2; key=footprint; val=0805; } + ha:change_attrib { net=R1; key=footprint; val=0805; } + ha:del_conn { net=div; term=CN1-2; } + ha:del_conn { net=Vcc; term=CN1-3; } + ha:add_conn { net=Vcc; term=CN1-2; } + ha:add_conn { net=div; term=CN1-3; } + } + } + ha:layer_stack { + li:groups { + ha:0 { + name = top_paste + ha:type { top=1; paste=1; } + li:layers { 9; } + } + ha:1 { + name = top_silk + ha:type { silk=1; top=1; } + li:layers { 8; } + } + ha:2 { + name = top_mask + ha:type { top=1; mask=1; } + li:layers { 10; } + } + ha:3 { + name = top_copper + ha:type { copper=1; top=1; } + li:layers { 0; 2; } + } + ha:4 { + name = grp_4 + ha:type { substrate=1; intern=1; } + li:layers { } + ha:attributes { + thickness={0.7375mm } + } + } + ha:5 { + name = Intern + ha:type { copper=1; intern=1; } + li:layers { 5; } + } + ha:6 { + name = grp_6 + ha:type { substrate=1; intern=1; } + li:layers { } + ha:attributes { + thickness={0.125mm } + } + } + ha:7 { + name = Intern + ha:type { copper=1; intern=1; } + li:layers { 4; } + } + ha:8 { + name = grp_8 + ha:type { substrate=1; intern=1; } + li:layers { } + ha:attributes { + thickness={0.7375mm } + } + } + ha:9 { + name = global_outline + ha:type { boundary=1; } + li:layers { 6; } + purpose = uroute + } + ha:10 { + name = bottom_copper + ha:type { bottom=1; copper=1; } + li:layers { 1; 3; } + } + ha:11 { + name = bottom_mask + ha:type { bottom=1; mask=1; } + li:layers { 11; } + } + ha:12 { + name = bottom_silk + ha:type { silk=1; bottom=1; } + li:layers { 7; } + } + ha:13 { + name = bottom_paste + ha:type { bottom=1; paste=1; } + li:layers { 12; } + } + ha:14 { + name = pmech + ha:type { mech=1; } + li:layers { 13; } + purpose = proute + } + ha:15 { + name = umech + ha:type { mech=1; } + li:layers { 14; } + purpose = uroute + } + ha:16 { + name = top_assy + ha:type { top=1; doc=1; } + li:layers { 15; } + ha:attributes { + init-invis=1 + } + purpose = assy + } + ha:17 { + name = bot_assy + ha:type { bottom=1; doc=1; } + li:layers { 16; } + ha:attributes { + init-invis=1 + } + purpose = assy + } + ha:18 { + name = fab + ha:type { top=1; doc=1; } + li:layers { 17; } + ha:attributes { + init-invis=1 + } + purpose = fab + } + } + } + li:pcb-rnd-conf-v1 { + ha:overwrite { + ha:design { + text_font_id = 0 + } + ha:editor { + lock_names = 1 + only_names = 0 + line_refraction = 1 + buffer_number = 0 + grids_idx = 4 + grid = 25.00 mil + } + ha:plugins { + ha:import_sch { + li:args { + div.tdx + } + import_fmt = tEDAx + } + } + } + } + ha:pixmaps { + } +} Index: tags/1.0.5/doc/examples/backann/div.rs =================================================================== --- tags/1.0.5/doc/examples/backann/div.rs (nonexistent) +++ tags/1.0.5/doc/examples/backann/div.rs (revision 10414) @@ -0,0 +1,470 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=OOg+ImBfqQSX8Difwh8AAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.1 { + uuid=8/SYZ/pfBzxyqFA12WQAAAAC; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAg; + li:objects { + ha:polygon.11 { + li:outline { + ha:line { x1=0; y1=0; x2=80000; y2=0; } + ha:line { x1=80000; y1=0; x2=80000; y2=20000; } + ha:line { x1=80000; y1=20000; x2=0; y2=20000; } + ha:line { x1=0; y1=20000; x2=0; y2=0; } + } + stroke=titlebox-frame; + fill=titlebox-fill; + } + ha:line.12 { x1=0; y1=10000; x2=80000; y2=10000; stroke=titlebox-frame; } + ha:line.13 { x1=40000; y1=10000; x2=40000; y2=0; stroke=titlebox-frame; } + ha:text.20 { x1=1000; y1=16500; dyntext=0; stroke=titlebox-big; text=TITLE; } + ha:text.21 { x1=1000; y1=10500; x2=79000; y2=16000; dyntext=1; stroke=titlebox-big; text=%../../A.title%; } + ha:text.22 { x1=1000; y1=5500; dyntext=0; stroke=titlebox-small; text={PROJECT:}; } + ha:text.23 { x1=13000; y1=5500; x2=39000; y2=9500; dyntext=1; stroke=titlebox-big; text=%project.name%; } + ha:text.24 { x1=1000; y1=500; dyntext=0; stroke=titlebox-small; text={PAGE:}; } + ha:text.25 { x1=10000; y1=500; x2=39000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.page%; } + ha:text.26 { x1=41000; y1=5500; dyntext=0; stroke=titlebox-small; text={FILE:}; } + ha:text.27 { x1=48000; y1=5500; x2=79000; y2=9500; dyntext=1; stroke=titlebox-big; text=%filename%; } + ha:text.28 { x1=41000; y1=500; dyntext=0; stroke=titlebox-small; text={MAINTAINER:}; } + ha:text.29 { x1=55000; y1=500; x2=79000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.maintainer%; } + } + ha:attrib { + purpose=titlebox + } + } + ha:group.2 { + uuid=OOg+ImBfqQSX8Difwh8AAAAJ; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=88000; y=136000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=OOg+ImBfqQSX8Difwh8AAAAK; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; floater=1; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=OOg+ImBfqQSX8Difwh8AAAAL; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; floater=1; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + ha:text.6 { x1=16000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-secondary; text=%../A.footprint%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=R1 + role=symbol + value=1k + } + } + ha:group.3 { + uuid=OOg+ImBfqQSX8Difwh8AAAAM; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=88000; y=108000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=OOg+ImBfqQSX8Difwh8AAAAN; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; floater=1; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=OOg+ImBfqQSX8Difwh8AAAAO; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; floater=1; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + ha:text.6 { x1=16000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-secondary; text=%../A.footprint%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=R2 + role=symbol + value=4k7 + } + } + ha:group.4 { + uuid=OOg+ImBfqQSX8Difwh8AAAAT; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB6; + x=88000; y=140000; + li:objects { + ha:group.1 { + uuid=OOg+ImBfqQSX8Difwh8AAAAU; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB7; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-4000; y1=4000; dyntext=0; stroke=sym-primary; text=Vcc; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:Vcc} + } + role=symbol + } + } + ha:group.5 { + uuid=OOg+ImBfqQSX8Difwh8AAAAZ; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=88000; y=84000; + li:objects { + ha:group.1 { + uuid=OOg+ImBfqQSX8Difwh8AAAAa; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.6 { + uuid=OOg+ImBfqQSX8Difwh8AAAAb; + li:objects { + ha:line.1 { x1=88000; y1=140000; x2=88000; y2=136000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.7 { + li:conn { + /2/6/1 + /2/2/2/1 + } + } + ha:connection.8 { + li:conn { + /2/6/1 + /2/4/1/1 + } + } + ha:group.9 { + uuid=OOg+ImBfqQSX8Difwh8AAAAc; + li:objects { + ha:line.2 { x1=72000; y1=112000; x2=88000; y2=112000; stroke=wire; } + ha:line.4 { x1=88000; y1=116000; x2=88000; y2=108000; stroke=wire; } + ha:line.5 { x1=88000; y1=112000; x2=88000; y2=112000; stroke=junction; } + ha:text.6 { x1=80000; y1=112000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=div + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.12 { + uuid=OOg+ImBfqQSX8Difwh8AAAAd; + li:objects { + ha:line.1 { x1=88000; y1=88000; x2=88000; y2=84000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.13 { + li:conn { + /2/12/1 + /2/3/1/1 + } + } + ha:group.15 { + uuid=OOg+ImBfqQSX8Difwh8AAAAm; src_uuid=OOg+ImBfqQSX8Difwh8AAAAi; + x=68000; y=108000; mirx=1; + li:objects { + ha:text.1 { x1=8000; y1=0; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:group.2 { + uuid=OOg+ImBfqQSX8Difwh8AAAAn; src_uuid=OOg+ImBfqQSX8Difwh8AAAAj; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:group.3 { + uuid=OOg+ImBfqQSX8Difwh8AAAAo; src_uuid=OOg+ImBfqQSX8Difwh8AAAAk; + x=0; y=4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.4 { + uuid=OOg+ImBfqQSX8Difwh8AAAAp; src_uuid=OOg+ImBfqQSX8Difwh8AAAAl; + x=0; y=8000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + name=3 + role=terminal + } + } + ha:polygon.5 { + li:outline { + ha:line { x1=0; y1=-2000; x2=0; y2=10000; } + ha:line { x1=0; y1=10000; x2=4000; y2=10000; } + ha:line { x1=4000; y1=10000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=0; y2=-2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + footprint=connector(3,1) + name=CN1 + role=symbol + } + } + ha:connection.16 { + li:conn { + /2/12/1 + /2/5/1/1 + } + } + ha:connection.18 { + li:conn { + /2/15/3/1 + /2/9/2 + } + } + ha:group.19 { + uuid=OOg+ImBfqQSX8Difwh8AAAAs; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB6; + x=76000; y=120000; + li:objects { + ha:group.1 { + uuid=OOg+ImBfqQSX8Difwh8AAAAt; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB7; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-4000; y1=4000; dyntext=0; stroke=sym-primary; text=Vcc; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:Vcc} + } + role=symbol + } + } + ha:group.20 { + uuid=OOg+ImBfqQSX8Difwh8AAAAw; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=76000; y=104000; + li:objects { + ha:group.1 { + uuid=OOg+ImBfqQSX8Difwh8AAAAx; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.21 { + uuid=OOg+ImBfqQSX8Difwh8AAAAy; + li:objects { + ha:line.1 { x1=72000; y1=108000; x2=76000; y2=108000; stroke=wire; } + ha:line.2 { x1=76000; y1=108000; x2=76000; y2=104000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.22 { + li:conn { + /2/21/1 + /2/15/2/1 + } + } + ha:connection.23 { + li:conn { + /2/21/2 + /2/20/1/1 + } + } + ha:group.24 { + uuid=OOg+ImBfqQSX8Difwh8AAAAz; + li:objects { + ha:line.1 { x1=72000; y1=116000; x2=76000; y2=116000; stroke=wire; } + ha:line.2 { x1=76000; y1=116000; x2=76000; y2=120000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.25 { + li:conn { + /2/24/1 + /2/15/4/1 + } + } + ha:connection.26 { + li:conn { + /2/24/2 + /2/19/1/1 + } + } + ha:connection.27 { + li:conn { + /2/9/4 + /2/2/1/1 + } + } + ha:connection.28 { + li:conn { + /2/9/4 + /2/3/2/1 + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer=Tibor 'Igor2' Palinkas + page=1 of 1 + print_page=A/4 + title=resistor divider plugin + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 1 + grid = 2.0480 mm + } + } + } +} Index: tags/1.0.5/doc/examples/backann/div.tdx =================================================================== --- tags/1.0.5/doc/examples/backann/div.tdx (nonexistent) +++ tags/1.0.5/doc/examples/backann/div.tdx (revision 10414) @@ -0,0 +1,16 @@ +tEDAx v1 +begin netlist v1 +footprint CN1 connector(3,1) +footprint R1 1206 +value R1 1k +footprint R2 1206 +value R2 4k7 +conn Vcc R1 1 +conn Vcc CN1 3 +conn GND R2 2 +conn GND CN1 1 +conn div CN1 2 +conn div R1 2 +conn div R2 1 +end netlist + Index: tags/1.0.5/doc/examples/devmap.rs =================================================================== --- tags/1.0.5/doc/examples/devmap.rs (nonexistent) +++ tags/1.0.5/doc/examples/devmap.rs (revision 10414) @@ -0,0 +1,793 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAEk; + li:objects { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAD5; + loclib_name=2n7002_sot23 + li:objects { + } + ha:attrib { + footprint=sot23 + li:portmap { + {G->pcb/pinnum=1} + {S->pcb/pinnum=2} + {D->pcb/pinnum=3} + } + } + } + ha:group.2 { + uuid=iNOQfJpO6hT/HFDFGjoAAAD6; + loclib_name=irf510_to220 + li:objects { + } + ha:attrib { + footprint=TO220 + li:portmap { + {G->pcb/pinnum=1} + {S->pcb/pinnum=3} + {D->pcb/pinnum=2} + } + } + } + } + ha:attrib { + ha:purpose = { value=devmap; prio=0; } + } + } + } + } + ha:obj_direct.2 { + uuid=iNOQfJpO6hT/HFDFGjoAAAEj; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAD7; + x=132000; y=68000; + li:objects { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAD8; + x=12000; y=12000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; floater=1; } + } + ha:attrib { + name=D + role=terminal + } + } + ha:group.2 { + uuid=iNOQfJpO6hT/HFDFGjoAAAD9; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; floater=1; } + } + ha:attrib { + name=G + role=terminal + } + } + ha:text.3 { x1=20000; y1=-12000; rot=90.000000; dyntext=1; stroke=sym-secondary; text=%../a.devmap%; floater=1; } + ha:text.4 { x1=4000; y1=8000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:arc.5 { cx=11000; cy=3000; r=5500; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:line.6 { x1=4000; y1=0; x2=8000; y2=0; stroke=sym-decor; } + ha:line.7 { x1=9000; y1=-1000; x2=9000; y2=1000; stroke=sym-decor; } + ha:line.8 { x1=9000; y1=2000; x2=9000; y2=4000; stroke=sym-decor; } + ha:line.9 { x1=9000; y1=5000; x2=9000; y2=7000; stroke=sym-decor; } + ha:line.10 { x1=9000; y1=3000; x2=12000; y2=3000; stroke=sym-decor; } + ha:line.11 { x1=9000; y1=0; x2=12000; y2=0; stroke=sym-decor; } + ha:line.12 { x1=9000; y1=6000; x2=12000; y2=6000; stroke=sym-decor; } + ha:line.13 { x1=12000; y1=6000; x2=12000; y2=8000; stroke=sym-decor; } + ha:line.14 { x1=12000; y1=-4000; x2=12000; y2=3000; stroke=sym-decor; } + ha:line.15 { x1=13000; y1=3000; x2=15000; y2=3000; stroke=sym-decor; } + ha:line.16 { x1=15000; y1=3000; x2=14000; y2=4000; stroke=sym-decor; } + ha:line.17 { x1=14000; y1=4000; x2=13000; y2=3000; stroke=sym-decor; } + ha:line.18 { x1=13000; y1=4000; x2=15000; y2=4000; stroke=sym-decor; } + ha:line.19 { x1=12000; y1=7000; x2=14000; y2=7000; stroke=sym-decor; } + ha:line.20 { x1=14000; y1=-1000; x2=12000; y2=-1000; stroke=sym-decor; } + ha:line.21 { x1=8000; y1=7000; x2=8000; y2=0; stroke=sym-decor; } + ha:polygon.22 { + li:outline { + ha:line { x1=10000; y1=4000; x2=9000; y2=3000; } + ha:line { x1=9000; y1=3000; x2=10000; y2=2000; } + ha:line { x1=10000; y1=2000; x2=10000; y2=4000; } + } + stroke=sym-decor; + fill=sym-decor; + } + ha:group.23 { + uuid=iNOQfJpO6hT/HFDFGjoAAAD+; + x=12000; y=-4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; floater=1; } + } + ha:attrib { + name=S + role=terminal + } + } + ha:line.24 { x1=14000; y1=-1000; x2=14000; y2=3000; stroke=sym-decor; } + ha:line.25 { x1=14000; y1=4000; x2=14000; y2=7000; stroke=sym-decor; } + } + ha:attrib { + devmap=2n7002_sot23 + name=Q1 + role=symbol + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + sym-license-dist=GPLv2+ + sym-license-use=Public Domain + sym-source=sch-rnd default symbol lib + } + } + ha:group.7 { + uuid=iNOQfJpO6hT/HFDFGjoAAAD/; + x=116000; y=64000; mirx=1; + li:objects { + ha:text.1 { x1=8000; y1=-4000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:group.2 { + uuid=iNOQfJpO6hT/HFDFGjoAAAEA; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:group.3 { + uuid=iNOQfJpO6hT/HFDFGjoAAAEB; + x=0; y=4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.4 { + uuid=iNOQfJpO6hT/HFDFGjoAAAEC; + x=0; y=8000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + name=3 + role=terminal + } + } + ha:polygon.5 { + li:outline { + ha:line { x1=0; y1=-2000; x2=0; y2=10000; } + ha:line { x1=0; y1=10000; x2=4000; y2=10000; } + ha:line { x1=4000; y1=10000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=0; y2=-2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + name=CONN1 + role=symbol + } + } + ha:group.11 { + uuid=iNOQfJpO6hT/HFDFGjoAAAED; + x=144000; y=52000; + li:objects { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAEE; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + li:connect { + {1:GND} + } + role=symbol + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + sym-license-dist=GPLv2+ + sym-license-use=Public Domain + sym-source=sch-rnd default symbol lib + } + } + ha:group.13 { + uuid=iNOQfJpO6hT/HFDFGjoAAAEF; + x=146000; y=94000; rot=90.000000; + li:objects { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAEG; + li:objects { + ha:line.1 { x1=18000; y1=2000; x2=15000; y2=2000; stroke=term-primary; } + } + ha:attrib { + pinlabel=2 + pinnumber=2 + pinseq=2 + pintype=pas + ha:role = { value=terminal; prio=0; } + } + } + ha:group.2 { + uuid=iNOQfJpO6hT/HFDFGjoAAAEH; + li:objects { + ha:line.1 { x1=0; y1=2000; x2=3000; y2=2000; stroke=term-primary; } + } + ha:attrib { + pinlabel=1 + pinnumber=1 + pinseq=1 + pintype=pas + ha:role = { value=terminal; prio=0; } + } + } + ha:polygon.3 { + li:outline { + ha:line { x1=3000; y1=0; x2=3000; y2=4000; } + ha:line { x1=3000; y1=4000; x2=15000; y2=4000; } + ha:line { x1=15000; y1=4000; x2=15000; y2=0; } + ha:line { x1=15000; y1=0; x2=3000; y2=0; } + } + stroke=sym-decor; + } + ha:text.4 { x1=8000; y1=4000; dyntext=1; stroke=sym-decor; text=%../A.refdes%; floater=1; } + } + ha:attrib { + device=RESISTOR + refdes=R1 + ha:role = { value=symbol; prio=0; } + } + } + ha:group.15 { + uuid=iNOQfJpO6hT/HFDFGjoAAAEI; + x=144000; y=140000; + li:objects { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAEJ; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-4000; y1=4000; dyntext=0; stroke=sym-primary; text=Vcc; } + } + ha:attrib { + li:connect { + {1:Vcc} + } + role=symbol + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + sym-license-dist=GPLv2+ + sym-license-use=Public Domain + sym-source=sch-rnd default symbol lib + } + } + ha:group.20 { + uuid=iNOQfJpO6hT/HFDFGjoAAAEK; + li:objects { + ha:line.1 { x1=144000; y1=140000; x2=144000; y2=112000; stroke=wire; } + ha:line.2 { x1=168000; y1=122000; x2=144000; y2=122000; stroke=wire; } + ha:line.3 { x1=144000; y1=122000; x2=144000; y2=122000; stroke=junction; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.24 { + uuid=iNOQfJpO6hT/HFDFGjoAAAEL; + x=168000; y=122000; + li:objects { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAEM; + x=12000; y=12000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; floater=1; } + } + ha:attrib { + name=D + role=terminal + } + } + ha:group.2 { + uuid=iNOQfJpO6hT/HFDFGjoAAAEN; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; floater=1; } + } + ha:attrib { + name=G + role=terminal + } + } + ha:text.3 { x1=8000; y1=-30000; rot=90.000000; dyntext=1; stroke=sym-secondary; text=%../a.devmap%; floater=1; } + ha:text.4 { x1=4000; y1=8000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:arc.5 { cx=11000; cy=3000; r=5500; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:line.6 { x1=4000; y1=0; x2=8000; y2=0; stroke=sym-decor; } + ha:line.7 { x1=9000; y1=-1000; x2=9000; y2=1000; stroke=sym-decor; } + ha:line.8 { x1=9000; y1=2000; x2=9000; y2=4000; stroke=sym-decor; } + ha:line.9 { x1=9000; y1=5000; x2=9000; y2=7000; stroke=sym-decor; } + ha:line.10 { x1=9000; y1=3000; x2=12000; y2=3000; stroke=sym-decor; } + ha:line.11 { x1=9000; y1=0; x2=12000; y2=0; stroke=sym-decor; } + ha:line.12 { x1=9000; y1=6000; x2=12000; y2=6000; stroke=sym-decor; } + ha:line.13 { x1=12000; y1=6000; x2=12000; y2=8000; stroke=sym-decor; } + ha:line.14 { x1=12000; y1=-4000; x2=12000; y2=3000; stroke=sym-decor; } + ha:line.15 { x1=13000; y1=3000; x2=15000; y2=3000; stroke=sym-decor; } + ha:line.16 { x1=15000; y1=3000; x2=14000; y2=4000; stroke=sym-decor; } + ha:line.17 { x1=14000; y1=4000; x2=13000; y2=3000; stroke=sym-decor; } + ha:line.18 { x1=13000; y1=4000; x2=15000; y2=4000; stroke=sym-decor; } + ha:line.19 { x1=12000; y1=7000; x2=14000; y2=7000; stroke=sym-decor; } + ha:line.20 { x1=14000; y1=-1000; x2=12000; y2=-1000; stroke=sym-decor; } + ha:line.21 { x1=8000; y1=7000; x2=8000; y2=0; stroke=sym-decor; } + ha:polygon.22 { + li:outline { + ha:line { x1=10000; y1=4000; x2=9000; y2=3000; } + ha:line { x1=9000; y1=3000; x2=10000; y2=2000; } + ha:line { x1=10000; y1=2000; x2=10000; y2=4000; } + } + stroke=sym-decor; + fill=sym-decor; + } + ha:group.23 { + uuid=iNOQfJpO6hT/HFDFGjoAAAEO; + x=12000; y=-4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; floater=1; } + } + ha:attrib { + name=S + role=terminal + } + } + ha:line.24 { x1=14000; y1=-1000; x2=14000; y2=3000; stroke=sym-decor; } + ha:line.25 { x1=14000; y1=4000; x2=14000; y2=7000; stroke=sym-decor; } + } + ha:attrib { + devmap=irf510_to220 + name=Q2 + role=symbol + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + sym-license-dist=GPLv2+ + sym-license-use=Public Domain + sym-source=sch-rnd default symbol lib + } + } + ha:group.26 { + uuid=iNOQfJpO6hT/HFDFGjoAAAEP; + li:objects { + ha:line.1 { x1=180000; y1=114000; x2=180000; y2=52000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.28 { + uuid=iNOQfJpO6hT/HFDFGjoAAAEQ; + x=180000; y=52000; + li:objects { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAER; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + li:connect { + {1:GND} + } + role=symbol + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + sym-license-dist=GPLv2+ + sym-license-use=Public Domain + sym-source=sch-rnd default symbol lib + } + } + ha:group.31 { + uuid=iNOQfJpO6hT/HFDFGjoAAAES; + x=196000; y=138000; + li:objects { + ha:text.1 { x1=8000; y1=-4000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:group.2 { + uuid=iNOQfJpO6hT/HFDFGjoAAAET; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:group.3 { + uuid=iNOQfJpO6hT/HFDFGjoAAAEU; + x=0; y=4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:polygon.4 { + li:outline { + ha:line { x1=0; y1=-2000; x2=0; y2=6000; } + ha:line { x1=0; y1=6000; x2=4000; y2=6000; } + ha:line { x1=4000; y1=6000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=0; y2=-2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + name=CONN2 + role=symbol + } + } + ha:group.32 { + uuid=iNOQfJpO6hT/HFDFGjoAAAEV; + li:objects { + ha:line.1 { x1=180000; y1=134000; x2=180000; y2=142000; stroke=wire; } + ha:line.2 { x1=180000; y1=142000; x2=192000; y2=142000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.35 { + uuid=iNOQfJpO6hT/HFDFGjoAAAEW; + li:objects { + ha:line.1 { x1=192000; y1=138000; x2=190000; y2=138000; stroke=wire; } + ha:line.2 { x1=190000; y1=138000; x2=190000; y2=132000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.37 { + uuid=iNOQfJpO6hT/HFDFGjoAAAEX; + x=190000; y=132000; + li:objects { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAEY; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + li:connect { + {1:GND} + } + role=symbol + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + sym-license-dist=GPLv2+ + sym-license-use=Public Domain + sym-source=sch-rnd default symbol lib + } + } + ha:group.39 { + uuid=iNOQfJpO6hT/HFDFGjoAAAEZ; + li:objects { + ha:polygon.11 { + li:outline { + ha:line { x1=0; y1=0; x2=80000; y2=0; } + ha:line { x1=80000; y1=0; x2=80000; y2=20000; } + ha:line { x1=80000; y1=20000; x2=0; y2=20000; } + ha:line { x1=0; y1=20000; x2=0; y2=0; } + } + stroke=titlebox-frame; + fill=titlebox-fill; + } + ha:line.12 { x1=0; y1=10000; x2=80000; y2=10000; stroke=titlebox-frame; } + ha:line.13 { x1=40000; y1=10000; x2=40000; y2=0; stroke=titlebox-frame; } + ha:text.20 { x1=1000; y1=16500; dyntext=0; stroke=titlebox-big; text=TITLE; } + ha:text.21 { x1=1000; y1=10500; x2=79000; y2=16000; dyntext=1; stroke=titlebox-big; text=%../../A.title%; } + ha:text.22 { x1=1000; y1=5500; dyntext=0; stroke=titlebox-small; text={PROJECT:}; } + ha:text.23 { x1=13000; y1=5500; x2=39000; y2=9500; dyntext=1; stroke=titlebox-big; text=%project.name%; } + ha:text.24 { x1=1000; y1=500; dyntext=0; stroke=titlebox-small; text={PAGE:}; } + ha:text.25 { x1=10000; y1=500; x2=39000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.page%; } + ha:text.26 { x1=41000; y1=5500; dyntext=0; stroke=titlebox-small; text={FILE:}; } + ha:text.27 { x1=48000; y1=5500; x2=79000; y2=9500; dyntext=1; stroke=titlebox-big; text=%filename%; } + ha:text.28 { x1=41000; y1=500; dyntext=0; stroke=titlebox-small; text={MAINTAINER:}; } + ha:text.29 { x1=55000; y1=500; x2=79000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.maintainer%; } + } + ha:attrib { + purpose=titlebox + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + sym-license-dist=GPLv2+ + sym-license-use=Public Domain + sym-source=sch-rnd default symbol lib + } + } + ha:connection.42 { + li:conn { + /2/20/1 + /2/13/1/1 + } + } + ha:connection.43 { + li:conn { + /2/20/1 + /2/15/1/1 + } + } + ha:connection.44 { + li:conn { + /2/24/2/1 + /2/20/2 + } + } + ha:connection.45 { + li:conn { + /2/26/1 + /2/24/23/1 + } + } + ha:connection.46 { + li:conn { + /2/28/1/1 + /2/26/1 + } + } + ha:connection.47 { + li:conn { + /2/32/1 + /2/24/1/1 + } + } + ha:connection.48 { + li:conn { + /2/32/2 + /2/31/3/1 + } + } + ha:connection.49 { + li:conn { + /2/35/1 + /2/31/2/1 + } + } + ha:connection.50 { + li:conn { + /2/37/1/1 + /2/35/2 + } + } + ha:group.51 { + uuid=iNOQfJpO6hT/HFDFGjoAAAEa; + li:objects { + ha:line.1 { x1=120000; y1=72000; x2=124000; y2=72000; stroke=wire; } + ha:line.2 { x1=124000; y1=72000; x2=124000; y2=80000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.52 { + li:conn { + /2/51/1 + /2/7/4/1 + } + } + ha:group.53 { + uuid=iNOQfJpO6hT/HFDFGjoAAAEb; + li:objects { + ha:line.1 { x1=120000; y1=64000; x2=124000; y2=64000; stroke=wire; } + ha:line.2 { x1=124000; y1=64000; x2=124000; y2=56000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.54 { + li:conn { + /2/53/1 + /2/7/2/1 + } + } + ha:group.55 { + uuid=iNOQfJpO6hT/HFDFGjoAAAEc; + x=124000; y=56000; + li:objects { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAEd; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + li:connect { + {1:GND} + } + role=symbol + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + sym-license-dist=GPLv2+ + sym-license-use=Public Domain + sym-source=sch-rnd default symbol lib + } + } + ha:connection.56 { + li:conn { + /2/55/1/1 + /2/53/2 + } + } + ha:group.57 { + uuid=iNOQfJpO6hT/HFDFGjoAAAEe; + x=124000; y=80000; + li:objects { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAEf; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-4000; y1=4000; dyntext=0; stroke=sym-primary; text=Vcc; } + } + ha:attrib { + li:connect { + {1:Vcc} + } + role=symbol + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + sym-license-dist=GPLv2+ + sym-license-use=Public Domain + sym-source=sch-rnd default symbol lib + } + } + ha:connection.58 { + li:conn { + /2/57/1/1 + /2/51/2 + } + } + ha:group.59 { + uuid=iNOQfJpO6hT/HFDFGjoAAAEg; + li:objects { + ha:line.1 { x1=120000; y1=68000; x2=132000; y2=68000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.60 { + li:conn { + /2/59/1 + /2/1/2/1 + } + } + ha:connection.61 { + li:conn { + /2/59/1 + /2/7/3/1 + } + } + ha:group.62 { + uuid=iNOQfJpO6hT/HFDFGjoAAAEh; + li:objects { + ha:line.1 { x1=144000; y1=52000; x2=144000; y2=60000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.63 { + li:conn { + /2/62/1 + /2/1/23/1 + } + } + ha:connection.64 { + li:conn { + /2/62/1 + /2/11/1/1 + } + } + ha:group.65 { + uuid=iNOQfJpO6hT/HFDFGjoAAAEi; + li:objects { + ha:line.1 { x1=144000; y1=94000; x2=144000; y2=80000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.66 { + li:conn { + /2/65/1 + /2/1/1/1 + } + } + ha:connection.67 { + li:conn { + /2/65/1 + /2/13/2/1 + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer=Tibor 'Igor2' Palinkas + page=1 of 1 + print_page=A/4 + title=sch-rnd devmap example + } + } +} Index: tags/1.0.5/doc/examples/devmaps/swap2.devmap =================================================================== --- tags/1.0.5/doc/examples/devmaps/swap2.devmap (nonexistent) +++ tags/1.0.5/doc/examples/devmaps/swap2.devmap (revision 10414) @@ -0,0 +1,9 @@ +ha:std_devmap.v1 { + ha:comp_attribs { + comment={swap2: swap pins 1 and 2 for pcb} + li:portmap={ + {1->pcb/pinnum=2} + {2->pcb/pinnum=1} + } + } +} Index: tags/1.0.5/doc/examples/dnp_comp.rs =================================================================== --- tags/1.0.5/doc/examples/dnp_comp.rs (nonexistent) +++ tags/1.0.5/doc/examples/dnp_comp.rs (revision 10414) @@ -0,0 +1,852 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + ha:group.1 { + uuid=E4wBSbBPnQTyLrlukNMAAAAV; + li:objects { + ha:group.1 { + uuid=E4wBSbBPnQTyLrlukNMAAAAW; loclib_name=lm358_so8; + li:objects { + } + ha:attrib { + footprint=so(8) + li:portmap { + {1/in- -> pcb/pinnum=2} + {1/in+ -> pcb/pinnum=3} + {1/out -> pcb/pinnum=1} + {1/V+ -> pcb/pinnum=8} + {1/V- -> pcb/pinnum=4} + {2/in- -> pcb/pinnum=6} + {2/in+ -> pcb/pinnum=5} + {2/out -> pcb/pinnum=7} + {2/V+ -> pcb/pinnum=8} + {2/V- -> pcb/pinnum=4} + } + } + } + } + ha:attrib { + ha:purpose = { value=devmap; prio=0; } + } + } + } + } + ha:obj_direct.2 { + uuid=E4wBSbBPnQTyLrlukNMAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.1 { + uuid=8/SYZ/pfBzxyqFA12WQAAAAC; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAg; + li:objects { + ha:polygon.11 { + li:outline { + ha:line { x1=0; y1=0; x2=80000; y2=0; } + ha:line { x1=80000; y1=0; x2=80000; y2=20000; } + ha:line { x1=80000; y1=20000; x2=0; y2=20000; } + ha:line { x1=0; y1=20000; x2=0; y2=0; } + } + stroke=titlebox-frame; + fill=titlebox-fill; + } + ha:line.12 { x1=0; y1=10000; x2=80000; y2=10000; stroke=titlebox-frame; } + ha:line.13 { x1=40000; y1=10000; x2=40000; y2=0; stroke=titlebox-frame; } + ha:text.20 { x1=1000; y1=16500; dyntext=0; stroke=titlebox-big; text=TITLE; } + ha:text.21 { x1=1000; y1=10500; x2=79000; y2=16000; dyntext=1; stroke=titlebox-big; text=%../../A.title%; } + ha:text.22 { x1=1000; y1=5500; dyntext=0; stroke=titlebox-small; text={PROJECT:}; } + ha:text.23 { x1=13000; y1=5500; x2=39000; y2=9500; dyntext=1; stroke=titlebox-big; text=%project.name%; } + ha:text.24 { x1=1000; y1=500; dyntext=0; stroke=titlebox-small; text={PAGE:}; } + ha:text.25 { x1=10000; y1=500; x2=39000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.page%; } + ha:text.26 { x1=41000; y1=5500; dyntext=0; stroke=titlebox-small; text={FILE:}; } + ha:text.27 { x1=48000; y1=5500; x2=79000; y2=9500; dyntext=1; stroke=titlebox-big; text=%filename%; } + ha:text.28 { x1=41000; y1=500; dyntext=0; stroke=titlebox-small; text={MAINTAINER:}; } + ha:text.29 { x1=55000; y1=500; x2=79000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.maintainer%; } + ha:text.30 { x1=79000; y1=16000; mirx=1; dyntext=1; stroke=sheet-decor; text=%stance.model% %stance.sub_major% %stance.sub_minor% %stance.test_bench% %view.name%; } + } + ha:attrib { + purpose=titlebox + } + } + ha:group.16 { + uuid=E4wBSbBPnQTyLrlukNMAAABB; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAH; + x=124000; y=104000; miry=1; + li:objects { + ha:group.1 { + uuid=E4wBSbBPnQTyLrlukNMAAABC; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAI; + x=-20000; y=4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=in+ + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.2 { + uuid=E4wBSbBPnQTyLrlukNMAAABD; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAJ; + x=-20000; y=-4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=in- + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:group.3 { + uuid=E4wBSbBPnQTyLrlukNMAAABE; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAK; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=out + role=terminal + ha:spice/pinnum = { value=3; prio=31050; } + } + } + ha:line.4 { x1=-20000; y1=-8000; x2=-20000; y2=8000; stroke=sym-decor; } + ha:line.5 { x1=-20000; y1=8000; x2=-4000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=-4000; y1=0; x2=-20000; y2=-8000; stroke=sym-decor; } + ha:line.7 { x1=-18000; y1=5000; x2=-18000; y2=3000; stroke=sym-decor; } + ha:line.8 { x1=-19000; y1=4000; x2=-17000; y2=4000; stroke=sym-decor; } + ha:line.9 { x1=-19000; y1=-4000; x2=-17000; y2=-4000; stroke=sym-decor; } + ha:group.10 { + uuid=E4wBSbBPnQTyLrlukNMAAABF; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAL; + x=-12000; y=-4000; rot=270.000000; mirx=1; miry=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=0; y1=-1000; rot=180.000000; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=V- + role=terminal + ha:spice/pinnum = { value=5; prio=31050; } + } + } + ha:group.11 { + uuid=E4wBSbBPnQTyLrlukNMAAABG; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAM; + x=-12000; y=8000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=-4000; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=V+ + role=terminal + ha:spice/pinnum = { value=4; prio=31050; } + } + } + ha:text.12 { x1=-21000; y1=9000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -slot=1 + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + devmap=lm358_so8 + name=U1 + dnp=1 + role=symbol + } + } + ha:group.22 { + uuid=E4wBSbBPnQTyLrlukNMAAABM; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=104000; y=136000; miry=1; + li:objects { + ha:group.1 { + uuid=E4wBSbBPnQTyLrlukNMAAABN; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=E4wBSbBPnQTyLrlukNMAAABO; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=R1 + role=symbol + ha:spice/prefix = { value=R; prio=31050; } + value=47k + } + } + ha:group.23 { + uuid=E4wBSbBPnQTyLrlukNMAAABP; src_uuid=E4wBSbBPnQTyLrlukNMAAAAp; + x=16000; y=244000; miry=1; + li:objects { + ha:line.1 { x1=84000; y1=136000; x2=76000; y2=136000; stroke=wire; } + ha:line.2 { x1=76000; y1=136000; x2=76000; y2=108000; stroke=wire; } + ha:line.4 { x1=68000; y1=108000; x2=88000; y2=108000; stroke=wire; } + ha:line.5 { x1=76000; y1=108000; x2=76000; y2=108000; stroke=junction; } + ha:text.6 { x1=76000; y1=112000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=opa_neg + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.24 { + li:conn { + /2/23/1 + /2/16/2/1 + } + } + ha:connection.25 { + li:conn { + /2/22/2/1 + /2/23/4 + } + } + ha:group.26 { + uuid=E4wBSbBPnQTyLrlukNMAAABQ; src_uuid=E4wBSbBPnQTyLrlukNMAAAAq; + x=16000; y=244000; miry=1; + li:objects { + ha:line.1 { x1=108000; y1=108000; x2=124000; y2=108000; stroke=wire; } + ha:line.2 { x1=124000; y1=108000; x2=124000; y2=140000; stroke=wire; } + ha:line.4 { x1=108000; y1=140000; x2=148000; y2=140000; stroke=wire; } + ha:line.5 { x1=124000; y1=140000; x2=124000; y2=140000; stroke=junction; } + ha:text.6 { x1=132000; y1=140000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=out + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.27 { + li:conn { + /2/26/1 + /2/22/1/1 + } + } + ha:connection.28 { + li:conn { + /2/16/3/1 + /2/26/4 + } + } + ha:group.29 { + uuid=E4wBSbBPnQTyLrlukNMAAABR; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=64000; y=136000; miry=1; + li:objects { + ha:group.1 { + uuid=E4wBSbBPnQTyLrlukNMAAABS; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=E4wBSbBPnQTyLrlukNMAAABT; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=R2 + role=symbol + ha:spice/prefix = { value=R; prio=31050; } + value=10k + } + } + ha:group.30 { + uuid=E4wBSbBPnQTyLrlukNMAAABY; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=124000; y=116000; + li:objects { + ha:group.1 { + uuid=E4wBSbBPnQTyLrlukNMAAABZ; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.31 { + uuid=E4wBSbBPnQTyLrlukNMAAABa; + li:objects { + ha:line.1 { x1=112000; y1=112000; x2=112000; y2=120000; stroke=wire; } + ha:line.2 { x1=112000; y1=120000; x2=124000; y2=120000; stroke=wire; } + ha:line.3 { x1=124000; y1=120000; x2=124000; y2=116000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.32 { + li:conn { + /2/31/1 + /2/16/10/1 + } + } + ha:connection.33 { + li:conn { + /2/31/3 + /2/30/1/1 + } + } + ha:group.34 { + uuid=E4wBSbBPnQTyLrlukNMAAABf; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB6; + x=124000; y=96000; + li:objects { + ha:group.1 { + uuid=E4wBSbBPnQTyLrlukNMAAABg; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB7; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-4000; y1=4000; x2=4000; y2=7000; halign=center; dyntext=0; stroke=sym-primary; text=Vcc; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:Vcc} + } + role=symbol + } + } + ha:group.37 { + uuid=E4wBSbBPnQTyLrlukNMAAABi; + li:objects { + ha:line.1 { x1=112000; y1=96000; x2=112000; y2=92000; stroke=wire; } + ha:line.2 { x1=112000; y1=92000; x2=124000; y2=92000; stroke=wire; } + ha:line.3 { x1=124000; y1=92000; x2=124000; y2=96000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.38 { + li:conn { + /2/37/1 + /2/16/11/1 + } + } + ha:connection.39 { + li:conn { + /2/37/3 + /2/34/1/1 + } + } + ha:group.40 { + uuid=E4wBSbBPnQTyLrlukNMAAABj; + li:objects { + ha:line.1 { x1=100000; y1=100000; x2=92000; y2=100000; stroke=wire; } + ha:line.2 { x1=92000; y1=100000; x2=92000; y2=92000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.41 { + li:conn { + /2/40/1 + /2/16/1/1 + } + } + ha:group.42 { + uuid=E4wBSbBPnQTyLrlukNMAAABm; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=92000; y=92000; + li:objects { + ha:group.1 { + uuid=E4wBSbBPnQTyLrlukNMAAABn; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:connection.43 { + li:conn { + /2/42/1/1 + /2/40/2 + } + } + ha:connection.44 { + li:conn { + /2/23/4 + /2/29/1/1 + } + } + ha:group.45 { + uuid=E4wBSbBPnQTyLrlukNMAAABo; + li:objects { + ha:line.2 { x1=48000; y1=136000; x2=64000; y2=136000; stroke=wire; } + ha:text.3 { x1=56000; y1=136000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=in + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.46 { + li:conn { + /2/29/2/1 + /2/45/2 + } + } + ha:group.47 { + uuid=E4wBSbBPnQTyLrlukNMAAABx; src_uuid=E4wBSbBPnQTyLrlukNMAAABt; + x=168000; y=100000; + li:objects { + ha:text.1 { x1=0; y1=-2000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:group.2 { + uuid=E4wBSbBPnQTyLrlukNMAAABy; src_uuid=E4wBSbBPnQTyLrlukNMAAABu; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:group.3 { + uuid=E4wBSbBPnQTyLrlukNMAAABz; src_uuid=E4wBSbBPnQTyLrlukNMAAABv; + x=0; y=4000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.4 { + uuid=E4wBSbBPnQTyLrlukNMAAAB0; src_uuid=E4wBSbBPnQTyLrlukNMAAABw; + x=0; y=8000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=3 + role=terminal + } + } + ha:polygon.5 { + li:outline { + ha:line { x1=0; y1=-2000; x2=0; y2=10000; } + ha:line { x1=0; y1=10000; x2=4000; y2=10000; } + ha:line { x1=4000; y1=10000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=0; y2=-2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + name=CONN2 + role=symbol + } + } + ha:group.48 { + uuid=E4wBSbBPnQTyLrlukNMAAAB1; src_uuid=E4wBSbBPnQTyLrlukNMAAABt; + x=44000; y=132000; mirx=1; + li:objects { + ha:text.1 { x1=0; y1=-2000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:group.2 { + uuid=E4wBSbBPnQTyLrlukNMAAAB2; src_uuid=E4wBSbBPnQTyLrlukNMAAABu; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:group.3 { + uuid=E4wBSbBPnQTyLrlukNMAAAB3; src_uuid=E4wBSbBPnQTyLrlukNMAAABv; + x=0; y=4000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.4 { + uuid=E4wBSbBPnQTyLrlukNMAAAB4; src_uuid=E4wBSbBPnQTyLrlukNMAAABw; + x=0; y=8000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=3 + role=terminal + } + } + ha:polygon.5 { + li:outline { + ha:line { x1=0; y1=-2000; x2=0; y2=10000; } + ha:line { x1=0; y1=10000; x2=4000; y2=10000; } + ha:line { x1=4000; y1=10000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=0; y2=-2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + name=CONN1 + role=symbol + } + } + ha:connection.49 { + li:conn { + /2/45/2 + /2/48/3/1 + } + } + ha:connection.50 { + li:conn { + /2/26/4 + /2/47/3/1 + } + } + ha:group.51 { + uuid=E4wBSbBPnQTyLrlukNMAAAB5; + li:objects { + ha:line.1 { x1=164000; y1=108000; x2=160000; y2=108000; stroke=wire; } + ha:line.2 { x1=160000; y1=108000; x2=160000; y2=116000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.52 { + li:conn { + /2/51/1 + /2/47/4/1 + } + } + ha:group.53 { + uuid=E4wBSbBPnQTyLrlukNMAAAB6; + li:objects { + ha:line.1 { x1=164000; y1=100000; x2=160000; y2=100000; stroke=wire; } + ha:line.2 { x1=160000; y1=100000; x2=160000; y2=92000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.54 { + li:conn { + /2/53/1 + /2/47/2/1 + } + } + ha:group.55 { + uuid=E4wBSbBPnQTyLrlukNMAAAB7; + li:objects { + ha:line.1 { x1=48000; y1=140000; x2=52000; y2=140000; stroke=wire; } + ha:line.2 { x1=52000; y1=140000; x2=52000; y2=148000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.56 { + li:conn { + /2/55/1 + /2/48/4/1 + } + } + ha:group.57 { + uuid=E4wBSbBPnQTyLrlukNMAAAB8; + li:objects { + ha:line.1 { x1=48000; y1=132000; x2=52000; y2=132000; stroke=wire; } + ha:line.2 { x1=52000; y1=132000; x2=52000; y2=124000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.58 { + li:conn { + /2/57/1 + /2/48/2/1 + } + } + ha:group.59 { + uuid=E4wBSbBPnQTyLrlukNMAAAB/; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=52000; y=124000; + li:objects { + ha:group.1 { + uuid=E4wBSbBPnQTyLrlukNMAAACA; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:connection.60 { + li:conn { + /2/59/1/1 + /2/57/2 + } + } + ha:group.61 { + uuid=E4wBSbBPnQTyLrlukNMAAACB; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=160000; y=92000; + li:objects { + ha:group.1 { + uuid=E4wBSbBPnQTyLrlukNMAAACC; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:connection.62 { + li:conn { + /2/61/1/1 + /2/53/2 + } + } + ha:group.63 { + uuid=E4wBSbBPnQTyLrlukNMAAACF; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB6; + x=160000; y=116000; + li:objects { + ha:group.1 { + uuid=E4wBSbBPnQTyLrlukNMAAACG; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB7; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-4000; y1=4000; x2=4000; y2=7000; halign=center; dyntext=0; stroke=sym-primary; text=Vcc; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:Vcc} + } + role=symbol + } + } + ha:connection.64 { + li:conn { + /2/63/1/1 + /2/51/2 + } + } + ha:group.65 { + uuid=E4wBSbBPnQTyLrlukNMAAACH; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB6; + x=52000; y=148000; + li:objects { + ha:group.1 { + uuid=E4wBSbBPnQTyLrlukNMAAACI; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB7; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-4000; y1=4000; x2=4000; y2=7000; halign=center; dyntext=0; stroke=sym-primary; text=Vcc; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:Vcc} + } + role=symbol + } + } + ha:connection.66 { + li:conn { + /2/65/1/1 + /2/55/2 + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer=Tibor 'Igor2' Palinkas + page=1 of 1 + print_page=A/4 + title=DNP (do not populate) component U1 example + } + } +} Index: tags/1.0.5/doc/examples/funcmap/fmexample.rs =================================================================== --- tags/1.0.5/doc/examples/funcmap/fmexample.rs (nonexistent) +++ tags/1.0.5/doc/examples/funcmap/fmexample.rs (revision 10414) @@ -0,0 +1,378 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + ha:group.1 { + uuid=9zxyxUYSJTIZuLJrNpIAAAAv; + li:objects { + ha:group.1 { + uuid=9zxyxUYSJTIZuLJrNpIAAAAw; loclib_name=attiny24; + li:objects { + } + ha:attrib { + li:funcmap/ports { + { PB0/PB0 -> sigtype=digital; } + { PB0/PCINT8 -> sigtype=digital; dir=input } + { PB0/XTAL1 -> sigtype=analog; } + { PB1/PB1 -> sigtype=digital; } + { PB1/PCINT9 -> sigtype=digital; dir=input } + { PB1/XTAL2 -> sigtype=analog; } + { PB3/PB3 -> sigtype=digital; } + { PB3/PCINT11 -> sigtype=digital; dir=input } + { PB3/RESET -> sigtype=digital; dir=input } + { PB2/PB2 -> sigtype=digital; } + { PB2/PCINT10 -> sigtype=digital; dir=input } + { PB2/OC0A -> sigtype=digital; dir=output } + { PB2/INT0 -> sigtype=digital; dir=input } + { PA7/PA7 -> sigtype=digital; } + { PA7/PCINT7 -> sigtype=digital; dir=input } + { PA7/OC0B -> sigtype=digital; dir=output } + { PA7/ADC7 -> sigtype=digital; dir=input } + { PA6/PA6 -> sigtype=digital; } + { PA6/PCINT6 -> sigtype=digital; dir=input } + { PA6/MOSI -> sigtype=digital; } + { PA6/DI -> sigtype=digital; dir=input } + { PA6/SDA -> sigtype=digital; } + { PA6/OC1A -> sigtype=digital; dir=output } + { PA6/ADC6 -> sigtype=analog; dir=input } + { PA0/PA0 -> sigtype=digital; } + { PA0/PCINT0 -> sigtype=digital; dir=input } + { PA0/AREF+ADC0-> sigtype=analog; dir=input } + { PA1/PA1 -> sigtype=digital; } + { PA1/PCINT1 -> sigtype=digital; dir=input } + { PA1/AIN0 -> sigtype=analog; dir=input } + { PA1/ADC1 -> sigtype=analog; dir=input } + { PA2/PA2 -> sigtype=digital; } + { PA2/PCINT2 -> sigtype=digital; dir=input } + { PA2/AIN1 -> sigtype=analog; dir=input } + { PA2/ADC2 -> sigtype=analog; dir=input } + { PA3/PA3 -> sigtype=digital; } + { PA3/PCINT3 -> sigtype=digital; dir=input } + { PA3/ADC3 -> sigtype=analog; dir=input } + { PA4/PA4 -> sigtype=digital; } + { PA4/PCINT4 -> sigtype=digital; dir=input } + { PA4/SCK -> sigtype=digital; } + { PA4/SCL -> sigtype=digital; } + { PA4/ADC4 -> sigtype=analog; dir=input } + { PA5/PA5 -> sigtype=digital; } + { PA5/PCINT5 -> sigtype=digital; dir=input } + { PA5/MISO -> sigtype=digital; } + { PA5/DO -> sigtype=digital; dir=output } + { PA5/OC1B -> sigtype=digital; dir=output } + { PA5/ADC5 -> sigtype=analog; dir=input } + } + li:funcmap/strong_groups { + { SPI -> SCK, MISO, MOSI } + { I2C -> SDA, SCL } + { USI -> SCK, DI, DO } + } + li:funcmap/weak_groups { + { gpio -> PB0, PB1, PB2, PB3, PA6, PA7, PA0, PA1, PA2, PA3, PA4, PA5 } + { pcint -> PCINT8, PCINT9, PCINT11, PCINT10, PCINT7, PCINT6, PCINT0, PCINT1, PCINT2, PCINT3, PCINT4, PCINT5 } + { xtal -> XTAL1, XTAL2 } + { PWM -> OC0A, OC0B, OC1A, OC1B } + { adc -> AREF+ADC0, ADC1, ADC2, ADC3, ADC4, ADC5, ADC6, ADC7 } + { comparator -> AIN0, AIN1 } + } + } + } + } + ha:attrib { + ha:purpose = { value=funcmap; prio=0; } + } + } + } + } + ha:obj_direct.2 { + uuid=JkQTZjOhkCU1+/zzmokAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.1 { + uuid=8/SYZ/pfBzxyqFA12WQAAAAC; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAg; + li:objects { + ha:polygon.11 { + li:outline { + ha:line { x1=0; y1=0; x2=80000; y2=0; } + ha:line { x1=80000; y1=0; x2=80000; y2=20000; } + ha:line { x1=80000; y1=20000; x2=0; y2=20000; } + ha:line { x1=0; y1=20000; x2=0; y2=0; } + } + stroke=titlebox-frame; + fill=titlebox-fill; + } + ha:line.12 { x1=0; y1=10000; x2=80000; y2=10000; stroke=titlebox-frame; } + ha:line.13 { x1=40000; y1=10000; x2=40000; y2=0; stroke=titlebox-frame; } + ha:text.20 { x1=1000; y1=16500; dyntext=0; stroke=titlebox-big; text=TITLE; } + ha:text.21 { x1=1000; y1=10500; x2=79000; y2=16000; dyntext=1; stroke=titlebox-big; text=%../../A.title%; } + ha:text.22 { x1=1000; y1=5500; dyntext=0; stroke=titlebox-small; text={PROJECT:}; } + ha:text.23 { x1=13000; y1=5500; x2=39000; y2=9500; dyntext=1; stroke=titlebox-big; text=%project.name%; } + ha:text.24 { x1=1000; y1=500; dyntext=0; stroke=titlebox-small; text={PAGE:}; } + ha:text.25 { x1=10000; y1=500; x2=39000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.page%; } + ha:text.26 { x1=41000; y1=5500; dyntext=0; stroke=titlebox-small; text={FILE:}; } + ha:text.27 { x1=48000; y1=5500; x2=79000; y2=9500; dyntext=1; stroke=titlebox-big; text=%filename%; } + ha:text.28 { x1=41000; y1=500; dyntext=0; stroke=titlebox-small; text={MAINTAINER:}; } + ha:text.29 { x1=55000; y1=500; x2=79000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.maintainer%; } + ha:text.30 { x1=79000; y1=16000; mirx=1; dyntext=1; stroke=sheet-decor; text=%stance.model% %stance.sub_major% %stance.sub_minor% %stance.test_bench% %view.name%; } + } + ha:attrib { + purpose=titlebox + } + } + ha:group.2 { + uuid=9zxyxUYSJTIZuLJrNpIAAAAg; src_uuid=39wCeHrJAKAVyPyQU3EAAAAP; + x=76000; y=56000; + li:objects { + ha:text.1 { x1=-8000; y1=-4000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.2 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=32000; } + ha:line { x1=0; y1=32000; x2=16000; y2=32000; } + ha:line { x1=16000; y1=32000; x2=16000; y2=0; } + ha:line { x1=16000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + } + ha:group.3 { + uuid=9zxyxUYSJTIZuLJrNpIAAAAh; src_uuid=39wCeHrJAKAVyPyQU3EAAAAB; + x=0; y=28000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../A.name%; } + } + ha:attrib { + name=Vcc + pinnum=1 + role=terminal + } + } + ha:group.4 { + uuid=9zxyxUYSJTIZuLJrNpIAAAAi; src_uuid=39wCeHrJAKAVyPyQU3EAAAAC; + x=0; y=24000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PB0 + pinnum=2 + role=terminal + } + } + ha:group.5 { + uuid=9zxyxUYSJTIZuLJrNpIAAAAj; src_uuid=39wCeHrJAKAVyPyQU3EAAAAD; + x=0; y=20000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PB1 + pinnum=3 + role=terminal + } + } + ha:group.6 { + uuid=9zxyxUYSJTIZuLJrNpIAAAAk; src_uuid=39wCeHrJAKAVyPyQU3EAAAAE; + x=0; y=16000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PB3 + pinnum=4 + role=terminal + } + } + ha:group.7 { + uuid=9zxyxUYSJTIZuLJrNpIAAAAl; src_uuid=39wCeHrJAKAVyPyQU3EAAAAF; + x=0; y=12000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PB2 + pinnum=5 + role=terminal + } + } + ha:group.8 { + uuid=9zxyxUYSJTIZuLJrNpIAAAAm; src_uuid=39wCeHrJAKAVyPyQU3EAAAAG; + x=0; y=8000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PA7 + pinnum=6 + role=terminal + } + } + ha:group.9 { + uuid=9zxyxUYSJTIZuLJrNpIAAAAn; src_uuid=39wCeHrJAKAVyPyQU3EAAAAH; + x=0; y=4000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PA6 + pinnum=7 + role=terminal + } + } + ha:group.10 { + uuid=9zxyxUYSJTIZuLJrNpIAAAAo; src_uuid=39wCeHrJAKAVyPyQU3EAAAAI; + x=16000; y=28000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../A.name%; } + } + ha:attrib { + name=GND + pinnum=14 + role=terminal + } + } + ha:group.11 { + uuid=9zxyxUYSJTIZuLJrNpIAAAAp; src_uuid=39wCeHrJAKAVyPyQU3EAAAAJ; + x=16000; y=24000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PA0 + pinnum=13 + role=terminal + } + } + ha:group.12 { + uuid=9zxyxUYSJTIZuLJrNpIAAAAq; src_uuid=39wCeHrJAKAVyPyQU3EAAAAK; + x=16000; y=20000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PA1 + pinnum=12 + role=terminal + } + } + ha:group.13 { + uuid=9zxyxUYSJTIZuLJrNpIAAAAr; src_uuid=39wCeHrJAKAVyPyQU3EAAAAL; + x=16000; y=16000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PA2 + pinnum=11 + role=terminal + } + } + ha:group.14 { + uuid=9zxyxUYSJTIZuLJrNpIAAAAs; src_uuid=39wCeHrJAKAVyPyQU3EAAAAM; + x=16000; y=12000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PA3 + pinnum=10 + role=terminal + } + } + ha:group.15 { + uuid=9zxyxUYSJTIZuLJrNpIAAAAt; src_uuid=39wCeHrJAKAVyPyQU3EAAAAN; + x=16000; y=8000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PA4 + pinnum=9 + role=terminal + } + } + ha:group.16 { + uuid=9zxyxUYSJTIZuLJrNpIAAAAu; src_uuid=39wCeHrJAKAVyPyQU3EAAAAO; + x=16000; y=4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + funcmap/name=MISO + name=PA5 + pinnum=8 + role=terminal + } + } + ha:text.18 { x1=-8000; y1=-8000; dyntext=1; stroke=sym-secondary; text=%../A.device%; floater=1; } + } + ha:attrib { + -symbol-generator=boxsym-rnd + device=attiny24 + funcmap=attiny24 + name=U1 + role=symbol + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer=Tibor 'Igor2' Palinkas + page=1/1 + print_page=A/4 + title=sch-rnd funcmap example + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 2 + grid = 4.0960 mm + } + } + } +} Index: tags/1.0.5/doc/examples/funcmap/funcmap/attiny24.funcmap =================================================================== --- tags/1.0.5/doc/examples/funcmap/funcmap/attiny24.funcmap (nonexistent) +++ tags/1.0.5/doc/examples/funcmap/funcmap/attiny24.funcmap (revision 10414) @@ -0,0 +1,83 @@ +ha:funcmap.v1 { + ha:comp_attribs { + li:funcmap/ports { + { PB0/PB0 -> sigtype=digital; } + { PB0/PCINT8 -> sigtype=digital; dir=input } + { PB0/XTAL1 -> sigtype=analog; } + + { PB1/PB1 -> sigtype=digital; } + { PB1/PCINT9 -> sigtype=digital; dir=input } + { PB1/XTAL2 -> sigtype=analog; } + + { PB3/PB3 -> sigtype=digital; } + { PB3/PCINT11 -> sigtype=digital; dir=input } + { PB3/RESET -> sigtype=digital; dir=input } + + { PB2/PB2 -> sigtype=digital; } + { PB2/PCINT10 -> sigtype=digital; dir=input } + { PB2/OC0A -> sigtype=digital; dir=output } + { PB2/INT0 -> sigtype=digital; dir=input } + + { PA7/PA7 -> sigtype=digital; } + { PA7/PCINT7 -> sigtype=digital; dir=input } + { PA7/OC0B -> sigtype=digital; dir=output } + { PA7/ADC7 -> sigtype=digital; dir=input } + + { PA6/PA6 -> sigtype=digital; } + { PA6/PCINT6 -> sigtype=digital; dir=input } + { PA6/MOSI -> sigtype=digital; } + { PA6/DI -> sigtype=digital; dir=input } + { PA6/SDA -> sigtype=digital; } + { PA6/OC1A -> sigtype=digital; dir=output } + { PA6/ADC6 -> sigtype=analog; dir=input } + + { PA0/PA0 -> sigtype=digital; } + { PA0/PCINT0 -> sigtype=digital; dir=input } + { PA0/AREF+ADC0-> sigtype=analog; dir=input } + + { PA1/PA1 -> sigtype=digital; } + { PA1/PCINT1 -> sigtype=digital; dir=input } + { PA1/AIN0 -> sigtype=analog; dir=input } + { PA1/ADC1 -> sigtype=analog; dir=input } + + { PA2/PA2 -> sigtype=digital; } + { PA2/PCINT2 -> sigtype=digital; dir=input } + { PA2/AIN1 -> sigtype=analog; dir=input } + { PA2/ADC2 -> sigtype=analog; dir=input } + + { PA3/PA3 -> sigtype=digital; } + { PA3/PCINT3 -> sigtype=digital; dir=input } + { PA3/ADC3 -> sigtype=analog; dir=input } + + { PA4/PA4 -> sigtype=digital; } + { PA4/PCINT4 -> sigtype=digital; dir=input } + { PA4/SCK -> sigtype=digital; } + { PA4/SCL -> sigtype=digital; } + { PA4/ADC4 -> sigtype=analog; dir=input } + + { PA5/PA5 -> sigtype=digital; } + { PA5/PCINT5 -> sigtype=digital; dir=input } + { PA5/MISO -> sigtype=digital; } + { PA5/DO -> sigtype=digital; dir=output } + { PA5/OC1B -> sigtype=digital; dir=output } + { PA5/ADC5 -> sigtype=analog; dir=input } + } + + # sorting for display + li:funcmap/weak_groups { + { gpio -> PB0, PB1, PB2, PB3, PA6, PA7, PA0, PA1, PA2, PA3, PA4, PA5 } + { pcint -> PCINT8, PCINT9, PCINT11, PCINT10, PCINT7, PCINT6, PCINT0, PCINT1, PCINT2, PCINT3, PCINT4, PCINT5 } + { xtal -> XTAL1, XTAL2 } + { PWM -> OC0A, OC0B, OC1A, OC1B } + { adc -> AREF+ADC0, ADC1, ADC2, ADC3, ADC4, ADC5, ADC6, ADC7 } + { comparator -> AIN0, AIN1 } + } + + # have to be selected all at once + li:funcmap/strong_groups { + { SPI -> SCK, MISO, MOSI } + { I2C -> SDA, SCL } + { USI -> SCK, DI, DO } + } + } +} Index: tags/1.0.5/doc/examples/funcmap/symbol/attiny24.bs =================================================================== --- tags/1.0.5/doc/examples/funcmap/symbol/attiny24.bs (nonexistent) +++ tags/1.0.5/doc/examples/funcmap/symbol/attiny24.bs (revision 10414) @@ -0,0 +1,94 @@ +refdes U?? + +pinalign left center +pinalign right center +attr device attiny24 +attr funcmap attiny24 +text_size_mult 0.7 + +shape box + +begin pin Vcc + num 1 + loc left +end pin + +begin pin PB0 + num 2 + loc left + funcmap +end pin + +begin pin PB1 + num 3 + loc left + funcmap +end pin + +begin pin PB3 + num 4 + loc left + funcmap +end pin + +begin pin PB2 + num 5 + loc left + funcmap +end pin + +begin pin PA7 + num 6 + loc left + funcmap +end pin + +begin pin PA6 + num 7 + loc left + funcmap +end pin + + + +begin pin GND + num 14 + loc right +end pin + +begin pin PA0 + num 13 + loc right + funcmap +end pin + +begin pin PA1 + num 12 + loc right + funcmap +end pin + +begin pin PA2 + num 11 + loc right + funcmap +end pin + +begin pin PA3 + num 10 + loc right + funcmap +end pin + +begin pin PA4 + num 9 + loc right + funcmap +end pin + +begin pin PA5 + num 8 + loc right + funcmap +end pin + Index: tags/1.0.5/doc/examples/funcmap/symbol/attiny24.ry =================================================================== --- tags/1.0.5/doc/examples/funcmap/symbol/attiny24.ry (nonexistent) +++ tags/1.0.5/doc/examples/funcmap/symbol/attiny24.ry (revision 10414) @@ -0,0 +1,229 @@ +ha:cschem-group-v1 { + ha:group.1 { + uuid=39wCeHrJAKAVyPyQU3EAAAAP; + li:objects { + ha:text.1 { x1=-8000; y1=-4000; rot=0; stroke=sym-primary; dyntext=1; floater=1; text={%../A.name%}; } + ha:polygon.2 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=32000; stroke=sym-decor; } + ha:line { x1=0; y1=32000; x2=16000; y2=32000; stroke=sym-decor; } + ha:line { x1=16000; y1=32000; x2=16000; y2=0; stroke=sym-decor; } + ha:line { x1=16000; y1=0; x2=0; y2=0; stroke=sym-decor; } + } + stroke=sym-decor + } + ha:group.3 { + uuid=39wCeHrJAKAVyPyQU3EAAAAB; + x=0; y=28000; + rot=0; mirx=1; miry=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; rot=0; stroke=term-primary; dyntext=1; text={%../a.display/name%}; } + ha:text.3 { x1=-500; y1=-2000; rot=0; mirx=1; stroke=term-secondary; dyntext=1; text={%../A.name%}; } + } + ha:attrib { + role=terminal; + pinnum=1; + name=Vcc; + } + } + ha:group.4 { + uuid=39wCeHrJAKAVyPyQU3EAAAAC; + x=0; y=24000; + rot=0; mirx=1; miry=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; rot=0; stroke=term-primary; dyntext=1; text={%../a.display/name%}; } + ha:text.3 { x1=-500; y1=-2000; rot=0; mirx=1; stroke=term-secondary; dyntext=1; text={%../a.funcmap/name%}; } + } + ha:attrib { + role=terminal; + pinnum=2; + name=PB0; + } + } + ha:group.5 { + uuid=39wCeHrJAKAVyPyQU3EAAAAD; + x=0; y=20000; + rot=0; mirx=1; miry=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; rot=0; stroke=term-primary; dyntext=1; text={%../a.display/name%}; } + ha:text.3 { x1=-500; y1=-2000; rot=0; mirx=1; stroke=term-secondary; dyntext=1; text={%../a.funcmap/name%}; } + } + ha:attrib { + role=terminal; + pinnum=3; + name=PB1; + } + } + ha:group.6 { + uuid=39wCeHrJAKAVyPyQU3EAAAAE; + x=0; y=16000; + rot=0; mirx=1; miry=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; rot=0; stroke=term-primary; dyntext=1; text={%../a.display/name%}; } + ha:text.3 { x1=-500; y1=-2000; rot=0; mirx=1; stroke=term-secondary; dyntext=1; text={%../a.funcmap/name%}; } + } + ha:attrib { + role=terminal; + pinnum=4; + name=PB3; + } + } + ha:group.7 { + uuid=39wCeHrJAKAVyPyQU3EAAAAF; + x=0; y=12000; + rot=0; mirx=1; miry=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; rot=0; stroke=term-primary; dyntext=1; text={%../a.display/name%}; } + ha:text.3 { x1=-500; y1=-2000; rot=0; mirx=1; stroke=term-secondary; dyntext=1; text={%../a.funcmap/name%}; } + } + ha:attrib { + role=terminal; + pinnum=5; + name=PB2; + } + } + ha:group.8 { + uuid=39wCeHrJAKAVyPyQU3EAAAAG; + x=0; y=8000; + rot=0; mirx=1; miry=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; rot=0; stroke=term-primary; dyntext=1; text={%../a.display/name%}; } + ha:text.3 { x1=-500; y1=-2000; rot=0; mirx=1; stroke=term-secondary; dyntext=1; text={%../a.funcmap/name%}; } + } + ha:attrib { + role=terminal; + pinnum=6; + name=PA7; + } + } + ha:group.9 { + uuid=39wCeHrJAKAVyPyQU3EAAAAH; + x=0; y=4000; + rot=0; mirx=1; miry=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; rot=0; stroke=term-primary; dyntext=1; text={%../a.display/name%}; } + ha:text.3 { x1=-500; y1=-2000; rot=0; mirx=1; stroke=term-secondary; dyntext=1; text={%../a.funcmap/name%}; } + } + ha:attrib { + role=terminal; + pinnum=7; + name=PA6; + } + } + ha:group.10 { + uuid=39wCeHrJAKAVyPyQU3EAAAAI; + x=16000; y=28000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; rot=0; stroke=term-primary; dyntext=1; text={%../a.display/name%}; } + ha:text.3 { x1=-500; y1=-2000; rot=0; mirx=1; stroke=term-secondary; dyntext=1; text={%../A.name%}; } + } + ha:attrib { + role=terminal; + pinnum=14; + name=GND; + } + } + ha:group.11 { + uuid=39wCeHrJAKAVyPyQU3EAAAAJ; + x=16000; y=24000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; rot=0; stroke=term-primary; dyntext=1; text={%../a.display/name%}; } + ha:text.3 { x1=-500; y1=-2000; rot=0; mirx=1; stroke=term-secondary; dyntext=1; text={%../a.funcmap/name%}; } + } + ha:attrib { + role=terminal; + pinnum=13; + name=PA0; + } + } + ha:group.12 { + uuid=39wCeHrJAKAVyPyQU3EAAAAK; + x=16000; y=20000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; rot=0; stroke=term-primary; dyntext=1; text={%../a.display/name%}; } + ha:text.3 { x1=-500; y1=-2000; rot=0; mirx=1; stroke=term-secondary; dyntext=1; text={%../a.funcmap/name%}; } + } + ha:attrib { + role=terminal; + pinnum=12; + name=PA1; + } + } + ha:group.13 { + uuid=39wCeHrJAKAVyPyQU3EAAAAL; + x=16000; y=16000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; rot=0; stroke=term-primary; dyntext=1; text={%../a.display/name%}; } + ha:text.3 { x1=-500; y1=-2000; rot=0; mirx=1; stroke=term-secondary; dyntext=1; text={%../a.funcmap/name%}; } + } + ha:attrib { + role=terminal; + pinnum=11; + name=PA2; + } + } + ha:group.14 { + uuid=39wCeHrJAKAVyPyQU3EAAAAM; + x=16000; y=12000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; rot=0; stroke=term-primary; dyntext=1; text={%../a.display/name%}; } + ha:text.3 { x1=-500; y1=-2000; rot=0; mirx=1; stroke=term-secondary; dyntext=1; text={%../a.funcmap/name%}; } + } + ha:attrib { + role=terminal; + pinnum=10; + name=PA3; + } + } + ha:group.15 { + uuid=39wCeHrJAKAVyPyQU3EAAAAN; + x=16000; y=8000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; rot=0; stroke=term-primary; dyntext=1; text={%../a.display/name%}; } + ha:text.3 { x1=-500; y1=-2000; rot=0; mirx=1; stroke=term-secondary; dyntext=1; text={%../a.funcmap/name%}; } + } + ha:attrib { + role=terminal; + pinnum=9; + name=PA4; + } + } + ha:group.16 { + uuid=39wCeHrJAKAVyPyQU3EAAAAO; + x=16000; y=4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; rot=0; stroke=term-primary; dyntext=1; text={%../a.display/name%}; } + ha:text.3 { x1=-500; y1=-2000; rot=0; mirx=1; stroke=term-secondary; dyntext=1; text={%../a.funcmap/name%}; } + } + ha:attrib { + role=terminal; + pinnum=8; + name=PA5; + } + } + ha:text.17 { x1=-8000; y1=-8000; rot=0; stroke=sym-secondary; dyntext=1; floater=1; text={%../A.funcmap%}; } + ha:text.18 { x1=-8000; y1=-12000; rot=0; stroke=sym-secondary; dyntext=1; floater=1; text={%../A.device%}; } + } + ha:attrib { + role=symbol; + name={U?}; + -symbol-generator=boxsym-rnd; + funcmap=attiny24; + device=attiny24; + } + } +} Index: tags/1.0.5/doc/examples/hierarchic/10_cpu/10_cpu.tdx =================================================================== --- tags/1.0.5/doc/examples/hierarchic/10_cpu/10_cpu.tdx (nonexistent) +++ tags/1.0.5/doc/examples/hierarchic/10_cpu/10_cpu.tdx (revision 10414) @@ -0,0 +1,216 @@ +tEDAx v1 +begin netlist v1 +footprint CN1 connecto(6,1) +pinname CN1 3 3 +pinname CN1 4 4 +pinname CN1 5 5 +pinname CN1 6 6 +pinname CN1 1 1 +pinname CN1 2 2 +footprint R101 1206 +value R101 1k +device R101 resistor +pinname R101 1 1 +pinname R101 2 2 +footprint R102 1206 +value R102 1k +device R102 resistor +pinname R102 1 1 +pinname R102 2 2 +footprint R103 1206 +value R103 1k +device R103 resistor +pinname R103 1 1 +pinname R103 2 2 +footprint Q102 SOT23 +device Q102 2n7002 +pinname Q102 2 S +pinname Q102 3 D +pinname Q102 1 G +footprint Q103 SOT23 +device Q103 2n7002 +pinname Q103 2 S +pinname Q103 3 D +pinname Q103 1 G +pinname U301 3 out +pinname U301 1 in +pinname U301 2 gnd +value R301 510 +device R301 resistor +pinname R301 1 1 +pinname R301 2 2 +footprint D201 minimelf +device D201 1n4148 +pinname D201 1 C +pinname D201 2 A +footprint D202 minimelf +device D202 1n4148 +pinname D202 1 C +pinname D202 2 A +footprint D211 minimelf +device D211 1n4148 +pinname D211 1 C +pinname D211 2 A +footprint D212 minimelf +device D212 1n4148 +pinname D212 1 C +pinname D212 2 A +footprint U1 dip(20) +pinname U1 12 rx1 +pinname U1 17 rx2 +pinname U1 10 col1 +pinname U1 11 col2 +pinname U1 15 col3 +pinname U1 16 col4 +pinname U1 1 Vcc +pinname U1 6 row1 +pinname U1 7 row2 +pinname U1 9 row3 +pinname U1 8 row4 +pinname U1 13 tx1 +pinname U1 18 tx2 +pinname U1 2 Vss +footprint D221 minimelf +device D221 1n4148 +pinname D221 1 C +pinname D221 2 A +footprint SW201 dip(6) +pinname SW201 1 1 +pinname SW201 2 2 +footprint SW202 dip(6) +pinname SW202 1 1 +pinname SW202 2 2 +footprint SW203 dip(6) +pinname SW203 1 1 +pinname SW203 2 2 +footprint D222 minimelf +device D222 1n4148 +pinname D222 1 C +pinname D222 2 A +footprint D223 minimelf +device D223 1n4148 +pinname D223 1 C +pinname D223 2 A +footprint SW211 dip(6) +pinname SW211 1 1 +pinname SW211 2 2 +footprint SW212 dip(6) +pinname SW212 1 1 +pinname SW212 2 2 +footprint SW213 dip(6) +pinname SW213 1 1 +pinname SW213 2 2 +footprint D213 minimelf +device D213 1n4148 +pinname D213 1 C +pinname D213 2 A +footprint D203 minimelf +device D203 1n4148 +pinname D203 1 C +pinname D203 2 A +footprint SW221 dip(6) +pinname SW221 1 1 +pinname SW221 2 2 +footprint SW222 dip(6) +pinname SW222 1 1 +pinname SW222 2 2 +footprint SW223 dip(6) +pinname SW223 1 1 +pinname SW223 2 2 +value C301 10u +device C301 capacitor +pinname C301 N N +pinname C301 P P +value C302 100n +device C302 capacitor +pinname C302 1 1 +pinname C302 2 2 +value C303 100n +device C303 capacitor +pinname C303 1 1 +pinname C303 2 2 +footprint D301 LED5 +device D301 led5 +pinname D301 1 C +pinname D301 2 A +conn readout_tx R102 1 +conn readout_tx Q102 3 +conn readout_tx CN1 3 +conn Vcc C303 1 +conn Vcc R301 1 +conn Vcc U301 3 +conn Vcc U1 1 +conn Vcc R102 2 +conn Vcc R103 2 +conn GND CN1 1 +conn GND U301 2 +conn GND U1 2 +conn GND C302 2 +conn GND D301 1 +conn GND C301 N +conn GND C303 2 +conn GND Q102 2 +conn GND Q103 2 +conn anon_net_10 R103 1 +conn anon_net_10 Q103 3 +conn anon_net_10 U1 17 +conn anon_net_12 D201 2 +conn anon_net_12 SW201 1 +conn anon_net_13 D211 2 +conn anon_net_13 SW211 1 +conn anon_net_14 D221 2 +conn anon_net_14 SW221 1 +conn anon_net_15 D202 2 +conn anon_net_15 SW202 1 +conn anon_net_16 D212 2 +conn anon_net_16 SW212 1 +conn anon_net_17 D222 2 +conn anon_net_17 SW222 1 +conn anon_net_18 D203 2 +conn anon_net_18 SW203 1 +conn anon_net_19 D213 2 +conn anon_net_19 SW213 1 +conn anon_net_22 D222 1 +conn anon_net_22 D212 1 +conn anon_net_22 D202 1 +conn anon_net_22 U1 7 +conn anon_net_20 D223 2 +conn anon_net_20 SW223 1 +conn anon_net_21 D221 1 +conn anon_net_21 D211 1 +conn anon_net_21 D201 1 +conn anon_net_21 U1 6 +conn anon_net_25 SW211 2 +conn anon_net_25 SW213 2 +conn anon_net_25 SW212 2 +conn anon_net_25 U1 11 +conn anon_net_23 D223 1 +conn anon_net_23 D213 1 +conn anon_net_23 D203 1 +conn anon_net_23 U1 9 +conn anon_net_24 SW201 2 +conn anon_net_24 SW203 2 +conn anon_net_24 SW202 2 +conn anon_net_24 U1 10 +conn anon_net_26 SW221 2 +conn anon_net_26 SW223 2 +conn anon_net_26 SW222 2 +conn anon_net_26 U1 15 +conn anon_net_1 R101 1 +conn anon_net_1 U1 13 +conn anon_net_6 Q102 1 +conn anon_net_6 U1 18 +conn anon_net_32 R301 2 +conn anon_net_32 D301 2 +conn terminal_rx U1 12 +conn terminal_rx CN1 6 +conn terminal_tx R101 2 +conn terminal_tx CN1 5 +conn V12_dc C302 1 +conn V12_dc U301 1 +conn V12_dc C301 P +conn V12_dc CN1 2 +conn readout_rx Q103 1 +conn readout_rx CN1 4 +end netlist + Index: tags/1.0.5/doc/examples/hierarchic/10_cpu/button_mx.rs =================================================================== --- tags/1.0.5/doc/examples/hierarchic/10_cpu/button_mx.rs (nonexistent) +++ tags/1.0.5/doc/examples/hierarchic/10_cpu/button_mx.rs (revision 10414) @@ -0,0 +1,1580 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + ha:group.1 { + uuid=GOjvawM2mgwjKV+ohqMAAAAr; + li:objects { + ha:group.1 { + uuid=GOjvawM2mgwjKV+ohqMAAAAs; loclib_name=2n7002_sot23; + li:objects { + } + ha:attrib { + device=2n7002 + footprint=SOT23 + li:portmap { + {G->pcb/pinnum=1} + {S->pcb/pinnum=2} + {D->pcb/pinnum=3} + } + } + } + ha:group.2 { + uuid=Zj+oUtIHRUPA2aMj1qcAAAC0; loclib_name=1n4148_minimelf; + li:objects { + } + ha:attrib { + device=1n4148 + footprint=minimelf + li:portmap { + {C->pcb/pinnum=1} + {A->pcb/pinnum=2} + } + } + } + } + ha:attrib { + ha:purpose = { value=devmap; prio=0; } + } + } + } + } + ha:obj_direct.2 { + uuid=GOjvawM2mgwjKV+ohqMAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.1 { + uuid=8/SYZ/pfBzxyqFA12WQAAAAC; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAg; + li:objects { + ha:polygon.11 { + li:outline { + ha:line { x1=0; y1=0; x2=80000; y2=0; } + ha:line { x1=80000; y1=0; x2=80000; y2=20000; } + ha:line { x1=80000; y1=20000; x2=0; y2=20000; } + ha:line { x1=0; y1=20000; x2=0; y2=0; } + } + stroke=titlebox-frame; + fill=titlebox-fill; + } + ha:line.12 { x1=0; y1=10000; x2=80000; y2=10000; stroke=titlebox-frame; } + ha:line.13 { x1=40000; y1=10000; x2=40000; y2=0; stroke=titlebox-frame; } + ha:text.20 { x1=1000; y1=16500; dyntext=0; stroke=titlebox-big; text=TITLE; } + ha:text.21 { x1=1000; y1=10500; x2=79000; y2=16000; dyntext=1; stroke=titlebox-big; text=%../../A.title%; } + ha:text.22 { x1=1000; y1=5500; dyntext=0; stroke=titlebox-small; text={PROJECT:}; } + ha:text.23 { x1=13000; y1=5500; x2=39000; y2=9500; dyntext=1; stroke=titlebox-big; text=%project.name%; } + ha:text.24 { x1=1000; y1=500; dyntext=0; stroke=titlebox-small; text={PAGE:}; } + ha:text.25 { x1=10000; y1=500; x2=39000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.page%; } + ha:text.26 { x1=41000; y1=5500; dyntext=0; stroke=titlebox-small; text={FILE:}; } + ha:text.27 { x1=48000; y1=5500; x2=79000; y2=9500; dyntext=1; stroke=titlebox-big; text=%filename%; } + ha:text.28 { x1=41000; y1=500; dyntext=0; stroke=titlebox-small; text={MAINTAINER:}; } + ha:text.29 { x1=55000; y1=500; x2=79000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.maintainer%; } + ha:text.30 { x1=79000; y1=16000; mirx=1; dyntext=1; stroke=sheet-decor; text=%stance.model% %stance.sub_major% %stance.sub_minor% %stance.test_bench% %view.name%; } + } + ha:attrib { + purpose=titlebox + } + } + ha:group.91 { + uuid=Zj+oUtIHRUPA2aMj1qcAAAA9; + x=76000; y=156000; + li:objects { + ha:group.1 { + uuid=Zj+oUtIHRUPA2aMj1qcAAAA+; src_uuid=GOjvawM2mgwjKV+ohqMAAAAD; + x=20000; y=-12000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=row3 + pinnum=9 + role=terminal + } + } + ha:group.2 { + uuid=Zj+oUtIHRUPA2aMj1qcAAAA/; src_uuid=GOjvawM2mgwjKV+ohqMAAAAD; + x=20000; y=-16000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=row4 + pinnum=8 + role=terminal + } + } + ha:group.3 { + uuid=Zj+oUtIHRUPA2aMj1qcAAABA; src_uuid=GOjvawM2mgwjKV+ohqMAAAAD; + x=20000; y=-24000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=col1 + pinnum=10 + role=terminal + } + } + ha:group.4 { + uuid=Zj+oUtIHRUPA2aMj1qcAAABB; src_uuid=GOjvawM2mgwjKV+ohqMAAAAD; + x=20000; y=-28000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=col2 + pinnum=11 + role=terminal + } + } + ha:polygon.5 { + li:outline { + ha:line { x1=16000; y1=0; x2=16000; y2=-40000; } + ha:line { x1=16000; y1=-40000; x2=0; y2=-40000; } + ha:line { x1=0; y1=-40000; x2=0; y2=0; } + ha:line { x1=0; y1=0; x2=16000; y2=0; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + ha:group.6 { + uuid=Zj+oUtIHRUPA2aMj1qcAAABC; src_uuid=GOjvawM2mgwjKV+ohqMAAAAD; + x=20000; y=-4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=row1 + pinnum=6 + role=terminal + } + } + ha:group.7 { + uuid=Zj+oUtIHRUPA2aMj1qcAAABD; src_uuid=GOjvawM2mgwjKV+ohqMAAAAD; + x=20000; y=-8000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=row2 + pinnum=7 + role=terminal + } + } + ha:group.8 { + uuid=Zj+oUtIHRUPA2aMj1qcAAABE; src_uuid=GOjvawM2mgwjKV+ohqMAAAAD; + x=20000; y=-32000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=col3 + pinnum=15 + role=terminal + } + } + ha:group.9 { + uuid=Zj+oUtIHRUPA2aMj1qcAAABF; src_uuid=GOjvawM2mgwjKV+ohqMAAAAD; + x=20000; y=-36000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=col4 + pinnum=16 + role=terminal + } + } + ha:text.10 { x1=0; y1=0; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + footprint=dip(20) + name=U1 + role=symbol + } + } + ha:group.93 { + uuid=Zj+oUtIHRUPA2aMj1qcAAACf; src_uuid=Zj+oUtIHRUPA2aMj1qcAAACZ; + x=140000; y=180000; + li:objects { + ha:text.1 { x1=6000; y1=-4000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:group.2 { + uuid=Zj+oUtIHRUPA2aMj1qcAAACg; src_uuid=Zj+oUtIHRUPA2aMj1qcAAACa; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.3 { x1=0; y1=0; x2=1200; y2=0; stroke=sym-decor; } + ha:arc.4 { cx=1600; cy=0; r=400; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:group.5 { + uuid=Zj+oUtIHRUPA2aMj1qcAAACh; src_uuid=Zj+oUtIHRUPA2aMj1qcAAACb; + x=8000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:line.6 { x1=6800; y1=0; x2=8000; y2=0; stroke=sym-decor; } + ha:arc.7 { cx=6400; cy=0; r=400; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:line.8 { x1=0; y1=0; x2=0; y2=0; stroke=sym-decor; } + ha:line.9 { x1=0; y1=0; x2=1200; y2=0; stroke=sym-decor; } + ha:arc.10 { cx=1600; cy=0; r=400; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:line.11 { x1=1200; y1=3600; x2=6800; y2=3600; stroke=sym-decor; } + ha:line.12 { x1=1600; y1=8000; x2=6400; y2=8000; stroke=sym-decor; } + ha:line.13 { x1=1600; y1=8000; x2=1600; y2=7200; stroke=sym-decor; } + ha:line.14 { x1=6400; y1=8000; x2=6400; y2=7200; stroke=sym-decor; } + ha:line.15 { x1=4000; y1=3600; x2=4000; y2=8000; stroke=sym-decor; } + } + ha:attrib { + footprint=dip(6) + name=SW201 + role=symbol + spice/omit=yes + } + } + ha:group.95 { + uuid=Zj+oUtIHRUPA2aMj1qcAAACx; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAN; + x=132000; y=176000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=Zj+oUtIHRUPA2aMj1qcAAACy; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAO; + x=16000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=C + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.2 { + uuid=Zj+oUtIHRUPA2aMj1qcAAACz; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAP; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=A + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:text.3 { x1=12000; y1=5000; rot=90.000000; dyntext=1; stroke=sym-secondary; text=%../a.devmap%; floater=1; } + ha:text.4 { x1=8000; y1=5000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.5 { x1=12000; y1=0; x2=10000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=4000; y1=0; x2=6000; y2=0; stroke=sym-decor; } + ha:line.7 { x1=6000; y1=4000; x2=10000; y2=0; stroke=sym-decor; } + ha:line.8 { x1=10000; y1=0; x2=6000; y2=-4000; stroke=sym-decor; } + ha:line.9 { x1=6000; y1=4000; x2=6000; y2=-4000; stroke=sym-decor; } + ha:line.10 { x1=10000; y1=4000; x2=10000; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + devmap=1n4148_minimelf + name=D201 + role=symbol + ha:spice/prefix = { value=D; prio=31050; } + } + } + ha:group.96 { + uuid=Zj+oUtIHRUPA2aMj1qcAAAC1; + x=-4000; y=52000; + li:objects { + ha:line.1 { x1=136000; y1=124000; x2=136000; y2=128000; stroke=wire; } + ha:line.2 { x1=136000; y1=128000; x2=140000; y2=128000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.99 { + uuid=Zj+oUtIHRUPA2aMj1qcAAAC9; src_uuid=Zj+oUtIHRUPA2aMj1qcAAACZ; + x=176000; y=180000; + li:objects { + ha:text.1 { x1=6000; y1=-4000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:group.2 { + uuid=Zj+oUtIHRUPA2aMj1qcAAAC+; src_uuid=Zj+oUtIHRUPA2aMj1qcAAACa; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.3 { x1=0; y1=0; x2=1200; y2=0; stroke=sym-decor; } + ha:arc.4 { cx=1600; cy=0; r=400; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:group.5 { + uuid=Zj+oUtIHRUPA2aMj1qcAAAC/; src_uuid=Zj+oUtIHRUPA2aMj1qcAAACb; + x=8000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:line.6 { x1=6800; y1=0; x2=8000; y2=0; stroke=sym-decor; } + ha:arc.7 { cx=6400; cy=0; r=400; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:line.8 { x1=0; y1=0; x2=0; y2=0; stroke=sym-decor; } + ha:line.9 { x1=0; y1=0; x2=1200; y2=0; stroke=sym-decor; } + ha:arc.10 { cx=1600; cy=0; r=400; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:line.11 { x1=1200; y1=3600; x2=6800; y2=3600; stroke=sym-decor; } + ha:line.12 { x1=1600; y1=8000; x2=6400; y2=8000; stroke=sym-decor; } + ha:line.13 { x1=1600; y1=8000; x2=1600; y2=7200; stroke=sym-decor; } + ha:line.14 { x1=6400; y1=8000; x2=6400; y2=7200; stroke=sym-decor; } + ha:line.15 { x1=4000; y1=3600; x2=4000; y2=8000; stroke=sym-decor; } + } + ha:attrib { + footprint=dip(6) + name=SW211 + role=symbol + spice/omit=yes + } + } + ha:group.100 { + uuid=Zj+oUtIHRUPA2aMj1qcAAADA; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAN; + x=168000; y=176000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=Zj+oUtIHRUPA2aMj1qcAAADB; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAO; + x=16000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=C + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.2 { + uuid=Zj+oUtIHRUPA2aMj1qcAAADC; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAP; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=A + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:text.3 { x1=12000; y1=5000; rot=90.000000; dyntext=1; stroke=sym-secondary; text=%../a.devmap%; floater=1; } + ha:text.4 { x1=8000; y1=5000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.5 { x1=12000; y1=0; x2=10000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=4000; y1=0; x2=6000; y2=0; stroke=sym-decor; } + ha:line.7 { x1=6000; y1=4000; x2=10000; y2=0; stroke=sym-decor; } + ha:line.8 { x1=10000; y1=0; x2=6000; y2=-4000; stroke=sym-decor; } + ha:line.9 { x1=6000; y1=4000; x2=6000; y2=-4000; stroke=sym-decor; } + ha:line.10 { x1=10000; y1=4000; x2=10000; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + devmap=1n4148_minimelf + name=D211 + role=symbol + ha:spice/prefix = { value=D; prio=31050; } + } + } + ha:group.101 { + uuid=Zj+oUtIHRUPA2aMj1qcAAADD; src_uuid=Zj+oUtIHRUPA2aMj1qcAAAC1; + x=32000; y=52000; + li:objects { + ha:line.1 { x1=136000; y1=124000; x2=136000; y2=128000; stroke=wire; } + ha:line.2 { x1=136000; y1=128000; x2=140000; y2=128000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.104 { + uuid=Zj+oUtIHRUPA2aMj1qcAAADL; src_uuid=Zj+oUtIHRUPA2aMj1qcAAACZ; + x=212000; y=180000; + li:objects { + ha:text.1 { x1=6000; y1=-4000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:group.2 { + uuid=Zj+oUtIHRUPA2aMj1qcAAADM; src_uuid=Zj+oUtIHRUPA2aMj1qcAAACa; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.3 { x1=0; y1=0; x2=1200; y2=0; stroke=sym-decor; } + ha:arc.4 { cx=1600; cy=0; r=400; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:group.5 { + uuid=Zj+oUtIHRUPA2aMj1qcAAADN; src_uuid=Zj+oUtIHRUPA2aMj1qcAAACb; + x=8000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:line.6 { x1=6800; y1=0; x2=8000; y2=0; stroke=sym-decor; } + ha:arc.7 { cx=6400; cy=0; r=400; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:line.8 { x1=0; y1=0; x2=0; y2=0; stroke=sym-decor; } + ha:line.9 { x1=0; y1=0; x2=1200; y2=0; stroke=sym-decor; } + ha:arc.10 { cx=1600; cy=0; r=400; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:line.11 { x1=1200; y1=3600; x2=6800; y2=3600; stroke=sym-decor; } + ha:line.12 { x1=1600; y1=8000; x2=6400; y2=8000; stroke=sym-decor; } + ha:line.13 { x1=1600; y1=8000; x2=1600; y2=7200; stroke=sym-decor; } + ha:line.14 { x1=6400; y1=8000; x2=6400; y2=7200; stroke=sym-decor; } + ha:line.15 { x1=4000; y1=3600; x2=4000; y2=8000; stroke=sym-decor; } + } + ha:attrib { + footprint=dip(6) + name=SW221 + role=symbol + spice/omit=yes + } + } + ha:group.105 { + uuid=Zj+oUtIHRUPA2aMj1qcAAADO; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAN; + x=204000; y=176000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=Zj+oUtIHRUPA2aMj1qcAAADP; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAO; + x=16000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=C + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.2 { + uuid=Zj+oUtIHRUPA2aMj1qcAAADQ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAP; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=A + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:text.3 { x1=12000; y1=5000; rot=90.000000; dyntext=1; stroke=sym-secondary; text=%../a.devmap%; floater=1; } + ha:text.4 { x1=8000; y1=5000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.5 { x1=12000; y1=0; x2=10000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=4000; y1=0; x2=6000; y2=0; stroke=sym-decor; } + ha:line.7 { x1=6000; y1=4000; x2=10000; y2=0; stroke=sym-decor; } + ha:line.8 { x1=10000; y1=0; x2=6000; y2=-4000; stroke=sym-decor; } + ha:line.9 { x1=6000; y1=4000; x2=6000; y2=-4000; stroke=sym-decor; } + ha:line.10 { x1=10000; y1=4000; x2=10000; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + devmap=1n4148_minimelf + name=D221 + role=symbol + ha:spice/prefix = { value=D; prio=31050; } + } + } + ha:group.106 { + uuid=Zj+oUtIHRUPA2aMj1qcAAADR; src_uuid=Zj+oUtIHRUPA2aMj1qcAAAC1; + x=68000; y=52000; + li:objects { + ha:line.1 { x1=136000; y1=124000; x2=136000; y2=128000; stroke=wire; } + ha:line.2 { x1=136000; y1=128000; x2=140000; y2=128000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.109 { + uuid=Zj+oUtIHRUPA2aMj1qcAAADn; src_uuid=Zj+oUtIHRUPA2aMj1qcAAACZ; + x=140000; y=144000; + li:objects { + ha:text.1 { x1=6000; y1=-4000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:group.2 { + uuid=Zj+oUtIHRUPA2aMj1qcAAADo; src_uuid=Zj+oUtIHRUPA2aMj1qcAAACa; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.3 { x1=0; y1=0; x2=1200; y2=0; stroke=sym-decor; } + ha:arc.4 { cx=1600; cy=0; r=400; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:group.5 { + uuid=Zj+oUtIHRUPA2aMj1qcAAADp; src_uuid=Zj+oUtIHRUPA2aMj1qcAAACb; + x=8000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:line.6 { x1=6800; y1=0; x2=8000; y2=0; stroke=sym-decor; } + ha:arc.7 { cx=6400; cy=0; r=400; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:line.8 { x1=0; y1=0; x2=0; y2=0; stroke=sym-decor; } + ha:line.9 { x1=0; y1=0; x2=1200; y2=0; stroke=sym-decor; } + ha:arc.10 { cx=1600; cy=0; r=400; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:line.11 { x1=1200; y1=3600; x2=6800; y2=3600; stroke=sym-decor; } + ha:line.12 { x1=1600; y1=8000; x2=6400; y2=8000; stroke=sym-decor; } + ha:line.13 { x1=1600; y1=8000; x2=1600; y2=7200; stroke=sym-decor; } + ha:line.14 { x1=6400; y1=8000; x2=6400; y2=7200; stroke=sym-decor; } + ha:line.15 { x1=4000; y1=3600; x2=4000; y2=8000; stroke=sym-decor; } + } + ha:attrib { + footprint=dip(6) + name=SW202 + role=symbol + spice/omit=yes + } + } + ha:group.110 { + uuid=Zj+oUtIHRUPA2aMj1qcAAADq; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAN; + x=132000; y=140000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=Zj+oUtIHRUPA2aMj1qcAAADr; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAO; + x=16000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=C + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.2 { + uuid=Zj+oUtIHRUPA2aMj1qcAAADs; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAP; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=A + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:text.3 { x1=12000; y1=5000; rot=90.000000; dyntext=1; stroke=sym-secondary; text=%../a.devmap%; floater=1; } + ha:text.4 { x1=8000; y1=5000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.5 { x1=12000; y1=0; x2=10000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=4000; y1=0; x2=6000; y2=0; stroke=sym-decor; } + ha:line.7 { x1=6000; y1=4000; x2=10000; y2=0; stroke=sym-decor; } + ha:line.8 { x1=10000; y1=0; x2=6000; y2=-4000; stroke=sym-decor; } + ha:line.9 { x1=6000; y1=4000; x2=6000; y2=-4000; stroke=sym-decor; } + ha:line.10 { x1=10000; y1=4000; x2=10000; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + devmap=1n4148_minimelf + name=D202 + role=symbol + ha:spice/prefix = { value=D; prio=31050; } + } + } + ha:group.111 { + uuid=Zj+oUtIHRUPA2aMj1qcAAADt; src_uuid=Zj+oUtIHRUPA2aMj1qcAAAC1; + x=-4000; y=16000; + li:objects { + ha:line.1 { x1=136000; y1=124000; x2=136000; y2=128000; stroke=wire; } + ha:line.2 { x1=136000; y1=128000; x2=140000; y2=128000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.114 { + uuid=Zj+oUtIHRUPA2aMj1qcAAADu; src_uuid=Zj+oUtIHRUPA2aMj1qcAAACZ; + x=176000; y=144000; + li:objects { + ha:text.1 { x1=6000; y1=-4000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:group.2 { + uuid=Zj+oUtIHRUPA2aMj1qcAAADv; src_uuid=Zj+oUtIHRUPA2aMj1qcAAACa; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.3 { x1=0; y1=0; x2=1200; y2=0; stroke=sym-decor; } + ha:arc.4 { cx=1600; cy=0; r=400; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:group.5 { + uuid=Zj+oUtIHRUPA2aMj1qcAAADw; src_uuid=Zj+oUtIHRUPA2aMj1qcAAACb; + x=8000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:line.6 { x1=6800; y1=0; x2=8000; y2=0; stroke=sym-decor; } + ha:arc.7 { cx=6400; cy=0; r=400; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:line.8 { x1=0; y1=0; x2=0; y2=0; stroke=sym-decor; } + ha:line.9 { x1=0; y1=0; x2=1200; y2=0; stroke=sym-decor; } + ha:arc.10 { cx=1600; cy=0; r=400; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:line.11 { x1=1200; y1=3600; x2=6800; y2=3600; stroke=sym-decor; } + ha:line.12 { x1=1600; y1=8000; x2=6400; y2=8000; stroke=sym-decor; } + ha:line.13 { x1=1600; y1=8000; x2=1600; y2=7200; stroke=sym-decor; } + ha:line.14 { x1=6400; y1=8000; x2=6400; y2=7200; stroke=sym-decor; } + ha:line.15 { x1=4000; y1=3600; x2=4000; y2=8000; stroke=sym-decor; } + } + ha:attrib { + footprint=dip(6) + name=SW212 + role=symbol + spice/omit=yes + } + } + ha:group.115 { + uuid=Zj+oUtIHRUPA2aMj1qcAAADx; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAN; + x=168000; y=140000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=Zj+oUtIHRUPA2aMj1qcAAADy; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAO; + x=16000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=C + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.2 { + uuid=Zj+oUtIHRUPA2aMj1qcAAADz; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAP; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=A + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:text.3 { x1=12000; y1=5000; rot=90.000000; dyntext=1; stroke=sym-secondary; text=%../a.devmap%; floater=1; } + ha:text.4 { x1=8000; y1=5000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.5 { x1=12000; y1=0; x2=10000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=4000; y1=0; x2=6000; y2=0; stroke=sym-decor; } + ha:line.7 { x1=6000; y1=4000; x2=10000; y2=0; stroke=sym-decor; } + ha:line.8 { x1=10000; y1=0; x2=6000; y2=-4000; stroke=sym-decor; } + ha:line.9 { x1=6000; y1=4000; x2=6000; y2=-4000; stroke=sym-decor; } + ha:line.10 { x1=10000; y1=4000; x2=10000; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + devmap=1n4148_minimelf + name=D212 + role=symbol + ha:spice/prefix = { value=D; prio=31050; } + } + } + ha:group.116 { + uuid=Zj+oUtIHRUPA2aMj1qcAAAD0; src_uuid=Zj+oUtIHRUPA2aMj1qcAAAC1; + x=32000; y=16000; + li:objects { + ha:line.1 { x1=136000; y1=124000; x2=136000; y2=128000; stroke=wire; } + ha:line.2 { x1=136000; y1=128000; x2=140000; y2=128000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.119 { + uuid=Zj+oUtIHRUPA2aMj1qcAAAD1; src_uuid=Zj+oUtIHRUPA2aMj1qcAAACZ; + x=212000; y=144000; + li:objects { + ha:text.1 { x1=6000; y1=-4000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:group.2 { + uuid=Zj+oUtIHRUPA2aMj1qcAAAD2; src_uuid=Zj+oUtIHRUPA2aMj1qcAAACa; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.3 { x1=0; y1=0; x2=1200; y2=0; stroke=sym-decor; } + ha:arc.4 { cx=1600; cy=0; r=400; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:group.5 { + uuid=Zj+oUtIHRUPA2aMj1qcAAAD3; src_uuid=Zj+oUtIHRUPA2aMj1qcAAACb; + x=8000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:line.6 { x1=6800; y1=0; x2=8000; y2=0; stroke=sym-decor; } + ha:arc.7 { cx=6400; cy=0; r=400; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:line.8 { x1=0; y1=0; x2=0; y2=0; stroke=sym-decor; } + ha:line.9 { x1=0; y1=0; x2=1200; y2=0; stroke=sym-decor; } + ha:arc.10 { cx=1600; cy=0; r=400; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:line.11 { x1=1200; y1=3600; x2=6800; y2=3600; stroke=sym-decor; } + ha:line.12 { x1=1600; y1=8000; x2=6400; y2=8000; stroke=sym-decor; } + ha:line.13 { x1=1600; y1=8000; x2=1600; y2=7200; stroke=sym-decor; } + ha:line.14 { x1=6400; y1=8000; x2=6400; y2=7200; stroke=sym-decor; } + ha:line.15 { x1=4000; y1=3600; x2=4000; y2=8000; stroke=sym-decor; } + } + ha:attrib { + footprint=dip(6) + name=SW222 + role=symbol + spice/omit=yes + } + } + ha:group.120 { + uuid=Zj+oUtIHRUPA2aMj1qcAAAD4; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAN; + x=204000; y=140000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=Zj+oUtIHRUPA2aMj1qcAAAD5; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAO; + x=16000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=C + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.2 { + uuid=Zj+oUtIHRUPA2aMj1qcAAAD6; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAP; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=A + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:text.3 { x1=12000; y1=5000; rot=90.000000; dyntext=1; stroke=sym-secondary; text=%../a.devmap%; floater=1; } + ha:text.4 { x1=8000; y1=5000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.5 { x1=12000; y1=0; x2=10000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=4000; y1=0; x2=6000; y2=0; stroke=sym-decor; } + ha:line.7 { x1=6000; y1=4000; x2=10000; y2=0; stroke=sym-decor; } + ha:line.8 { x1=10000; y1=0; x2=6000; y2=-4000; stroke=sym-decor; } + ha:line.9 { x1=6000; y1=4000; x2=6000; y2=-4000; stroke=sym-decor; } + ha:line.10 { x1=10000; y1=4000; x2=10000; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + devmap=1n4148_minimelf + name=D222 + role=symbol + ha:spice/prefix = { value=D; prio=31050; } + } + } + ha:group.121 { + uuid=Zj+oUtIHRUPA2aMj1qcAAAD7; src_uuid=Zj+oUtIHRUPA2aMj1qcAAAC1; + x=68000; y=16000; + li:objects { + ha:line.1 { x1=136000; y1=124000; x2=136000; y2=128000; stroke=wire; } + ha:line.2 { x1=136000; y1=128000; x2=140000; y2=128000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.124 { + uuid=Zj+oUtIHRUPA2aMj1qcAAAD8; src_uuid=Zj+oUtIHRUPA2aMj1qcAAACZ; + x=140000; y=108000; + li:objects { + ha:text.1 { x1=6000; y1=-4000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:group.2 { + uuid=Zj+oUtIHRUPA2aMj1qcAAAD9; src_uuid=Zj+oUtIHRUPA2aMj1qcAAACa; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.3 { x1=0; y1=0; x2=1200; y2=0; stroke=sym-decor; } + ha:arc.4 { cx=1600; cy=0; r=400; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:group.5 { + uuid=Zj+oUtIHRUPA2aMj1qcAAAD+; src_uuid=Zj+oUtIHRUPA2aMj1qcAAACb; + x=8000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:line.6 { x1=6800; y1=0; x2=8000; y2=0; stroke=sym-decor; } + ha:arc.7 { cx=6400; cy=0; r=400; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:line.8 { x1=0; y1=0; x2=0; y2=0; stroke=sym-decor; } + ha:line.9 { x1=0; y1=0; x2=1200; y2=0; stroke=sym-decor; } + ha:arc.10 { cx=1600; cy=0; r=400; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:line.11 { x1=1200; y1=3600; x2=6800; y2=3600; stroke=sym-decor; } + ha:line.12 { x1=1600; y1=8000; x2=6400; y2=8000; stroke=sym-decor; } + ha:line.13 { x1=1600; y1=8000; x2=1600; y2=7200; stroke=sym-decor; } + ha:line.14 { x1=6400; y1=8000; x2=6400; y2=7200; stroke=sym-decor; } + ha:line.15 { x1=4000; y1=3600; x2=4000; y2=8000; stroke=sym-decor; } + } + ha:attrib { + footprint=dip(6) + name=SW203 + role=symbol + spice/omit=yes + } + } + ha:group.125 { + uuid=Zj+oUtIHRUPA2aMj1qcAAAD/; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAN; + x=132000; y=104000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=Zj+oUtIHRUPA2aMj1qcAAAEA; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAO; + x=16000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=C + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.2 { + uuid=Zj+oUtIHRUPA2aMj1qcAAAEB; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAP; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=A + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:text.3 { x1=12000; y1=5000; rot=90.000000; dyntext=1; stroke=sym-secondary; text=%../a.devmap%; floater=1; } + ha:text.4 { x1=8000; y1=5000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.5 { x1=12000; y1=0; x2=10000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=4000; y1=0; x2=6000; y2=0; stroke=sym-decor; } + ha:line.7 { x1=6000; y1=4000; x2=10000; y2=0; stroke=sym-decor; } + ha:line.8 { x1=10000; y1=0; x2=6000; y2=-4000; stroke=sym-decor; } + ha:line.9 { x1=6000; y1=4000; x2=6000; y2=-4000; stroke=sym-decor; } + ha:line.10 { x1=10000; y1=4000; x2=10000; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + devmap=1n4148_minimelf + name=D203 + role=symbol + ha:spice/prefix = { value=D; prio=31050; } + } + } + ha:group.126 { + uuid=Zj+oUtIHRUPA2aMj1qcAAAEC; src_uuid=Zj+oUtIHRUPA2aMj1qcAAAC1; + x=-4000; y=-20000; + li:objects { + ha:line.1 { x1=136000; y1=124000; x2=136000; y2=128000; stroke=wire; } + ha:line.2 { x1=136000; y1=128000; x2=140000; y2=128000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.129 { + uuid=Zj+oUtIHRUPA2aMj1qcAAAED; src_uuid=Zj+oUtIHRUPA2aMj1qcAAACZ; + x=176000; y=108000; + li:objects { + ha:text.1 { x1=6000; y1=-4000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:group.2 { + uuid=Zj+oUtIHRUPA2aMj1qcAAAEE; src_uuid=Zj+oUtIHRUPA2aMj1qcAAACa; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.3 { x1=0; y1=0; x2=1200; y2=0; stroke=sym-decor; } + ha:arc.4 { cx=1600; cy=0; r=400; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:group.5 { + uuid=Zj+oUtIHRUPA2aMj1qcAAAEF; src_uuid=Zj+oUtIHRUPA2aMj1qcAAACb; + x=8000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:line.6 { x1=6800; y1=0; x2=8000; y2=0; stroke=sym-decor; } + ha:arc.7 { cx=6400; cy=0; r=400; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:line.8 { x1=0; y1=0; x2=0; y2=0; stroke=sym-decor; } + ha:line.9 { x1=0; y1=0; x2=1200; y2=0; stroke=sym-decor; } + ha:arc.10 { cx=1600; cy=0; r=400; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:line.11 { x1=1200; y1=3600; x2=6800; y2=3600; stroke=sym-decor; } + ha:line.12 { x1=1600; y1=8000; x2=6400; y2=8000; stroke=sym-decor; } + ha:line.13 { x1=1600; y1=8000; x2=1600; y2=7200; stroke=sym-decor; } + ha:line.14 { x1=6400; y1=8000; x2=6400; y2=7200; stroke=sym-decor; } + ha:line.15 { x1=4000; y1=3600; x2=4000; y2=8000; stroke=sym-decor; } + } + ha:attrib { + footprint=dip(6) + name=SW213 + role=symbol + spice/omit=yes + } + } + ha:group.130 { + uuid=Zj+oUtIHRUPA2aMj1qcAAAEG; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAN; + x=168000; y=104000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=Zj+oUtIHRUPA2aMj1qcAAAEH; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAO; + x=16000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=C + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.2 { + uuid=Zj+oUtIHRUPA2aMj1qcAAAEI; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAP; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=A + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:text.3 { x1=12000; y1=5000; rot=90.000000; dyntext=1; stroke=sym-secondary; text=%../a.devmap%; floater=1; } + ha:text.4 { x1=8000; y1=5000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.5 { x1=12000; y1=0; x2=10000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=4000; y1=0; x2=6000; y2=0; stroke=sym-decor; } + ha:line.7 { x1=6000; y1=4000; x2=10000; y2=0; stroke=sym-decor; } + ha:line.8 { x1=10000; y1=0; x2=6000; y2=-4000; stroke=sym-decor; } + ha:line.9 { x1=6000; y1=4000; x2=6000; y2=-4000; stroke=sym-decor; } + ha:line.10 { x1=10000; y1=4000; x2=10000; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + devmap=1n4148_minimelf + name=D213 + role=symbol + ha:spice/prefix = { value=D; prio=31050; } + } + } + ha:group.131 { + uuid=Zj+oUtIHRUPA2aMj1qcAAAEJ; src_uuid=Zj+oUtIHRUPA2aMj1qcAAAC1; + x=32000; y=-20000; + li:objects { + ha:line.1 { x1=136000; y1=124000; x2=136000; y2=128000; stroke=wire; } + ha:line.2 { x1=136000; y1=128000; x2=140000; y2=128000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.134 { + uuid=Zj+oUtIHRUPA2aMj1qcAAAEK; src_uuid=Zj+oUtIHRUPA2aMj1qcAAACZ; + x=212000; y=108000; + li:objects { + ha:text.1 { x1=6000; y1=-4000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:group.2 { + uuid=Zj+oUtIHRUPA2aMj1qcAAAEL; src_uuid=Zj+oUtIHRUPA2aMj1qcAAACa; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.3 { x1=0; y1=0; x2=1200; y2=0; stroke=sym-decor; } + ha:arc.4 { cx=1600; cy=0; r=400; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:group.5 { + uuid=Zj+oUtIHRUPA2aMj1qcAAAEM; src_uuid=Zj+oUtIHRUPA2aMj1qcAAACb; + x=8000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:line.6 { x1=6800; y1=0; x2=8000; y2=0; stroke=sym-decor; } + ha:arc.7 { cx=6400; cy=0; r=400; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:line.8 { x1=0; y1=0; x2=0; y2=0; stroke=sym-decor; } + ha:line.9 { x1=0; y1=0; x2=1200; y2=0; stroke=sym-decor; } + ha:arc.10 { cx=1600; cy=0; r=400; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:line.11 { x1=1200; y1=3600; x2=6800; y2=3600; stroke=sym-decor; } + ha:line.12 { x1=1600; y1=8000; x2=6400; y2=8000; stroke=sym-decor; } + ha:line.13 { x1=1600; y1=8000; x2=1600; y2=7200; stroke=sym-decor; } + ha:line.14 { x1=6400; y1=8000; x2=6400; y2=7200; stroke=sym-decor; } + ha:line.15 { x1=4000; y1=3600; x2=4000; y2=8000; stroke=sym-decor; } + } + ha:attrib { + footprint=dip(6) + name=SW223 + role=symbol + spice/omit=yes + } + } + ha:group.135 { + uuid=Zj+oUtIHRUPA2aMj1qcAAAEN; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAN; + x=204000; y=104000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=Zj+oUtIHRUPA2aMj1qcAAAEO; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAO; + x=16000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=C + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.2 { + uuid=Zj+oUtIHRUPA2aMj1qcAAAEP; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAP; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=A + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:text.3 { x1=12000; y1=5000; rot=90.000000; dyntext=1; stroke=sym-secondary; text=%../a.devmap%; floater=1; } + ha:text.4 { x1=8000; y1=5000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.5 { x1=12000; y1=0; x2=10000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=4000; y1=0; x2=6000; y2=0; stroke=sym-decor; } + ha:line.7 { x1=6000; y1=4000; x2=10000; y2=0; stroke=sym-decor; } + ha:line.8 { x1=10000; y1=0; x2=6000; y2=-4000; stroke=sym-decor; } + ha:line.9 { x1=6000; y1=4000; x2=6000; y2=-4000; stroke=sym-decor; } + ha:line.10 { x1=10000; y1=4000; x2=10000; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + devmap=1n4148_minimelf + name=D223 + role=symbol + ha:spice/prefix = { value=D; prio=31050; } + } + } + ha:group.136 { + uuid=Zj+oUtIHRUPA2aMj1qcAAAEQ; src_uuid=Zj+oUtIHRUPA2aMj1qcAAAC1; + x=68000; y=-20000; + li:objects { + ha:line.1 { x1=136000; y1=124000; x2=136000; y2=128000; stroke=wire; } + ha:line.2 { x1=136000; y1=128000; x2=140000; y2=128000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.165 { + li:conn { + /2/96/1 + /2/95/2/1 + } + } + ha:connection.166 { + li:conn { + /2/96/2 + /2/93/2/1 + } + } + ha:connection.167 { + li:conn { + /2/101/1 + /2/100/2/1 + } + } + ha:connection.168 { + li:conn { + /2/101/2 + /2/99/2/1 + } + } + ha:connection.169 { + li:conn { + /2/106/1 + /2/105/2/1 + } + } + ha:connection.170 { + li:conn { + /2/106/2 + /2/104/2/1 + } + } + ha:connection.171 { + li:conn { + /2/111/1 + /2/110/2/1 + } + } + ha:connection.172 { + li:conn { + /2/111/2 + /2/109/2/1 + } + } + ha:connection.173 { + li:conn { + /2/116/1 + /2/115/2/1 + } + } + ha:connection.174 { + li:conn { + /2/116/2 + /2/114/2/1 + } + } + ha:connection.175 { + li:conn { + /2/121/1 + /2/120/2/1 + } + } + ha:connection.176 { + li:conn { + /2/121/2 + /2/119/2/1 + } + } + ha:connection.179 { + li:conn { + /2/126/1 + /2/125/2/1 + } + } + ha:connection.180 { + li:conn { + /2/126/2 + /2/124/2/1 + } + } + ha:connection.183 { + li:conn { + /2/131/1 + /2/130/2/1 + } + } + ha:connection.184 { + li:conn { + /2/131/2 + /2/129/2/1 + } + } + ha:connection.187 { + li:conn { + /2/136/1 + /2/135/2/1 + } + } + ha:connection.188 { + li:conn { + /2/136/2 + /2/134/2/1 + } + } + ha:connection.189 { + li:conn { + /2/105/1/1 + /2/207/4 + } + } + ha:connection.190 { + li:conn { + /2/100/1/1 + /2/207/5 + } + } + ha:connection.191 { + li:conn { + /2/95/1/1 + /2/207/7 + } + } + ha:connection.192 { + li:conn { + /2/120/1/1 + /2/209/3 + } + } + ha:connection.193 { + li:conn { + /2/115/1/1 + /2/209/4 + } + } + ha:connection.194 { + li:conn { + /2/110/1/1 + /2/209/6 + } + } + ha:connection.195 { + li:conn { + /2/135/1/1 + /2/211/4 + } + } + ha:connection.196 { + li:conn { + /2/130/1/1 + /2/211/5 + } + } + ha:connection.197 { + li:conn { + /2/125/1/1 + /2/211/7 + } + } + ha:connection.198 { + li:conn { + /2/93/5/1 + /2/213/4 + } + } + ha:connection.199 { + li:conn { + /2/124/5/1 + /2/213/6 + } + } + ha:connection.200 { + li:conn { + /2/109/5/1 + /2/213/8 + } + } + ha:connection.201 { + li:conn { + /2/99/5/1 + /2/215/5 + } + } + ha:connection.202 { + li:conn { + /2/129/5/1 + /2/215/7 + } + } + ha:connection.203 { + li:conn { + /2/114/5/1 + /2/215/9 + } + } + ha:connection.204 { + li:conn { + /2/104/5/1 + /2/217/4 + } + } + ha:connection.205 { + li:conn { + /2/134/5/1 + /2/217/6 + } + } + ha:connection.206 { + li:conn { + /2/119/5/1 + /2/217/8 + } + } + ha:group.207 { + uuid=Zj+oUtIHRUPA2aMj1qcAAAEZ; + li:objects { + ha:line.1 { x1=96000; y1=152000; x2=104000; y2=152000; stroke=wire; } + ha:line.2 { x1=104000; y1=152000; x2=104000; y2=156000; stroke=wire; } + ha:line.4 { x1=204000; y1=156000; x2=204000; y2=160000; stroke=wire; } + ha:line.5 { x1=168000; y1=160000; x2=168000; y2=156000; stroke=wire; } + ha:line.6 { x1=168000; y1=156000; x2=168000; y2=156000; stroke=junction; } + ha:line.7 { x1=132000; y1=160000; x2=132000; y2=156000; stroke=wire; } + ha:line.8 { x1=132000; y1=156000; x2=132000; y2=156000; stroke=junction; } + ha:line.9 { x1=104000; y1=156000; x2=204000; y2=156000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.208 { + li:conn { + /2/207/1 + /2/91/6/1 + } + } + ha:group.209 { + uuid=Zj+oUtIHRUPA2aMj1qcAAAEa; + li:objects { + ha:line.1 { x1=96000; y1=148000; x2=124000; y2=148000; stroke=wire; } + ha:line.2 { x1=124000; y1=120000; x2=204000; y2=120000; stroke=wire; } + ha:line.3 { x1=204000; y1=120000; x2=204000; y2=124000; stroke=wire; } + ha:line.4 { x1=168000; y1=124000; x2=168000; y2=120000; stroke=wire; } + ha:line.5 { x1=168000; y1=120000; x2=168000; y2=120000; stroke=junction; } + ha:line.6 { x1=132000; y1=124000; x2=132000; y2=120000; stroke=wire; } + ha:line.7 { x1=132000; y1=120000; x2=132000; y2=120000; stroke=junction; } + ha:line.8 { x1=124000; y1=148000; x2=124000; y2=120000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.210 { + li:conn { + /2/209/1 + /2/91/7/1 + } + } + ha:group.211 { + uuid=Zj+oUtIHRUPA2aMj1qcAAAEb; + li:objects { + ha:line.1 { x1=96000; y1=144000; x2=120000; y2=144000; stroke=wire; } + ha:line.2 { x1=120000; y1=144000; x2=120000; y2=84000; stroke=wire; } + ha:line.4 { x1=204000; y1=84000; x2=204000; y2=88000; stroke=wire; } + ha:line.5 { x1=168000; y1=88000; x2=168000; y2=84000; stroke=wire; } + ha:line.6 { x1=168000; y1=84000; x2=168000; y2=84000; stroke=junction; } + ha:line.7 { x1=132000; y1=88000; x2=132000; y2=84000; stroke=wire; } + ha:line.8 { x1=132000; y1=84000; x2=132000; y2=84000; stroke=junction; } + ha:line.9 { x1=120000; y1=84000; x2=204000; y2=84000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.212 { + li:conn { + /2/211/1 + /2/91/1/1 + } + } + ha:group.213 { + uuid=Zj+oUtIHRUPA2aMj1qcAAAEc; + li:objects { + ha:line.1 { x1=96000; y1=132000; x2=116000; y2=132000; stroke=wire; } + ha:line.3 { x1=116000; y1=80000; x2=116000; y2=132000; stroke=wire; } + ha:line.4 { x1=152000; y1=180000; x2=156000; y2=180000; stroke=wire; } + ha:line.5 { x1=156000; y1=180000; x2=156000; y2=80000; stroke=wire; } + ha:line.6 { x1=152000; y1=108000; x2=156000; y2=108000; stroke=wire; } + ha:line.7 { x1=156000; y1=108000; x2=156000; y2=108000; stroke=junction; } + ha:line.8 { x1=152000; y1=144000; x2=156000; y2=144000; stroke=wire; } + ha:line.9 { x1=156000; y1=144000; x2=156000; y2=144000; stroke=junction; } + ha:line.10 { x1=116000; y1=80000; x2=156000; y2=80000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.214 { + li:conn { + /2/213/1 + /2/91/3/1 + } + } + ha:group.215 { + uuid=Zj+oUtIHRUPA2aMj1qcAAAEd; + li:objects { + ha:line.1 { x1=96000; y1=128000; x2=112000; y2=128000; stroke=wire; } + ha:line.3 { x1=112000; y1=76000; x2=112000; y2=128000; stroke=wire; } + ha:line.4 { x1=112000; y1=76000; x2=192000; y2=76000; stroke=wire; } + ha:line.5 { x1=188000; y1=180000; x2=192000; y2=180000; stroke=wire; } + ha:line.7 { x1=188000; y1=108000; x2=192000; y2=108000; stroke=wire; } + ha:line.8 { x1=192000; y1=108000; x2=192000; y2=108000; stroke=junction; } + ha:line.9 { x1=188000; y1=144000; x2=192000; y2=144000; stroke=wire; } + ha:line.10 { x1=192000; y1=144000; x2=192000; y2=144000; stroke=junction; } + ha:line.11 { x1=192000; y1=76000; x2=192000; y2=180000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.216 { + li:conn { + /2/215/1 + /2/91/4/1 + } + } + ha:group.217 { + uuid=Zj+oUtIHRUPA2aMj1qcAAAEe; + li:objects { + ha:line.1 { x1=96000; y1=124000; x2=108000; y2=124000; stroke=wire; } + ha:line.2 { x1=108000; y1=124000; x2=108000; y2=72000; stroke=wire; } + ha:line.3 { x1=108000; y1=72000; x2=228000; y2=72000; stroke=wire; } + ha:line.4 { x1=224000; y1=180000; x2=228000; y2=180000; stroke=wire; } + ha:line.6 { x1=224000; y1=108000; x2=228000; y2=108000; stroke=wire; } + ha:line.7 { x1=228000; y1=108000; x2=228000; y2=108000; stroke=junction; } + ha:line.8 { x1=224000; y1=144000; x2=228000; y2=144000; stroke=wire; } + ha:line.9 { x1=228000; y1=144000; x2=228000; y2=144000; stroke=junction; } + ha:line.10 { x1=228000; y1=72000; x2=228000; y2=180000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.218 { + li:conn { + /2/217/1 + /2/91/8/1 + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer=Tibor 'Igor2' Palinkas + page=2/4 + print_page=A/4 + title=button matrix, 3*3 + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 2 + grid = 4.0960 mm + } + } + } +} Index: tags/1.0.5/doc/examples/hierarchic/10_cpu/main.rs =================================================================== --- tags/1.0.5/doc/examples/hierarchic/10_cpu/main.rs (nonexistent) +++ tags/1.0.5/doc/examples/hierarchic/10_cpu/main.rs (revision 10414) @@ -0,0 +1,481 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=k24MaEHH5dTW8BU3R+wAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.1 { + uuid=8/SYZ/pfBzxyqFA12WQAAAAC; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAg; + li:objects { + ha:polygon.11 { + li:outline { + ha:line { x1=0; y1=0; x2=80000; y2=0; } + ha:line { x1=80000; y1=0; x2=80000; y2=20000; } + ha:line { x1=80000; y1=20000; x2=0; y2=20000; } + ha:line { x1=0; y1=20000; x2=0; y2=0; } + } + stroke=titlebox-frame; + fill=titlebox-fill; + } + ha:line.12 { x1=0; y1=10000; x2=80000; y2=10000; stroke=titlebox-frame; } + ha:line.13 { x1=40000; y1=10000; x2=40000; y2=0; stroke=titlebox-frame; } + ha:text.20 { x1=1000; y1=16500; dyntext=0; stroke=titlebox-big; text=TITLE; } + ha:text.21 { x1=1000; y1=10500; x2=79000; y2=16000; dyntext=1; stroke=titlebox-big; text=%../../A.title%; } + ha:text.22 { x1=1000; y1=5500; dyntext=0; stroke=titlebox-small; text={PROJECT:}; } + ha:text.23 { x1=13000; y1=5500; x2=39000; y2=9500; dyntext=1; stroke=titlebox-big; text=%project.name%; } + ha:text.24 { x1=1000; y1=500; dyntext=0; stroke=titlebox-small; text={PAGE:}; } + ha:text.25 { x1=10000; y1=500; x2=39000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.page%; } + ha:text.26 { x1=41000; y1=5500; dyntext=0; stroke=titlebox-small; text={FILE:}; } + ha:text.27 { x1=48000; y1=5500; x2=79000; y2=9500; dyntext=1; stroke=titlebox-big; text=%filename%; } + ha:text.28 { x1=41000; y1=500; dyntext=0; stroke=titlebox-small; text={MAINTAINER:}; } + ha:text.29 { x1=55000; y1=500; x2=79000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.maintainer%; } + ha:text.30 { x1=79000; y1=16000; mirx=1; dyntext=1; stroke=sheet-decor; text=%stance.model% %stance.sub_major% %stance.sub_minor% %stance.test_bench% %view.name%; } + } + ha:attrib { + purpose=titlebox + } + } + ha:group.3 { + uuid=+6YGVDtwpVypVzYJj6AAAAC0; src_uuid=Q8cSXpoK0QkYCcKy+asAAABC; + x=56000; y=144000; + li:objects { + ha:group.1 { + uuid=+6YGVDtwpVypVzYJj6AAAAC1; src_uuid=GOjvawM2mgwjKV+ohqMAAAAD; + x=20000; y=-4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=term_rx + role=terminal + } + } + ha:group.2 { + uuid=+6YGVDtwpVypVzYJj6AAAAC2; src_uuid=GOjvawM2mgwjKV+ohqMAAAAD; + x=20000; y=-8000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=term_tx + role=terminal + } + } + ha:group.3 { + uuid=+6YGVDtwpVypVzYJj6AAAAC3; src_uuid=GOjvawM2mgwjKV+ohqMAAAAD; + x=20000; y=-16000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=inv_rx + role=terminal + } + } + ha:group.4 { + uuid=+6YGVDtwpVypVzYJj6AAAAC4; src_uuid=GOjvawM2mgwjKV+ohqMAAAAD; + x=20000; y=-20000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=inv_tx + role=terminal + } + } + ha:polygon.5 { + li:outline { + ha:line { x1=16000; y1=0; x2=16000; y2=-24000; } + ha:line { x1=16000; y1=-24000; x2=0; y2=-24000; } + ha:line { x1=0; y1=-24000; x2=0; y2=0; } + ha:line { x1=0; y1=0; x2=16000; y2=0; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + ha:text.6 { x1=0; y1=0; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:text.7 { x1=2000; y1=-4000; dyntext=1; stroke=sym-secondary; text=%../A.cschem/child/name%; floater=1; } + } + ha:attrib { + cschem/child/name=serial + name=S1 + role=symbol + } + } + ha:group.4 { + uuid=+6YGVDtwpVypVzYJj6AAAAC+; src_uuid=Q8cSXpoK0QkYCcKy+asAAABC; + x=58000; y=108000; + li:objects { + ha:polygon.5 { + li:outline { + ha:line { x1=14000; y1=0; x2=14000; y2=-24000; } + ha:line { x1=14000; y1=-24000; x2=-2000; y2=-24000; } + ha:line { x1=-2000; y1=-24000; x2=-2000; y2=0; } + ha:line { x1=-2000; y1=0; x2=14000; y2=0; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + ha:text.6 { x1=0; y1=0; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:text.7 { x1=2000; y1=-4000; dyntext=1; stroke=sym-secondary; text=%../A.cschem/child/name%; floater=1; } + } + ha:attrib { + cschem/child/name=button_mx + name=S2 + role=symbol + } + } + ha:group.5 { + uuid=+6YGVDtwpVypVzYJj6AAAADI; src_uuid=Q8cSXpoK0QkYCcKy+asAAABC; + x=56000; y=76000; + li:objects { + ha:group.4 { + uuid=+6YGVDtwpVypVzYJj6AAAADM; src_uuid=GOjvawM2mgwjKV+ohqMAAAAD; + x=-4000; y=-12000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=Vin + role=terminal + } + } + ha:polygon.5 { + li:outline { + ha:line { x1=16000; y1=0; x2=16000; y2=-24000; } + ha:line { x1=16000; y1=-24000; x2=0; y2=-24000; } + ha:line { x1=0; y1=-24000; x2=0; y2=0; } + ha:line { x1=0; y1=0; x2=16000; y2=0; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + ha:text.6 { x1=0; y1=0; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:text.7 { x1=2000; y1=-4000; dyntext=1; stroke=sym-secondary; text=%../A.cschem/child/name%; floater=1; } + } + ha:attrib { + cschem/child/name=psu + name=S3 + role=symbol + } + } + ha:group.6 { + uuid=+6YGVDtwpVypVzYJj6AAAADb; src_uuid=+6YGVDtwpVypVzYJj6AAAADU; + x=144000; y=96000; + li:objects { + ha:text.1 { x1=0; y1=22000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:group.2 { + uuid=+6YGVDtwpVypVzYJj6AAAADc; src_uuid=+6YGVDtwpVypVzYJj6AAAADV; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:group.3 { + uuid=+6YGVDtwpVypVzYJj6AAAADd; src_uuid=+6YGVDtwpVypVzYJj6AAAADW; + x=0; y=4000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.4 { + uuid=+6YGVDtwpVypVzYJj6AAAADe; src_uuid=+6YGVDtwpVypVzYJj6AAAADX; + x=0; y=8000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=3 + role=terminal + } + } + ha:group.5 { + uuid=+6YGVDtwpVypVzYJj6AAAADf; src_uuid=+6YGVDtwpVypVzYJj6AAAADY; + x=0; y=12000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=4 + role=terminal + } + } + ha:group.6 { + uuid=+6YGVDtwpVypVzYJj6AAAADg; src_uuid=+6YGVDtwpVypVzYJj6AAAADZ; + x=0; y=16000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=5 + role=terminal + } + } + ha:group.7 { + uuid=+6YGVDtwpVypVzYJj6AAAADh; src_uuid=+6YGVDtwpVypVzYJj6AAAADa; + x=0; y=20000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=6 + role=terminal + } + } + ha:polygon.8 { + li:outline { + ha:line { x1=0; y1=-2000; x2=0; y2=22000; } + ha:line { x1=0; y1=22000; x2=4000; y2=22000; } + ha:line { x1=4000; y1=22000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=0; y2=-2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + footprint=connector(6,1) + name=CN1 + role=symbol + spice/omit=yes + } + } + ha:group.7 { + uuid=+6YGVDtwpVypVzYJj6AAAADi; + li:objects { + ha:line.1 { x1=76000; y1=140000; x2=128000; y2=140000; stroke=wire; } + ha:line.2 { x1=128000; y1=140000; x2=128000; y2=116000; stroke=wire; } + ha:line.3 { x1=128000; y1=116000; x2=140000; y2=116000; stroke=wire; } + ha:text.4 { x1=108000; y1=140000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=terminal_rx + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.8 { + li:conn { + /2/7/1 + /2/3/1/1 + } + } + ha:connection.9 { + li:conn { + /2/7/3 + /2/6/7/1 + } + } + ha:group.10 { + uuid=+6YGVDtwpVypVzYJj6AAAADj; + li:objects { + ha:line.1 { x1=76000; y1=136000; x2=124000; y2=136000; stroke=wire; } + ha:line.2 { x1=124000; y1=136000; x2=124000; y2=112000; stroke=wire; } + ha:line.3 { x1=124000; y1=112000; x2=140000; y2=112000; stroke=wire; } + ha:text.4 { x1=108000; y1=136000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=terminal_tx + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.11 { + li:conn { + /2/10/1 + /2/3/2/1 + } + } + ha:connection.12 { + li:conn { + /2/10/3 + /2/6/6/1 + } + } + ha:group.13 { + uuid=+6YGVDtwpVypVzYJj6AAAADk; + li:objects { + ha:line.1 { x1=76000; y1=128000; x2=116000; y2=128000; stroke=wire; } + ha:line.2 { x1=116000; y1=128000; x2=116000; y2=108000; stroke=wire; } + ha:line.3 { x1=116000; y1=108000; x2=140000; y2=108000; stroke=wire; } + ha:text.4 { x1=96000; y1=128000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=readout_rx + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.14 { + li:conn { + /2/13/1 + /2/3/3/1 + } + } + ha:connection.15 { + li:conn { + /2/13/3 + /2/6/5/1 + } + } + ha:group.16 { + uuid=+6YGVDtwpVypVzYJj6AAAADl; + li:objects { + ha:line.1 { x1=76000; y1=124000; x2=112000; y2=124000; stroke=wire; } + ha:line.2 { x1=112000; y1=124000; x2=112000; y2=104000; stroke=wire; } + ha:line.3 { x1=112000; y1=104000; x2=140000; y2=104000; stroke=wire; } + ha:text.4 { x1=96000; y1=124000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=readout_tx + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.17 { + li:conn { + /2/16/1 + /2/3/4/1 + } + } + ha:connection.18 { + li:conn { + /2/16/3 + /2/6/4/1 + } + } + ha:group.19 { + uuid=+6YGVDtwpVypVzYJj6AAAADm; + li:objects { + ha:line.1 { x1=52000; y1=64000; x2=44000; y2=64000; stroke=wire; } + ha:line.2 { x1=44000; y1=64000; x2=44000; y2=44000; stroke=wire; } + ha:line.3 { x1=44000; y1=44000; x2=112000; y2=44000; stroke=wire; } + ha:line.4 { x1=112000; y1=44000; x2=112000; y2=100000; stroke=wire; } + ha:line.5 { x1=112000; y1=100000; x2=140000; y2=100000; stroke=wire; } + ha:text.6 { x1=112000; y1=96000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=V12_dc + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.20 { + li:conn { + /2/19/1 + /2/5/4/1 + } + } + ha:connection.21 { + li:conn { + /2/19/5 + /2/6/3/1 + } + } + ha:group.22 { + uuid=+6YGVDtwpVypVzYJj6AAAADn; + li:objects { + ha:line.1 { x1=140000; y1=96000; x2=136000; y2=96000; stroke=wire; } + ha:line.2 { x1=136000; y1=96000; x2=136000; y2=92000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.23 { + li:conn { + /2/22/1 + /2/6/2/1 + } + } + ha:group.24 { + uuid=+6YGVDtwpVypVzYJj6AAAADs; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=136000; y=92000; + li:objects { + ha:group.1 { + uuid=+6YGVDtwpVypVzYJj6AAAADt; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + drc/require_graphical_conn=1 + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:connection.25 { + li:conn { + /2/24/1/1 + /2/22/2 + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer=Tibor 'Igor2' Palinkas + page=1/4 + print_page=A/4 + title=CPU board, block diagram + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 2 + grid = 4.0960 mm + } + } + } +} Index: tags/1.0.5/doc/examples/hierarchic/10_cpu/project.lht =================================================================== --- tags/1.0.5/doc/examples/hierarchic/10_cpu/project.lht (nonexistent) +++ tags/1.0.5/doc/examples/hierarchic/10_cpu/project.lht (revision 10414) @@ -0,0 +1,16 @@ +ha:coraleda-project-v1 { + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:prj { + li:root_sheets { + main.rs + } + li:aux_sheets { + button_mx.rs + psu.rs + serial.rs + } + } + } + } +} Index: tags/1.0.5/doc/examples/hierarchic/10_cpu/psu.rs =================================================================== --- tags/1.0.5/doc/examples/hierarchic/10_cpu/psu.rs (nonexistent) +++ tags/1.0.5/doc/examples/hierarchic/10_cpu/psu.rs (revision 10414) @@ -0,0 +1,977 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + ha:group.1 { + uuid=T7RkhKr/RbyI7kwRboIAAAAw; + li:objects { + ha:group.1 { + uuid=T7RkhKr/RbyI7kwRboIAAAAx; loclib_name=led5; + li:objects { + } + ha:attrib { + device=led5 + footprint=LED5 + li:portmap { + {C->pcb/pinnum=1} + {A->pcb/pinnum=2} + } + } + } + ha:group.2 { + uuid=wv2G1HNG+FBgM2e70J8AAADN; loclib_name=pol_rcy; + li:objects { + } + ha:attrib { + li:portmap { + {P->pcb/pinnum=1} + {N->pcb/pinnum=2} + } + } + } + } + ha:attrib { + ha:purpose = { value=devmap; prio=0; } + } + } + } + } + ha:obj_direct.2 { + uuid=T7RkhKr/RbyI7kwRboIAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.1 { + uuid=8/SYZ/pfBzxyqFA12WQAAAAC; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAg; + li:objects { + ha:polygon.11 { + li:outline { + ha:line { x1=0; y1=0; x2=80000; y2=0; } + ha:line { x1=80000; y1=0; x2=80000; y2=20000; } + ha:line { x1=80000; y1=20000; x2=0; y2=20000; } + ha:line { x1=0; y1=20000; x2=0; y2=0; } + } + stroke=titlebox-frame; + fill=titlebox-fill; + } + ha:line.12 { x1=0; y1=10000; x2=80000; y2=10000; stroke=titlebox-frame; } + ha:line.13 { x1=40000; y1=10000; x2=40000; y2=0; stroke=titlebox-frame; } + ha:text.20 { x1=1000; y1=16500; dyntext=0; stroke=titlebox-big; text=TITLE; } + ha:text.21 { x1=1000; y1=10500; x2=79000; y2=16000; dyntext=1; stroke=titlebox-big; text=%../../A.title%; } + ha:text.22 { x1=1000; y1=5500; dyntext=0; stroke=titlebox-small; text={PROJECT:}; } + ha:text.23 { x1=13000; y1=5500; x2=39000; y2=9500; dyntext=1; stroke=titlebox-big; text=%project.name%; } + ha:text.24 { x1=1000; y1=500; dyntext=0; stroke=titlebox-small; text={PAGE:}; } + ha:text.25 { x1=10000; y1=500; x2=39000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.page%; } + ha:text.26 { x1=41000; y1=5500; dyntext=0; stroke=titlebox-small; text={FILE:}; } + ha:text.27 { x1=48000; y1=5500; x2=79000; y2=9500; dyntext=1; stroke=titlebox-big; text=%filename%; } + ha:text.28 { x1=41000; y1=500; dyntext=0; stroke=titlebox-small; text={MAINTAINER:}; } + ha:text.29 { x1=55000; y1=500; x2=79000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.maintainer%; } + ha:text.30 { x1=79000; y1=16000; mirx=1; dyntext=1; stroke=sheet-decor; text=%stance.model% %stance.sub_major% %stance.sub_minor% %stance.test_bench% %view.name%; } + } + ha:attrib { + purpose=titlebox + } + } + ha:group.2 { + uuid=T7RkhKr/RbyI7kwRboIAAAAL; src_uuid=iNOQfJpO6hT/HFDFGjoAAABo; + x=88000; y=92000; + li:objects { + ha:text.1 { x1=0; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.2 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=8000; } + ha:line { x1=0; y1=8000; x2=24000; y2=8000; } + ha:line { x1=24000; y1=8000; x2=24000; y2=0; } + ha:line { x1=24000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + } + ha:group.3 { + uuid=T7RkhKr/RbyI7kwRboIAAAAM; src_uuid=iNOQfJpO6hT/HFDFGjoAAABp; + x=0; y=4000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../A.name%; } + } + ha:attrib { + name=in + pinnum=1 + role=terminal + } + } + ha:group.4 { + uuid=T7RkhKr/RbyI7kwRboIAAAAN; src_uuid=iNOQfJpO6hT/HFDFGjoAAABq; + x=24000; y=4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../A.name%; } + } + ha:attrib { + name=out + pinnum=3 + role=terminal + } + } + ha:group.5 { + uuid=T7RkhKr/RbyI7kwRboIAAAAO; src_uuid=iNOQfJpO6hT/HFDFGjoAAABr; + x=12000; y=0; rot=-90.000000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../A.name%; } + } + ha:attrib { + name=gnd + pinnum=2 + role=terminal + } + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + -symbol_generator=boxsym-rnd + device=7805 + footprint=TO220 + name=U301 + role=symbol + } + } + ha:group.3 { + uuid=T7RkhKr/RbyI7kwRboIAAAAV; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAh; + x=120000; y=88000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=T7RkhKr/RbyI7kwRboIAAAAW; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAi; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=T7RkhKr/RbyI7kwRboIAAAAX; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAj; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.5 { x1=9000; y1=5000; x2=9000; y2=-5000; stroke=sym-decor; } + ha:line.6 { x1=11000; y1=5000; x2=11000; y2=-5000; stroke=sym-decor; } + ha:line.7 { x1=4000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.8 { x1=11000; y1=0; x2=16000; y2=0; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + ha:device = { value=capacitor; prio=31050; } + footprint=1206 + name=C303 + role=symbol + ha:spice/prefix = { value=C; prio=31050; } + value=100n + } + } + ha:group.4 { + uuid=T7RkhKr/RbyI7kwRboIAAAAe; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAk; + x=60000; y=88000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=T7RkhKr/RbyI7kwRboIAAAAf; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAl; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=N + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.2 { + uuid=T7RkhKr/RbyI7kwRboIAAAAg; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAm; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=P + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:text.3 { x1=12000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.5 { x1=9000; y1=5000; x2=9000; y2=-5000; stroke=sym-decor; } + ha:line.6 { x1=4000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.7 { x1=11000; y1=0; x2=16000; y2=0; stroke=sym-decor; } + ha:arc.8 { cx=34000; cy=0; r=23000; sang=167.500000; dang=25.000000; stroke=sym-decor; } + ha:line.9 { x1=6000; y1=-3000; x2=8000; y2=-3000; stroke=sym-decor; } + ha:line.10 { x1=7000; y1=-4000; x2=7000; y2=-2000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + ha:device = { value=capacitor; prio=31050; } + devmap=pol_rcy + footprint=rcy(200) + name=C301 + role=symbol + ha:spice/prefix = { value=C; prio=31050; } + value=10u + } + } + ha:group.5 { + uuid=T7RkhKr/RbyI7kwRboIAAAAl; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=100000; y=64000; + li:objects { + ha:group.1 { + uuid=T7RkhKr/RbyI7kwRboIAAAAm; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + drc/require_graphical_conn=1 + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.6 { + uuid=T7RkhKr/RbyI7kwRboIAAAAt; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAQ; + x=168000; y=64000; + li:objects { + ha:group.1 { + uuid=T7RkhKr/RbyI7kwRboIAAAAu; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAR; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=C + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.2 { + uuid=T7RkhKr/RbyI7kwRboIAAAAv; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAS; + x=-16000; y=0; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=A + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:line.3 { x1=-4000; y1=0; x2=-6000; y2=0; stroke=sym-decor; } + ha:line.4 { x1=-12000; y1=0; x2=-10000; y2=0; stroke=sym-decor; } + ha:line.5 { x1=-10000; y1=4000; x2=-6000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=-6000; y1=0; x2=-10000; y2=-4000; stroke=sym-decor; } + ha:line.7 { x1=-10000; y1=4000; x2=-10000; y2=-4000; stroke=sym-decor; } + ha:line.8 { x1=-6000; y1=4000; x2=-6000; y2=-4000; stroke=sym-decor; } + ha:text.9 { x1=-4000; y1=13000; rot=90.000000; dyntext=1; stroke=sym-secondary; text=%../a.devmap%; floater=1; } + ha:text.10 { x1=-8000; y1=13000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.11 { x1=-8000; y1=8000; x2=-6000; y2=11000; stroke=sym-decor; } + ha:line.12 { x1=-6000; y1=11000; x2=-7000; y2=10000; stroke=sym-decor; } + ha:line.13 { x1=-6000; y1=11000; x2=-6517; y2=9545; stroke=sym-decor; } + ha:line.14 { x1=-10000; y1=7000; x2=-8000; y2=10000; stroke=sym-decor; } + ha:line.15 { x1=-8000; y1=10000; x2=-8000; y2=8000; stroke=sym-decor; } + ha:line.16 { x1=-8303; y1=6354; x2=-6303; y2=9354; stroke=sym-decor; } + ha:line.17 { x1=-6303; y1=9354; x2=-7303; y2=8354; stroke=sym-decor; } + ha:line.18 { x1=-6303; y1=9354; x2=-6820; y2=7899; stroke=sym-decor; } + ha:line.19 { x1=-10303; y1=5354; x2=-8303; y2=8354; stroke=sym-decor; } + ha:line.20 { x1=-8303; y1=8354; x2=-8303; y2=6354; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + devmap=led5 + name=D301 + role=symbol + ha:spice/prefix = { value=D; prio=31050; } + } + } + ha:group.7 { + uuid=T7RkhKr/RbyI7kwRboIAAAA4; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=144000; y=88000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=T7RkhKr/RbyI7kwRboIAAAA5; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=T7RkhKr/RbyI7kwRboIAAAA6; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + ha:device = { value=resistor; prio=31050; } + footprint=1206 + name=R301 + role=symbol + ha:spice/prefix = { value=R; prio=31050; } + value=510 + } + } + ha:group.8 { + uuid=T7RkhKr/RbyI7kwRboIAAAA7; + x=0; y=-48000; + li:objects { + ha:line.1 { x1=100000; y1=136000; x2=100000; y2=112000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.11 { + uuid=T7RkhKr/RbyI7kwRboIAAAA8; + x=0; y=-48000; + li:objects { + ha:line.2 { x1=120000; y1=144000; x2=120000; y2=136000; stroke=wire; } + ha:line.4 { x1=120000; y1=144000; x2=120000; y2=144000; stroke=junction; } + ha:line.6 { x1=144000; y1=144000; x2=144000; y2=136000; stroke=wire; } + ha:line.7 { x1=144000; y1=144000; x2=144000; y2=144000; stroke=junction; } + ha:line.8 { x1=116000; y1=144000; x2=172000; y2=144000; stroke=wire; } + ha:line.9 { x1=172000; y1=144000; x2=172000; y2=148000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.15 { + uuid=T7RkhKr/RbyI7kwRboIAAAA/; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=120000; y=64000; + li:objects { + ha:group.1 { + uuid=T7RkhKr/RbyI7kwRboIAAABA; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + drc/require_graphical_conn=1 + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.16 { + uuid=T7RkhKr/RbyI7kwRboIAAABB; + x=0; y=-48000; + li:objects { + ha:line.1 { x1=120000; y1=116000; x2=120000; y2=112000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.19 { + uuid=T7RkhKr/RbyI7kwRboIAAABJ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAh; + x=80000; y=88000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=T7RkhKr/RbyI7kwRboIAAABK; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAi; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=T7RkhKr/RbyI7kwRboIAAABL; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAj; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.5 { x1=9000; y1=5000; x2=9000; y2=-5000; stroke=sym-decor; } + ha:line.6 { x1=11000; y1=5000; x2=11000; y2=-5000; stroke=sym-decor; } + ha:line.7 { x1=4000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.8 { x1=11000; y1=0; x2=16000; y2=0; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + ha:device = { value=capacitor; prio=31050; } + footprint=1206 + name=C302 + role=symbol + ha:spice/prefix = { value=C; prio=31050; } + value=100n + } + } + ha:group.20 { + uuid=T7RkhKr/RbyI7kwRboIAAABM; src_uuid=T7RkhKr/RbyI7kwRboIAAAA8; + x=-40000; y=-48000; + li:objects { + ha:line.2 { x1=120000; y1=144000; x2=120000; y2=136000; stroke=wire; } + ha:line.3 { x1=124000; y1=144000; x2=92000; y2=144000; stroke=wire; } + ha:line.4 { x1=120000; y1=144000; x2=120000; y2=144000; stroke=junction; } + ha:line.5 { x1=100000; y1=144000; x2=100000; y2=136000; stroke=wire; } + ha:line.6 { x1=100000; y1=144000; x2=100000; y2=144000; stroke=junction; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.22 { + uuid=T7RkhKr/RbyI7kwRboIAAABN; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=80000; y=64000; + li:objects { + ha:group.1 { + uuid=T7RkhKr/RbyI7kwRboIAAABO; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + drc/require_graphical_conn=1 + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.23 { + uuid=T7RkhKr/RbyI7kwRboIAAABP; src_uuid=T7RkhKr/RbyI7kwRboIAAABB; + x=-40000; y=-48000; + li:objects { + ha:line.1 { x1=120000; y1=116000; x2=120000; y2=112000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.28 { + uuid=T7RkhKr/RbyI7kwRboIAAABQ; + x=0; y=-48000; + li:objects { + ha:line.1 { x1=144000; y1=116000; x2=144000; y2=112000; stroke=wire; } + ha:line.2 { x1=144000; y1=112000; x2=152000; y2=112000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.31 { + uuid=T7RkhKr/RbyI7kwRboIAAABT; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=172000; y=64000; + li:objects { + ha:group.1 { + uuid=T7RkhKr/RbyI7kwRboIAAABU; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + drc/require_graphical_conn=1 + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.32 { + uuid=T7RkhKr/RbyI7kwRboIAAABV; + x=0; y=-48000; + li:objects { + ha:line.1 { x1=168000; y1=112000; x2=172000; y2=112000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.36 { + uuid=T7RkhKr/RbyI7kwRboIAAABW; + x=0; y=-48000; + li:objects { + ha:line.1 { x1=60000; y1=116000; x2=60000; y2=112000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.38 { + uuid=T7RkhKr/RbyI7kwRboIAAABZ; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=60000; y=64000; + li:objects { + ha:group.1 { + uuid=T7RkhKr/RbyI7kwRboIAAABa; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + drc/require_graphical_conn=1 + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.40 { + uuid=T7RkhKr/RbyI7kwRboIAAABf; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB6; + x=172000; y=100000; + li:objects { + ha:group.1 { + uuid=T7RkhKr/RbyI7kwRboIAAABg; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB7; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + drc/require_graphical_conn=1 + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-4000; y1=4000; x2=4000; y2=7000; halign=center; dyntext=0; stroke=sym-primary; text=Vcc; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:Vcc} + } + role=symbol + } + } + ha:group.42 { + uuid=T7RkhKr/RbyI7kwRboIAAABj; src_uuid=AHibvjaMiL5NH+9/wR0AAAAG; + x=52000; y=96000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-5000; y1=-1500; mirx=1; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:line.3 { x1=-4000; y1=0; x2=-5000; y2=2000; stroke=sheet-decor; } + ha:line.4 { x1=-4000; y1=0; x2=-5000; y2=-2000; stroke=sheet-decor; } + ha:line.5 { x1=-5000; y1=-2000; x2=-17000; y2=-2000; stroke=sheet-decor; } + ha:line.6 { x1=-17000; y1=2000; x2=-5000; y2=2000; stroke=sheet-decor; } + ha:line.7 { x1=-17000; y1=2000; x2=-17000; y2=-2000; stroke=sheet-decor; } + } + ha:attrib { + -sym-comment={ Sheet level terminal (not really a symbol) for subsheet input net in a hierarchy } + -sym-copyright=(C) 2024 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=Vin + role=terminal + } + } + ha:connection.44 { + li:conn { + /2/8/1 + /2/2/5/1 + } + } + ha:connection.45 { + li:conn { + /2/8/1 + /2/5/1/1 + } + } + ha:connection.46 { + li:conn { + /2/11/2 + /2/3/2/1 + } + } + ha:connection.47 { + li:conn { + /2/11/6 + /2/7/2/1 + } + } + ha:connection.48 { + li:conn { + /2/11/8 + /2/2/4/1 + } + } + ha:connection.49 { + li:conn { + /2/16/1 + /2/3/1/1 + } + } + ha:connection.50 { + li:conn { + /2/16/1 + /2/15/1/1 + } + } + ha:connection.51 { + li:conn { + /2/20/2 + /2/19/2/1 + } + } + ha:connection.52 { + li:conn { + /2/20/3 + /2/2/3/1 + } + } + ha:connection.53 { + li:conn { + /2/20/5 + /2/4/2/1 + } + } + ha:connection.54 { + li:conn { + /2/23/1 + /2/19/1/1 + } + } + ha:connection.55 { + li:conn { + /2/23/1 + /2/22/1/1 + } + } + ha:connection.56 { + li:conn { + /2/28/1 + /2/7/1/1 + } + } + ha:connection.57 { + li:conn { + /2/28/2 + /2/6/2/1 + } + } + ha:connection.58 { + li:conn { + /2/32/1 + /2/31/1/1 + } + } + ha:connection.59 { + li:conn { + /2/32/1 + /2/6/1/1 + } + } + ha:connection.60 { + li:conn { + /2/36/1 + /2/4/1/1 + } + } + ha:connection.61 { + li:conn { + /2/38/1/1 + /2/36/1 + } + } + ha:connection.62 { + li:conn { + /2/40/1/1 + /2/11/9 + } + } + ha:connection.63 { + li:conn { + /2/42/1 + /2/20/3 + } + } + ha:group.67 { + uuid=iV6mVSrBkvVTynZQqdkAAADI; + x=204000; y=100000; + li:objects { + ha:polygon.1 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=-12000; } + ha:line { x1=0; y1=-12000; x2=16000; y2=-12000; } + ha:line { x1=16000; y1=-12000; x2=16000; y2=0; } + ha:line { x1=16000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + ha:group.2 { + uuid=iV6mVSrBkvVTynZQqdkAAADJ; src_uuid=dp4EN5+Q1YO5vR+GW1UAAAAs; + x=8000; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=Vcc + pinnum=1 + role=terminal + } + } + ha:group.3 { + uuid=iV6mVSrBkvVTynZQqdkAAADK; src_uuid=dp4EN5+Q1YO5vR+GW1UAAAAs; + x=8000; y=-16000; rot=90.000000; mirx=1; miry=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=Vss + pinnum=2 + role=terminal + } + } + ha:text.4 { x1=0; y1=0; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + name=U1 + role=symbol + } + } + ha:group.68 { + uuid=iV6mVSrBkvVTynZQqdkAAADN; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB6; + x=212000; y=104000; + li:objects { + ha:group.1 { + uuid=iV6mVSrBkvVTynZQqdkAAADO; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB7; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + drc/require_graphical_conn=1 + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-4000; y1=4000; x2=4000; y2=7000; halign=center; dyntext=0; stroke=sym-primary; text=Vcc; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:Vcc} + } + role=symbol + } + } + ha:connection.69 { + li:conn { + /2/68/1/1 + /2/67/2/1 + } + } + ha:group.70 { + uuid=iV6mVSrBkvVTynZQqdkAAADR; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=212000; y=84000; + li:objects { + ha:group.1 { + uuid=iV6mVSrBkvVTynZQqdkAAADS; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + drc/require_graphical_conn=1 + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:connection.71 { + li:conn { + /2/70/1/1 + /2/67/3/1 + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer=Tibor 'Igor2' Palinkas + page=3/4 + print_page=A/4 + title=power supply + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 2 + grid = 4.0960 mm + } + } + } +} Index: tags/1.0.5/doc/examples/hierarchic/10_cpu/serial.rs =================================================================== --- tags/1.0.5/doc/examples/hierarchic/10_cpu/serial.rs (nonexistent) +++ tags/1.0.5/doc/examples/hierarchic/10_cpu/serial.rs (revision 10414) @@ -0,0 +1,967 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + ha:group.1 { + uuid=GOjvawM2mgwjKV+ohqMAAAAr; + li:objects { + ha:group.1 { + uuid=GOjvawM2mgwjKV+ohqMAAAAs; loclib_name=2n7002_sot23; + li:objects { + } + ha:attrib { + device=2n7002 + footprint=SOT23 + li:portmap { + {G->pcb/pinnum=1} + {S->pcb/pinnum=2} + {D->pcb/pinnum=3} + } + } + } + } + ha:attrib { + ha:purpose = { value=devmap; prio=0; } + } + } + } + } + ha:obj_direct.2 { + uuid=GOjvawM2mgwjKV+ohqMAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.1 { + uuid=8/SYZ/pfBzxyqFA12WQAAAAC; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAg; + li:objects { + ha:polygon.11 { + li:outline { + ha:line { x1=0; y1=0; x2=80000; y2=0; } + ha:line { x1=80000; y1=0; x2=80000; y2=20000; } + ha:line { x1=80000; y1=20000; x2=0; y2=20000; } + ha:line { x1=0; y1=20000; x2=0; y2=0; } + } + stroke=titlebox-frame; + fill=titlebox-fill; + } + ha:line.12 { x1=0; y1=10000; x2=80000; y2=10000; stroke=titlebox-frame; } + ha:line.13 { x1=40000; y1=10000; x2=40000; y2=0; stroke=titlebox-frame; } + ha:text.20 { x1=1000; y1=16500; dyntext=0; stroke=titlebox-big; text=TITLE; } + ha:text.21 { x1=1000; y1=10500; x2=79000; y2=16000; dyntext=1; stroke=titlebox-big; text=%../../A.title%; } + ha:text.22 { x1=1000; y1=5500; dyntext=0; stroke=titlebox-small; text={PROJECT:}; } + ha:text.23 { x1=13000; y1=5500; x2=39000; y2=9500; dyntext=1; stroke=titlebox-big; text=%project.name%; } + ha:text.24 { x1=1000; y1=500; dyntext=0; stroke=titlebox-small; text={PAGE:}; } + ha:text.25 { x1=10000; y1=500; x2=39000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.page%; } + ha:text.26 { x1=41000; y1=5500; dyntext=0; stroke=titlebox-small; text={FILE:}; } + ha:text.27 { x1=48000; y1=5500; x2=79000; y2=9500; dyntext=1; stroke=titlebox-big; text=%filename%; } + ha:text.28 { x1=41000; y1=500; dyntext=0; stroke=titlebox-small; text={MAINTAINER:}; } + ha:text.29 { x1=55000; y1=500; x2=79000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.maintainer%; } + ha:text.30 { x1=79000; y1=16000; mirx=1; dyntext=1; stroke=sheet-decor; text=%stance.model% %stance.sub_major% %stance.sub_minor% %stance.test_bench% %view.name%; } + } + ha:attrib { + purpose=titlebox + } + } + ha:group.7 { + uuid=GOjvawM2mgwjKV+ohqMAAAAQ; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=108000; y=140000; + li:objects { + ha:group.1 { + uuid=GOjvawM2mgwjKV+ohqMAAAAR; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=GOjvawM2mgwjKV+ohqMAAAAS; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=8000; y1=-2000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=4000; y1=2000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + ha:device = { value=resistor; prio=31050; } + footprint=1206 + name=R101 + role=symbol + ha:spice/prefix = { value=R; prio=31050; } + value=1k + } + } + ha:group.9 { + uuid=GOjvawM2mgwjKV+ohqMAAAAW; + li:objects { + ha:line.1 { x1=96000; y1=140000; x2=108000; y2=140000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.11 { + li:conn { + /2/9/1 + /2/7/2/1 + } + } + ha:group.12 { + uuid=GOjvawM2mgwjKV+ohqMAAAAX; + li:objects { + ha:line.1 { x1=96000; y1=144000; x2=104000; y2=144000; stroke=wire; } + ha:line.2 { x1=104000; y1=144000; x2=104000; y2=148000; stroke=wire; } + ha:line.3 { x1=104000; y1=148000; x2=140000; y2=148000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.14 { + uuid=GOjvawM2mgwjKV+ohqMAAAAY; + li:objects { + ha:line.1 { x1=128000; y1=140000; x2=140000; y2=140000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.15 { + li:conn { + /2/14/1 + /2/7/1/1 + } + } + ha:group.16 { + uuid=GOjvawM2mgwjKV+ohqMAAAAb; src_uuid=AHibvjaMiL5NH+9/wR0AAAAG; + x=140000; y=148000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-5000; y1=-1500; mirx=1; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:line.3 { x1=-4000; y1=0; x2=-5000; y2=2000; stroke=sheet-decor; } + ha:line.4 { x1=-4000; y1=0; x2=-5000; y2=-2000; stroke=sheet-decor; } + ha:line.5 { x1=-5000; y1=-2000; x2=-17000; y2=-2000; stroke=sheet-decor; } + ha:line.6 { x1=-17000; y1=2000; x2=-5000; y2=2000; stroke=sheet-decor; } + ha:line.7 { x1=-17000; y1=2000; x2=-17000; y2=-2000; stroke=sheet-decor; } + } + ha:attrib { + -sym-comment={ Sheet level terminal (not really a symbol) for subsheet input net in a hierarchy } + -sym-copyright=(C) 2024 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=term_rx + role=terminal + } + } + ha:group.17 { + uuid=GOjvawM2mgwjKV+ohqMAAAAe; src_uuid=AHibvjaMiL5NH+9/wR0AAAAI; + x=140000; y=140000; + li:objects { + ha:line.1 { x1=4000; y1=0; x2=0; y2=0; stroke=term-decor; } + ha:text.2 { x1=4500; y1=-1500; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:line.3 { x1=17000; y1=0; x2=16000; y2=2000; stroke=sheet-decor; } + ha:line.4 { x1=17000; y1=0; x2=16000; y2=-2000; stroke=sheet-decor; } + ha:line.5 { x1=16000; y1=-2000; x2=4000; y2=-2000; stroke=sheet-decor; } + ha:line.6 { x1=4000; y1=2000; x2=16000; y2=2000; stroke=sheet-decor; } + ha:line.7 { x1=4000; y1=2000; x2=4000; y2=-2000; stroke=sheet-decor; } + } + ha:attrib { + -sym-comment={ Sheet level terminal (not really a symbol) for subsheet output net in a hierarchy } + -sym-copyright=(C) 2024 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=term_tx + role=terminal + } + } + ha:connection.18 { + li:conn { + /2/16/1 + /2/12/3 + } + } + ha:connection.19 { + li:conn { + /2/17/1 + /2/14/1 + } + } + ha:group.20 { + uuid=GOjvawM2mgwjKV+ohqMAAAAn; src_uuid=iNOQfJpO6hT/HFDFGjoAAACC; + x=120000; y=80000; + li:objects { + ha:group.1 { + uuid=GOjvawM2mgwjKV+ohqMAAAAo; src_uuid=iNOQfJpO6hT/HFDFGjoAAACD; + x=12000; y=12000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=D + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:group.2 { + uuid=GOjvawM2mgwjKV+ohqMAAAAp; src_uuid=iNOQfJpO6hT/HFDFGjoAAACE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=G + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:text.3 { x1=8000; y1=8000; rot=90.000000; dyntext=1; stroke=sym-secondary; text=%../a.devmap%; floater=1; } + ha:text.4 { x1=4000; y1=8000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:arc.5 { cx=11000; cy=3000; r=5500; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:line.6 { x1=4000; y1=0; x2=8000; y2=0; stroke=sym-decor; } + ha:line.7 { x1=9000; y1=-1000; x2=9000; y2=1000; stroke=sym-decor; } + ha:line.8 { x1=9000; y1=2000; x2=9000; y2=4000; stroke=sym-decor; } + ha:line.9 { x1=9000; y1=5000; x2=9000; y2=7000; stroke=sym-decor; } + ha:line.10 { x1=9000; y1=3000; x2=12000; y2=3000; stroke=sym-decor; } + ha:line.11 { x1=9000; y1=0; x2=12000; y2=0; stroke=sym-decor; } + ha:line.12 { x1=9000; y1=6000; x2=12000; y2=6000; stroke=sym-decor; } + ha:line.13 { x1=12000; y1=6000; x2=12000; y2=8000; stroke=sym-decor; } + ha:line.14 { x1=12000; y1=-4000; x2=12000; y2=3000; stroke=sym-decor; } + ha:line.15 { x1=13000; y1=3000; x2=15000; y2=3000; stroke=sym-decor; } + ha:line.16 { x1=15000; y1=3000; x2=14000; y2=4000; stroke=sym-decor; } + ha:line.17 { x1=14000; y1=4000; x2=13000; y2=3000; stroke=sym-decor; } + ha:line.18 { x1=13000; y1=4000; x2=15000; y2=4000; stroke=sym-decor; } + ha:line.19 { x1=12000; y1=7000; x2=14000; y2=7000; stroke=sym-decor; } + ha:line.20 { x1=14000; y1=-1000; x2=12000; y2=-1000; stroke=sym-decor; } + ha:line.21 { x1=8000; y1=7000; x2=8000; y2=0; stroke=sym-decor; } + ha:polygon.22 { + li:outline { + ha:line { x1=10000; y1=4000; x2=9000; y2=3000; } + ha:line { x1=9000; y1=3000; x2=10000; y2=2000; } + ha:line { x1=10000; y1=2000; x2=10000; y2=4000; } + } + stroke=sym-decor; + fill=sym-decor; + } + ha:group.23 { + uuid=GOjvawM2mgwjKV+ohqMAAAAq; src_uuid=iNOQfJpO6hT/HFDFGjoAAACF; + x=12000; y=-4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=S + role=terminal + ha:spice/pinnum = { value=3; prio=31050; } + } + } + ha:line.24 { x1=14000; y1=-1000; x2=14000; y2=3000; stroke=sym-decor; } + ha:line.25 { x1=14000; y1=4000; x2=14000; y2=7000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + devmap=2n7002_sot23 + name=Q102 + role=symbol + ha:spice/prefix = { value=M; prio=31050; } + } + } + ha:group.21 { + uuid=GOjvawM2mgwjKV+ohqMAAAAw; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=132000; y=100000; rot=90.000000; + li:objects { + ha:group.1 { + uuid=GOjvawM2mgwjKV+ohqMAAAAx; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=GOjvawM2mgwjKV+ohqMAAAAy; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=8000; y1=-2000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=4000; y1=2000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + ha:device = { value=resistor; prio=31050; } + footprint=1206 + name=R102 + role=symbol + ha:spice/prefix = { value=R; prio=31050; } + value=1k + } + } + ha:group.22 { + uuid=GOjvawM2mgwjKV+ohqMAAAAz; + li:objects { + ha:line.1 { x1=132000; y1=92000; x2=132000; y2=100000; stroke=wire; } + ha:line.2 { x1=132000; y1=96000; x2=144000; y2=96000; stroke=wire; } + ha:line.3 { x1=132000; y1=96000; x2=132000; y2=96000; stroke=junction; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.24 { + li:conn { + /2/22/1 + /2/21/2/1 + } + } + ha:group.25 { + uuid=GOjvawM2mgwjKV+ohqMAAAA0; + li:objects { + ha:line.1 { x1=132000; y1=120000; x2=132000; y2=124000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.26 { + li:conn { + /2/25/1 + /2/21/1/1 + } + } + ha:group.27 { + uuid=GOjvawM2mgwjKV+ohqMAAAA5; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB6; + x=132000; y=124000; + li:objects { + ha:group.1 { + uuid=GOjvawM2mgwjKV+ohqMAAAA6; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB7; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + drc/require_graphical_conn=1 + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-4000; y1=4000; x2=4000; y2=7000; halign=center; dyntext=0; stroke=sym-primary; text=Vcc; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:Vcc} + } + role=symbol + } + } + ha:connection.28 { + li:conn { + /2/27/1/1 + /2/25/1 + } + } + ha:connection.29 { + li:conn { + /2/22/1 + /2/20/1/1 + } + } + ha:group.30 { + uuid=GOjvawM2mgwjKV+ohqMAAAA7; + li:objects { + ha:line.2 { x1=96000; y1=128000; x2=108000; y2=128000; stroke=wire; } + ha:line.3 { x1=108000; y1=128000; x2=108000; y2=80000; stroke=wire; } + ha:line.4 { x1=108000; y1=80000; x2=120000; y2=80000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.32 { + li:conn { + /2/30/4 + /2/20/2/1 + } + } + ha:group.33 { + uuid=GOjvawM2mgwjKV+ohqMAAABA; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=132000; y=68000; + li:objects { + ha:group.1 { + uuid=GOjvawM2mgwjKV+ohqMAAABB; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + drc/require_graphical_conn=1 + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.34 { + uuid=GOjvawM2mgwjKV+ohqMAAABC; + li:objects { + ha:line.1 { x1=132000; y1=72000; x2=132000; y2=68000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.35 { + li:conn { + /2/34/1 + /2/20/23/1 + } + } + ha:connection.36 { + li:conn { + /2/34/1 + /2/33/1/1 + } + } + ha:group.47 { + uuid=GOjvawM2mgwjKV+ohqMAAABY; src_uuid=AHibvjaMiL5NH+9/wR0AAAAI; + x=144000; y=96000; + li:objects { + ha:line.1 { x1=4000; y1=0; x2=0; y2=0; stroke=term-decor; } + ha:text.2 { x1=4500; y1=-1500; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:line.3 { x1=17000; y1=0; x2=16000; y2=2000; stroke=sheet-decor; } + ha:line.4 { x1=17000; y1=0; x2=16000; y2=-2000; stroke=sheet-decor; } + ha:line.5 { x1=16000; y1=-2000; x2=4000; y2=-2000; stroke=sheet-decor; } + ha:line.6 { x1=4000; y1=2000; x2=16000; y2=2000; stroke=sheet-decor; } + ha:line.7 { x1=4000; y1=2000; x2=4000; y2=-2000; stroke=sheet-decor; } + } + ha:attrib { + -sym-comment={ Sheet level terminal (not really a symbol) for subsheet output net in a hierarchy } + -sym-copyright=(C) 2024 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=inv_tx + role=terminal + } + } + ha:connection.48 { + li:conn { + /2/47/1 + /2/22/2 + } + } + ha:group.49 { + uuid=Q8cSXpoK0QkYCcKy+asAAAAv; src_uuid=iNOQfJpO6hT/HFDFGjoAAACC; + x=196000; y=80000; mirx=1; + li:objects { + ha:group.1 { + uuid=Q8cSXpoK0QkYCcKy+asAAAAw; src_uuid=iNOQfJpO6hT/HFDFGjoAAACD; + x=12000; y=12000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=D + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:group.2 { + uuid=Q8cSXpoK0QkYCcKy+asAAAAx; src_uuid=iNOQfJpO6hT/HFDFGjoAAACE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=G + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:text.3 { x1=8000; y1=8000; rot=90.000000; dyntext=1; stroke=sym-secondary; text=%../a.devmap%; floater=1; } + ha:text.4 { x1=4000; y1=8000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:arc.5 { cx=11000; cy=3000; r=5500; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:line.6 { x1=4000; y1=0; x2=8000; y2=0; stroke=sym-decor; } + ha:line.7 { x1=9000; y1=-1000; x2=9000; y2=1000; stroke=sym-decor; } + ha:line.8 { x1=9000; y1=2000; x2=9000; y2=4000; stroke=sym-decor; } + ha:line.9 { x1=9000; y1=5000; x2=9000; y2=7000; stroke=sym-decor; } + ha:line.10 { x1=9000; y1=3000; x2=12000; y2=3000; stroke=sym-decor; } + ha:line.11 { x1=9000; y1=0; x2=12000; y2=0; stroke=sym-decor; } + ha:line.12 { x1=9000; y1=6000; x2=12000; y2=6000; stroke=sym-decor; } + ha:line.13 { x1=12000; y1=6000; x2=12000; y2=8000; stroke=sym-decor; } + ha:line.14 { x1=12000; y1=-4000; x2=12000; y2=3000; stroke=sym-decor; } + ha:line.15 { x1=13000; y1=3000; x2=15000; y2=3000; stroke=sym-decor; } + ha:line.16 { x1=15000; y1=3000; x2=14000; y2=4000; stroke=sym-decor; } + ha:line.17 { x1=14000; y1=4000; x2=13000; y2=3000; stroke=sym-decor; } + ha:line.18 { x1=13000; y1=4000; x2=15000; y2=4000; stroke=sym-decor; } + ha:line.19 { x1=12000; y1=7000; x2=14000; y2=7000; stroke=sym-decor; } + ha:line.20 { x1=14000; y1=-1000; x2=12000; y2=-1000; stroke=sym-decor; } + ha:line.21 { x1=8000; y1=7000; x2=8000; y2=0; stroke=sym-decor; } + ha:polygon.22 { + li:outline { + ha:line { x1=10000; y1=4000; x2=9000; y2=3000; } + ha:line { x1=9000; y1=3000; x2=10000; y2=2000; } + ha:line { x1=10000; y1=2000; x2=10000; y2=4000; } + } + stroke=sym-decor; + fill=sym-decor; + } + ha:group.23 { + uuid=Q8cSXpoK0QkYCcKy+asAAAAy; src_uuid=iNOQfJpO6hT/HFDFGjoAAACF; + x=12000; y=-4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=S + role=terminal + ha:spice/pinnum = { value=3; prio=31050; } + } + } + ha:line.24 { x1=14000; y1=-1000; x2=14000; y2=3000; stroke=sym-decor; } + ha:line.25 { x1=14000; y1=4000; x2=14000; y2=7000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + devmap=2n7002_sot23 + name=Q103 + role=symbol + ha:spice/prefix = { value=M; prio=31050; } + } + } + ha:group.50 { + uuid=Q8cSXpoK0QkYCcKy+asAAAAz; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=184000; y=100000; rot=90.000000; mirx=1; + li:objects { + ha:group.1 { + uuid=Q8cSXpoK0QkYCcKy+asAAAA0; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=Q8cSXpoK0QkYCcKy+asAAAA1; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=8000; y1=-2000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=4000; y1=2000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + ha:device = { value=resistor; prio=31050; } + footprint=1206 + name=R103 + role=symbol + ha:spice/prefix = { value=R; prio=31050; } + value=1k + } + } + ha:group.54 { + uuid=Q8cSXpoK0QkYCcKy+asAAAA3; src_uuid=GOjvawM2mgwjKV+ohqMAAAA0; + x=316000; y=0; mirx=1; + li:objects { + ha:line.1 { x1=132000; y1=120000; x2=132000; y2=124000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.56 { + uuid=Q8cSXpoK0QkYCcKy+asAAAA4; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB6; + x=184000; y=124000; mirx=1; + li:objects { + ha:group.1 { + uuid=Q8cSXpoK0QkYCcKy+asAAAA5; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB7; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + drc/require_graphical_conn=1 + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-4000; y1=4000; x2=4000; y2=7000; halign=center; dyntext=0; stroke=sym-primary; text=Vcc; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:Vcc} + } + role=symbol + } + } + ha:group.58 { + uuid=Q8cSXpoK0QkYCcKy+asAAAA6; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=184000; y=68000; mirx=1; + li:objects { + ha:group.1 { + uuid=Q8cSXpoK0QkYCcKy+asAAAA7; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + drc/require_graphical_conn=1 + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.59 { + uuid=Q8cSXpoK0QkYCcKy+asAAAA8; src_uuid=GOjvawM2mgwjKV+ohqMAAABC; + x=316000; y=0; mirx=1; + li:objects { + ha:line.1 { x1=132000; y1=72000; x2=132000; y2=68000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.64 { + li:conn { + /2/50/2/1 + /2/70/2 + } + } + ha:connection.65 { + li:conn { + /2/49/1/1 + /2/70/2 + } + } + ha:connection.66 { + li:conn { + /2/54/1 + /2/50/1/1 + } + } + ha:connection.67 { + li:conn { + /2/56/1/1 + /2/54/1 + } + } + ha:connection.68 { + li:conn { + /2/59/1 + /2/49/23/1 + } + } + ha:connection.69 { + li:conn { + /2/59/1 + /2/58/1/1 + } + } + ha:group.70 { + uuid=Q8cSXpoK0QkYCcKy+asAAAA+; + li:objects { + ha:line.1 { x1=96000; y1=132000; x2=172000; y2=132000; stroke=wire; } + ha:line.2 { x1=184000; y1=92000; x2=184000; y2=100000; stroke=wire; } + ha:line.3 { x1=184000; y1=96000; x2=172000; y2=96000; stroke=wire; } + ha:line.4 { x1=184000; y1=96000; x2=184000; y2=96000; stroke=junction; } + ha:line.5 { x1=172000; y1=132000; x2=172000; y2=96000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.72 { + uuid=Q8cSXpoK0QkYCcKy+asAAAA/; + li:objects { + ha:line.1 { x1=196000; y1=80000; x2=208000; y2=80000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.73 { + li:conn { + /2/72/1 + /2/49/2/1 + } + } + ha:group.74 { + uuid=Q8cSXpoK0QkYCcKy+asAAABB; src_uuid=AHibvjaMiL5NH+9/wR0AAAAG; + x=208000; y=80000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-5000; y1=-1500; mirx=1; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:line.3 { x1=-4000; y1=0; x2=-5000; y2=2000; stroke=sheet-decor; } + ha:line.4 { x1=-4000; y1=0; x2=-5000; y2=-2000; stroke=sheet-decor; } + ha:line.5 { x1=-5000; y1=-2000; x2=-17000; y2=-2000; stroke=sheet-decor; } + ha:line.6 { x1=-17000; y1=2000; x2=-5000; y2=2000; stroke=sheet-decor; } + ha:line.7 { x1=-17000; y1=2000; x2=-17000; y2=-2000; stroke=sheet-decor; } + } + ha:attrib { + -sym-comment={ Sheet level terminal (not really a symbol) for subsheet input net in a hierarchy } + -sym-copyright=(C) 2024 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=inv_rx + role=terminal + } + } + ha:connection.75 { + li:conn { + /2/74/1 + /2/72/1 + } + } + ha:group.76 { + uuid=Q8cSXpoK0QkYCcKy+asAAABC; + x=76000; y=148000; + li:objects { + ha:group.1 { + uuid=Q8cSXpoK0QkYCcKy+asAAABD; src_uuid=GOjvawM2mgwjKV+ohqMAAAAD; + x=20000; y=-4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=rx1 + pinnum=12 + role=terminal + } + } + ha:group.2 { + uuid=Q8cSXpoK0QkYCcKy+asAAABE; src_uuid=GOjvawM2mgwjKV+ohqMAAAAD; + x=20000; y=-8000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=tx1 + pinnum=13 + role=terminal + } + } + ha:group.3 { + uuid=Q8cSXpoK0QkYCcKy+asAAABF; src_uuid=GOjvawM2mgwjKV+ohqMAAAAD; + x=20000; y=-16000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=rx2 + pinnum=17 + role=terminal + } + } + ha:group.4 { + uuid=Q8cSXpoK0QkYCcKy+asAAABG; src_uuid=GOjvawM2mgwjKV+ohqMAAAAD; + x=20000; y=-20000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=tx2 + pinnum=18 + role=terminal + } + } + ha:polygon.5 { + li:outline { + ha:line { x1=16000; y1=0; x2=16000; y2=-24000; } + ha:line { x1=16000; y1=-24000; x2=0; y2=-24000; } + ha:line { x1=0; y1=-24000; x2=0; y2=0; } + ha:line { x1=0; y1=0; x2=16000; y2=0; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + ha:text.6 { x1=0; y1=0; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + name=U1 + role=symbol + } + } + ha:connection.77 { + li:conn { + /2/12/1 + /2/76/1/1 + } + } + ha:connection.78 { + li:conn { + /2/9/1 + /2/76/2/1 + } + } + ha:connection.79 { + li:conn { + /2/70/1 + /2/76/3/1 + } + } + ha:connection.80 { + li:conn { + /2/30/2 + /2/76/4/1 + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer=Tibor 'Igor2' Palinkas + page=4/4 + print_page=A/4 + title={serial ports: terminal and inverted} + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 2 + grid = 4.0960 mm + } + } + } +} Index: tags/1.0.5/doc/examples/hierarchic/20_led/led.rs =================================================================== --- tags/1.0.5/doc/examples/hierarchic/20_led/led.rs (nonexistent) +++ tags/1.0.5/doc/examples/hierarchic/20_led/led.rs (revision 10414) @@ -0,0 +1,495 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + ha:group.1 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAP; + li:objects { + ha:group.1 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAQ; loclib_name=2n7002_sot23; + li:objects { + } + ha:attrib { + device=2n7002 + footprint=SOT23 + li:portmap { + {G->pcb/pinnum=1} + {S->pcb/pinnum=2} + {D->pcb/pinnum=3} + } + } + } + ha:group.2 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAj; loclib_name=led5; + li:objects { + } + ha:attrib { + device=led5 + footprint=LED5 + li:portmap { + {C->pcb/pinnum=1} + {A->pcb/pinnum=2} + } + } + } + } + ha:attrib { + ha:purpose = { value=devmap; prio=0; } + } + } + } + } + ha:obj_direct.2 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.1 { + uuid=8/SYZ/pfBzxyqFA12WQAAAAC; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAg; + li:objects { + ha:polygon.11 { + li:outline { + ha:line { x1=0; y1=0; x2=80000; y2=0; } + ha:line { x1=80000; y1=0; x2=80000; y2=20000; } + ha:line { x1=80000; y1=20000; x2=0; y2=20000; } + ha:line { x1=0; y1=20000; x2=0; y2=0; } + } + stroke=titlebox-frame; + fill=titlebox-fill; + } + ha:line.12 { x1=0; y1=10000; x2=80000; y2=10000; stroke=titlebox-frame; } + ha:line.13 { x1=40000; y1=10000; x2=40000; y2=0; stroke=titlebox-frame; } + ha:text.20 { x1=1000; y1=16500; dyntext=0; stroke=titlebox-big; text=TITLE; } + ha:text.21 { x1=1000; y1=10500; x2=79000; y2=16000; dyntext=1; stroke=titlebox-big; text=%../../A.title%; } + ha:text.22 { x1=1000; y1=5500; dyntext=0; stroke=titlebox-small; text={PROJECT:}; } + ha:text.23 { x1=13000; y1=5500; x2=39000; y2=9500; dyntext=1; stroke=titlebox-big; text=%project.name%; } + ha:text.24 { x1=1000; y1=500; dyntext=0; stroke=titlebox-small; text={PAGE:}; } + ha:text.25 { x1=10000; y1=500; x2=39000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.page%; } + ha:text.26 { x1=41000; y1=5500; dyntext=0; stroke=titlebox-small; text={FILE:}; } + ha:text.27 { x1=48000; y1=5500; x2=79000; y2=9500; dyntext=1; stroke=titlebox-big; text=%filename%; } + ha:text.28 { x1=41000; y1=500; dyntext=0; stroke=titlebox-small; text={MAINTAINER:}; } + ha:text.29 { x1=55000; y1=500; x2=79000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.maintainer%; } + ha:text.30 { x1=79000; y1=16000; mirx=1; dyntext=1; stroke=sheet-decor; text=%stance.model% %stance.sub_major% %stance.sub_minor% %stance.test_bench% %view.name%; } + } + ha:attrib { + purpose=titlebox + } + } + ha:group.2 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAL; src_uuid=iNOQfJpO6hT/HFDFGjoAAACC; + x=96000; y=104000; + li:objects { + ha:group.1 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAM; src_uuid=iNOQfJpO6hT/HFDFGjoAAACD; + x=12000; y=12000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=D + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:group.2 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAN; src_uuid=iNOQfJpO6hT/HFDFGjoAAACE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=G + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:text.3 { x1=8000; y1=8000; rot=90.000000; dyntext=1; stroke=sym-secondary; text=%../a.devmap%; floater=1; } + ha:text.4 { x1=4000; y1=8000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:arc.5 { cx=11000; cy=3000; r=5500; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:line.6 { x1=4000; y1=0; x2=8000; y2=0; stroke=sym-decor; } + ha:line.7 { x1=9000; y1=-1000; x2=9000; y2=1000; stroke=sym-decor; } + ha:line.8 { x1=9000; y1=2000; x2=9000; y2=4000; stroke=sym-decor; } + ha:line.9 { x1=9000; y1=5000; x2=9000; y2=7000; stroke=sym-decor; } + ha:line.10 { x1=9000; y1=3000; x2=12000; y2=3000; stroke=sym-decor; } + ha:line.11 { x1=9000; y1=0; x2=12000; y2=0; stroke=sym-decor; } + ha:line.12 { x1=9000; y1=6000; x2=12000; y2=6000; stroke=sym-decor; } + ha:line.13 { x1=12000; y1=6000; x2=12000; y2=8000; stroke=sym-decor; } + ha:line.14 { x1=12000; y1=-4000; x2=12000; y2=3000; stroke=sym-decor; } + ha:line.15 { x1=13000; y1=3000; x2=15000; y2=3000; stroke=sym-decor; } + ha:line.16 { x1=15000; y1=3000; x2=14000; y2=4000; stroke=sym-decor; } + ha:line.17 { x1=14000; y1=4000; x2=13000; y2=3000; stroke=sym-decor; } + ha:line.18 { x1=13000; y1=4000; x2=15000; y2=4000; stroke=sym-decor; } + ha:line.19 { x1=12000; y1=7000; x2=14000; y2=7000; stroke=sym-decor; } + ha:line.20 { x1=14000; y1=-1000; x2=12000; y2=-1000; stroke=sym-decor; } + ha:line.21 { x1=8000; y1=7000; x2=8000; y2=0; stroke=sym-decor; } + ha:polygon.22 { + li:outline { + ha:line { x1=10000; y1=4000; x2=9000; y2=3000; } + ha:line { x1=9000; y1=3000; x2=10000; y2=2000; } + ha:line { x1=10000; y1=2000; x2=10000; y2=4000; } + } + stroke=sym-decor; + fill=sym-decor; + } + ha:group.23 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAO; src_uuid=iNOQfJpO6hT/HFDFGjoAAACF; + x=12000; y=-4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=S + role=terminal + ha:spice/pinnum = { value=3; prio=31050; } + } + } + ha:line.24 { x1=14000; y1=-1000; x2=14000; y2=3000; stroke=sym-decor; } + ha:line.25 { x1=14000; y1=4000; x2=14000; y2=7000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + devmap=2n7002_sot23 + name=./Q1 + role=symbol + ha:spice/prefix = { value=M; prio=31050; } + } + } + ha:group.3 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAX; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=108000; y=168000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAY; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAZ; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + ha:device = { value=resistor; prio=31050; } + footprint=1206 + name=./R1 + role=symbol + ha:spice/prefix = { value=R; prio=31050; } + value=510 + } + } + ha:group.4 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAg; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAQ; + x=108000; y=124000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAh; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAR; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=C + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.2 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAi; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAS; + x=-16000; y=0; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=A + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:line.3 { x1=-4000; y1=0; x2=-6000; y2=0; stroke=sym-decor; } + ha:line.4 { x1=-12000; y1=0; x2=-10000; y2=0; stroke=sym-decor; } + ha:line.5 { x1=-10000; y1=4000; x2=-6000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=-6000; y1=0; x2=-10000; y2=-4000; stroke=sym-decor; } + ha:line.7 { x1=-10000; y1=4000; x2=-10000; y2=-4000; stroke=sym-decor; } + ha:line.8 { x1=-6000; y1=4000; x2=-6000; y2=-4000; stroke=sym-decor; } + ha:text.9 { x1=-4000; y1=13000; rot=90.000000; dyntext=1; stroke=sym-secondary; text=%../a.devmap%; floater=1; } + ha:text.10 { x1=-8000; y1=13000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.11 { x1=-8000; y1=8000; x2=-6000; y2=11000; stroke=sym-decor; } + ha:line.12 { x1=-6000; y1=11000; x2=-7000; y2=10000; stroke=sym-decor; } + ha:line.13 { x1=-6000; y1=11000; x2=-6517; y2=9545; stroke=sym-decor; } + ha:line.14 { x1=-10000; y1=7000; x2=-8000; y2=10000; stroke=sym-decor; } + ha:line.15 { x1=-8000; y1=10000; x2=-8000; y2=8000; stroke=sym-decor; } + ha:line.16 { x1=-8303; y1=6354; x2=-6303; y2=9354; stroke=sym-decor; } + ha:line.17 { x1=-6303; y1=9354; x2=-7303; y2=8354; stroke=sym-decor; } + ha:line.18 { x1=-6303; y1=9354; x2=-6820; y2=7899; stroke=sym-decor; } + ha:line.19 { x1=-10303; y1=5354; x2=-8303; y2=8354; stroke=sym-decor; } + ha:line.20 { x1=-8303; y1=8354; x2=-8303; y2=6354; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + devmap=led5 + name=./D1 + role=symbol + ha:spice/prefix = { value=D; prio=31050; } + } + } + ha:group.5 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAk; + li:objects { + ha:line.1 { x1=108000; y1=116000; x2=108000; y2=124000; stroke=wire; } + ha:text.2 { x1=110000; y1=120000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=./led_fet + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.6 { + li:conn { + /2/5/1 + /2/2/1/1 + } + } + ha:connection.7 { + li:conn { + /2/5/1 + /2/4/1/1 + } + } + ha:group.8 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAl; + li:objects { + ha:line.1 { x1=108000; y1=140000; x2=108000; y2=148000; stroke=wire; } + ha:text.2 { x1=110000; y1=144000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=res_led + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.9 { + li:conn { + /2/8/1 + /2/3/1/1 + } + } + ha:connection.10 { + li:conn { + /2/8/1 + /2/4/2/1 + } + } + ha:connection.12 { + li:conn { + /2/3/2/1 + /2/14/3 + } + } + ha:group.14 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAo; + li:objects { + ha:line.1 { x1=84000; y1=176000; x2=108000; y2=176000; stroke=wire; } + ha:line.3 { x1=108000; y1=168000; x2=108000; y2=176000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.16 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAp; + li:objects { + ha:line.1 { x1=96000; y1=104000; x2=84000; y2=104000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.17 { + li:conn { + /2/16/1 + /2/2/2/1 + } + } + ha:group.20 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAs; + li:objects { + ha:line.1 { x1=108000; y1=96000; x2=108000; y2=88000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.21 { + li:conn { + /2/20/1 + /2/2/23/1 + } + } + ha:group.22 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAx; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=108000; y=88000; + li:objects { + ha:group.1 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAy; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + drc/require_graphical_conn=1 + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:connection.23 { + li:conn { + /2/22/1/1 + /2/20/1 + } + } + ha:group.24 { + uuid=2SRAr8t6oTchmYmlPFsAAAA9; src_uuid=AHibvjaMiL5NH+9/wR0AAAAG; + x=84000; y=176000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-5000; y1=-1500; mirx=1; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:line.3 { x1=-4000; y1=0; x2=-5000; y2=2000; stroke=sheet-decor; } + ha:line.4 { x1=-4000; y1=0; x2=-5000; y2=-2000; stroke=sheet-decor; } + ha:line.5 { x1=-5000; y1=-2000; x2=-17000; y2=-2000; stroke=sheet-decor; } + ha:line.6 { x1=-17000; y1=2000; x2=-5000; y2=2000; stroke=sheet-decor; } + ha:line.7 { x1=-17000; y1=2000; x2=-17000; y2=-2000; stroke=sheet-decor; } + } + ha:attrib { + -sym-comment={ Sheet level terminal (not really a symbol) for subsheet input net in a hierarchy } + -sym-copyright=(C) 2024 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=Vin + role=terminal + } + } + ha:connection.25 { + li:conn { + /2/24/1 + /2/14/1 + } + } + ha:group.26 { + uuid=2SRAr8t6oTchmYmlPFsAAAA/; src_uuid=AHibvjaMiL5NH+9/wR0AAAAG; + x=84000; y=104000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-5000; y1=-1500; mirx=1; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:line.3 { x1=-4000; y1=0; x2=-5000; y2=2000; stroke=sheet-decor; } + ha:line.4 { x1=-4000; y1=0; x2=-5000; y2=-2000; stroke=sheet-decor; } + ha:line.5 { x1=-5000; y1=-2000; x2=-17000; y2=-2000; stroke=sheet-decor; } + ha:line.6 { x1=-17000; y1=2000; x2=-5000; y2=2000; stroke=sheet-decor; } + ha:line.7 { x1=-17000; y1=2000; x2=-17000; y2=-2000; stroke=sheet-decor; } + } + ha:attrib { + -sym-comment={ Sheet level terminal (not really a symbol) for subsheet input net in a hierarchy } + -sym-copyright=(C) 2024 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=ctrl + role=terminal + } + } + ha:connection.27 { + li:conn { + /2/26/1 + /2/16/1 + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer=Tibor 'Igor2' Palinkas + page=2/2 + print_page=A/4 + title=LED and driver + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 1 + grid = 2.0480 mm + } + } + } +} Index: tags/1.0.5/doc/examples/hierarchic/20_led/main.rs =================================================================== --- tags/1.0.5/doc/examples/hierarchic/20_led/main.rs (nonexistent) +++ tags/1.0.5/doc/examples/hierarchic/20_led/main.rs (revision 10414) @@ -0,0 +1,703 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + ha:group.1 { + uuid=Of4kyoIScCrE774KCa4AAABc; + li:objects { + ha:group.1 { + uuid=Of4kyoIScCrE774KCa4AAABd; loclib_name=attiny24.funcmap; + li:objects { + } + ha:attrib { + li:funcmap/ports { + { PB0/PB0 -> sigtype=digital; } + { PB0/PCINT8 -> sigtype=digital; dir=input } + { PB0/XTAL1 -> sigtype=analog; } + { PB1/PB1 -> sigtype=digital; } + { PB1/PCINT9 -> sigtype=digital; dir=input } + { PB1/XTAL2 -> sigtype=analog; } + { PB3/PB3 -> sigtype=digital; } + { PB3/PCINT11 -> sigtype=digital; dir=input } + { PB3/RESET -> sigtype=digital; dir=input } + { PB2/PB2 -> sigtype=digital; } + { PB2/PCINT10 -> sigtype=digital; dir=input } + { PB2/OC0A -> sigtype=digital; dir=output } + { PB2/INT0 -> sigtype=digital; dir=input } + { PA7/PA7 -> sigtype=digital; } + { PA7/PCINT7 -> sigtype=digital; dir=input } + { PA7/OC0B -> sigtype=digital; dir=output } + { PA7/ADC7 -> sigtype=digital; dir=input } + { PA6/PA6 -> sigtype=digital; } + { PA6/PCINT6 -> sigtype=digital; dir=input } + { PA6/MOSI -> sigtype=digital; } + { PA6/DI -> sigtype=digital; dir=input } + { PA6/SDA -> sigtype=digital; } + { PA6/OC1A -> sigtype=digital; dir=output } + { PA6/ADC6 -> sigtype=analog; dir=input } + { PA0/PA0 -> sigtype=digital; } + { PA0/PCINT0 -> sigtype=digital; dir=input } + { PA0/AREF+ADC0-> sigtype=analog; dir=input } + { PA1/PA1 -> sigtype=digital; } + { PA1/PCINT1 -> sigtype=digital; dir=input } + { PA1/AIN0 -> sigtype=analog; dir=input } + { PA1/ADC1 -> sigtype=analog; dir=input } + { PA2/PA2 -> sigtype=digital; } + { PA2/PCINT2 -> sigtype=digital; dir=input } + { PA2/AIN1 -> sigtype=analog; dir=input } + { PA2/ADC2 -> sigtype=analog; dir=input } + { PA3/PA3 -> sigtype=digital; } + { PA3/PCINT3 -> sigtype=digital; dir=input } + { PA3/ADC3 -> sigtype=analog; dir=input } + { PA4/PA4 -> sigtype=digital; } + { PA4/PCINT4 -> sigtype=digital; dir=input } + { PA4/SCK -> sigtype=digital; } + { PA4/SCL -> sigtype=digital; } + { PA4/ADC4 -> sigtype=analog; dir=input } + { PA5/PA5 -> sigtype=digital; } + { PA5/PCINT5 -> sigtype=digital; dir=input } + { PA5/MISO -> sigtype=digital; } + { PA5/DO -> sigtype=digital; dir=output } + { PA5/OC1B -> sigtype=digital; dir=output } + { PA5/ADC5 -> sigtype=analog; dir=input } + } + li:funcmap/strong_groups { + { SPI -> SCK, MISO, MOSI } + { I2C -> SDA, SCL } + { USI -> SCK, DI, DO } + } + li:funcmap/weak_groups { + { gpio -> PB0, PB1, PB2, PB3, PA6, PA7, PA0, PA1, PA2, PA3, PA4, PA5 } + { pcint -> PCINT8, PCINT9, PCINT11, PCINT10, PCINT7, PCINT6, PCINT0, PCINT1, PCINT2, PCINT3, PCINT4, PCINT5 } + { xtal -> XTAL1, XTAL2 } + { PWM -> OC0A, OC0B, OC1A, OC1B } + { adc -> AREF+ADC0, ADC1, ADC2, ADC3, ADC4, ADC5, ADC6, ADC7 } + { comparator -> AIN0, AIN1 } + } + } + } + } + ha:attrib { + ha:purpose = { value=funcmap; prio=0; } + } + } + } + } + ha:obj_direct.2 { + uuid=Of4kyoIScCrE774KCa4AAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.1 { + uuid=8/SYZ/pfBzxyqFA12WQAAAAC; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAg; + li:objects { + ha:polygon.11 { + li:outline { + ha:line { x1=0; y1=0; x2=80000; y2=0; } + ha:line { x1=80000; y1=0; x2=80000; y2=20000; } + ha:line { x1=80000; y1=20000; x2=0; y2=20000; } + ha:line { x1=0; y1=20000; x2=0; y2=0; } + } + stroke=titlebox-frame; + fill=titlebox-fill; + } + ha:line.12 { x1=0; y1=10000; x2=80000; y2=10000; stroke=titlebox-frame; } + ha:line.13 { x1=40000; y1=10000; x2=40000; y2=0; stroke=titlebox-frame; } + ha:text.20 { x1=1000; y1=16500; dyntext=0; stroke=titlebox-big; text=TITLE; } + ha:text.21 { x1=1000; y1=10500; x2=79000; y2=16000; dyntext=1; stroke=titlebox-big; text=%../../A.title%; } + ha:text.22 { x1=1000; y1=5500; dyntext=0; stroke=titlebox-small; text={PROJECT:}; } + ha:text.23 { x1=13000; y1=5500; x2=39000; y2=9500; dyntext=1; stroke=titlebox-big; text=%project.name%; } + ha:text.24 { x1=1000; y1=500; dyntext=0; stroke=titlebox-small; text={PAGE:}; } + ha:text.25 { x1=10000; y1=500; x2=39000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.page%; } + ha:text.26 { x1=41000; y1=5500; dyntext=0; stroke=titlebox-small; text={FILE:}; } + ha:text.27 { x1=48000; y1=5500; x2=79000; y2=9500; dyntext=1; stroke=titlebox-big; text=%filename%; } + ha:text.28 { x1=41000; y1=500; dyntext=0; stroke=titlebox-small; text={MAINTAINER:}; } + ha:text.29 { x1=55000; y1=500; x2=79000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.maintainer%; } + ha:text.30 { x1=79000; y1=16000; mirx=1; dyntext=1; stroke=sheet-decor; text=%stance.model% %stance.sub_major% %stance.sub_minor% %stance.test_bench% %view.name%; } + } + ha:attrib { + purpose=titlebox + } + } + ha:group.8 { + uuid=Of4kyoIScCrE774KCa4AAAAK; + x=136000; y=92000; + li:objects { + ha:group.1 { + uuid=Of4kyoIScCrE774KCa4AAAAL; src_uuid=Of4kyoIScCrE774KCa4AAAAD; + x=-8000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=ctrl + role=terminal + } + } + ha:group.2 { + uuid=Of4kyoIScCrE774KCa4AAAAM; src_uuid=Of4kyoIScCrE774KCa4AAAAD; + x=0; y=8000; rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=Vin + role=terminal + } + } + ha:polygon.3 { + li:outline { + ha:line { x1=-8000; y1=8000; x2=-8000; y2=-8000; } + ha:line { x1=-8000; y1=-8000; x2=8000; y2=-8000; } + ha:line { x1=8000; y1=-8000; x2=8000; y2=8000; } + ha:line { x1=8000; y1=8000; x2=-8000; y2=8000; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + ha:text.4 { x1=-8000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:text.5 { x1=-1000; y1=-1000; dyntext=1; stroke=sym-secondary; text=%../A.cschem/child/name%; floater=1; } + } + ha:attrib { + cschem/child/name=led + name=S1 + role=symbol + } + } + ha:group.9 { + uuid=Of4kyoIScCrE774KCa4AAABN; src_uuid=+oSyprNFSw9F5MMrBkcAAAAP; + x=68000; y=68000; + li:objects { + ha:text.1 { x1=-8000; y1=-4000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.2 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=36000; } + ha:line { x1=0; y1=36000; x2=24000; y2=36000; } + ha:line { x1=24000; y1=36000; x2=24000; y2=0; } + ha:line { x1=24000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + } + ha:group.3 { + uuid=Of4kyoIScCrE774KCa4AAABO; src_uuid=+oSyprNFSw9F5MMrBkcAAAAB; + x=0; y=24000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PB0 + pinnum=2 + role=terminal + } + } + ha:group.4 { + uuid=Of4kyoIScCrE774KCa4AAABP; src_uuid=+oSyprNFSw9F5MMrBkcAAAAC; + x=0; y=20000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PB1 + pinnum=3 + role=terminal + } + } + ha:group.5 { + uuid=Of4kyoIScCrE774KCa4AAABQ; src_uuid=+oSyprNFSw9F5MMrBkcAAAAD; + x=0; y=16000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PB2 + pinnum=5 + role=terminal + } + } + ha:group.6 { + uuid=Of4kyoIScCrE774KCa4AAABR; src_uuid=+oSyprNFSw9F5MMrBkcAAAAE; + x=0; y=12000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PB3 + pinnum=4 + role=terminal + } + } + ha:group.7 { + uuid=Of4kyoIScCrE774KCa4AAABS; src_uuid=+oSyprNFSw9F5MMrBkcAAAAF; + x=24000; y=32000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PA0 + pinnum=13 + role=terminal + } + } + ha:group.8 { + uuid=Of4kyoIScCrE774KCa4AAABT; src_uuid=+oSyprNFSw9F5MMrBkcAAAAG; + x=24000; y=28000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PA1 + pinnum=12 + role=terminal + } + } + ha:group.9 { + uuid=Of4kyoIScCrE774KCa4AAABU; src_uuid=+oSyprNFSw9F5MMrBkcAAAAH; + x=24000; y=24000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PA2 + pinnum=11 + role=terminal + } + } + ha:group.10 { + uuid=Of4kyoIScCrE774KCa4AAABV; src_uuid=+oSyprNFSw9F5MMrBkcAAAAI; + x=24000; y=20000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PA3 + pinnum=10 + role=terminal + } + } + ha:group.11 { + uuid=Of4kyoIScCrE774KCa4AAABW; src_uuid=+oSyprNFSw9F5MMrBkcAAAAJ; + x=24000; y=16000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PA4 + pinnum=9 + role=terminal + } + } + ha:group.12 { + uuid=Of4kyoIScCrE774KCa4AAABX; src_uuid=+oSyprNFSw9F5MMrBkcAAAAK; + x=24000; y=12000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + funcmap/name=OC1B + name=PA5 + pinnum=8 + role=terminal + } + } + ha:group.13 { + uuid=Of4kyoIScCrE774KCa4AAABY; src_uuid=+oSyprNFSw9F5MMrBkcAAAAL; + x=24000; y=8000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + funcmap/name=OC1A + name=PA6 + pinnum=7 + role=terminal + } + } + ha:group.14 { + uuid=Of4kyoIScCrE774KCa4AAABZ; src_uuid=+oSyprNFSw9F5MMrBkcAAAAM; + x=24000; y=4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + funcmap/name=PA7 + name=PA7 + pinnum=6 + role=terminal + } + } + ha:group.15 { + uuid=Of4kyoIScCrE774KCa4AAABa; src_uuid=+oSyprNFSw9F5MMrBkcAAAAN; + x=12000; y=36000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=0; stroke=term-secondary; text=VCC; } + } + ha:attrib { + name=VCC + pinnum=1 + role=terminal + } + } + ha:group.16 { + uuid=Of4kyoIScCrE774KCa4AAABb; src_uuid=+oSyprNFSw9F5MMrBkcAAAAO; + x=12000; y=0; rot=-90.000000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=0; stroke=term-secondary; text=GND; } + } + ha:attrib { + name=GND + pinnum=14 + role=terminal + } + } + ha:text.17 { x1=-8000; y1=-8000; dyntext=1; stroke=sym-secondary; text=%../A.funcmap%; floater=1; } + ha:text.18 { x1=-8000; y1=-12000; dyntext=1; stroke=sym-secondary; text=%../A.footprint%; floater=1; } + ha:text.19 { x1=-8000; y1=-16000; dyntext=1; stroke=sym-secondary; text=%../A.device%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2023 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=edakrill/igor2 + -symbol-generator=boxsym-rnd + device=attiny24 + footprint=so(14) + funcmap=attiny24.funcmap + name=U1 + role=symbol + } + } + ha:group.10 { + uuid=Of4kyoIScCrE774KCa4AAABi; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB6; + x=80000; y=112000; + li:objects { + ha:group.1 { + uuid=Of4kyoIScCrE774KCa4AAABj; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB7; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + drc/require_graphical_conn=1 + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-4000; y1=4000; x2=4000; y2=7000; halign=center; dyntext=0; stroke=sym-primary; text=Vcc; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:Vcc} + } + role=symbol + } + } + ha:group.11 { + uuid=Of4kyoIScCrE774KCa4AAABk; + li:objects { + ha:line.1 { x1=80000; y1=112000; x2=80000; y2=108000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.12 { + li:conn { + /2/11/1 + /2/9/15/1 + } + } + ha:connection.13 { + li:conn { + /2/11/1 + /2/10/1/1 + } + } + ha:group.17 { + uuid=Of4kyoIScCrE774KCa4AAABp; src_uuid=Of4kyoIScCrE774KCa4AAAAK; + x=136000; y=60000; + li:objects { + ha:group.1 { + uuid=Of4kyoIScCrE774KCa4AAABq; src_uuid=Of4kyoIScCrE774KCa4AAAAD; + x=-8000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=ctrl + role=terminal + } + } + ha:group.2 { + uuid=Of4kyoIScCrE774KCa4AAABr; src_uuid=Of4kyoIScCrE774KCa4AAAAD; + x=0; y=8000; rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=Vin + role=terminal + } + } + ha:polygon.3 { + li:outline { + ha:line { x1=-8000; y1=8000; x2=-8000; y2=-8000; } + ha:line { x1=-8000; y1=-8000; x2=8000; y2=-8000; } + ha:line { x1=8000; y1=-8000; x2=8000; y2=8000; } + ha:line { x1=8000; y1=8000; x2=-8000; y2=8000; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + ha:text.4 { x1=-8000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:text.5 { x1=-1000; y1=-1000; dyntext=1; stroke=sym-secondary; text=%../A.cschem/child/name%; floater=1; } + } + ha:attrib { + cschem/child/name=led + name=S2 + role=symbol + } + } + ha:group.20 { + uuid=Of4kyoIScCrE774KCa4AAAB6; src_uuid=iNOQfJpO6hT/HFDFGjoAAABv; + x=136000; y=72000; + li:objects { + ha:group.1 { + uuid=Of4kyoIScCrE774KCa4AAAB7; src_uuid=iNOQfJpO6hT/HFDFGjoAAABw; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + drc/require_graphical_conn=1 + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-6000; y1=4000; x2=6000; y2=7000; halign=center; dyntext=1; stroke=sym-primary; text=%../A.rail%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:forge { + delete,forge/tmp + scalar,forge/tmp + {sub,^,1:,forge/tmp} + suba,$,rail,forge/tmp + array,connect + append,connect,forge/tmp + } + rail=V9V + role=symbol + } + } + ha:connection.21 { + li:conn { + /2/20/1/1 + /2/17/2/1 + } + } + ha:group.22 { + uuid=Of4kyoIScCrE774KCa4AAAB8; src_uuid=iNOQfJpO6hT/HFDFGjoAAABv; + x=136000; y=104000; + li:objects { + ha:group.1 { + uuid=Of4kyoIScCrE774KCa4AAAB9; src_uuid=iNOQfJpO6hT/HFDFGjoAAABw; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + drc/require_graphical_conn=1 + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-6000; y1=4000; x2=6000; y2=7000; halign=center; dyntext=1; stroke=sym-primary; text=%../A.rail%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:forge { + delete,forge/tmp + scalar,forge/tmp + {sub,^,1:,forge/tmp} + suba,$,rail,forge/tmp + array,connect + append,connect,forge/tmp + } + rail=V9V + role=symbol + } + } + ha:connection.23 { + li:conn { + /2/22/1/1 + /2/8/2/1 + } + } + ha:group.24 { + uuid=Of4kyoIScCrE774KCa4AAACC; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=80000; y=64000; + li:objects { + ha:group.1 { + uuid=Of4kyoIScCrE774KCa4AAACD; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + drc/require_graphical_conn=1 + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:connection.25 { + li:conn { + /2/24/1/1 + /2/9/16/1 + } + } + ha:group.26 { + uuid=Of4kyoIScCrE774KCa4AAACE; + li:objects { + ha:line.1 { x1=96000; y1=76000; x2=112000; y2=76000; stroke=wire; } + ha:line.2 { x1=112000; y1=76000; x2=112000; y2=60000; stroke=wire; } + ha:line.3 { x1=112000; y1=60000; x2=124000; y2=60000; stroke=wire; } + ha:text.4 { x1=112000; y1=60000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=pwm1a + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.27 { + li:conn { + /2/26/1 + /2/9/13/1 + } + } + ha:connection.28 { + li:conn { + /2/26/3 + /2/17/1/1 + } + } + ha:group.29 { + uuid=Of4kyoIScCrE774KCa4AAACF; + li:objects { + ha:line.1 { x1=96000; y1=80000; x2=112000; y2=80000; stroke=wire; } + ha:line.2 { x1=112000; y1=80000; x2=112000; y2=92000; stroke=wire; } + ha:line.3 { x1=112000; y1=92000; x2=124000; y2=92000; stroke=wire; } + ha:text.4 { x1=112000; y1=92000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=pwm1b + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.30 { + li:conn { + /2/29/1 + /2/9/12/1 + } + } + ha:connection.31 { + li:conn { + /2/29/3 + /2/8/1/1 + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer=Tibor 'Igor2' Palinkas + page=1/2 + print_page=A/4 + title=programmable blinking LEDs + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 2 + grid = 4.0960 mm + } + } + } +} Index: tags/1.0.5/doc/examples/hierarchic/20_led/project.lht =================================================================== --- tags/1.0.5/doc/examples/hierarchic/20_led/project.lht (nonexistent) +++ tags/1.0.5/doc/examples/hierarchic/20_led/project.lht (revision 10414) @@ -0,0 +1,14 @@ +ha:coraleda-project-v1 { + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:prj { + li:root_sheets { + main.rs + } + li:aux_sheets { + led.rs + } + } + } + } +} Index: tags/1.0.5/doc/examples/hierarchic/22_led/led.rs =================================================================== --- tags/1.0.5/doc/examples/hierarchic/22_led/led.rs (nonexistent) +++ tags/1.0.5/doc/examples/hierarchic/22_led/led.rs (revision 10414) @@ -0,0 +1,497 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + ha:group.1 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAP; + li:objects { + ha:group.1 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAQ; loclib_name=2n7002_sot23; + li:objects { + } + ha:attrib { + device=2n7002 + footprint=SOT23 + li:portmap { + {G->pcb/pinnum=1} + {S->pcb/pinnum=2} + {D->pcb/pinnum=3} + } + } + } + ha:group.2 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAj; loclib_name=led5; + li:objects { + } + ha:attrib { + device=led5 + footprint=LED5 + li:portmap { + {C->pcb/pinnum=1} + {A->pcb/pinnum=2} + } + } + } + } + ha:attrib { + ha:purpose = { value=devmap; prio=0; } + } + } + } + } + ha:obj_direct.2 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.1 { + uuid=8/SYZ/pfBzxyqFA12WQAAAAC; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAg; + li:objects { + ha:polygon.11 { + li:outline { + ha:line { x1=0; y1=0; x2=80000; y2=0; } + ha:line { x1=80000; y1=0; x2=80000; y2=20000; } + ha:line { x1=80000; y1=20000; x2=0; y2=20000; } + ha:line { x1=0; y1=20000; x2=0; y2=0; } + } + stroke=titlebox-frame; + fill=titlebox-fill; + } + ha:line.12 { x1=0; y1=10000; x2=80000; y2=10000; stroke=titlebox-frame; } + ha:line.13 { x1=40000; y1=10000; x2=40000; y2=0; stroke=titlebox-frame; } + ha:text.20 { x1=1000; y1=16500; dyntext=0; stroke=titlebox-big; text=TITLE; } + ha:text.21 { x1=1000; y1=10500; x2=79000; y2=16000; dyntext=1; stroke=titlebox-big; text=%../../A.title%; } + ha:text.22 { x1=1000; y1=5500; dyntext=0; stroke=titlebox-small; text={PROJECT:}; } + ha:text.23 { x1=13000; y1=5500; x2=39000; y2=9500; dyntext=1; stroke=titlebox-big; text=%project.name%; } + ha:text.24 { x1=1000; y1=500; dyntext=0; stroke=titlebox-small; text={PAGE:}; } + ha:text.25 { x1=10000; y1=500; x2=39000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.page%; } + ha:text.26 { x1=41000; y1=5500; dyntext=0; stroke=titlebox-small; text={FILE:}; } + ha:text.27 { x1=48000; y1=5500; x2=79000; y2=9500; dyntext=1; stroke=titlebox-big; text=%filename%; } + ha:text.28 { x1=41000; y1=500; dyntext=0; stroke=titlebox-small; text={MAINTAINER:}; } + ha:text.29 { x1=55000; y1=500; x2=79000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.maintainer%; } + ha:text.30 { x1=79000; y1=16000; mirx=1; dyntext=1; stroke=sheet-decor; text=%stance.model% %stance.sub_major% %stance.sub_minor% %stance.test_bench% %view.name%; } + } + ha:attrib { + purpose=titlebox + } + } + ha:group.2 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAL; src_uuid=iNOQfJpO6hT/HFDFGjoAAACC; + x=96000; y=104000; + li:objects { + ha:group.1 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAM; src_uuid=iNOQfJpO6hT/HFDFGjoAAACD; + x=12000; y=12000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=D + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:group.2 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAN; src_uuid=iNOQfJpO6hT/HFDFGjoAAACE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=G + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:text.3 { x1=8000; y1=8000; rot=90.000000; dyntext=1; stroke=sym-secondary; text=%../a.devmap%; floater=1; } + ha:text.4 { x1=4000; y1=8000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:arc.5 { cx=11000; cy=3000; r=5500; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:line.6 { x1=4000; y1=0; x2=8000; y2=0; stroke=sym-decor; } + ha:line.7 { x1=9000; y1=-1000; x2=9000; y2=1000; stroke=sym-decor; } + ha:line.8 { x1=9000; y1=2000; x2=9000; y2=4000; stroke=sym-decor; } + ha:line.9 { x1=9000; y1=5000; x2=9000; y2=7000; stroke=sym-decor; } + ha:line.10 { x1=9000; y1=3000; x2=12000; y2=3000; stroke=sym-decor; } + ha:line.11 { x1=9000; y1=0; x2=12000; y2=0; stroke=sym-decor; } + ha:line.12 { x1=9000; y1=6000; x2=12000; y2=6000; stroke=sym-decor; } + ha:line.13 { x1=12000; y1=6000; x2=12000; y2=8000; stroke=sym-decor; } + ha:line.14 { x1=12000; y1=-4000; x2=12000; y2=3000; stroke=sym-decor; } + ha:line.15 { x1=13000; y1=3000; x2=15000; y2=3000; stroke=sym-decor; } + ha:line.16 { x1=15000; y1=3000; x2=14000; y2=4000; stroke=sym-decor; } + ha:line.17 { x1=14000; y1=4000; x2=13000; y2=3000; stroke=sym-decor; } + ha:line.18 { x1=13000; y1=4000; x2=15000; y2=4000; stroke=sym-decor; } + ha:line.19 { x1=12000; y1=7000; x2=14000; y2=7000; stroke=sym-decor; } + ha:line.20 { x1=14000; y1=-1000; x2=12000; y2=-1000; stroke=sym-decor; } + ha:line.21 { x1=8000; y1=7000; x2=8000; y2=0; stroke=sym-decor; } + ha:polygon.22 { + li:outline { + ha:line { x1=10000; y1=4000; x2=9000; y2=3000; } + ha:line { x1=9000; y1=3000; x2=10000; y2=2000; } + ha:line { x1=10000; y1=2000; x2=10000; y2=4000; } + } + stroke=sym-decor; + fill=sym-decor; + } + ha:group.23 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAO; src_uuid=iNOQfJpO6hT/HFDFGjoAAACF; + x=12000; y=-4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=S + role=terminal + ha:spice/pinnum = { value=3; prio=31050; } + } + } + ha:line.24 { x1=14000; y1=-1000; x2=14000; y2=3000; stroke=sym-decor; } + ha:line.25 { x1=14000; y1=4000; x2=14000; y2=7000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + devmap=2n7002_sot23 + name=./Q1 + role=symbol + ha:spice/prefix = { value=M; prio=31050; } + } + } + ha:group.3 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAX; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=108000; y=168000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAY; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAZ; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + ha:device = { value=resistor; prio=31050; } + footprint=1206 + name=./R1 + role=symbol + ha:spice/prefix = { value=R; prio=31050; } + value=510 + } + } + ha:group.4 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAg; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAQ; + x=108000; y=124000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAh; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAR; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=C + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.2 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAi; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAS; + x=-16000; y=0; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=A + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:line.3 { x1=-4000; y1=0; x2=-6000; y2=0; stroke=sym-decor; } + ha:line.4 { x1=-12000; y1=0; x2=-10000; y2=0; stroke=sym-decor; } + ha:line.5 { x1=-10000; y1=4000; x2=-6000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=-6000; y1=0; x2=-10000; y2=-4000; stroke=sym-decor; } + ha:line.7 { x1=-10000; y1=4000; x2=-10000; y2=-4000; stroke=sym-decor; } + ha:line.8 { x1=-6000; y1=4000; x2=-6000; y2=-4000; stroke=sym-decor; } + ha:text.9 { x1=-4000; y1=13000; rot=90.000000; dyntext=1; stroke=sym-secondary; text=%../a.devmap%; floater=1; } + ha:text.10 { x1=-8000; y1=13000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.11 { x1=-8000; y1=8000; x2=-6000; y2=11000; stroke=sym-decor; } + ha:line.12 { x1=-6000; y1=11000; x2=-7000; y2=10000; stroke=sym-decor; } + ha:line.13 { x1=-6000; y1=11000; x2=-6517; y2=9545; stroke=sym-decor; } + ha:line.14 { x1=-10000; y1=7000; x2=-8000; y2=10000; stroke=sym-decor; } + ha:line.15 { x1=-8000; y1=10000; x2=-8000; y2=8000; stroke=sym-decor; } + ha:line.16 { x1=-8303; y1=6354; x2=-6303; y2=9354; stroke=sym-decor; } + ha:line.17 { x1=-6303; y1=9354; x2=-7303; y2=8354; stroke=sym-decor; } + ha:line.18 { x1=-6303; y1=9354; x2=-6820; y2=7899; stroke=sym-decor; } + ha:line.19 { x1=-10303; y1=5354; x2=-8303; y2=8354; stroke=sym-decor; } + ha:line.20 { x1=-8303; y1=8354; x2=-8303; y2=6354; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + devmap=led5 + name=./D1 + role=symbol + ha:spice/prefix = { value=D; prio=31050; } + } + } + ha:group.5 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAk; + li:objects { + ha:line.1 { x1=108000; y1=116000; x2=108000; y2=124000; stroke=wire; } + ha:text.2 { x1=110000; y1=120000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=./led_fet + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.6 { + li:conn { + /2/5/1 + /2/2/1/1 + } + } + ha:connection.7 { + li:conn { + /2/5/1 + /2/4/1/1 + } + } + ha:group.8 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAl; + li:objects { + ha:line.1 { x1=108000; y1=140000; x2=108000; y2=148000; stroke=wire; } + ha:text.2 { x1=110000; y1=144000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=./res_led + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.9 { + li:conn { + /2/8/1 + /2/3/1/1 + } + } + ha:connection.10 { + li:conn { + /2/8/1 + /2/4/2/1 + } + } + ha:connection.12 { + li:conn { + /2/3/2/1 + /2/14/3 + } + } + ha:group.14 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAo; + li:objects { + ha:line.1 { x1=84000; y1=176000; x2=108000; y2=176000; stroke=wire; } + ha:line.3 { x1=108000; y1=168000; x2=108000; y2=176000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.16 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAp; + li:objects { + ha:line.1 { x1=96000; y1=104000; x2=84000; y2=104000; stroke=wire; } + ha:text.2 { x1=88000; y1=104000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=./gate + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.17 { + li:conn { + /2/16/1 + /2/2/2/1 + } + } + ha:group.20 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAs; + li:objects { + ha:line.1 { x1=108000; y1=96000; x2=108000; y2=88000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.21 { + li:conn { + /2/20/1 + /2/2/23/1 + } + } + ha:group.22 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAx; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=108000; y=88000; + li:objects { + ha:group.1 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAy; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + drc/require_graphical_conn=1 + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:connection.23 { + li:conn { + /2/22/1/1 + /2/20/1 + } + } + ha:group.24 { + uuid=/vAQ7urXB5Qp0gPFDvkAAAA9; src_uuid=AHibvjaMiL5NH+9/wR0AAAAG; + x=84000; y=176000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-5000; y1=-1500; mirx=1; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:line.3 { x1=-4000; y1=0; x2=-5000; y2=2000; stroke=sheet-decor; } + ha:line.4 { x1=-4000; y1=0; x2=-5000; y2=-2000; stroke=sheet-decor; } + ha:line.5 { x1=-5000; y1=-2000; x2=-17000; y2=-2000; stroke=sheet-decor; } + ha:line.6 { x1=-17000; y1=2000; x2=-5000; y2=2000; stroke=sheet-decor; } + ha:line.7 { x1=-17000; y1=2000; x2=-17000; y2=-2000; stroke=sheet-decor; } + } + ha:attrib { + -sym-comment={ Sheet level terminal (not really a symbol) for subsheet input net in a hierarchy } + -sym-copyright=(C) 2024 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=Vin + role=terminal + } + } + ha:group.25 { + uuid=/vAQ7urXB5Qp0gPFDvkAAAA/; src_uuid=AHibvjaMiL5NH+9/wR0AAAAG; + x=84000; y=104000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-5000; y1=-1500; mirx=1; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:line.3 { x1=-4000; y1=0; x2=-5000; y2=2000; stroke=sheet-decor; } + ha:line.4 { x1=-4000; y1=0; x2=-5000; y2=-2000; stroke=sheet-decor; } + ha:line.5 { x1=-5000; y1=-2000; x2=-17000; y2=-2000; stroke=sheet-decor; } + ha:line.6 { x1=-17000; y1=2000; x2=-5000; y2=2000; stroke=sheet-decor; } + ha:line.7 { x1=-17000; y1=2000; x2=-17000; y2=-2000; stroke=sheet-decor; } + } + ha:attrib { + -sym-comment={ Sheet level terminal (not really a symbol) for subsheet input net in a hierarchy } + -sym-copyright=(C) 2024 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=ctrl + role=terminal + } + } + ha:connection.26 { + li:conn { + /2/24/1 + /2/14/1 + } + } + ha:connection.27 { + li:conn { + /2/25/1 + /2/16/1 + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer=Tibor 'Igor2' Palinkas + page=2/2 + print_page=A/4 + title=LED and driver + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 1 + grid = 2.0480 mm + } + } + } +} Index: tags/1.0.5/doc/examples/hierarchic/22_led/main.rs =================================================================== --- tags/1.0.5/doc/examples/hierarchic/22_led/main.rs (nonexistent) +++ tags/1.0.5/doc/examples/hierarchic/22_led/main.rs (revision 10414) @@ -0,0 +1,706 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + ha:group.1 { + uuid=Of4kyoIScCrE774KCa4AAABc; + li:objects { + ha:group.1 { + uuid=Of4kyoIScCrE774KCa4AAABd; loclib_name=attiny24.funcmap; + li:objects { + } + ha:attrib { + li:funcmap/ports { + { PB0/PB0 -> sigtype=digital; } + { PB0/PCINT8 -> sigtype=digital; dir=input } + { PB0/XTAL1 -> sigtype=analog; } + { PB1/PB1 -> sigtype=digital; } + { PB1/PCINT9 -> sigtype=digital; dir=input } + { PB1/XTAL2 -> sigtype=analog; } + { PB3/PB3 -> sigtype=digital; } + { PB3/PCINT11 -> sigtype=digital; dir=input } + { PB3/RESET -> sigtype=digital; dir=input } + { PB2/PB2 -> sigtype=digital; } + { PB2/PCINT10 -> sigtype=digital; dir=input } + { PB2/OC0A -> sigtype=digital; dir=output } + { PB2/INT0 -> sigtype=digital; dir=input } + { PA7/PA7 -> sigtype=digital; } + { PA7/PCINT7 -> sigtype=digital; dir=input } + { PA7/OC0B -> sigtype=digital; dir=output } + { PA7/ADC7 -> sigtype=digital; dir=input } + { PA6/PA6 -> sigtype=digital; } + { PA6/PCINT6 -> sigtype=digital; dir=input } + { PA6/MOSI -> sigtype=digital; } + { PA6/DI -> sigtype=digital; dir=input } + { PA6/SDA -> sigtype=digital; } + { PA6/OC1A -> sigtype=digital; dir=output } + { PA6/ADC6 -> sigtype=analog; dir=input } + { PA0/PA0 -> sigtype=digital; } + { PA0/PCINT0 -> sigtype=digital; dir=input } + { PA0/AREF+ADC0-> sigtype=analog; dir=input } + { PA1/PA1 -> sigtype=digital; } + { PA1/PCINT1 -> sigtype=digital; dir=input } + { PA1/AIN0 -> sigtype=analog; dir=input } + { PA1/ADC1 -> sigtype=analog; dir=input } + { PA2/PA2 -> sigtype=digital; } + { PA2/PCINT2 -> sigtype=digital; dir=input } + { PA2/AIN1 -> sigtype=analog; dir=input } + { PA2/ADC2 -> sigtype=analog; dir=input } + { PA3/PA3 -> sigtype=digital; } + { PA3/PCINT3 -> sigtype=digital; dir=input } + { PA3/ADC3 -> sigtype=analog; dir=input } + { PA4/PA4 -> sigtype=digital; } + { PA4/PCINT4 -> sigtype=digital; dir=input } + { PA4/SCK -> sigtype=digital; } + { PA4/SCL -> sigtype=digital; } + { PA4/ADC4 -> sigtype=analog; dir=input } + { PA5/PA5 -> sigtype=digital; } + { PA5/PCINT5 -> sigtype=digital; dir=input } + { PA5/MISO -> sigtype=digital; } + { PA5/DO -> sigtype=digital; dir=output } + { PA5/OC1B -> sigtype=digital; dir=output } + { PA5/ADC5 -> sigtype=analog; dir=input } + } + li:funcmap/strong_groups { + { SPI -> SCK, MISO, MOSI } + { I2C -> SDA, SCL } + { USI -> SCK, DI, DO } + } + li:funcmap/weak_groups { + { gpio -> PB0, PB1, PB2, PB3, PA6, PA7, PA0, PA1, PA2, PA3, PA4, PA5 } + { pcint -> PCINT8, PCINT9, PCINT11, PCINT10, PCINT7, PCINT6, PCINT0, PCINT1, PCINT2, PCINT3, PCINT4, PCINT5 } + { xtal -> XTAL1, XTAL2 } + { PWM -> OC0A, OC0B, OC1A, OC1B } + { adc -> AREF+ADC0, ADC1, ADC2, ADC3, ADC4, ADC5, ADC6, ADC7 } + { comparator -> AIN0, AIN1 } + } + } + } + } + ha:attrib { + ha:purpose = { value=funcmap; prio=0; } + } + } + } + } + ha:obj_direct.2 { + uuid=Of4kyoIScCrE774KCa4AAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.1 { + uuid=8/SYZ/pfBzxyqFA12WQAAAAC; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAg; + li:objects { + ha:polygon.11 { + li:outline { + ha:line { x1=0; y1=0; x2=80000; y2=0; } + ha:line { x1=80000; y1=0; x2=80000; y2=20000; } + ha:line { x1=80000; y1=20000; x2=0; y2=20000; } + ha:line { x1=0; y1=20000; x2=0; y2=0; } + } + stroke=titlebox-frame; + fill=titlebox-fill; + } + ha:line.12 { x1=0; y1=10000; x2=80000; y2=10000; stroke=titlebox-frame; } + ha:line.13 { x1=40000; y1=10000; x2=40000; y2=0; stroke=titlebox-frame; } + ha:text.20 { x1=1000; y1=16500; dyntext=0; stroke=titlebox-big; text=TITLE; } + ha:text.21 { x1=1000; y1=10500; x2=79000; y2=16000; dyntext=1; stroke=titlebox-big; text=%../../A.title%; } + ha:text.22 { x1=1000; y1=5500; dyntext=0; stroke=titlebox-small; text={PROJECT:}; } + ha:text.23 { x1=13000; y1=5500; x2=39000; y2=9500; dyntext=1; stroke=titlebox-big; text=%project.name%; } + ha:text.24 { x1=1000; y1=500; dyntext=0; stroke=titlebox-small; text={PAGE:}; } + ha:text.25 { x1=10000; y1=500; x2=39000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.page%; } + ha:text.26 { x1=41000; y1=5500; dyntext=0; stroke=titlebox-small; text={FILE:}; } + ha:text.27 { x1=48000; y1=5500; x2=79000; y2=9500; dyntext=1; stroke=titlebox-big; text=%filename%; } + ha:text.28 { x1=41000; y1=500; dyntext=0; stroke=titlebox-small; text={MAINTAINER:}; } + ha:text.29 { x1=55000; y1=500; x2=79000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.maintainer%; } + ha:text.30 { x1=79000; y1=16000; mirx=1; dyntext=1; stroke=sheet-decor; text=%stance.model% %stance.sub_major% %stance.sub_minor% %stance.test_bench% %view.name%; } + } + ha:attrib { + purpose=titlebox + } + } + ha:group.8 { + uuid=Of4kyoIScCrE774KCa4AAAAK; + x=136000; y=92000; + li:objects { + ha:group.1 { + uuid=Of4kyoIScCrE774KCa4AAAAL; src_uuid=Of4kyoIScCrE774KCa4AAAAD; + x=-8000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=ctrl + role=terminal + } + } + ha:group.2 { + uuid=Of4kyoIScCrE774KCa4AAAAM; src_uuid=Of4kyoIScCrE774KCa4AAAAD; + x=0; y=8000; rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=Vin + role=terminal + } + } + ha:polygon.3 { + li:outline { + ha:line { x1=-8000; y1=8000; x2=-8000; y2=-8000; } + ha:line { x1=-8000; y1=-8000; x2=8000; y2=-8000; } + ha:line { x1=8000; y1=-8000; x2=8000; y2=8000; } + ha:line { x1=8000; y1=8000; x2=-8000; y2=8000; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + ha:text.4 { x1=-8000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:text.5 { x1=-1000; y1=-1000; dyntext=1; stroke=sym-secondary; text=%../A.cschem/child/name%; floater=1; } + } + ha:attrib { + cschem/child/name=led + name=S1 + role=symbol + } + } + ha:group.9 { + uuid=Of4kyoIScCrE774KCa4AAABN; src_uuid=+oSyprNFSw9F5MMrBkcAAAAP; + x=68000; y=68000; + li:objects { + ha:text.1 { x1=-8000; y1=-4000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.2 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=36000; } + ha:line { x1=0; y1=36000; x2=24000; y2=36000; } + ha:line { x1=24000; y1=36000; x2=24000; y2=0; } + ha:line { x1=24000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + } + ha:group.3 { + uuid=Of4kyoIScCrE774KCa4AAABO; src_uuid=+oSyprNFSw9F5MMrBkcAAAAB; + x=0; y=24000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PB0 + pinnum=2 + role=terminal + } + } + ha:group.4 { + uuid=Of4kyoIScCrE774KCa4AAABP; src_uuid=+oSyprNFSw9F5MMrBkcAAAAC; + x=0; y=20000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PB1 + pinnum=3 + role=terminal + } + } + ha:group.5 { + uuid=Of4kyoIScCrE774KCa4AAABQ; src_uuid=+oSyprNFSw9F5MMrBkcAAAAD; + x=0; y=16000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PB2 + pinnum=5 + role=terminal + } + } + ha:group.6 { + uuid=Of4kyoIScCrE774KCa4AAABR; src_uuid=+oSyprNFSw9F5MMrBkcAAAAE; + x=0; y=12000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PB3 + pinnum=4 + role=terminal + } + } + ha:group.7 { + uuid=Of4kyoIScCrE774KCa4AAABS; src_uuid=+oSyprNFSw9F5MMrBkcAAAAF; + x=24000; y=32000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PA0 + pinnum=13 + role=terminal + } + } + ha:group.8 { + uuid=Of4kyoIScCrE774KCa4AAABT; src_uuid=+oSyprNFSw9F5MMrBkcAAAAG; + x=24000; y=28000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PA1 + pinnum=12 + role=terminal + } + } + ha:group.9 { + uuid=Of4kyoIScCrE774KCa4AAABU; src_uuid=+oSyprNFSw9F5MMrBkcAAAAH; + x=24000; y=24000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PA2 + pinnum=11 + role=terminal + } + } + ha:group.10 { + uuid=Of4kyoIScCrE774KCa4AAABV; src_uuid=+oSyprNFSw9F5MMrBkcAAAAI; + x=24000; y=20000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PA3 + pinnum=10 + role=terminal + } + } + ha:group.11 { + uuid=Of4kyoIScCrE774KCa4AAABW; src_uuid=+oSyprNFSw9F5MMrBkcAAAAJ; + x=24000; y=16000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PA4 + pinnum=9 + role=terminal + } + } + ha:group.12 { + uuid=Of4kyoIScCrE774KCa4AAABX; src_uuid=+oSyprNFSw9F5MMrBkcAAAAK; + x=24000; y=12000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + funcmap/name=OC1B + name=PA5 + pinnum=8 + role=terminal + } + } + ha:group.13 { + uuid=Of4kyoIScCrE774KCa4AAABY; src_uuid=+oSyprNFSw9F5MMrBkcAAAAL; + x=24000; y=8000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + funcmap/name=OC1A + name=PA6 + pinnum=7 + role=terminal + } + } + ha:group.14 { + uuid=Of4kyoIScCrE774KCa4AAABZ; src_uuid=+oSyprNFSw9F5MMrBkcAAAAM; + x=24000; y=4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + funcmap/name=PA7 + name=PA7 + pinnum=6 + role=terminal + } + } + ha:group.15 { + uuid=Of4kyoIScCrE774KCa4AAABa; src_uuid=+oSyprNFSw9F5MMrBkcAAAAN; + x=12000; y=36000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=0; stroke=term-secondary; text=VCC; } + } + ha:attrib { + name=VCC + pinnum=1 + role=terminal + } + } + ha:group.16 { + uuid=Of4kyoIScCrE774KCa4AAABb; src_uuid=+oSyprNFSw9F5MMrBkcAAAAO; + x=12000; y=0; rot=-90.000000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=0; stroke=term-secondary; text=GND; } + } + ha:attrib { + name=GND + pinnum=14 + role=terminal + } + } + ha:text.17 { x1=-8000; y1=-8000; dyntext=1; stroke=sym-secondary; text=%../A.funcmap%; floater=1; } + ha:text.18 { x1=-8000; y1=-12000; dyntext=1; stroke=sym-secondary; text=%../A.footprint%; floater=1; } + ha:text.19 { x1=-8000; y1=-16000; dyntext=1; stroke=sym-secondary; text=%../A.device%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2023 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=edakrill/igor2 + -symbol-generator=boxsym-rnd + device=attiny24 + footprint=so(14) + funcmap=attiny24.funcmap + name=U1 + role=symbol + } + } + ha:group.10 { + uuid=Of4kyoIScCrE774KCa4AAABi; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB6; + x=80000; y=112000; + li:objects { + ha:group.1 { + uuid=Of4kyoIScCrE774KCa4AAABj; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB7; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + drc/require_graphical_conn=1 + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-4000; y1=4000; x2=4000; y2=7000; halign=center; dyntext=0; stroke=sym-primary; text=Vcc; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:Vcc} + } + role=symbol + } + } + ha:group.11 { + uuid=Of4kyoIScCrE774KCa4AAABk; + li:objects { + ha:line.1 { x1=80000; y1=112000; x2=80000; y2=108000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.12 { + li:conn { + /2/11/1 + /2/9/15/1 + } + } + ha:connection.13 { + li:conn { + /2/11/1 + /2/10/1/1 + } + } + ha:group.17 { + uuid=Of4kyoIScCrE774KCa4AAABp; src_uuid=Of4kyoIScCrE774KCa4AAAAK; + x=136000; y=60000; + li:objects { + ha:group.1 { + uuid=Of4kyoIScCrE774KCa4AAABq; src_uuid=Of4kyoIScCrE774KCa4AAAAD; + x=-8000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=ctrl + role=terminal + } + } + ha:group.2 { + uuid=Of4kyoIScCrE774KCa4AAABr; src_uuid=Of4kyoIScCrE774KCa4AAAAD; + x=0; y=8000; rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=Vin + role=terminal + } + } + ha:polygon.3 { + li:outline { + ha:line { x1=-8000; y1=8000; x2=-8000; y2=-8000; } + ha:line { x1=-8000; y1=-8000; x2=8000; y2=-8000; } + ha:line { x1=8000; y1=-8000; x2=8000; y2=8000; } + ha:line { x1=8000; y1=8000; x2=-8000; y2=8000; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + ha:text.4 { x1=-8000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:text.5 { x1=-1000; y1=-1000; dyntext=1; stroke=sym-secondary; text=%../A.cschem/child/name%; floater=1; } + } + ha:attrib { + cschem/child/name=led + name=S2 + role=symbol + } + } + ha:group.20 { + uuid=Of4kyoIScCrE774KCa4AAAB6; src_uuid=iNOQfJpO6hT/HFDFGjoAAABv; + x=136000; y=72000; + li:objects { + ha:group.1 { + uuid=Of4kyoIScCrE774KCa4AAAB7; src_uuid=iNOQfJpO6hT/HFDFGjoAAABw; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + drc/require_graphical_conn=1 + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-6000; y1=4000; x2=6000; y2=7000; halign=center; dyntext=1; stroke=sym-primary; text=%../A.rail%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:forge { + delete,forge/tmp + scalar,forge/tmp + {sub,^,1:,forge/tmp} + suba,$,rail,forge/tmp + array,connect + append,connect,forge/tmp + } + rail=V9V + role=symbol + } + } + ha:connection.21 { + li:conn { + /2/20/1/1 + /2/17/2/1 + } + } + ha:group.22 { + uuid=Of4kyoIScCrE774KCa4AAAB8; src_uuid=iNOQfJpO6hT/HFDFGjoAAABv; + x=136000; y=104000; + li:objects { + ha:group.1 { + uuid=Of4kyoIScCrE774KCa4AAAB9; src_uuid=iNOQfJpO6hT/HFDFGjoAAABw; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + drc/require_graphical_conn=1 + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-6000; y1=4000; x2=6000; y2=7000; halign=center; dyntext=1; stroke=sym-primary; text=%../A.rail%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:forge { + delete,forge/tmp + scalar,forge/tmp + {sub,^,1:,forge/tmp} + suba,$,rail,forge/tmp + array,connect + append,connect,forge/tmp + } + rail=V9V + role=symbol + } + } + ha:connection.23 { + li:conn { + /2/22/1/1 + /2/8/2/1 + } + } + ha:group.24 { + uuid=Of4kyoIScCrE774KCa4AAACC; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=80000; y=64000; + li:objects { + ha:group.1 { + uuid=Of4kyoIScCrE774KCa4AAACD; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + drc/require_graphical_conn=1 + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:connection.25 { + li:conn { + /2/24/1/1 + /2/9/16/1 + } + } + ha:group.26 { + uuid=Of4kyoIScCrE774KCa4AAACE; + li:objects { + ha:line.1 { x1=96000; y1=76000; x2=112000; y2=76000; stroke=wire; } + ha:line.2 { x1=112000; y1=76000; x2=112000; y2=60000; stroke=wire; } + ha:line.3 { x1=112000; y1=60000; x2=124000; y2=60000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.27 { + li:conn { + /2/26/1 + /2/9/13/1 + } + } + ha:connection.28 { + li:conn { + /2/17/1/1 + /2/26/3 + } + } + ha:group.29 { + uuid=Of4kyoIScCrE774KCa4AAACF; + li:objects { + ha:line.1 { x1=96000; y1=80000; x2=112000; y2=80000; stroke=wire; } + ha:line.2 { x1=112000; y1=80000; x2=112000; y2=92000; stroke=wire; } + ha:line.3 { x1=112000; y1=92000; x2=124000; y2=92000; stroke=wire; } + ha:text.4 { x1=112000; y1=92000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=pwm1b + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.30 { + li:conn { + /2/29/1 + /2/9/12/1 + } + } + ha:connection.31 { + li:conn { + /2/29/3 + /2/8/1/1 + } + } + ha:text.34 { x1=104000; y1=48000; dyntext=0; stroke=sheet-decor; text=net not named; } + ha:line.36 { x1=114000; y1=51000; x2=114000; y2=59000; stroke=sheet-decor; } + ha:line.37 { x1=114000; y1=59000; x2=113000; y2=58000; stroke=sheet-decor; } + ha:line.38 { x1=114000; y1=59000; x2=114000; y2=58000; stroke=sheet-decor; } + ha:line.39 { x1=114000; y1=59000; x2=115000; y2=58000; stroke=sheet-decor; } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer=Tibor 'Igor2' Palinkas + page=1/2 + print_page=A/4 + title=programmable blinking LEDs + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 2 + grid = 4.0960 mm + } + } + } +} Index: tags/1.0.5/doc/examples/hierarchic/22_led/project.lht =================================================================== --- tags/1.0.5/doc/examples/hierarchic/22_led/project.lht (nonexistent) +++ tags/1.0.5/doc/examples/hierarchic/22_led/project.lht (revision 10414) @@ -0,0 +1,14 @@ +ha:coraleda-project-v1 { + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:prj { + li:root_sheets { + main.rs + } + li:aux_sheets { + led.rs + } + } + } + } +} Index: tags/1.0.5/doc/examples/hierarchic/24_led/led.rs =================================================================== --- tags/1.0.5/doc/examples/hierarchic/24_led/led.rs (nonexistent) +++ tags/1.0.5/doc/examples/hierarchic/24_led/led.rs (revision 10414) @@ -0,0 +1,624 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + ha:group.1 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAP; + li:objects { + ha:group.1 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAQ; loclib_name=2n7002_sot23; + li:objects { + } + ha:attrib { + device=2n7002 + footprint=SOT23 + li:portmap { + {G->pcb/pinnum=1} + {S->pcb/pinnum=2} + {D->pcb/pinnum=3} + } + } + } + ha:group.2 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAj; loclib_name=led5; + li:objects { + } + ha:attrib { + device=led5 + footprint=LED5 + li:portmap { + {C->pcb/pinnum=1} + {A->pcb/pinnum=2} + } + } + } + } + ha:attrib { + ha:purpose = { value=devmap; prio=0; } + } + } + } + } + ha:obj_direct.2 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.1 { + uuid=8/SYZ/pfBzxyqFA12WQAAAAC; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAg; + li:objects { + ha:polygon.11 { + li:outline { + ha:line { x1=0; y1=0; x2=80000; y2=0; } + ha:line { x1=80000; y1=0; x2=80000; y2=20000; } + ha:line { x1=80000; y1=20000; x2=0; y2=20000; } + ha:line { x1=0; y1=20000; x2=0; y2=0; } + } + stroke=titlebox-frame; + fill=titlebox-fill; + } + ha:line.12 { x1=0; y1=10000; x2=80000; y2=10000; stroke=titlebox-frame; } + ha:line.13 { x1=40000; y1=10000; x2=40000; y2=0; stroke=titlebox-frame; } + ha:text.20 { x1=1000; y1=16500; dyntext=0; stroke=titlebox-big; text=TITLE; } + ha:text.21 { x1=1000; y1=10500; x2=79000; y2=16000; dyntext=1; stroke=titlebox-big; text=%../../A.title%; } + ha:text.22 { x1=1000; y1=5500; dyntext=0; stroke=titlebox-small; text={PROJECT:}; } + ha:text.23 { x1=13000; y1=5500; x2=39000; y2=9500; dyntext=1; stroke=titlebox-big; text=%project.name%; } + ha:text.24 { x1=1000; y1=500; dyntext=0; stroke=titlebox-small; text={PAGE:}; } + ha:text.25 { x1=10000; y1=500; x2=39000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.page%; } + ha:text.26 { x1=41000; y1=5500; dyntext=0; stroke=titlebox-small; text={FILE:}; } + ha:text.27 { x1=48000; y1=5500; x2=79000; y2=9500; dyntext=1; stroke=titlebox-big; text=%filename%; } + ha:text.28 { x1=41000; y1=500; dyntext=0; stroke=titlebox-small; text={MAINTAINER:}; } + ha:text.29 { x1=55000; y1=500; x2=79000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.maintainer%; } + ha:text.30 { x1=79000; y1=16000; mirx=1; dyntext=1; stroke=sheet-decor; text=%stance.model% %stance.sub_major% %stance.sub_minor% %stance.test_bench% %view.name%; } + } + ha:attrib { + purpose=titlebox + } + } + ha:group.2 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAL; src_uuid=iNOQfJpO6hT/HFDFGjoAAACC; + x=96000; y=104000; + li:objects { + ha:group.1 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAM; src_uuid=iNOQfJpO6hT/HFDFGjoAAACD; + x=12000; y=12000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=D + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:group.2 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAN; src_uuid=iNOQfJpO6hT/HFDFGjoAAACE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=G + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:text.3 { x1=8000; y1=8000; rot=90.000000; dyntext=1; stroke=sym-secondary; text=%../a.devmap%; floater=1; } + ha:text.4 { x1=4000; y1=8000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:arc.5 { cx=11000; cy=3000; r=5500; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:line.6 { x1=4000; y1=0; x2=8000; y2=0; stroke=sym-decor; } + ha:line.7 { x1=9000; y1=-1000; x2=9000; y2=1000; stroke=sym-decor; } + ha:line.8 { x1=9000; y1=2000; x2=9000; y2=4000; stroke=sym-decor; } + ha:line.9 { x1=9000; y1=5000; x2=9000; y2=7000; stroke=sym-decor; } + ha:line.10 { x1=9000; y1=3000; x2=12000; y2=3000; stroke=sym-decor; } + ha:line.11 { x1=9000; y1=0; x2=12000; y2=0; stroke=sym-decor; } + ha:line.12 { x1=9000; y1=6000; x2=12000; y2=6000; stroke=sym-decor; } + ha:line.13 { x1=12000; y1=6000; x2=12000; y2=8000; stroke=sym-decor; } + ha:line.14 { x1=12000; y1=-4000; x2=12000; y2=3000; stroke=sym-decor; } + ha:line.15 { x1=13000; y1=3000; x2=15000; y2=3000; stroke=sym-decor; } + ha:line.16 { x1=15000; y1=3000; x2=14000; y2=4000; stroke=sym-decor; } + ha:line.17 { x1=14000; y1=4000; x2=13000; y2=3000; stroke=sym-decor; } + ha:line.18 { x1=13000; y1=4000; x2=15000; y2=4000; stroke=sym-decor; } + ha:line.19 { x1=12000; y1=7000; x2=14000; y2=7000; stroke=sym-decor; } + ha:line.20 { x1=14000; y1=-1000; x2=12000; y2=-1000; stroke=sym-decor; } + ha:line.21 { x1=8000; y1=7000; x2=8000; y2=0; stroke=sym-decor; } + ha:polygon.22 { + li:outline { + ha:line { x1=10000; y1=4000; x2=9000; y2=3000; } + ha:line { x1=9000; y1=3000; x2=10000; y2=2000; } + ha:line { x1=10000; y1=2000; x2=10000; y2=4000; } + } + stroke=sym-decor; + fill=sym-decor; + } + ha:group.23 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAO; src_uuid=iNOQfJpO6hT/HFDFGjoAAACF; + x=12000; y=-4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=S + role=terminal + ha:spice/pinnum = { value=3; prio=31050; } + } + } + ha:line.24 { x1=14000; y1=-1000; x2=14000; y2=3000; stroke=sym-decor; } + ha:line.25 { x1=14000; y1=4000; x2=14000; y2=7000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + devmap=2n7002_sot23 + name=./Q1 + role=symbol + ha:spice/prefix = { value=M; prio=31050; } + } + } + ha:group.3 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAX; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=108000; y=168000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAY; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAZ; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + ha:device = { value=resistor; prio=31050; } + footprint=1206 + name=./R1 + role=symbol + ha:spice/prefix = { value=R; prio=31050; } + value=510 + } + } + ha:group.4 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAg; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAQ; + x=108000; y=124000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAh; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAR; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=C + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.2 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAi; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAS; + x=-16000; y=0; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=A + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:line.3 { x1=-4000; y1=0; x2=-6000; y2=0; stroke=sym-decor; } + ha:line.4 { x1=-12000; y1=0; x2=-10000; y2=0; stroke=sym-decor; } + ha:line.5 { x1=-10000; y1=4000; x2=-6000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=-6000; y1=0; x2=-10000; y2=-4000; stroke=sym-decor; } + ha:line.7 { x1=-10000; y1=4000; x2=-10000; y2=-4000; stroke=sym-decor; } + ha:line.8 { x1=-6000; y1=4000; x2=-6000; y2=-4000; stroke=sym-decor; } + ha:text.9 { x1=-4000; y1=13000; rot=90.000000; dyntext=1; stroke=sym-secondary; text=%../a.devmap%; floater=1; } + ha:text.10 { x1=-8000; y1=13000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.11 { x1=-8000; y1=8000; x2=-6000; y2=11000; stroke=sym-decor; } + ha:line.12 { x1=-6000; y1=11000; x2=-7000; y2=10000; stroke=sym-decor; } + ha:line.13 { x1=-6000; y1=11000; x2=-6517; y2=9545; stroke=sym-decor; } + ha:line.14 { x1=-10000; y1=7000; x2=-8000; y2=10000; stroke=sym-decor; } + ha:line.15 { x1=-8000; y1=10000; x2=-8000; y2=8000; stroke=sym-decor; } + ha:line.16 { x1=-8303; y1=6354; x2=-6303; y2=9354; stroke=sym-decor; } + ha:line.17 { x1=-6303; y1=9354; x2=-7303; y2=8354; stroke=sym-decor; } + ha:line.18 { x1=-6303; y1=9354; x2=-6820; y2=7899; stroke=sym-decor; } + ha:line.19 { x1=-10303; y1=5354; x2=-8303; y2=8354; stroke=sym-decor; } + ha:line.20 { x1=-8303; y1=8354; x2=-8303; y2=6354; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + devmap=led5 + name=./D1 + role=symbol + ha:spice/prefix = { value=D; prio=31050; } + } + } + ha:group.5 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAk; + li:objects { + ha:line.1 { x1=108000; y1=116000; x2=108000; y2=124000; stroke=wire; } + ha:text.2 { x1=110000; y1=120000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=./led_fet + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.6 { + li:conn { + /2/5/1 + /2/2/1/1 + } + } + ha:connection.7 { + li:conn { + /2/5/1 + /2/4/1/1 + } + } + ha:group.8 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAl; + li:objects { + ha:line.1 { x1=108000; y1=140000; x2=108000; y2=148000; stroke=wire; } + ha:text.2 { x1=110000; y1=144000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=./res_led + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.9 { + li:conn { + /2/8/1 + /2/3/1/1 + } + } + ha:connection.10 { + li:conn { + /2/8/1 + /2/4/2/1 + } + } + ha:connection.12 { + li:conn { + /2/3/2/1 + /2/14/3 + } + } + ha:group.14 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAo; + li:objects { + ha:line.1 { x1=84000; y1=176000; x2=108000; y2=176000; stroke=wire; } + ha:line.3 { x1=108000; y1=168000; x2=108000; y2=176000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.16 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAp; + li:objects { + ha:line.1 { x1=96000; y1=104000; x2=84000; y2=104000; stroke=wire; } + ha:text.2 { x1=88000; y1=104000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=./gate + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.17 { + li:conn { + /2/16/1 + /2/2/2/1 + } + } + ha:group.22 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAx; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=108000; y=68000; + li:objects { + ha:group.1 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAy; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + drc/require_graphical_conn=1 + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.24 { + uuid=/vAQ7urXB5Qp0gPFDvkAAAA9; src_uuid=AHibvjaMiL5NH+9/wR0AAAAG; + x=84000; y=176000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-5000; y1=-1500; mirx=1; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:line.3 { x1=-4000; y1=0; x2=-5000; y2=2000; stroke=sheet-decor; } + ha:line.4 { x1=-4000; y1=0; x2=-5000; y2=-2000; stroke=sheet-decor; } + ha:line.5 { x1=-5000; y1=-2000; x2=-17000; y2=-2000; stroke=sheet-decor; } + ha:line.6 { x1=-17000; y1=2000; x2=-5000; y2=2000; stroke=sheet-decor; } + ha:line.7 { x1=-17000; y1=2000; x2=-17000; y2=-2000; stroke=sheet-decor; } + } + ha:attrib { + -sym-comment={ Sheet level terminal (not really a symbol) for subsheet input net in a hierarchy } + -sym-copyright=(C) 2024 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=Vin + role=terminal + } + } + ha:group.25 { + uuid=/vAQ7urXB5Qp0gPFDvkAAAA/; src_uuid=AHibvjaMiL5NH+9/wR0AAAAG; + x=84000; y=104000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-5000; y1=-1500; mirx=1; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:line.3 { x1=-4000; y1=0; x2=-5000; y2=2000; stroke=sheet-decor; } + ha:line.4 { x1=-4000; y1=0; x2=-5000; y2=-2000; stroke=sheet-decor; } + ha:line.5 { x1=-5000; y1=-2000; x2=-17000; y2=-2000; stroke=sheet-decor; } + ha:line.6 { x1=-17000; y1=2000; x2=-5000; y2=2000; stroke=sheet-decor; } + ha:line.7 { x1=-17000; y1=2000; x2=-17000; y2=-2000; stroke=sheet-decor; } + } + ha:attrib { + -sym-comment={ Sheet level terminal (not really a symbol) for subsheet input net in a hierarchy } + -sym-copyright=(C) 2024 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=ctrl + role=terminal + } + } + ha:connection.26 { + li:conn { + /2/24/1 + /2/14/1 + } + } + ha:connection.27 { + li:conn { + /2/25/1 + /2/16/1 + } + } + ha:group.28 { + uuid=2vo3Yb2emwQ68/CAVhgAAAAc; src_uuid=iNOQfJpO6hT/HFDFGjoAAACC; + x=96000; y=80000; + li:objects { + ha:group.1 { + uuid=2vo3Yb2emwQ68/CAVhgAAAAd; src_uuid=iNOQfJpO6hT/HFDFGjoAAACD; + x=12000; y=12000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=D + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:group.2 { + uuid=2vo3Yb2emwQ68/CAVhgAAAAe; src_uuid=iNOQfJpO6hT/HFDFGjoAAACE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=G + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:text.3 { x1=8000; y1=8000; rot=90.000000; dyntext=1; stroke=sym-secondary; text=%../a.devmap%; floater=1; } + ha:text.4 { x1=4000; y1=8000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:arc.5 { cx=11000; cy=3000; r=5500; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:line.6 { x1=4000; y1=0; x2=8000; y2=0; stroke=sym-decor; } + ha:line.7 { x1=9000; y1=-1000; x2=9000; y2=1000; stroke=sym-decor; } + ha:line.8 { x1=9000; y1=2000; x2=9000; y2=4000; stroke=sym-decor; } + ha:line.9 { x1=9000; y1=5000; x2=9000; y2=7000; stroke=sym-decor; } + ha:line.10 { x1=9000; y1=3000; x2=12000; y2=3000; stroke=sym-decor; } + ha:line.11 { x1=9000; y1=0; x2=12000; y2=0; stroke=sym-decor; } + ha:line.12 { x1=9000; y1=6000; x2=12000; y2=6000; stroke=sym-decor; } + ha:line.13 { x1=12000; y1=6000; x2=12000; y2=8000; stroke=sym-decor; } + ha:line.14 { x1=12000; y1=-4000; x2=12000; y2=3000; stroke=sym-decor; } + ha:line.15 { x1=13000; y1=3000; x2=15000; y2=3000; stroke=sym-decor; } + ha:line.16 { x1=15000; y1=3000; x2=14000; y2=4000; stroke=sym-decor; } + ha:line.17 { x1=14000; y1=4000; x2=13000; y2=3000; stroke=sym-decor; } + ha:line.18 { x1=13000; y1=4000; x2=15000; y2=4000; stroke=sym-decor; } + ha:line.19 { x1=12000; y1=7000; x2=14000; y2=7000; stroke=sym-decor; } + ha:line.20 { x1=14000; y1=-1000; x2=12000; y2=-1000; stroke=sym-decor; } + ha:line.21 { x1=8000; y1=7000; x2=8000; y2=0; stroke=sym-decor; } + ha:polygon.22 { + li:outline { + ha:line { x1=10000; y1=4000; x2=9000; y2=3000; } + ha:line { x1=9000; y1=3000; x2=10000; y2=2000; } + ha:line { x1=10000; y1=2000; x2=10000; y2=4000; } + } + stroke=sym-decor; + fill=sym-decor; + } + ha:group.23 { + uuid=2vo3Yb2emwQ68/CAVhgAAAAf; src_uuid=iNOQfJpO6hT/HFDFGjoAAACF; + x=12000; y=-4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=S + role=terminal + ha:spice/pinnum = { value=3; prio=31050; } + } + } + ha:line.24 { x1=14000; y1=-1000; x2=14000; y2=3000; stroke=sym-decor; } + ha:line.25 { x1=14000; y1=4000; x2=14000; y2=7000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + devmap=2n7002_sot23 + name=./Q2 + role=symbol + ha:spice/prefix = { value=M; prio=31050; } + } + } + ha:group.29 { + uuid=2vo3Yb2emwQ68/CAVhgAAAAg; + li:objects { + ha:line.1 { x1=108000; y1=96000; x2=108000; y2=92000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.30 { + li:conn { + /2/29/1 + /2/2/23/1 + } + } + ha:connection.31 { + li:conn { + /2/29/1 + /2/28/1/1 + } + } + ha:group.32 { + uuid=2vo3Yb2emwQ68/CAVhgAAAAh; + li:objects { + ha:line.1 { x1=96000; y1=80000; x2=84000; y2=80000; stroke=wire; } + ha:text.2 { x1=72000; y1=78000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=blink_enable + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.33 { + li:conn { + /2/32/1 + /2/28/2/1 + } + } + ha:group.34 { + uuid=2vo3Yb2emwQ68/CAVhgAAAAi; + li:objects { + ha:line.1 { x1=108000; y1=72000; x2=108000; y2=68000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.35 { + li:conn { + /2/34/1 + /2/22/1/1 + } + } + ha:connection.36 { + li:conn { + /2/34/1 + /2/28/23/1 + } + } + ha:line.37 { x1=80000; y1=76000; x2=80000; y2=66000; stroke=sheet-decor; } + ha:line.38 { x1=80000; y1=76000; x2=79000; y2=75000; stroke=sheet-decor; } + ha:line.39 { x1=80000; y1=76000; x2=81000; y2=75000; stroke=sheet-decor; } + ha:text.40 { x1=76000; y1=66000; miry=1; dyntext=0; stroke=sheet-decor; text=global net; } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer=Tibor 'Igor2' Palinkas + page=2/2 + print_page=A/4 + title=LED and driver + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 1 + grid = 2.0480 mm + } + } + } +} Index: tags/1.0.5/doc/examples/hierarchic/24_led/main.rs =================================================================== --- tags/1.0.5/doc/examples/hierarchic/24_led/main.rs (nonexistent) +++ tags/1.0.5/doc/examples/hierarchic/24_led/main.rs (revision 10414) @@ -0,0 +1,728 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + ha:group.1 { + uuid=Of4kyoIScCrE774KCa4AAABc; + li:objects { + ha:group.1 { + uuid=Of4kyoIScCrE774KCa4AAABd; loclib_name=attiny24.funcmap; + li:objects { + } + ha:attrib { + li:funcmap/ports { + { PB0/PB0 -> sigtype=digital; } + { PB0/PCINT8 -> sigtype=digital; dir=input } + { PB0/XTAL1 -> sigtype=analog; } + { PB1/PB1 -> sigtype=digital; } + { PB1/PCINT9 -> sigtype=digital; dir=input } + { PB1/XTAL2 -> sigtype=analog; } + { PB3/PB3 -> sigtype=digital; } + { PB3/PCINT11 -> sigtype=digital; dir=input } + { PB3/RESET -> sigtype=digital; dir=input } + { PB2/PB2 -> sigtype=digital; } + { PB2/PCINT10 -> sigtype=digital; dir=input } + { PB2/OC0A -> sigtype=digital; dir=output } + { PB2/INT0 -> sigtype=digital; dir=input } + { PA7/PA7 -> sigtype=digital; } + { PA7/PCINT7 -> sigtype=digital; dir=input } + { PA7/OC0B -> sigtype=digital; dir=output } + { PA7/ADC7 -> sigtype=digital; dir=input } + { PA6/PA6 -> sigtype=digital; } + { PA6/PCINT6 -> sigtype=digital; dir=input } + { PA6/MOSI -> sigtype=digital; } + { PA6/DI -> sigtype=digital; dir=input } + { PA6/SDA -> sigtype=digital; } + { PA6/OC1A -> sigtype=digital; dir=output } + { PA6/ADC6 -> sigtype=analog; dir=input } + { PA0/PA0 -> sigtype=digital; } + { PA0/PCINT0 -> sigtype=digital; dir=input } + { PA0/AREF+ADC0-> sigtype=analog; dir=input } + { PA1/PA1 -> sigtype=digital; } + { PA1/PCINT1 -> sigtype=digital; dir=input } + { PA1/AIN0 -> sigtype=analog; dir=input } + { PA1/ADC1 -> sigtype=analog; dir=input } + { PA2/PA2 -> sigtype=digital; } + { PA2/PCINT2 -> sigtype=digital; dir=input } + { PA2/AIN1 -> sigtype=analog; dir=input } + { PA2/ADC2 -> sigtype=analog; dir=input } + { PA3/PA3 -> sigtype=digital; } + { PA3/PCINT3 -> sigtype=digital; dir=input } + { PA3/ADC3 -> sigtype=analog; dir=input } + { PA4/PA4 -> sigtype=digital; } + { PA4/PCINT4 -> sigtype=digital; dir=input } + { PA4/SCK -> sigtype=digital; } + { PA4/SCL -> sigtype=digital; } + { PA4/ADC4 -> sigtype=analog; dir=input } + { PA5/PA5 -> sigtype=digital; } + { PA5/PCINT5 -> sigtype=digital; dir=input } + { PA5/MISO -> sigtype=digital; } + { PA5/DO -> sigtype=digital; dir=output } + { PA5/OC1B -> sigtype=digital; dir=output } + { PA5/ADC5 -> sigtype=analog; dir=input } + } + li:funcmap/strong_groups { + { SPI -> SCK, MISO, MOSI } + { I2C -> SDA, SCL } + { USI -> SCK, DI, DO } + } + li:funcmap/weak_groups { + { gpio -> PB0, PB1, PB2, PB3, PA6, PA7, PA0, PA1, PA2, PA3, PA4, PA5 } + { pcint -> PCINT8, PCINT9, PCINT11, PCINT10, PCINT7, PCINT6, PCINT0, PCINT1, PCINT2, PCINT3, PCINT4, PCINT5 } + { xtal -> XTAL1, XTAL2 } + { PWM -> OC0A, OC0B, OC1A, OC1B } + { adc -> AREF+ADC0, ADC1, ADC2, ADC3, ADC4, ADC5, ADC6, ADC7 } + { comparator -> AIN0, AIN1 } + } + } + } + } + ha:attrib { + ha:purpose = { value=funcmap; prio=0; } + } + } + } + } + ha:obj_direct.2 { + uuid=Of4kyoIScCrE774KCa4AAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.1 { + uuid=8/SYZ/pfBzxyqFA12WQAAAAC; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAg; + li:objects { + ha:polygon.11 { + li:outline { + ha:line { x1=0; y1=0; x2=80000; y2=0; } + ha:line { x1=80000; y1=0; x2=80000; y2=20000; } + ha:line { x1=80000; y1=20000; x2=0; y2=20000; } + ha:line { x1=0; y1=20000; x2=0; y2=0; } + } + stroke=titlebox-frame; + fill=titlebox-fill; + } + ha:line.12 { x1=0; y1=10000; x2=80000; y2=10000; stroke=titlebox-frame; } + ha:line.13 { x1=40000; y1=10000; x2=40000; y2=0; stroke=titlebox-frame; } + ha:text.20 { x1=1000; y1=16500; dyntext=0; stroke=titlebox-big; text=TITLE; } + ha:text.21 { x1=1000; y1=10500; x2=79000; y2=16000; dyntext=1; stroke=titlebox-big; text=%../../A.title%; } + ha:text.22 { x1=1000; y1=5500; dyntext=0; stroke=titlebox-small; text={PROJECT:}; } + ha:text.23 { x1=13000; y1=5500; x2=39000; y2=9500; dyntext=1; stroke=titlebox-big; text=%project.name%; } + ha:text.24 { x1=1000; y1=500; dyntext=0; stroke=titlebox-small; text={PAGE:}; } + ha:text.25 { x1=10000; y1=500; x2=39000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.page%; } + ha:text.26 { x1=41000; y1=5500; dyntext=0; stroke=titlebox-small; text={FILE:}; } + ha:text.27 { x1=48000; y1=5500; x2=79000; y2=9500; dyntext=1; stroke=titlebox-big; text=%filename%; } + ha:text.28 { x1=41000; y1=500; dyntext=0; stroke=titlebox-small; text={MAINTAINER:}; } + ha:text.29 { x1=55000; y1=500; x2=79000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.maintainer%; } + ha:text.30 { x1=79000; y1=16000; mirx=1; dyntext=1; stroke=sheet-decor; text=%stance.model% %stance.sub_major% %stance.sub_minor% %stance.test_bench% %view.name%; } + } + ha:attrib { + purpose=titlebox + } + } + ha:group.8 { + uuid=Of4kyoIScCrE774KCa4AAAAK; + x=136000; y=92000; + li:objects { + ha:group.1 { + uuid=Of4kyoIScCrE774KCa4AAAAL; src_uuid=Of4kyoIScCrE774KCa4AAAAD; + x=-8000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=ctrl + role=terminal + } + } + ha:group.2 { + uuid=Of4kyoIScCrE774KCa4AAAAM; src_uuid=Of4kyoIScCrE774KCa4AAAAD; + x=0; y=8000; rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=Vin + role=terminal + } + } + ha:polygon.3 { + li:outline { + ha:line { x1=-8000; y1=8000; x2=-8000; y2=-8000; } + ha:line { x1=-8000; y1=-8000; x2=8000; y2=-8000; } + ha:line { x1=8000; y1=-8000; x2=8000; y2=8000; } + ha:line { x1=8000; y1=8000; x2=-8000; y2=8000; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + ha:text.4 { x1=-8000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:text.5 { x1=-1000; y1=-1000; dyntext=1; stroke=sym-secondary; text=%../A.cschem/child/name%; floater=1; } + } + ha:attrib { + cschem/child/name=led + name=S1 + role=symbol + } + } + ha:group.9 { + uuid=Of4kyoIScCrE774KCa4AAABN; src_uuid=+oSyprNFSw9F5MMrBkcAAAAP; + x=68000; y=68000; + li:objects { + ha:text.1 { x1=-8000; y1=-4000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.2 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=36000; } + ha:line { x1=0; y1=36000; x2=24000; y2=36000; } + ha:line { x1=24000; y1=36000; x2=24000; y2=0; } + ha:line { x1=24000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + } + ha:group.3 { + uuid=Of4kyoIScCrE774KCa4AAABO; src_uuid=+oSyprNFSw9F5MMrBkcAAAAB; + x=0; y=24000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PB0 + pinnum=2 + role=terminal + } + } + ha:group.4 { + uuid=Of4kyoIScCrE774KCa4AAABP; src_uuid=+oSyprNFSw9F5MMrBkcAAAAC; + x=0; y=20000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PB1 + pinnum=3 + role=terminal + } + } + ha:group.5 { + uuid=Of4kyoIScCrE774KCa4AAABQ; src_uuid=+oSyprNFSw9F5MMrBkcAAAAD; + x=0; y=16000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PB2 + pinnum=5 + role=terminal + } + } + ha:group.6 { + uuid=Of4kyoIScCrE774KCa4AAABR; src_uuid=+oSyprNFSw9F5MMrBkcAAAAE; + x=0; y=12000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PB3 + pinnum=4 + role=terminal + } + } + ha:group.7 { + uuid=Of4kyoIScCrE774KCa4AAABS; src_uuid=+oSyprNFSw9F5MMrBkcAAAAF; + x=24000; y=32000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PA0 + pinnum=13 + role=terminal + } + } + ha:group.8 { + uuid=Of4kyoIScCrE774KCa4AAABT; src_uuid=+oSyprNFSw9F5MMrBkcAAAAG; + x=24000; y=28000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PA1 + pinnum=12 + role=terminal + } + } + ha:group.9 { + uuid=Of4kyoIScCrE774KCa4AAABU; src_uuid=+oSyprNFSw9F5MMrBkcAAAAH; + x=24000; y=24000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PA2 + pinnum=11 + role=terminal + } + } + ha:group.10 { + uuid=Of4kyoIScCrE774KCa4AAABV; src_uuid=+oSyprNFSw9F5MMrBkcAAAAI; + x=24000; y=20000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PA3 + pinnum=10 + role=terminal + } + } + ha:group.11 { + uuid=Of4kyoIScCrE774KCa4AAABW; src_uuid=+oSyprNFSw9F5MMrBkcAAAAJ; + x=24000; y=16000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PA4 + pinnum=9 + role=terminal + } + } + ha:group.12 { + uuid=Of4kyoIScCrE774KCa4AAABX; src_uuid=+oSyprNFSw9F5MMrBkcAAAAK; + x=24000; y=12000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + funcmap/name=OC1B + name=PA5 + pinnum=8 + role=terminal + } + } + ha:group.13 { + uuid=Of4kyoIScCrE774KCa4AAABY; src_uuid=+oSyprNFSw9F5MMrBkcAAAAL; + x=24000; y=8000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + funcmap/name=OC1A + name=PA6 + pinnum=7 + role=terminal + } + } + ha:group.14 { + uuid=Of4kyoIScCrE774KCa4AAABZ; src_uuid=+oSyprNFSw9F5MMrBkcAAAAM; + x=24000; y=4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + funcmap/name=PA7 + name=PA7 + pinnum=6 + role=terminal + } + } + ha:group.15 { + uuid=Of4kyoIScCrE774KCa4AAABa; src_uuid=+oSyprNFSw9F5MMrBkcAAAAN; + x=12000; y=36000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=0; stroke=term-secondary; text=VCC; } + } + ha:attrib { + name=VCC + pinnum=1 + role=terminal + } + } + ha:group.16 { + uuid=Of4kyoIScCrE774KCa4AAABb; src_uuid=+oSyprNFSw9F5MMrBkcAAAAO; + x=12000; y=0; rot=-90.000000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=0; stroke=term-secondary; text=GND; } + } + ha:attrib { + name=GND + pinnum=14 + role=terminal + } + } + ha:text.17 { x1=-8000; y1=-8000; dyntext=1; stroke=sym-secondary; text=%../A.funcmap%; floater=1; } + ha:text.18 { x1=-8000; y1=-12000; dyntext=1; stroke=sym-secondary; text=%../A.footprint%; floater=1; } + ha:text.19 { x1=-8000; y1=-16000; dyntext=1; stroke=sym-secondary; text=%../A.device%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2023 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=edakrill/igor2 + -symbol-generator=boxsym-rnd + device=attiny24 + footprint=so(14) + funcmap=attiny24.funcmap + name=U1 + role=symbol + } + } + ha:group.10 { + uuid=Of4kyoIScCrE774KCa4AAABi; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB6; + x=80000; y=112000; + li:objects { + ha:group.1 { + uuid=Of4kyoIScCrE774KCa4AAABj; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB7; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + drc/require_graphical_conn=1 + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-4000; y1=4000; x2=4000; y2=7000; halign=center; dyntext=0; stroke=sym-primary; text=Vcc; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:Vcc} + } + role=symbol + } + } + ha:group.11 { + uuid=Of4kyoIScCrE774KCa4AAABk; + li:objects { + ha:line.1 { x1=80000; y1=112000; x2=80000; y2=108000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.12 { + li:conn { + /2/11/1 + /2/9/15/1 + } + } + ha:connection.13 { + li:conn { + /2/11/1 + /2/10/1/1 + } + } + ha:group.17 { + uuid=Of4kyoIScCrE774KCa4AAABp; src_uuid=Of4kyoIScCrE774KCa4AAAAK; + x=136000; y=60000; + li:objects { + ha:group.1 { + uuid=Of4kyoIScCrE774KCa4AAABq; src_uuid=Of4kyoIScCrE774KCa4AAAAD; + x=-8000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=ctrl + role=terminal + } + } + ha:group.2 { + uuid=Of4kyoIScCrE774KCa4AAABr; src_uuid=Of4kyoIScCrE774KCa4AAAAD; + x=0; y=8000; rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=Vin + role=terminal + } + } + ha:polygon.3 { + li:outline { + ha:line { x1=-8000; y1=8000; x2=-8000; y2=-8000; } + ha:line { x1=-8000; y1=-8000; x2=8000; y2=-8000; } + ha:line { x1=8000; y1=-8000; x2=8000; y2=8000; } + ha:line { x1=8000; y1=8000; x2=-8000; y2=8000; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + ha:text.4 { x1=-8000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:text.5 { x1=-1000; y1=-1000; dyntext=1; stroke=sym-secondary; text=%../A.cschem/child/name%; floater=1; } + } + ha:attrib { + cschem/child/name=led + name=S2 + role=symbol + } + } + ha:group.20 { + uuid=Of4kyoIScCrE774KCa4AAAB6; src_uuid=iNOQfJpO6hT/HFDFGjoAAABv; + x=136000; y=72000; + li:objects { + ha:group.1 { + uuid=Of4kyoIScCrE774KCa4AAAB7; src_uuid=iNOQfJpO6hT/HFDFGjoAAABw; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + drc/require_graphical_conn=1 + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-6000; y1=4000; x2=6000; y2=7000; halign=center; dyntext=1; stroke=sym-primary; text=%../A.rail%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:forge { + delete,forge/tmp + scalar,forge/tmp + {sub,^,1:,forge/tmp} + suba,$,rail,forge/tmp + array,connect + append,connect,forge/tmp + } + rail=V9V + role=symbol + } + } + ha:connection.21 { + li:conn { + /2/20/1/1 + /2/17/2/1 + } + } + ha:group.22 { + uuid=Of4kyoIScCrE774KCa4AAAB8; src_uuid=iNOQfJpO6hT/HFDFGjoAAABv; + x=136000; y=104000; + li:objects { + ha:group.1 { + uuid=Of4kyoIScCrE774KCa4AAAB9; src_uuid=iNOQfJpO6hT/HFDFGjoAAABw; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + drc/require_graphical_conn=1 + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-6000; y1=4000; x2=6000; y2=7000; halign=center; dyntext=1; stroke=sym-primary; text=%../A.rail%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:forge { + delete,forge/tmp + scalar,forge/tmp + {sub,^,1:,forge/tmp} + suba,$,rail,forge/tmp + array,connect + append,connect,forge/tmp + } + rail=V9V + role=symbol + } + } + ha:connection.23 { + li:conn { + /2/22/1/1 + /2/8/2/1 + } + } + ha:group.24 { + uuid=Of4kyoIScCrE774KCa4AAACC; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=80000; y=64000; + li:objects { + ha:group.1 { + uuid=Of4kyoIScCrE774KCa4AAACD; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + drc/require_graphical_conn=1 + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:connection.25 { + li:conn { + /2/24/1/1 + /2/9/16/1 + } + } + ha:group.26 { + uuid=Of4kyoIScCrE774KCa4AAACE; + li:objects { + ha:line.1 { x1=96000; y1=76000; x2=112000; y2=76000; stroke=wire; } + ha:line.2 { x1=112000; y1=76000; x2=112000; y2=60000; stroke=wire; } + ha:line.3 { x1=112000; y1=60000; x2=124000; y2=60000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.27 { + li:conn { + /2/26/1 + /2/9/13/1 + } + } + ha:connection.28 { + li:conn { + /2/17/1/1 + /2/26/3 + } + } + ha:group.29 { + uuid=Of4kyoIScCrE774KCa4AAACF; + li:objects { + ha:line.1 { x1=96000; y1=80000; x2=112000; y2=80000; stroke=wire; } + ha:line.2 { x1=112000; y1=80000; x2=112000; y2=92000; stroke=wire; } + ha:line.3 { x1=112000; y1=92000; x2=124000; y2=92000; stroke=wire; } + ha:text.4 { x1=112000; y1=92000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=pwm1b + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.30 { + li:conn { + /2/29/1 + /2/9/12/1 + } + } + ha:connection.31 { + li:conn { + /2/29/3 + /2/8/1/1 + } + } + ha:text.34 { x1=104000; y1=48000; dyntext=0; stroke=sheet-decor; text=net not named; } + ha:line.36 { x1=114000; y1=51000; x2=114000; y2=59000; stroke=sheet-decor; } + ha:line.37 { x1=114000; y1=59000; x2=113000; y2=58000; stroke=sheet-decor; } + ha:line.38 { x1=114000; y1=59000; x2=114000; y2=58000; stroke=sheet-decor; } + ha:line.39 { x1=114000; y1=59000; x2=115000; y2=58000; stroke=sheet-decor; } + ha:group.41 { + uuid=bsad3yWdIT7crMp6fuAAAABE; src_uuid=2vo3Yb2emwQ68/CAVhgAAAAh; + x=12000; y=20000; + li:objects { + ha:line.1 { x1=96000; y1=80000; x2=84000; y2=80000; stroke=wire; } + ha:text.2 { x1=97000; y1=78000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=blink_enable + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.42 { + li:conn { + /2/41/1 + /2/9/7/1 + } + } + ha:line.43 { x1=112000; y1=102000; x2=112000; y2=112000; stroke=sheet-decor; } + ha:line.44 { x1=112000; y1=102000; x2=111000; y2=103000; stroke=sheet-decor; } + ha:line.45 { x1=112000; y1=102000; x2=113000; y2=103000; stroke=sheet-decor; } + ha:text.46 { x1=108000; y1=112000; dyntext=0; stroke=sheet-decor; text=global net; } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer=Tibor 'Igor2' Palinkas + page=1/2 + print_page=A/4 + title=programmable blinking LEDs + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 0 + grid = 1.0240 mm + } + } + } +} Index: tags/1.0.5/doc/examples/hierarchic/24_led/project.lht =================================================================== --- tags/1.0.5/doc/examples/hierarchic/24_led/project.lht (nonexistent) +++ tags/1.0.5/doc/examples/hierarchic/24_led/project.lht (revision 10414) @@ -0,0 +1,14 @@ +ha:coraleda-project-v1 { + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:prj { + li:root_sheets { + main.rs + } + li:aux_sheets { + led.rs + } + } + } + } +} Index: tags/1.0.5/doc/examples/hierarchic/32_subtree/led.rs =================================================================== --- tags/1.0.5/doc/examples/hierarchic/32_subtree/led.rs (nonexistent) +++ tags/1.0.5/doc/examples/hierarchic/32_subtree/led.rs (revision 10414) @@ -0,0 +1,624 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + ha:group.1 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAP; + li:objects { + ha:group.1 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAQ; loclib_name=2n7002_sot23; + li:objects { + } + ha:attrib { + device=2n7002 + footprint=SOT23 + li:portmap { + {G->pcb/pinnum=1} + {S->pcb/pinnum=2} + {D->pcb/pinnum=3} + } + } + } + ha:group.2 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAj; loclib_name=led5; + li:objects { + } + ha:attrib { + device=led5 + footprint=LED5 + li:portmap { + {C->pcb/pinnum=1} + {A->pcb/pinnum=2} + } + } + } + } + ha:attrib { + ha:purpose = { value=devmap; prio=0; } + } + } + } + } + ha:obj_direct.2 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.1 { + uuid=8/SYZ/pfBzxyqFA12WQAAAAC; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAg; + li:objects { + ha:polygon.11 { + li:outline { + ha:line { x1=0; y1=0; x2=80000; y2=0; } + ha:line { x1=80000; y1=0; x2=80000; y2=20000; } + ha:line { x1=80000; y1=20000; x2=0; y2=20000; } + ha:line { x1=0; y1=20000; x2=0; y2=0; } + } + stroke=titlebox-frame; + fill=titlebox-fill; + } + ha:line.12 { x1=0; y1=10000; x2=80000; y2=10000; stroke=titlebox-frame; } + ha:line.13 { x1=40000; y1=10000; x2=40000; y2=0; stroke=titlebox-frame; } + ha:text.20 { x1=1000; y1=16500; dyntext=0; stroke=titlebox-big; text=TITLE; } + ha:text.21 { x1=1000; y1=10500; x2=79000; y2=16000; dyntext=1; stroke=titlebox-big; text=%../../A.title%; } + ha:text.22 { x1=1000; y1=5500; dyntext=0; stroke=titlebox-small; text={PROJECT:}; } + ha:text.23 { x1=13000; y1=5500; x2=39000; y2=9500; dyntext=1; stroke=titlebox-big; text=%project.name%; } + ha:text.24 { x1=1000; y1=500; dyntext=0; stroke=titlebox-small; text={PAGE:}; } + ha:text.25 { x1=10000; y1=500; x2=39000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.page%; } + ha:text.26 { x1=41000; y1=5500; dyntext=0; stroke=titlebox-small; text={FILE:}; } + ha:text.27 { x1=48000; y1=5500; x2=79000; y2=9500; dyntext=1; stroke=titlebox-big; text=%filename%; } + ha:text.28 { x1=41000; y1=500; dyntext=0; stroke=titlebox-small; text={MAINTAINER:}; } + ha:text.29 { x1=55000; y1=500; x2=79000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.maintainer%; } + ha:text.30 { x1=79000; y1=16000; mirx=1; dyntext=1; stroke=sheet-decor; text=%stance.model% %stance.sub_major% %stance.sub_minor% %stance.test_bench% %view.name%; } + } + ha:attrib { + purpose=titlebox + } + } + ha:group.2 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAL; src_uuid=iNOQfJpO6hT/HFDFGjoAAACC; + x=96000; y=104000; + li:objects { + ha:group.1 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAM; src_uuid=iNOQfJpO6hT/HFDFGjoAAACD; + x=12000; y=12000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=D + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:group.2 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAN; src_uuid=iNOQfJpO6hT/HFDFGjoAAACE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=G + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:text.3 { x1=8000; y1=8000; rot=90.000000; dyntext=1; stroke=sym-secondary; text=%../a.devmap%; floater=1; } + ha:text.4 { x1=4000; y1=8000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:arc.5 { cx=11000; cy=3000; r=5500; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:line.6 { x1=4000; y1=0; x2=8000; y2=0; stroke=sym-decor; } + ha:line.7 { x1=9000; y1=-1000; x2=9000; y2=1000; stroke=sym-decor; } + ha:line.8 { x1=9000; y1=2000; x2=9000; y2=4000; stroke=sym-decor; } + ha:line.9 { x1=9000; y1=5000; x2=9000; y2=7000; stroke=sym-decor; } + ha:line.10 { x1=9000; y1=3000; x2=12000; y2=3000; stroke=sym-decor; } + ha:line.11 { x1=9000; y1=0; x2=12000; y2=0; stroke=sym-decor; } + ha:line.12 { x1=9000; y1=6000; x2=12000; y2=6000; stroke=sym-decor; } + ha:line.13 { x1=12000; y1=6000; x2=12000; y2=8000; stroke=sym-decor; } + ha:line.14 { x1=12000; y1=-4000; x2=12000; y2=3000; stroke=sym-decor; } + ha:line.15 { x1=13000; y1=3000; x2=15000; y2=3000; stroke=sym-decor; } + ha:line.16 { x1=15000; y1=3000; x2=14000; y2=4000; stroke=sym-decor; } + ha:line.17 { x1=14000; y1=4000; x2=13000; y2=3000; stroke=sym-decor; } + ha:line.18 { x1=13000; y1=4000; x2=15000; y2=4000; stroke=sym-decor; } + ha:line.19 { x1=12000; y1=7000; x2=14000; y2=7000; stroke=sym-decor; } + ha:line.20 { x1=14000; y1=-1000; x2=12000; y2=-1000; stroke=sym-decor; } + ha:line.21 { x1=8000; y1=7000; x2=8000; y2=0; stroke=sym-decor; } + ha:polygon.22 { + li:outline { + ha:line { x1=10000; y1=4000; x2=9000; y2=3000; } + ha:line { x1=9000; y1=3000; x2=10000; y2=2000; } + ha:line { x1=10000; y1=2000; x2=10000; y2=4000; } + } + stroke=sym-decor; + fill=sym-decor; + } + ha:group.23 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAO; src_uuid=iNOQfJpO6hT/HFDFGjoAAACF; + x=12000; y=-4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=S + role=terminal + ha:spice/pinnum = { value=3; prio=31050; } + } + } + ha:line.24 { x1=14000; y1=-1000; x2=14000; y2=3000; stroke=sym-decor; } + ha:line.25 { x1=14000; y1=4000; x2=14000; y2=7000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + devmap=2n7002_sot23 + name=./Q1 + role=symbol + ha:spice/prefix = { value=M; prio=31050; } + } + } + ha:group.3 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAX; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=108000; y=168000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAY; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAZ; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + ha:device = { value=resistor; prio=31050; } + footprint=1206 + name=./R1 + role=symbol + ha:spice/prefix = { value=R; prio=31050; } + value=510 + } + } + ha:group.4 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAg; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAQ; + x=108000; y=124000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAh; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAR; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=C + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.2 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAi; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAS; + x=-16000; y=0; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=A + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:line.3 { x1=-4000; y1=0; x2=-6000; y2=0; stroke=sym-decor; } + ha:line.4 { x1=-12000; y1=0; x2=-10000; y2=0; stroke=sym-decor; } + ha:line.5 { x1=-10000; y1=4000; x2=-6000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=-6000; y1=0; x2=-10000; y2=-4000; stroke=sym-decor; } + ha:line.7 { x1=-10000; y1=4000; x2=-10000; y2=-4000; stroke=sym-decor; } + ha:line.8 { x1=-6000; y1=4000; x2=-6000; y2=-4000; stroke=sym-decor; } + ha:text.9 { x1=-4000; y1=13000; rot=90.000000; dyntext=1; stroke=sym-secondary; text=%../a.devmap%; floater=1; } + ha:text.10 { x1=-8000; y1=13000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.11 { x1=-8000; y1=8000; x2=-6000; y2=11000; stroke=sym-decor; } + ha:line.12 { x1=-6000; y1=11000; x2=-7000; y2=10000; stroke=sym-decor; } + ha:line.13 { x1=-6000; y1=11000; x2=-6517; y2=9545; stroke=sym-decor; } + ha:line.14 { x1=-10000; y1=7000; x2=-8000; y2=10000; stroke=sym-decor; } + ha:line.15 { x1=-8000; y1=10000; x2=-8000; y2=8000; stroke=sym-decor; } + ha:line.16 { x1=-8303; y1=6354; x2=-6303; y2=9354; stroke=sym-decor; } + ha:line.17 { x1=-6303; y1=9354; x2=-7303; y2=8354; stroke=sym-decor; } + ha:line.18 { x1=-6303; y1=9354; x2=-6820; y2=7899; stroke=sym-decor; } + ha:line.19 { x1=-10303; y1=5354; x2=-8303; y2=8354; stroke=sym-decor; } + ha:line.20 { x1=-8303; y1=8354; x2=-8303; y2=6354; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + devmap=led5 + name=./D1 + role=symbol + ha:spice/prefix = { value=D; prio=31050; } + } + } + ha:group.5 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAk; + li:objects { + ha:line.1 { x1=108000; y1=116000; x2=108000; y2=124000; stroke=wire; } + ha:text.2 { x1=110000; y1=120000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=./led_fet + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.6 { + li:conn { + /2/5/1 + /2/2/1/1 + } + } + ha:connection.7 { + li:conn { + /2/5/1 + /2/4/1/1 + } + } + ha:group.8 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAl; + li:objects { + ha:line.1 { x1=108000; y1=140000; x2=108000; y2=148000; stroke=wire; } + ha:text.2 { x1=110000; y1=144000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=./res_led + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.9 { + li:conn { + /2/8/1 + /2/3/1/1 + } + } + ha:connection.10 { + li:conn { + /2/8/1 + /2/4/2/1 + } + } + ha:connection.12 { + li:conn { + /2/3/2/1 + /2/14/3 + } + } + ha:group.14 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAo; + li:objects { + ha:line.1 { x1=84000; y1=176000; x2=108000; y2=176000; stroke=wire; } + ha:line.3 { x1=108000; y1=168000; x2=108000; y2=176000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.16 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAp; + li:objects { + ha:line.1 { x1=96000; y1=104000; x2=84000; y2=104000; stroke=wire; } + ha:text.2 { x1=88000; y1=104000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=./gate + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.17 { + li:conn { + /2/16/1 + /2/2/2/1 + } + } + ha:group.22 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAx; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=108000; y=68000; + li:objects { + ha:group.1 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAy; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + drc/require_graphical_conn=1 + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.24 { + uuid=/vAQ7urXB5Qp0gPFDvkAAAA9; src_uuid=AHibvjaMiL5NH+9/wR0AAAAG; + x=84000; y=176000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-5000; y1=-1500; mirx=1; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:line.3 { x1=-4000; y1=0; x2=-5000; y2=2000; stroke=sheet-decor; } + ha:line.4 { x1=-4000; y1=0; x2=-5000; y2=-2000; stroke=sheet-decor; } + ha:line.5 { x1=-5000; y1=-2000; x2=-17000; y2=-2000; stroke=sheet-decor; } + ha:line.6 { x1=-17000; y1=2000; x2=-5000; y2=2000; stroke=sheet-decor; } + ha:line.7 { x1=-17000; y1=2000; x2=-17000; y2=-2000; stroke=sheet-decor; } + } + ha:attrib { + -sym-comment={ Sheet level terminal (not really a symbol) for subsheet input net in a hierarchy } + -sym-copyright=(C) 2024 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=Vin + role=terminal + } + } + ha:group.25 { + uuid=/vAQ7urXB5Qp0gPFDvkAAAA/; src_uuid=AHibvjaMiL5NH+9/wR0AAAAG; + x=84000; y=104000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-5000; y1=-1500; mirx=1; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:line.3 { x1=-4000; y1=0; x2=-5000; y2=2000; stroke=sheet-decor; } + ha:line.4 { x1=-4000; y1=0; x2=-5000; y2=-2000; stroke=sheet-decor; } + ha:line.5 { x1=-5000; y1=-2000; x2=-17000; y2=-2000; stroke=sheet-decor; } + ha:line.6 { x1=-17000; y1=2000; x2=-5000; y2=2000; stroke=sheet-decor; } + ha:line.7 { x1=-17000; y1=2000; x2=-17000; y2=-2000; stroke=sheet-decor; } + } + ha:attrib { + -sym-comment={ Sheet level terminal (not really a symbol) for subsheet input net in a hierarchy } + -sym-copyright=(C) 2024 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=ctrl + role=terminal + } + } + ha:connection.26 { + li:conn { + /2/24/1 + /2/14/1 + } + } + ha:connection.27 { + li:conn { + /2/25/1 + /2/16/1 + } + } + ha:group.28 { + uuid=2vo3Yb2emwQ68/CAVhgAAAAc; src_uuid=iNOQfJpO6hT/HFDFGjoAAACC; + x=96000; y=80000; + li:objects { + ha:group.1 { + uuid=2vo3Yb2emwQ68/CAVhgAAAAd; src_uuid=iNOQfJpO6hT/HFDFGjoAAACD; + x=12000; y=12000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=D + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:group.2 { + uuid=2vo3Yb2emwQ68/CAVhgAAAAe; src_uuid=iNOQfJpO6hT/HFDFGjoAAACE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=G + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:text.3 { x1=8000; y1=8000; rot=90.000000; dyntext=1; stroke=sym-secondary; text=%../a.devmap%; floater=1; } + ha:text.4 { x1=4000; y1=8000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:arc.5 { cx=11000; cy=3000; r=5500; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:line.6 { x1=4000; y1=0; x2=8000; y2=0; stroke=sym-decor; } + ha:line.7 { x1=9000; y1=-1000; x2=9000; y2=1000; stroke=sym-decor; } + ha:line.8 { x1=9000; y1=2000; x2=9000; y2=4000; stroke=sym-decor; } + ha:line.9 { x1=9000; y1=5000; x2=9000; y2=7000; stroke=sym-decor; } + ha:line.10 { x1=9000; y1=3000; x2=12000; y2=3000; stroke=sym-decor; } + ha:line.11 { x1=9000; y1=0; x2=12000; y2=0; stroke=sym-decor; } + ha:line.12 { x1=9000; y1=6000; x2=12000; y2=6000; stroke=sym-decor; } + ha:line.13 { x1=12000; y1=6000; x2=12000; y2=8000; stroke=sym-decor; } + ha:line.14 { x1=12000; y1=-4000; x2=12000; y2=3000; stroke=sym-decor; } + ha:line.15 { x1=13000; y1=3000; x2=15000; y2=3000; stroke=sym-decor; } + ha:line.16 { x1=15000; y1=3000; x2=14000; y2=4000; stroke=sym-decor; } + ha:line.17 { x1=14000; y1=4000; x2=13000; y2=3000; stroke=sym-decor; } + ha:line.18 { x1=13000; y1=4000; x2=15000; y2=4000; stroke=sym-decor; } + ha:line.19 { x1=12000; y1=7000; x2=14000; y2=7000; stroke=sym-decor; } + ha:line.20 { x1=14000; y1=-1000; x2=12000; y2=-1000; stroke=sym-decor; } + ha:line.21 { x1=8000; y1=7000; x2=8000; y2=0; stroke=sym-decor; } + ha:polygon.22 { + li:outline { + ha:line { x1=10000; y1=4000; x2=9000; y2=3000; } + ha:line { x1=9000; y1=3000; x2=10000; y2=2000; } + ha:line { x1=10000; y1=2000; x2=10000; y2=4000; } + } + stroke=sym-decor; + fill=sym-decor; + } + ha:group.23 { + uuid=2vo3Yb2emwQ68/CAVhgAAAAf; src_uuid=iNOQfJpO6hT/HFDFGjoAAACF; + x=12000; y=-4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=S + role=terminal + ha:spice/pinnum = { value=3; prio=31050; } + } + } + ha:line.24 { x1=14000; y1=-1000; x2=14000; y2=3000; stroke=sym-decor; } + ha:line.25 { x1=14000; y1=4000; x2=14000; y2=7000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + devmap=2n7002_sot23 + name=./Q2 + role=symbol + ha:spice/prefix = { value=M; prio=31050; } + } + } + ha:group.29 { + uuid=2vo3Yb2emwQ68/CAVhgAAAAg; + li:objects { + ha:line.1 { x1=108000; y1=96000; x2=108000; y2=92000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.30 { + li:conn { + /2/29/1 + /2/2/23/1 + } + } + ha:connection.31 { + li:conn { + /2/29/1 + /2/28/1/1 + } + } + ha:group.32 { + uuid=2vo3Yb2emwQ68/CAVhgAAAAh; + li:objects { + ha:line.1 { x1=96000; y1=80000; x2=84000; y2=80000; stroke=wire; } + ha:text.2 { x1=70000; y1=78000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=^/blink_enable + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.33 { + li:conn { + /2/32/1 + /2/28/2/1 + } + } + ha:group.34 { + uuid=2vo3Yb2emwQ68/CAVhgAAAAi; + li:objects { + ha:line.1 { x1=108000; y1=72000; x2=108000; y2=68000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.35 { + li:conn { + /2/34/1 + /2/22/1/1 + } + } + ha:connection.36 { + li:conn { + /2/34/1 + /2/28/23/1 + } + } + ha:line.37 { x1=80000; y1=76000; x2=80000; y2=66000; stroke=sheet-decor; } + ha:line.38 { x1=80000; y1=76000; x2=79000; y2=75000; stroke=sheet-decor; } + ha:line.39 { x1=80000; y1=76000; x2=81000; y2=75000; stroke=sheet-decor; } + ha:text.40 { x1=72000; y1=66000; miry=1; dyntext=0; stroke=sheet-decor; text=subtree local net; } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer=Tibor 'Igor2' Palinkas + page=3/3 + print_page=A/4 + title=LED and driver + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 1 + grid = 2.0480 mm + } + } + } +} Index: tags/1.0.5/doc/examples/hierarchic/32_subtree/led_ctrl.rs =================================================================== --- tags/1.0.5/doc/examples/hierarchic/32_subtree/led_ctrl.rs (nonexistent) +++ tags/1.0.5/doc/examples/hierarchic/32_subtree/led_ctrl.rs (revision 10414) @@ -0,0 +1,910 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + ha:group.1 { + uuid=Of4kyoIScCrE774KCa4AAABc; + li:objects { + ha:group.1 { + uuid=Of4kyoIScCrE774KCa4AAABd; loclib_name=attiny24.funcmap; + li:objects { + } + ha:attrib { + li:funcmap/ports { + { PB0/PB0 -> sigtype=digital; } + { PB0/PCINT8 -> sigtype=digital; dir=input } + { PB0/XTAL1 -> sigtype=analog; } + { PB1/PB1 -> sigtype=digital; } + { PB1/PCINT9 -> sigtype=digital; dir=input } + { PB1/XTAL2 -> sigtype=analog; } + { PB3/PB3 -> sigtype=digital; } + { PB3/PCINT11 -> sigtype=digital; dir=input } + { PB3/RESET -> sigtype=digital; dir=input } + { PB2/PB2 -> sigtype=digital; } + { PB2/PCINT10 -> sigtype=digital; dir=input } + { PB2/OC0A -> sigtype=digital; dir=output } + { PB2/INT0 -> sigtype=digital; dir=input } + { PA7/PA7 -> sigtype=digital; } + { PA7/PCINT7 -> sigtype=digital; dir=input } + { PA7/OC0B -> sigtype=digital; dir=output } + { PA7/ADC7 -> sigtype=digital; dir=input } + { PA6/PA6 -> sigtype=digital; } + { PA6/PCINT6 -> sigtype=digital; dir=input } + { PA6/MOSI -> sigtype=digital; } + { PA6/DI -> sigtype=digital; dir=input } + { PA6/SDA -> sigtype=digital; } + { PA6/OC1A -> sigtype=digital; dir=output } + { PA6/ADC6 -> sigtype=analog; dir=input } + { PA0/PA0 -> sigtype=digital; } + { PA0/PCINT0 -> sigtype=digital; dir=input } + { PA0/AREF+ADC0-> sigtype=analog; dir=input } + { PA1/PA1 -> sigtype=digital; } + { PA1/PCINT1 -> sigtype=digital; dir=input } + { PA1/AIN0 -> sigtype=analog; dir=input } + { PA1/ADC1 -> sigtype=analog; dir=input } + { PA2/PA2 -> sigtype=digital; } + { PA2/PCINT2 -> sigtype=digital; dir=input } + { PA2/AIN1 -> sigtype=analog; dir=input } + { PA2/ADC2 -> sigtype=analog; dir=input } + { PA3/PA3 -> sigtype=digital; } + { PA3/PCINT3 -> sigtype=digital; dir=input } + { PA3/ADC3 -> sigtype=analog; dir=input } + { PA4/PA4 -> sigtype=digital; } + { PA4/PCINT4 -> sigtype=digital; dir=input } + { PA4/SCK -> sigtype=digital; } + { PA4/SCL -> sigtype=digital; } + { PA4/ADC4 -> sigtype=analog; dir=input } + { PA5/PA5 -> sigtype=digital; } + { PA5/PCINT5 -> sigtype=digital; dir=input } + { PA5/MISO -> sigtype=digital; } + { PA5/DO -> sigtype=digital; dir=output } + { PA5/OC1B -> sigtype=digital; dir=output } + { PA5/ADC5 -> sigtype=analog; dir=input } + } + li:funcmap/strong_groups { + { SPI -> SCK, MISO, MOSI } + { I2C -> SDA, SCL } + { USI -> SCK, DI, DO } + } + li:funcmap/weak_groups { + { gpio -> PB0, PB1, PB2, PB3, PA6, PA7, PA0, PA1, PA2, PA3, PA4, PA5 } + { pcint -> PCINT8, PCINT9, PCINT11, PCINT10, PCINT7, PCINT6, PCINT0, PCINT1, PCINT2, PCINT3, PCINT4, PCINT5 } + { xtal -> XTAL1, XTAL2 } + { PWM -> OC0A, OC0B, OC1A, OC1B } + { adc -> AREF+ADC0, ADC1, ADC2, ADC3, ADC4, ADC5, ADC6, ADC7 } + { comparator -> AIN0, AIN1 } + } + } + } + } + ha:attrib { + ha:purpose = { value=funcmap; prio=0; } + } + } + } + } + ha:obj_direct.2 { + uuid=Of4kyoIScCrE774KCa4AAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.1 { + uuid=8/SYZ/pfBzxyqFA12WQAAAAC; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAg; + li:objects { + ha:polygon.11 { + li:outline { + ha:line { x1=0; y1=0; x2=80000; y2=0; } + ha:line { x1=80000; y1=0; x2=80000; y2=20000; } + ha:line { x1=80000; y1=20000; x2=0; y2=20000; } + ha:line { x1=0; y1=20000; x2=0; y2=0; } + } + stroke=titlebox-frame; + fill=titlebox-fill; + } + ha:line.12 { x1=0; y1=10000; x2=80000; y2=10000; stroke=titlebox-frame; } + ha:line.13 { x1=40000; y1=10000; x2=40000; y2=0; stroke=titlebox-frame; } + ha:text.20 { x1=1000; y1=16500; dyntext=0; stroke=titlebox-big; text=TITLE; } + ha:text.21 { x1=1000; y1=10500; x2=79000; y2=16000; dyntext=1; stroke=titlebox-big; text=%../../A.title%; } + ha:text.22 { x1=1000; y1=5500; dyntext=0; stroke=titlebox-small; text={PROJECT:}; } + ha:text.23 { x1=13000; y1=5500; x2=39000; y2=9500; dyntext=1; stroke=titlebox-big; text=%project.name%; } + ha:text.24 { x1=1000; y1=500; dyntext=0; stroke=titlebox-small; text={PAGE:}; } + ha:text.25 { x1=10000; y1=500; x2=39000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.page%; } + ha:text.26 { x1=41000; y1=5500; dyntext=0; stroke=titlebox-small; text={FILE:}; } + ha:text.27 { x1=48000; y1=5500; x2=79000; y2=9500; dyntext=1; stroke=titlebox-big; text=%filename%; } + ha:text.28 { x1=41000; y1=500; dyntext=0; stroke=titlebox-small; text={MAINTAINER:}; } + ha:text.29 { x1=55000; y1=500; x2=79000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.maintainer%; } + ha:text.30 { x1=79000; y1=16000; mirx=1; dyntext=1; stroke=sheet-decor; text=%stance.model% %stance.sub_major% %stance.sub_minor% %stance.test_bench% %view.name%; } + } + ha:attrib { + purpose=titlebox + } + } + ha:group.8 { + uuid=Of4kyoIScCrE774KCa4AAAAK; + x=160000; y=92000; + li:objects { + ha:group.1 { + uuid=Of4kyoIScCrE774KCa4AAAAL; src_uuid=Of4kyoIScCrE774KCa4AAAAD; + x=-8000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=ctrl + role=terminal + } + } + ha:group.2 { + uuid=Of4kyoIScCrE774KCa4AAAAM; src_uuid=Of4kyoIScCrE774KCa4AAAAD; + x=0; y=8000; rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=Vin + role=terminal + } + } + ha:polygon.3 { + li:outline { + ha:line { x1=-8000; y1=8000; x2=-8000; y2=-8000; } + ha:line { x1=-8000; y1=-8000; x2=8000; y2=-8000; } + ha:line { x1=8000; y1=-8000; x2=8000; y2=8000; } + ha:line { x1=8000; y1=8000; x2=-8000; y2=8000; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + ha:text.4 { x1=-8000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:text.5 { x1=-1000; y1=-1000; dyntext=1; stroke=sym-secondary; text=%../A.cschem/child/name%; floater=1; } + } + ha:attrib { + cschem/child/name=led + name=S1 + role=symbol + } + } + ha:group.9 { + uuid=Of4kyoIScCrE774KCa4AAABN; src_uuid=+oSyprNFSw9F5MMrBkcAAAAP; + x=68000; y=68000; + li:objects { + ha:text.1 { x1=-8000; y1=-4000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.2 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=36000; } + ha:line { x1=0; y1=36000; x2=24000; y2=36000; } + ha:line { x1=24000; y1=36000; x2=24000; y2=0; } + ha:line { x1=24000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + } + ha:group.3 { + uuid=Of4kyoIScCrE774KCa4AAABO; src_uuid=+oSyprNFSw9F5MMrBkcAAAAB; + x=0; y=24000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + funcmap/name=PCINT8 + name=PB0 + pinnum=2 + role=terminal + } + } + ha:group.4 { + uuid=Of4kyoIScCrE774KCa4AAABP; src_uuid=+oSyprNFSw9F5MMrBkcAAAAC; + x=0; y=20000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PB1 + pinnum=3 + role=terminal + } + } + ha:group.5 { + uuid=Of4kyoIScCrE774KCa4AAABQ; src_uuid=+oSyprNFSw9F5MMrBkcAAAAD; + x=0; y=16000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + funcmap/name=OC0A + name=PB2 + pinnum=5 + role=terminal + } + } + ha:group.6 { + uuid=Of4kyoIScCrE774KCa4AAABR; src_uuid=+oSyprNFSw9F5MMrBkcAAAAE; + x=0; y=12000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PB3 + pinnum=4 + role=terminal + } + } + ha:group.7 { + uuid=Of4kyoIScCrE774KCa4AAABS; src_uuid=+oSyprNFSw9F5MMrBkcAAAAF; + x=24000; y=32000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PA0 + pinnum=13 + role=terminal + } + } + ha:group.8 { + uuid=Of4kyoIScCrE774KCa4AAABT; src_uuid=+oSyprNFSw9F5MMrBkcAAAAG; + x=24000; y=28000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PA1 + pinnum=12 + role=terminal + } + } + ha:group.9 { + uuid=Of4kyoIScCrE774KCa4AAABU; src_uuid=+oSyprNFSw9F5MMrBkcAAAAH; + x=24000; y=24000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PA2 + pinnum=11 + role=terminal + } + } + ha:group.10 { + uuid=Of4kyoIScCrE774KCa4AAABV; src_uuid=+oSyprNFSw9F5MMrBkcAAAAI; + x=24000; y=20000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PA3 + pinnum=10 + role=terminal + } + } + ha:group.11 { + uuid=Of4kyoIScCrE774KCa4AAABW; src_uuid=+oSyprNFSw9F5MMrBkcAAAAJ; + x=24000; y=16000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + funcmap/name=SCK + name=PA4 + pinnum=9 + role=terminal + } + } + ha:group.12 { + uuid=Of4kyoIScCrE774KCa4AAABX; src_uuid=+oSyprNFSw9F5MMrBkcAAAAK; + x=24000; y=12000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + funcmap/name=MISO + name=PA5 + pinnum=8 + role=terminal + } + } + ha:group.13 { + uuid=Of4kyoIScCrE774KCa4AAABY; src_uuid=+oSyprNFSw9F5MMrBkcAAAAL; + x=24000; y=8000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + funcmap/name=MOSI + name=PA6 + pinnum=7 + role=terminal + } + } + ha:group.14 { + uuid=Of4kyoIScCrE774KCa4AAABZ; src_uuid=+oSyprNFSw9F5MMrBkcAAAAM; + x=24000; y=4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + funcmap/name=OC0B + name=PA7 + pinnum=6 + role=terminal + } + } + ha:group.15 { + uuid=Of4kyoIScCrE774KCa4AAABa; src_uuid=+oSyprNFSw9F5MMrBkcAAAAN; + x=12000; y=36000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=0; stroke=term-secondary; text=VCC; } + } + ha:attrib { + name=VCC + pinnum=1 + role=terminal + } + } + ha:group.16 { + uuid=Of4kyoIScCrE774KCa4AAABb; src_uuid=+oSyprNFSw9F5MMrBkcAAAAO; + x=12000; y=0; rot=-90.000000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=0; stroke=term-secondary; text=GND; } + } + ha:attrib { + name=GND + pinnum=14 + role=terminal + } + } + ha:text.17 { x1=-8000; y1=-8000; dyntext=1; stroke=sym-secondary; text=%../A.funcmap%; floater=1; } + ha:text.18 { x1=-8000; y1=-12000; dyntext=1; stroke=sym-secondary; text=%../A.footprint%; floater=1; } + ha:text.19 { x1=-8000; y1=-16000; dyntext=1; stroke=sym-secondary; text=%../A.device%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2023 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=edakrill/igor2 + -symbol-generator=boxsym-rnd + device=attiny24 + footprint=so(14) + funcmap=attiny24.funcmap + name=./U1 + role=symbol + } + } + ha:group.10 { + uuid=Of4kyoIScCrE774KCa4AAABi; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB6; + x=80000; y=112000; + li:objects { + ha:group.1 { + uuid=Of4kyoIScCrE774KCa4AAABj; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB7; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + drc/require_graphical_conn=1 + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-4000; y1=4000; x2=4000; y2=7000; halign=center; dyntext=0; stroke=sym-primary; text=Vcc; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:Vcc} + } + role=symbol + } + } + ha:group.11 { + uuid=Of4kyoIScCrE774KCa4AAABk; + li:objects { + ha:line.1 { x1=80000; y1=112000; x2=80000; y2=108000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.12 { + li:conn { + /2/11/1 + /2/9/15/1 + } + } + ha:connection.13 { + li:conn { + /2/11/1 + /2/10/1/1 + } + } + ha:group.17 { + uuid=Of4kyoIScCrE774KCa4AAABp; src_uuid=Of4kyoIScCrE774KCa4AAAAK; + x=160000; y=60000; + li:objects { + ha:group.1 { + uuid=Of4kyoIScCrE774KCa4AAABq; src_uuid=Of4kyoIScCrE774KCa4AAAAD; + x=-8000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=ctrl + role=terminal + } + } + ha:group.2 { + uuid=Of4kyoIScCrE774KCa4AAABr; src_uuid=Of4kyoIScCrE774KCa4AAAAD; + x=0; y=8000; rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=Vin + role=terminal + } + } + ha:polygon.3 { + li:outline { + ha:line { x1=-8000; y1=8000; x2=-8000; y2=-8000; } + ha:line { x1=-8000; y1=-8000; x2=8000; y2=-8000; } + ha:line { x1=8000; y1=-8000; x2=8000; y2=8000; } + ha:line { x1=8000; y1=8000; x2=-8000; y2=8000; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + ha:text.4 { x1=-8000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:text.5 { x1=-1000; y1=-1000; dyntext=1; stroke=sym-secondary; text=%../A.cschem/child/name%; floater=1; } + } + ha:attrib { + cschem/child/name=led + name=S2 + role=symbol + } + } + ha:group.20 { + uuid=Of4kyoIScCrE774KCa4AAAB6; src_uuid=iNOQfJpO6hT/HFDFGjoAAABv; + x=160000; y=72000; + li:objects { + ha:group.1 { + uuid=Of4kyoIScCrE774KCa4AAAB7; src_uuid=iNOQfJpO6hT/HFDFGjoAAABw; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + drc/require_graphical_conn=1 + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-6000; y1=4000; x2=6000; y2=7000; halign=center; dyntext=1; stroke=sym-primary; text=%../A.rail%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:forge { + delete,forge/tmp + scalar,forge/tmp + {sub,^,1:,forge/tmp} + suba,$,rail,forge/tmp + array,connect + append,connect,forge/tmp + } + rail=V9V + role=symbol + } + } + ha:group.22 { + uuid=Of4kyoIScCrE774KCa4AAAB8; src_uuid=iNOQfJpO6hT/HFDFGjoAAABv; + x=160000; y=104000; + li:objects { + ha:group.1 { + uuid=Of4kyoIScCrE774KCa4AAAB9; src_uuid=iNOQfJpO6hT/HFDFGjoAAABw; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + drc/require_graphical_conn=1 + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-6000; y1=4000; x2=6000; y2=7000; halign=center; dyntext=1; stroke=sym-primary; text=%../A.rail%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:forge { + delete,forge/tmp + scalar,forge/tmp + {sub,^,1:,forge/tmp} + suba,$,rail,forge/tmp + array,connect + append,connect,forge/tmp + } + rail=V9V + role=symbol + } + } + ha:group.24 { + uuid=Of4kyoIScCrE774KCa4AAACC; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=80000; y=64000; + li:objects { + ha:group.1 { + uuid=Of4kyoIScCrE774KCa4AAACD; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + drc/require_graphical_conn=1 + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:connection.25 { + li:conn { + /2/24/1/1 + /2/9/16/1 + } + } + ha:group.26 { + uuid=Of4kyoIScCrE774KCa4AAACE; + li:objects { + ha:line.4 { x1=96000; y1=60000; x2=148000; y2=60000; stroke=wire; } + ha:line.5 { x1=96000; y1=60000; x2=96000; y2=48000; stroke=wire; } + ha:line.6 { x1=96000; y1=48000; x2=56000; y2=48000; stroke=wire; } + ha:line.7 { x1=56000; y1=48000; x2=56000; y2=84000; stroke=wire; } + ha:line.9 { x1=56000; y1=84000; x2=64000; y2=84000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.29 { + uuid=Of4kyoIScCrE774KCa4AAACF; + li:objects { + ha:line.3 { x1=132000; y1=92000; x2=148000; y2=92000; stroke=wire; } + ha:text.4 { x1=136000; y1=92000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + ha:line.5 { x1=132000; y1=72000; x2=132000; y2=92000; stroke=wire; } + ha:line.10 { x1=132000; y1=72000; x2=96000; y2=72000; stroke=wire; } + } + ha:attrib { + name=./pwm1b + ha:role = { value=wire-net; prio=0; } + } + } + ha:text.34 { x1=104000; y1=48000; dyntext=0; stroke=sheet-decor; text=net not named; } + ha:line.36 { x1=114000; y1=51000; x2=114000; y2=59000; stroke=sheet-decor; } + ha:line.37 { x1=114000; y1=59000; x2=113000; y2=58000; stroke=sheet-decor; } + ha:line.38 { x1=114000; y1=59000; x2=114000; y2=58000; stroke=sheet-decor; } + ha:line.39 { x1=114000; y1=59000; x2=115000; y2=58000; stroke=sheet-decor; } + ha:group.41 { + uuid=bsad3yWdIT7crMp6fuAAAABE; src_uuid=2vo3Yb2emwQ68/CAVhgAAAAh; + x=12000; y=20000; + li:objects { + ha:line.1 { x1=96000; y1=80000; x2=84000; y2=80000; stroke=wire; } + ha:text.2 { x1=97000; y1=78000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=v/blink_enable + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.42 { + li:conn { + /2/41/1 + /2/9/7/1 + } + } + ha:line.43 { x1=112000; y1=102000; x2=112000; y2=112000; stroke=sheet-decor; } + ha:line.44 { x1=112000; y1=102000; x2=111000; y2=103000; stroke=sheet-decor; } + ha:line.45 { x1=112000; y1=102000; x2=113000; y2=103000; stroke=sheet-decor; } + ha:text.46 { x1=105000; y1=112000; dyntext=0; stroke=sheet-decor; text=subtree local net; } + ha:connection.48 { + li:conn { + /2/26/9 + /2/9/5/1 + } + } + ha:connection.49 { + li:conn { + /2/26/4 + /2/17/1/1 + } + } + ha:connection.50 { + li:conn { + /2/29/3 + /2/8/1/1 + } + } + ha:connection.51 { + li:conn { + /2/20/1/1 + /2/17/2/1 + } + } + ha:connection.52 { + li:conn { + /2/22/1/1 + /2/8/2/1 + } + } + ha:connection.58 { + li:conn { + /2/9/14/1 + /2/29/10 + } + } + ha:group.59 { + uuid=O5gJDsFvHDpeyBGWhuYAAABK; src_uuid=AHibvjaMiL5NH+9/wR0AAAAK; + x=112000; y=92000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-5000; y1=-1500; mirx=1; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:line.3 { x1=-4000; y1=0; x2=-5000; y2=2000; stroke=sheet-decor; } + ha:line.4 { x1=-4000; y1=0; x2=-5000; y2=-2000; stroke=sheet-decor; } + ha:line.5 { x1=-5000; y1=-2000; x2=-16000; y2=-2000; stroke=sheet-decor; } + ha:line.6 { x1=-16000; y1=2000; x2=-5000; y2=2000; stroke=sheet-decor; } + ha:line.7 { x1=-16000; y1=-2000; x2=-17000; y2=0; stroke=sheet-decor; } + ha:line.8 { x1=-17000; y1=0; x2=-16000; y2=2000; stroke=sheet-decor; } + } + ha:attrib { + -sym-comment={ Sheet level terminal (not really a symbol) for subsheet input/output net in a hierarchy } + -sym-copyright=(C) 2024 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=SCK + role=terminal + } + } + ha:group.60 { + uuid=O5gJDsFvHDpeyBGWhuYAAABN; src_uuid=AHibvjaMiL5NH+9/wR0AAAAI; + x=112000; y=84000; + li:objects { + ha:line.1 { x1=4000; y1=0; x2=0; y2=0; stroke=term-decor; } + ha:text.2 { x1=4500; y1=-1500; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:line.3 { x1=17000; y1=0; x2=16000; y2=2000; stroke=sheet-decor; } + ha:line.4 { x1=17000; y1=0; x2=16000; y2=-2000; stroke=sheet-decor; } + ha:line.5 { x1=16000; y1=-2000; x2=4000; y2=-2000; stroke=sheet-decor; } + ha:line.6 { x1=4000; y1=2000; x2=16000; y2=2000; stroke=sheet-decor; } + ha:line.7 { x1=4000; y1=2000; x2=4000; y2=-2000; stroke=sheet-decor; } + } + ha:attrib { + -sym-comment={ Sheet level terminal (not really a symbol) for subsheet output net in a hierarchy } + -sym-copyright=(C) 2024 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=MISO + role=terminal + } + } + ha:group.61 { + uuid=O5gJDsFvHDpeyBGWhuYAAABQ; src_uuid=AHibvjaMiL5NH+9/wR0AAAAG; + x=112000; y=76000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-5000; y1=-1500; mirx=1; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:line.3 { x1=-4000; y1=0; x2=-5000; y2=2000; stroke=sheet-decor; } + ha:line.4 { x1=-4000; y1=0; x2=-5000; y2=-2000; stroke=sheet-decor; } + ha:line.5 { x1=-5000; y1=-2000; x2=-17000; y2=-2000; stroke=sheet-decor; } + ha:line.6 { x1=-17000; y1=2000; x2=-5000; y2=2000; stroke=sheet-decor; } + ha:line.7 { x1=-17000; y1=2000; x2=-17000; y2=-2000; stroke=sheet-decor; } + } + ha:attrib { + -sym-comment={ Sheet level terminal (not really a symbol) for subsheet input net in a hierarchy } + -sym-copyright=(C) 2024 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=MOSI + role=terminal + } + } + ha:group.62 { + uuid=O5gJDsFvHDpeyBGWhuYAAABR; + li:objects { + ha:line.1 { x1=96000; y1=76000; x2=112000; y2=76000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.63 { + li:conn { + /2/62/1 + /2/61/1 + } + } + ha:connection.64 { + li:conn { + /2/62/1 + /2/9/13/1 + } + } + ha:group.65 { + uuid=O5gJDsFvHDpeyBGWhuYAAABS; + li:objects { + ha:line.1 { x1=96000; y1=80000; x2=108000; y2=80000; stroke=wire; } + ha:line.2 { x1=108000; y1=80000; x2=108000; y2=84000; stroke=wire; } + ha:line.3 { x1=108000; y1=84000; x2=112000; y2=84000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.66 { + li:conn { + /2/65/1 + /2/9/12/1 + } + } + ha:connection.67 { + li:conn { + /2/65/3 + /2/60/1 + } + } + ha:group.68 { + uuid=O5gJDsFvHDpeyBGWhuYAAABT; + li:objects { + ha:line.1 { x1=96000; y1=84000; x2=104000; y2=84000; stroke=wire; } + ha:line.2 { x1=104000; y1=84000; x2=104000; y2=92000; stroke=wire; } + ha:line.3 { x1=104000; y1=92000; x2=112000; y2=92000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.69 { + li:conn { + /2/68/1 + /2/9/11/1 + } + } + ha:connection.70 { + li:conn { + /2/68/3 + /2/59/1 + } + } + ha:group.71 { + uuid=O5gJDsFvHDpeyBGWhuYAAABV; src_uuid=AHibvjaMiL5NH+9/wR0AAAAG; + x=60000; y=92000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-5000; y1=-1500; mirx=1; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:line.3 { x1=-4000; y1=0; x2=-5000; y2=2000; stroke=sheet-decor; } + ha:line.4 { x1=-4000; y1=0; x2=-5000; y2=-2000; stroke=sheet-decor; } + ha:line.5 { x1=-5000; y1=-2000; x2=-17000; y2=-2000; stroke=sheet-decor; } + ha:line.6 { x1=-17000; y1=2000; x2=-5000; y2=2000; stroke=sheet-decor; } + ha:line.7 { x1=-17000; y1=2000; x2=-17000; y2=-2000; stroke=sheet-decor; } + } + ha:attrib { + -sym-comment={ Sheet level terminal (not really a symbol) for subsheet input net in a hierarchy } + -sym-copyright=(C) 2024 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=SS + role=terminal + } + } + ha:group.72 { + uuid=O5gJDsFvHDpeyBGWhuYAAABW; + li:objects { + ha:line.1 { x1=60000; y1=92000; x2=64000; y2=92000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.73 { + li:conn { + /2/72/1 + /2/9/3/1 + } + } + ha:connection.74 { + li:conn { + /2/72/1 + /2/71/1 + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer=Tibor 'Igor2' Palinkas + page=2/3 + print_page=A/4 + title=2 channel blinking LEDs + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 2 + grid = 4.0960 mm + } + } + } +} Index: tags/1.0.5/doc/examples/hierarchic/32_subtree/main.rs =================================================================== --- tags/1.0.5/doc/examples/hierarchic/32_subtree/main.rs (nonexistent) +++ tags/1.0.5/doc/examples/hierarchic/32_subtree/main.rs (revision 10414) @@ -0,0 +1,669 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + ha:group.1 { + uuid=O5gJDsFvHDpeyBGWhuYAAACO; + li:objects { + ha:group.1 { + uuid=O5gJDsFvHDpeyBGWhuYAAACP; loclib_name=attiny24.funcmap; + li:objects { + } + ha:attrib { + li:funcmap/ports { + { PB0/PB0 -> sigtype=digital; } + { PB0/PCINT8 -> sigtype=digital; dir=input } + { PB0/XTAL1 -> sigtype=analog; } + { PB1/PB1 -> sigtype=digital; } + { PB1/PCINT9 -> sigtype=digital; dir=input } + { PB1/XTAL2 -> sigtype=analog; } + { PB3/PB3 -> sigtype=digital; } + { PB3/PCINT11 -> sigtype=digital; dir=input } + { PB3/RESET -> sigtype=digital; dir=input } + { PB2/PB2 -> sigtype=digital; } + { PB2/PCINT10 -> sigtype=digital; dir=input } + { PB2/OC0A -> sigtype=digital; dir=output } + { PB2/INT0 -> sigtype=digital; dir=input } + { PA7/PA7 -> sigtype=digital; } + { PA7/PCINT7 -> sigtype=digital; dir=input } + { PA7/OC0B -> sigtype=digital; dir=output } + { PA7/ADC7 -> sigtype=digital; dir=input } + { PA6/PA6 -> sigtype=digital; } + { PA6/PCINT6 -> sigtype=digital; dir=input } + { PA6/MOSI -> sigtype=digital; } + { PA6/DI -> sigtype=digital; dir=input } + { PA6/SDA -> sigtype=digital; } + { PA6/OC1A -> sigtype=digital; dir=output } + { PA6/ADC6 -> sigtype=analog; dir=input } + { PA0/PA0 -> sigtype=digital; } + { PA0/PCINT0 -> sigtype=digital; dir=input } + { PA0/AREF+ADC0-> sigtype=analog; dir=input } + { PA1/PA1 -> sigtype=digital; } + { PA1/PCINT1 -> sigtype=digital; dir=input } + { PA1/AIN0 -> sigtype=analog; dir=input } + { PA1/ADC1 -> sigtype=analog; dir=input } + { PA2/PA2 -> sigtype=digital; } + { PA2/PCINT2 -> sigtype=digital; dir=input } + { PA2/AIN1 -> sigtype=analog; dir=input } + { PA2/ADC2 -> sigtype=analog; dir=input } + { PA3/PA3 -> sigtype=digital; } + { PA3/PCINT3 -> sigtype=digital; dir=input } + { PA3/ADC3 -> sigtype=analog; dir=input } + { PA4/PA4 -> sigtype=digital; } + { PA4/PCINT4 -> sigtype=digital; dir=input } + { PA4/SCK -> sigtype=digital; } + { PA4/SCL -> sigtype=digital; } + { PA4/ADC4 -> sigtype=analog; dir=input } + { PA5/PA5 -> sigtype=digital; } + { PA5/PCINT5 -> sigtype=digital; dir=input } + { PA5/MISO -> sigtype=digital; } + { PA5/DO -> sigtype=digital; dir=output } + { PA5/OC1B -> sigtype=digital; dir=output } + { PA5/ADC5 -> sigtype=analog; dir=input } + } + li:funcmap/strong_groups { + { SPI -> SCK, MISO, MOSI } + { I2C -> SDA, SCL } + { USI -> SCK, DI, DO } + } + li:funcmap/weak_groups { + { gpio -> PB0, PB1, PB2, PB3, PA6, PA7, PA0, PA1, PA2, PA3, PA4, PA5 } + { pcint -> PCINT8, PCINT9, PCINT11, PCINT10, PCINT7, PCINT6, PCINT0, PCINT1, PCINT2, PCINT3, PCINT4, PCINT5 } + { xtal -> XTAL1, XTAL2 } + { PWM -> OC0A, OC0B, OC1A, OC1B } + { adc -> AREF+ADC0, ADC1, ADC2, ADC3, ADC4, ADC5, ADC6, ADC7 } + { comparator -> AIN0, AIN1 } + } + } + } + } + ha:attrib { + ha:purpose = { value=funcmap; prio=0; } + } + } + } + } + ha:obj_direct.2 { + uuid=OOdnhwzrc5OfJkz+B54AAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.1 { + uuid=8/SYZ/pfBzxyqFA12WQAAAAC; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAg; + li:objects { + ha:polygon.11 { + li:outline { + ha:line { x1=0; y1=0; x2=80000; y2=0; } + ha:line { x1=80000; y1=0; x2=80000; y2=20000; } + ha:line { x1=80000; y1=20000; x2=0; y2=20000; } + ha:line { x1=0; y1=20000; x2=0; y2=0; } + } + stroke=titlebox-frame; + fill=titlebox-fill; + } + ha:line.12 { x1=0; y1=10000; x2=80000; y2=10000; stroke=titlebox-frame; } + ha:line.13 { x1=40000; y1=10000; x2=40000; y2=0; stroke=titlebox-frame; } + ha:text.20 { x1=1000; y1=16500; dyntext=0; stroke=titlebox-big; text=TITLE; } + ha:text.21 { x1=1000; y1=10500; x2=79000; y2=16000; dyntext=1; stroke=titlebox-big; text=%../../A.title%; } + ha:text.22 { x1=1000; y1=5500; dyntext=0; stroke=titlebox-small; text={PROJECT:}; } + ha:text.23 { x1=13000; y1=5500; x2=39000; y2=9500; dyntext=1; stroke=titlebox-big; text=%project.name%; } + ha:text.24 { x1=1000; y1=500; dyntext=0; stroke=titlebox-small; text={PAGE:}; } + ha:text.25 { x1=10000; y1=500; x2=39000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.page%; } + ha:text.26 { x1=41000; y1=5500; dyntext=0; stroke=titlebox-small; text={FILE:}; } + ha:text.27 { x1=48000; y1=5500; x2=79000; y2=9500; dyntext=1; stroke=titlebox-big; text=%filename%; } + ha:text.28 { x1=41000; y1=500; dyntext=0; stroke=titlebox-small; text={MAINTAINER:}; } + ha:text.29 { x1=55000; y1=500; x2=79000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.maintainer%; } + ha:text.30 { x1=79000; y1=16000; mirx=1; dyntext=1; stroke=sheet-decor; text=%stance.model% %stance.sub_major% %stance.sub_minor% %stance.test_bench% %view.name%; } + } + ha:attrib { + purpose=titlebox + } + } + ha:group.7 { + uuid=7QqSQF9OzqvKXvT6bD0AAABI; + x=236000; y=120000; mirx=1; + li:objects { + ha:polygon.1 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=-28000; } + ha:line { x1=0; y1=-28000; x2=20000; y2=-28000; } + ha:line { x1=20000; y1=-28000; x2=20000; y2=0; } + ha:line { x1=20000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + ha:group.2 { + uuid=7QqSQF9OzqvKXvT6bD0AAABJ; src_uuid=7QqSQF9OzqvKXvT6bD0AAABD; + x=24000; y=-8000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=MISO + role=terminal + } + } + ha:group.3 { + uuid=7QqSQF9OzqvKXvT6bD0AAABK; src_uuid=7QqSQF9OzqvKXvT6bD0AAABD; + x=24000; y=-12000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=MOSI + role=terminal + } + } + ha:group.4 { + uuid=7QqSQF9OzqvKXvT6bD0AAABL; src_uuid=7QqSQF9OzqvKXvT6bD0AAABD; + x=24000; y=-16000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=SCK + role=terminal + } + } + ha:group.5 { + uuid=7QqSQF9OzqvKXvT6bD0AAABM; src_uuid=7QqSQF9OzqvKXvT6bD0AAABH; + x=24000; y=-24000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=SS + role=terminal + } + } + ha:text.6 { x1=0; y1=0; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + cschem/child/name=led_ctrl + name=S1 + role=symbol + } + } + ha:group.8 { + uuid=O5gJDsFvHDpeyBGWhuYAAABc; src_uuid=7QqSQF9OzqvKXvT6bD0AAABI; + x=236000; y=84000; mirx=1; + li:objects { + ha:polygon.1 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=-28000; } + ha:line { x1=0; y1=-28000; x2=20000; y2=-28000; } + ha:line { x1=20000; y1=-28000; x2=20000; y2=0; } + ha:line { x1=20000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + ha:group.2 { + uuid=O5gJDsFvHDpeyBGWhuYAAABd; src_uuid=7QqSQF9OzqvKXvT6bD0AAABD; + x=24000; y=-8000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=MISO + role=terminal + } + } + ha:group.3 { + uuid=O5gJDsFvHDpeyBGWhuYAAABe; src_uuid=7QqSQF9OzqvKXvT6bD0AAABD; + x=24000; y=-12000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=MOSI + role=terminal + } + } + ha:group.4 { + uuid=O5gJDsFvHDpeyBGWhuYAAABf; src_uuid=7QqSQF9OzqvKXvT6bD0AAABD; + x=24000; y=-16000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=SCK + role=terminal + } + } + ha:group.5 { + uuid=O5gJDsFvHDpeyBGWhuYAAABg; src_uuid=7QqSQF9OzqvKXvT6bD0AAABH; + x=24000; y=-24000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=SS + role=terminal + } + } + ha:text.6 { x1=0; y1=0; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + cschem/child/name=led_ctrl + name=S2 + role=symbol + } + } + ha:group.9 { + uuid=O5gJDsFvHDpeyBGWhuYAAAB/; src_uuid=+oSyprNFSw9F5MMrBkcAAAAP; + x=148000; y=84000; + li:objects { + ha:text.1 { x1=-8000; y1=-4000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.2 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=36000; } + ha:line { x1=0; y1=36000; x2=24000; y2=36000; } + ha:line { x1=24000; y1=36000; x2=24000; y2=0; } + ha:line { x1=24000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + } + ha:group.3 { + uuid=O5gJDsFvHDpeyBGWhuYAAACA; src_uuid=+oSyprNFSw9F5MMrBkcAAAAB; + x=0; y=24000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PB0 + pinnum=2 + role=terminal + } + } + ha:group.4 { + uuid=O5gJDsFvHDpeyBGWhuYAAACB; src_uuid=+oSyprNFSw9F5MMrBkcAAAAC; + x=0; y=20000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PB1 + pinnum=3 + role=terminal + } + } + ha:group.5 { + uuid=O5gJDsFvHDpeyBGWhuYAAACC; src_uuid=+oSyprNFSw9F5MMrBkcAAAAD; + x=0; y=16000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PB2 + pinnum=5 + role=terminal + } + } + ha:group.6 { + uuid=O5gJDsFvHDpeyBGWhuYAAACD; src_uuid=+oSyprNFSw9F5MMrBkcAAAAE; + x=0; y=12000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PB3 + pinnum=4 + role=terminal + } + } + ha:group.7 { + uuid=O5gJDsFvHDpeyBGWhuYAAACE; src_uuid=+oSyprNFSw9F5MMrBkcAAAAF; + x=24000; y=32000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PA0 + pinnum=13 + role=terminal + } + } + ha:group.8 { + uuid=O5gJDsFvHDpeyBGWhuYAAACF; src_uuid=+oSyprNFSw9F5MMrBkcAAAAG; + x=24000; y=28000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PA1 + pinnum=12 + role=terminal + } + } + ha:group.9 { + uuid=O5gJDsFvHDpeyBGWhuYAAACG; src_uuid=+oSyprNFSw9F5MMrBkcAAAAH; + x=24000; y=24000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PA2 + pinnum=11 + role=terminal + } + } + ha:group.10 { + uuid=O5gJDsFvHDpeyBGWhuYAAACH; src_uuid=+oSyprNFSw9F5MMrBkcAAAAI; + x=24000; y=20000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PA3 + pinnum=10 + role=terminal + } + } + ha:group.11 { + uuid=O5gJDsFvHDpeyBGWhuYAAACI; src_uuid=+oSyprNFSw9F5MMrBkcAAAAJ; + x=24000; y=16000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + funcmap/name=SCK + name=PA4 + pinnum=9 + role=terminal + } + } + ha:group.12 { + uuid=O5gJDsFvHDpeyBGWhuYAAACJ; src_uuid=+oSyprNFSw9F5MMrBkcAAAAK; + x=24000; y=12000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + funcmap/name=MISO + name=PA5 + pinnum=8 + role=terminal + } + } + ha:group.13 { + uuid=O5gJDsFvHDpeyBGWhuYAAACK; src_uuid=+oSyprNFSw9F5MMrBkcAAAAL; + x=24000; y=8000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + funcmap/name=MOSI + name=PA6 + pinnum=7 + role=terminal + } + } + ha:group.14 { + uuid=O5gJDsFvHDpeyBGWhuYAAACL; src_uuid=+oSyprNFSw9F5MMrBkcAAAAM; + x=24000; y=4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PA7 + pinnum=6 + role=terminal + } + } + ha:group.15 { + uuid=O5gJDsFvHDpeyBGWhuYAAACM; src_uuid=+oSyprNFSw9F5MMrBkcAAAAN; + x=12000; y=36000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=0; stroke=term-secondary; text=VCC; } + } + ha:attrib { + name=VCC + pinnum=1 + role=terminal + } + } + ha:group.16 { + uuid=O5gJDsFvHDpeyBGWhuYAAACN; src_uuid=+oSyprNFSw9F5MMrBkcAAAAO; + x=12000; y=0; rot=-90.000000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=0; stroke=term-secondary; text=GND; } + } + ha:attrib { + name=GND + pinnum=14 + role=terminal + } + } + ha:text.17 { x1=-8000; y1=-8000; dyntext=1; stroke=sym-secondary; text=%../A.funcmap%; floater=1; } + ha:text.18 { x1=-8000; y1=-12000; dyntext=1; stroke=sym-secondary; text=%../A.footprint%; floater=1; } + ha:text.19 { x1=-8000; y1=-16000; dyntext=1; stroke=sym-secondary; text=%../A.device%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2023 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=edakrill/igor2 + -symbol-generator=boxsym-rnd + device=attiny24 + footprint=so(14) + funcmap=attiny24.funcmap + name=U5 + role=symbol + } + } + ha:group.10 { + uuid=O5gJDsFvHDpeyBGWhuYAAACQ; + li:objects { + ha:line.1 { x1=176000; y1=96000; x2=200000; y2=96000; stroke=wire; } + ha:line.3 { x1=200000; y1=112000; x2=212000; y2=112000; stroke=wire; } + ha:line.4 { x1=200000; y1=76000; x2=200000; y2=112000; stroke=wire; } + ha:line.5 { x1=200000; y1=96000; x2=200000; y2=96000; stroke=junction; } + ha:line.6 { x1=200000; y1=76000; x2=212000; y2=76000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.11 { + li:conn { + /2/10/1 + /2/9/12/1 + } + } + ha:connection.12 { + li:conn { + /2/10/3 + /2/7/2/1 + } + } + ha:connection.13 { + li:conn { + /2/10/6 + /2/8/2/1 + } + } + ha:group.14 { + uuid=O5gJDsFvHDpeyBGWhuYAAACR; + li:objects { + ha:line.3 { x1=204000; y1=108000; x2=212000; y2=108000; stroke=wire; } + ha:line.4 { x1=176000; y1=92000; x2=204000; y2=92000; stroke=wire; } + ha:line.5 { x1=204000; y1=92000; x2=204000; y2=92000; stroke=junction; } + ha:line.6 { x1=204000; y1=72000; x2=204000; y2=108000; stroke=wire; } + ha:line.8 { x1=204000; y1=72000; x2=212000; y2=72000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.15 { + li:conn { + /2/9/13/1 + /2/14/4 + } + } + ha:connection.16 { + li:conn { + /2/14/3 + /2/7/3/1 + } + } + ha:connection.19 { + li:conn { + /2/8/3/1 + /2/14/8 + } + } + ha:group.20 { + uuid=O5gJDsFvHDpeyBGWhuYAAACT; + li:objects { + ha:line.1 { x1=212000; y1=68000; x2=208000; y2=68000; stroke=wire; } + ha:line.2 { x1=208000; y1=68000; x2=208000; y2=104000; stroke=wire; } + ha:line.3 { x1=208000; y1=104000; x2=212000; y2=104000; stroke=wire; } + ha:line.4 { x1=176000; y1=100000; x2=208000; y2=100000; stroke=wire; } + ha:line.5 { x1=208000; y1=100000; x2=208000; y2=100000; stroke=junction; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.21 { + li:conn { + /2/20/1 + /2/8/4/1 + } + } + ha:connection.22 { + li:conn { + /2/20/3 + /2/7/4/1 + } + } + ha:connection.23 { + li:conn { + /2/20/4 + /2/9/11/1 + } + } + ha:group.24 { + uuid=O5gJDsFvHDpeyBGWhuYAAACU; + li:objects { + ha:line.1 { x1=212000; y1=96000; x2=212000; y2=88000; stroke=wire; } + ha:line.2 { x1=212000; y1=88000; x2=240000; y2=88000; stroke=wire; } + ha:line.3 { x1=240000; y1=88000; x2=240000; y2=48000; stroke=wire; } + ha:line.4 { x1=240000; y1=48000; x2=128000; y2=48000; stroke=wire; } + ha:line.6 { x1=128000; y1=48000; x2=128000; y2=100000; stroke=wire; } + ha:line.7 { x1=128000; y1=100000; x2=144000; y2=100000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.25 { + li:conn { + /2/24/1 + /2/7/5/1 + } + } + ha:connection.26 { + li:conn { + /2/24/7 + /2/9/5/1 + } + } + ha:group.27 { + uuid=O5gJDsFvHDpeyBGWhuYAAACV; + li:objects { + ha:line.1 { x1=212000; y1=60000; x2=204000; y2=60000; stroke=wire; } + ha:line.2 { x1=204000; y1=60000; x2=204000; y2=52000; stroke=wire; } + ha:line.3 { x1=204000; y1=52000; x2=132000; y2=52000; stroke=wire; } + ha:line.4 { x1=132000; y1=52000; x2=132000; y2=96000; stroke=wire; } + ha:line.5 { x1=132000; y1=96000; x2=144000; y2=96000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.28 { + li:conn { + /2/27/1 + /2/8/5/1 + } + } + ha:connection.29 { + li:conn { + /2/27/5 + /2/9/6/1 + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer=Tibor 'Igor2' Palinkas + page=1/3 + print_page=A/4 + title=programmable blinking LEDs + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + } + } + } +} Index: tags/1.0.5/doc/examples/hierarchic/32_subtree/project.lht =================================================================== --- tags/1.0.5/doc/examples/hierarchic/32_subtree/project.lht (nonexistent) +++ tags/1.0.5/doc/examples/hierarchic/32_subtree/project.lht (revision 10414) @@ -0,0 +1,15 @@ +ha:coraleda-project-v1 { + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:prj { + li:root_sheets { + main.rs + } + li:aux_sheets { + led_ctrl.rs + led.rs + } + } + } + } +} Index: tags/1.0.5/doc/examples/hierarchic/50_hlibrary/hlibrary/led.rs =================================================================== --- tags/1.0.5/doc/examples/hierarchic/50_hlibrary/hlibrary/led.rs (nonexistent) +++ tags/1.0.5/doc/examples/hierarchic/50_hlibrary/hlibrary/led.rs (revision 10414) @@ -0,0 +1,495 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + ha:group.1 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAP; + li:objects { + ha:group.1 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAQ; loclib_name=2n7002_sot23; + li:objects { + } + ha:attrib { + device=2n7002 + footprint=SOT23 + li:portmap { + {G->pcb/pinnum=1} + {S->pcb/pinnum=2} + {D->pcb/pinnum=3} + } + } + } + ha:group.2 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAj; loclib_name=led5; + li:objects { + } + ha:attrib { + device=led5 + footprint=LED5 + li:portmap { + {C->pcb/pinnum=1} + {A->pcb/pinnum=2} + } + } + } + } + ha:attrib { + ha:purpose = { value=devmap; prio=0; } + } + } + } + } + ha:obj_direct.2 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.1 { + uuid=8/SYZ/pfBzxyqFA12WQAAAAC; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAg; + li:objects { + ha:polygon.11 { + li:outline { + ha:line { x1=0; y1=0; x2=80000; y2=0; } + ha:line { x1=80000; y1=0; x2=80000; y2=20000; } + ha:line { x1=80000; y1=20000; x2=0; y2=20000; } + ha:line { x1=0; y1=20000; x2=0; y2=0; } + } + stroke=titlebox-frame; + fill=titlebox-fill; + } + ha:line.12 { x1=0; y1=10000; x2=80000; y2=10000; stroke=titlebox-frame; } + ha:line.13 { x1=40000; y1=10000; x2=40000; y2=0; stroke=titlebox-frame; } + ha:text.20 { x1=1000; y1=16500; dyntext=0; stroke=titlebox-big; text=TITLE; } + ha:text.21 { x1=1000; y1=10500; x2=79000; y2=16000; dyntext=1; stroke=titlebox-big; text=%../../A.title%; } + ha:text.22 { x1=1000; y1=5500; dyntext=0; stroke=titlebox-small; text={PROJECT:}; } + ha:text.23 { x1=13000; y1=5500; x2=39000; y2=9500; dyntext=1; stroke=titlebox-big; text=%project.name%; } + ha:text.24 { x1=1000; y1=500; dyntext=0; stroke=titlebox-small; text={PAGE:}; } + ha:text.25 { x1=10000; y1=500; x2=39000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.page%; } + ha:text.26 { x1=41000; y1=5500; dyntext=0; stroke=titlebox-small; text={FILE:}; } + ha:text.27 { x1=48000; y1=5500; x2=79000; y2=9500; dyntext=1; stroke=titlebox-big; text=%filename%; } + ha:text.28 { x1=41000; y1=500; dyntext=0; stroke=titlebox-small; text={MAINTAINER:}; } + ha:text.29 { x1=55000; y1=500; x2=79000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.maintainer%; } + ha:text.30 { x1=79000; y1=16000; mirx=1; dyntext=1; stroke=sheet-decor; text=%stance.model% %stance.sub_major% %stance.sub_minor% %stance.test_bench% %view.name%; } + } + ha:attrib { + purpose=titlebox + } + } + ha:group.2 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAL; src_uuid=iNOQfJpO6hT/HFDFGjoAAACC; + x=96000; y=104000; + li:objects { + ha:group.1 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAM; src_uuid=iNOQfJpO6hT/HFDFGjoAAACD; + x=12000; y=12000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=D + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:group.2 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAN; src_uuid=iNOQfJpO6hT/HFDFGjoAAACE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=G + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:text.3 { x1=8000; y1=8000; rot=90.000000; dyntext=1; stroke=sym-secondary; text=%../a.devmap%; floater=1; } + ha:text.4 { x1=4000; y1=8000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:arc.5 { cx=11000; cy=3000; r=5500; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:line.6 { x1=4000; y1=0; x2=8000; y2=0; stroke=sym-decor; } + ha:line.7 { x1=9000; y1=-1000; x2=9000; y2=1000; stroke=sym-decor; } + ha:line.8 { x1=9000; y1=2000; x2=9000; y2=4000; stroke=sym-decor; } + ha:line.9 { x1=9000; y1=5000; x2=9000; y2=7000; stroke=sym-decor; } + ha:line.10 { x1=9000; y1=3000; x2=12000; y2=3000; stroke=sym-decor; } + ha:line.11 { x1=9000; y1=0; x2=12000; y2=0; stroke=sym-decor; } + ha:line.12 { x1=9000; y1=6000; x2=12000; y2=6000; stroke=sym-decor; } + ha:line.13 { x1=12000; y1=6000; x2=12000; y2=8000; stroke=sym-decor; } + ha:line.14 { x1=12000; y1=-4000; x2=12000; y2=3000; stroke=sym-decor; } + ha:line.15 { x1=13000; y1=3000; x2=15000; y2=3000; stroke=sym-decor; } + ha:line.16 { x1=15000; y1=3000; x2=14000; y2=4000; stroke=sym-decor; } + ha:line.17 { x1=14000; y1=4000; x2=13000; y2=3000; stroke=sym-decor; } + ha:line.18 { x1=13000; y1=4000; x2=15000; y2=4000; stroke=sym-decor; } + ha:line.19 { x1=12000; y1=7000; x2=14000; y2=7000; stroke=sym-decor; } + ha:line.20 { x1=14000; y1=-1000; x2=12000; y2=-1000; stroke=sym-decor; } + ha:line.21 { x1=8000; y1=7000; x2=8000; y2=0; stroke=sym-decor; } + ha:polygon.22 { + li:outline { + ha:line { x1=10000; y1=4000; x2=9000; y2=3000; } + ha:line { x1=9000; y1=3000; x2=10000; y2=2000; } + ha:line { x1=10000; y1=2000; x2=10000; y2=4000; } + } + stroke=sym-decor; + fill=sym-decor; + } + ha:group.23 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAO; src_uuid=iNOQfJpO6hT/HFDFGjoAAACF; + x=12000; y=-4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=S + role=terminal + ha:spice/pinnum = { value=3; prio=31050; } + } + } + ha:line.24 { x1=14000; y1=-1000; x2=14000; y2=3000; stroke=sym-decor; } + ha:line.25 { x1=14000; y1=4000; x2=14000; y2=7000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + devmap=2n7002_sot23 + name=./Q1 + role=symbol + ha:spice/prefix = { value=M; prio=31050; } + } + } + ha:group.3 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAX; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=108000; y=168000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAY; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAZ; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + ha:device = { value=resistor; prio=31050; } + footprint=1206 + name=./R1 + role=symbol + ha:spice/prefix = { value=R; prio=31050; } + value=510 + } + } + ha:group.4 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAg; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAQ; + x=108000; y=124000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAh; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAR; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=C + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.2 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAi; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAS; + x=-16000; y=0; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=A + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:line.3 { x1=-4000; y1=0; x2=-6000; y2=0; stroke=sym-decor; } + ha:line.4 { x1=-12000; y1=0; x2=-10000; y2=0; stroke=sym-decor; } + ha:line.5 { x1=-10000; y1=4000; x2=-6000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=-6000; y1=0; x2=-10000; y2=-4000; stroke=sym-decor; } + ha:line.7 { x1=-10000; y1=4000; x2=-10000; y2=-4000; stroke=sym-decor; } + ha:line.8 { x1=-6000; y1=4000; x2=-6000; y2=-4000; stroke=sym-decor; } + ha:text.9 { x1=-4000; y1=13000; rot=90.000000; dyntext=1; stroke=sym-secondary; text=%../a.devmap%; floater=1; } + ha:text.10 { x1=-8000; y1=13000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.11 { x1=-8000; y1=8000; x2=-6000; y2=11000; stroke=sym-decor; } + ha:line.12 { x1=-6000; y1=11000; x2=-7000; y2=10000; stroke=sym-decor; } + ha:line.13 { x1=-6000; y1=11000; x2=-6517; y2=9545; stroke=sym-decor; } + ha:line.14 { x1=-10000; y1=7000; x2=-8000; y2=10000; stroke=sym-decor; } + ha:line.15 { x1=-8000; y1=10000; x2=-8000; y2=8000; stroke=sym-decor; } + ha:line.16 { x1=-8303; y1=6354; x2=-6303; y2=9354; stroke=sym-decor; } + ha:line.17 { x1=-6303; y1=9354; x2=-7303; y2=8354; stroke=sym-decor; } + ha:line.18 { x1=-6303; y1=9354; x2=-6820; y2=7899; stroke=sym-decor; } + ha:line.19 { x1=-10303; y1=5354; x2=-8303; y2=8354; stroke=sym-decor; } + ha:line.20 { x1=-8303; y1=8354; x2=-8303; y2=6354; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + devmap=led5 + name=./D1 + role=symbol + ha:spice/prefix = { value=D; prio=31050; } + } + } + ha:group.5 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAk; + li:objects { + ha:line.1 { x1=108000; y1=116000; x2=108000; y2=124000; stroke=wire; } + ha:text.2 { x1=110000; y1=120000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=./led_fet + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.6 { + li:conn { + /2/5/1 + /2/2/1/1 + } + } + ha:connection.7 { + li:conn { + /2/5/1 + /2/4/1/1 + } + } + ha:group.8 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAl; + li:objects { + ha:line.1 { x1=108000; y1=140000; x2=108000; y2=148000; stroke=wire; } + ha:text.2 { x1=110000; y1=144000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=res_led + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.9 { + li:conn { + /2/8/1 + /2/3/1/1 + } + } + ha:connection.10 { + li:conn { + /2/8/1 + /2/4/2/1 + } + } + ha:connection.12 { + li:conn { + /2/3/2/1 + /2/14/3 + } + } + ha:group.14 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAo; + li:objects { + ha:line.1 { x1=84000; y1=176000; x2=108000; y2=176000; stroke=wire; } + ha:line.3 { x1=108000; y1=168000; x2=108000; y2=176000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.16 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAp; + li:objects { + ha:line.1 { x1=96000; y1=104000; x2=84000; y2=104000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.17 { + li:conn { + /2/16/1 + /2/2/2/1 + } + } + ha:group.20 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAs; + li:objects { + ha:line.1 { x1=108000; y1=96000; x2=108000; y2=88000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.21 { + li:conn { + /2/20/1 + /2/2/23/1 + } + } + ha:group.22 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAx; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=108000; y=88000; + li:objects { + ha:group.1 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAy; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + drc/require_graphical_conn=1 + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:connection.23 { + li:conn { + /2/22/1/1 + /2/20/1 + } + } + ha:group.24 { + uuid=2SRAr8t6oTchmYmlPFsAAAA9; src_uuid=AHibvjaMiL5NH+9/wR0AAAAG; + x=84000; y=176000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-5000; y1=-1500; mirx=1; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:line.3 { x1=-4000; y1=0; x2=-5000; y2=2000; stroke=sheet-decor; } + ha:line.4 { x1=-4000; y1=0; x2=-5000; y2=-2000; stroke=sheet-decor; } + ha:line.5 { x1=-5000; y1=-2000; x2=-17000; y2=-2000; stroke=sheet-decor; } + ha:line.6 { x1=-17000; y1=2000; x2=-5000; y2=2000; stroke=sheet-decor; } + ha:line.7 { x1=-17000; y1=2000; x2=-17000; y2=-2000; stroke=sheet-decor; } + } + ha:attrib { + -sym-comment={ Sheet level terminal (not really a symbol) for subsheet input net in a hierarchy } + -sym-copyright=(C) 2024 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=Vin + role=terminal + } + } + ha:connection.25 { + li:conn { + /2/24/1 + /2/14/1 + } + } + ha:group.26 { + uuid=2SRAr8t6oTchmYmlPFsAAAA/; src_uuid=AHibvjaMiL5NH+9/wR0AAAAG; + x=84000; y=104000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-5000; y1=-1500; mirx=1; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:line.3 { x1=-4000; y1=0; x2=-5000; y2=2000; stroke=sheet-decor; } + ha:line.4 { x1=-4000; y1=0; x2=-5000; y2=-2000; stroke=sheet-decor; } + ha:line.5 { x1=-5000; y1=-2000; x2=-17000; y2=-2000; stroke=sheet-decor; } + ha:line.6 { x1=-17000; y1=2000; x2=-5000; y2=2000; stroke=sheet-decor; } + ha:line.7 { x1=-17000; y1=2000; x2=-17000; y2=-2000; stroke=sheet-decor; } + } + ha:attrib { + -sym-comment={ Sheet level terminal (not really a symbol) for subsheet input net in a hierarchy } + -sym-copyright=(C) 2024 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=ctrl + role=terminal + } + } + ha:connection.27 { + li:conn { + /2/26/1 + /2/16/1 + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer=Tibor 'Igor2' Palinkas + page=reusable + print_page=A/4 + title=LED and driver + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 1 + grid = 2.0480 mm + } + } + } +} Index: tags/1.0.5/doc/examples/hierarchic/50_hlibrary/main.rs =================================================================== --- tags/1.0.5/doc/examples/hierarchic/50_hlibrary/main.rs (nonexistent) +++ tags/1.0.5/doc/examples/hierarchic/50_hlibrary/main.rs (revision 10414) @@ -0,0 +1,703 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + ha:group.1 { + uuid=Of4kyoIScCrE774KCa4AAABc; + li:objects { + ha:group.1 { + uuid=Of4kyoIScCrE774KCa4AAABd; loclib_name=attiny24.funcmap; + li:objects { + } + ha:attrib { + li:funcmap/ports { + { PB0/PB0 -> sigtype=digital; } + { PB0/PCINT8 -> sigtype=digital; dir=input } + { PB0/XTAL1 -> sigtype=analog; } + { PB1/PB1 -> sigtype=digital; } + { PB1/PCINT9 -> sigtype=digital; dir=input } + { PB1/XTAL2 -> sigtype=analog; } + { PB3/PB3 -> sigtype=digital; } + { PB3/PCINT11 -> sigtype=digital; dir=input } + { PB3/RESET -> sigtype=digital; dir=input } + { PB2/PB2 -> sigtype=digital; } + { PB2/PCINT10 -> sigtype=digital; dir=input } + { PB2/OC0A -> sigtype=digital; dir=output } + { PB2/INT0 -> sigtype=digital; dir=input } + { PA7/PA7 -> sigtype=digital; } + { PA7/PCINT7 -> sigtype=digital; dir=input } + { PA7/OC0B -> sigtype=digital; dir=output } + { PA7/ADC7 -> sigtype=digital; dir=input } + { PA6/PA6 -> sigtype=digital; } + { PA6/PCINT6 -> sigtype=digital; dir=input } + { PA6/MOSI -> sigtype=digital; } + { PA6/DI -> sigtype=digital; dir=input } + { PA6/SDA -> sigtype=digital; } + { PA6/OC1A -> sigtype=digital; dir=output } + { PA6/ADC6 -> sigtype=analog; dir=input } + { PA0/PA0 -> sigtype=digital; } + { PA0/PCINT0 -> sigtype=digital; dir=input } + { PA0/AREF+ADC0-> sigtype=analog; dir=input } + { PA1/PA1 -> sigtype=digital; } + { PA1/PCINT1 -> sigtype=digital; dir=input } + { PA1/AIN0 -> sigtype=analog; dir=input } + { PA1/ADC1 -> sigtype=analog; dir=input } + { PA2/PA2 -> sigtype=digital; } + { PA2/PCINT2 -> sigtype=digital; dir=input } + { PA2/AIN1 -> sigtype=analog; dir=input } + { PA2/ADC2 -> sigtype=analog; dir=input } + { PA3/PA3 -> sigtype=digital; } + { PA3/PCINT3 -> sigtype=digital; dir=input } + { PA3/ADC3 -> sigtype=analog; dir=input } + { PA4/PA4 -> sigtype=digital; } + { PA4/PCINT4 -> sigtype=digital; dir=input } + { PA4/SCK -> sigtype=digital; } + { PA4/SCL -> sigtype=digital; } + { PA4/ADC4 -> sigtype=analog; dir=input } + { PA5/PA5 -> sigtype=digital; } + { PA5/PCINT5 -> sigtype=digital; dir=input } + { PA5/MISO -> sigtype=digital; } + { PA5/DO -> sigtype=digital; dir=output } + { PA5/OC1B -> sigtype=digital; dir=output } + { PA5/ADC5 -> sigtype=analog; dir=input } + } + li:funcmap/strong_groups { + { SPI -> SCK, MISO, MOSI } + { I2C -> SDA, SCL } + { USI -> SCK, DI, DO } + } + li:funcmap/weak_groups { + { gpio -> PB0, PB1, PB2, PB3, PA6, PA7, PA0, PA1, PA2, PA3, PA4, PA5 } + { pcint -> PCINT8, PCINT9, PCINT11, PCINT10, PCINT7, PCINT6, PCINT0, PCINT1, PCINT2, PCINT3, PCINT4, PCINT5 } + { xtal -> XTAL1, XTAL2 } + { PWM -> OC0A, OC0B, OC1A, OC1B } + { adc -> AREF+ADC0, ADC1, ADC2, ADC3, ADC4, ADC5, ADC6, ADC7 } + { comparator -> AIN0, AIN1 } + } + } + } + } + ha:attrib { + ha:purpose = { value=funcmap; prio=0; } + } + } + } + } + ha:obj_direct.2 { + uuid=Of4kyoIScCrE774KCa4AAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.1 { + uuid=8/SYZ/pfBzxyqFA12WQAAAAC; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAg; + li:objects { + ha:polygon.11 { + li:outline { + ha:line { x1=0; y1=0; x2=80000; y2=0; } + ha:line { x1=80000; y1=0; x2=80000; y2=20000; } + ha:line { x1=80000; y1=20000; x2=0; y2=20000; } + ha:line { x1=0; y1=20000; x2=0; y2=0; } + } + stroke=titlebox-frame; + fill=titlebox-fill; + } + ha:line.12 { x1=0; y1=10000; x2=80000; y2=10000; stroke=titlebox-frame; } + ha:line.13 { x1=40000; y1=10000; x2=40000; y2=0; stroke=titlebox-frame; } + ha:text.20 { x1=1000; y1=16500; dyntext=0; stroke=titlebox-big; text=TITLE; } + ha:text.21 { x1=1000; y1=10500; x2=79000; y2=16000; dyntext=1; stroke=titlebox-big; text=%../../A.title%; } + ha:text.22 { x1=1000; y1=5500; dyntext=0; stroke=titlebox-small; text={PROJECT:}; } + ha:text.23 { x1=13000; y1=5500; x2=39000; y2=9500; dyntext=1; stroke=titlebox-big; text=%project.name%; } + ha:text.24 { x1=1000; y1=500; dyntext=0; stroke=titlebox-small; text={PAGE:}; } + ha:text.25 { x1=10000; y1=500; x2=39000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.page%; } + ha:text.26 { x1=41000; y1=5500; dyntext=0; stroke=titlebox-small; text={FILE:}; } + ha:text.27 { x1=48000; y1=5500; x2=79000; y2=9500; dyntext=1; stroke=titlebox-big; text=%filename%; } + ha:text.28 { x1=41000; y1=500; dyntext=0; stroke=titlebox-small; text={MAINTAINER:}; } + ha:text.29 { x1=55000; y1=500; x2=79000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.maintainer%; } + ha:text.30 { x1=79000; y1=16000; mirx=1; dyntext=1; stroke=sheet-decor; text=%stance.model% %stance.sub_major% %stance.sub_minor% %stance.test_bench% %view.name%; } + } + ha:attrib { + purpose=titlebox + } + } + ha:group.8 { + uuid=Of4kyoIScCrE774KCa4AAAAK; + x=136000; y=92000; + li:objects { + ha:group.1 { + uuid=Of4kyoIScCrE774KCa4AAAAL; src_uuid=Of4kyoIScCrE774KCa4AAAAD; + x=-8000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=ctrl + role=terminal + } + } + ha:group.2 { + uuid=Of4kyoIScCrE774KCa4AAAAM; src_uuid=Of4kyoIScCrE774KCa4AAAAD; + x=0; y=8000; rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=Vin + role=terminal + } + } + ha:polygon.3 { + li:outline { + ha:line { x1=-8000; y1=8000; x2=-8000; y2=-8000; } + ha:line { x1=-8000; y1=-8000; x2=8000; y2=-8000; } + ha:line { x1=8000; y1=-8000; x2=8000; y2=8000; } + ha:line { x1=8000; y1=8000; x2=-8000; y2=8000; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + ha:text.4 { x1=-8000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:text.5 { x1=-1000; y1=-1000; dyntext=1; stroke=sym-secondary; text=%../A.cschem/child/name%; floater=1; } + } + ha:attrib { + cschem/child/name=led + name=S1 + role=symbol + } + } + ha:group.9 { + uuid=Of4kyoIScCrE774KCa4AAABN; src_uuid=+oSyprNFSw9F5MMrBkcAAAAP; + x=68000; y=68000; + li:objects { + ha:text.1 { x1=-8000; y1=-4000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.2 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=36000; } + ha:line { x1=0; y1=36000; x2=24000; y2=36000; } + ha:line { x1=24000; y1=36000; x2=24000; y2=0; } + ha:line { x1=24000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + } + ha:group.3 { + uuid=Of4kyoIScCrE774KCa4AAABO; src_uuid=+oSyprNFSw9F5MMrBkcAAAAB; + x=0; y=24000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PB0 + pinnum=2 + role=terminal + } + } + ha:group.4 { + uuid=Of4kyoIScCrE774KCa4AAABP; src_uuid=+oSyprNFSw9F5MMrBkcAAAAC; + x=0; y=20000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PB1 + pinnum=3 + role=terminal + } + } + ha:group.5 { + uuid=Of4kyoIScCrE774KCa4AAABQ; src_uuid=+oSyprNFSw9F5MMrBkcAAAAD; + x=0; y=16000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PB2 + pinnum=5 + role=terminal + } + } + ha:group.6 { + uuid=Of4kyoIScCrE774KCa4AAABR; src_uuid=+oSyprNFSw9F5MMrBkcAAAAE; + x=0; y=12000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PB3 + pinnum=4 + role=terminal + } + } + ha:group.7 { + uuid=Of4kyoIScCrE774KCa4AAABS; src_uuid=+oSyprNFSw9F5MMrBkcAAAAF; + x=24000; y=32000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PA0 + pinnum=13 + role=terminal + } + } + ha:group.8 { + uuid=Of4kyoIScCrE774KCa4AAABT; src_uuid=+oSyprNFSw9F5MMrBkcAAAAG; + x=24000; y=28000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PA1 + pinnum=12 + role=terminal + } + } + ha:group.9 { + uuid=Of4kyoIScCrE774KCa4AAABU; src_uuid=+oSyprNFSw9F5MMrBkcAAAAH; + x=24000; y=24000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PA2 + pinnum=11 + role=terminal + } + } + ha:group.10 { + uuid=Of4kyoIScCrE774KCa4AAABV; src_uuid=+oSyprNFSw9F5MMrBkcAAAAI; + x=24000; y=20000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PA3 + pinnum=10 + role=terminal + } + } + ha:group.11 { + uuid=Of4kyoIScCrE774KCa4AAABW; src_uuid=+oSyprNFSw9F5MMrBkcAAAAJ; + x=24000; y=16000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PA4 + pinnum=9 + role=terminal + } + } + ha:group.12 { + uuid=Of4kyoIScCrE774KCa4AAABX; src_uuid=+oSyprNFSw9F5MMrBkcAAAAK; + x=24000; y=12000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + funcmap/name=OC1B + name=PA5 + pinnum=8 + role=terminal + } + } + ha:group.13 { + uuid=Of4kyoIScCrE774KCa4AAABY; src_uuid=+oSyprNFSw9F5MMrBkcAAAAL; + x=24000; y=8000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + funcmap/name=OC1A + name=PA6 + pinnum=7 + role=terminal + } + } + ha:group.14 { + uuid=Of4kyoIScCrE774KCa4AAABZ; src_uuid=+oSyprNFSw9F5MMrBkcAAAAM; + x=24000; y=4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + funcmap/name=PA7 + name=PA7 + pinnum=6 + role=terminal + } + } + ha:group.15 { + uuid=Of4kyoIScCrE774KCa4AAABa; src_uuid=+oSyprNFSw9F5MMrBkcAAAAN; + x=12000; y=36000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=0; stroke=term-secondary; text=VCC; } + } + ha:attrib { + name=VCC + pinnum=1 + role=terminal + } + } + ha:group.16 { + uuid=Of4kyoIScCrE774KCa4AAABb; src_uuid=+oSyprNFSw9F5MMrBkcAAAAO; + x=12000; y=0; rot=-90.000000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=0; stroke=term-secondary; text=GND; } + } + ha:attrib { + name=GND + pinnum=14 + role=terminal + } + } + ha:text.17 { x1=-8000; y1=-8000; dyntext=1; stroke=sym-secondary; text=%../A.funcmap%; floater=1; } + ha:text.18 { x1=-8000; y1=-12000; dyntext=1; stroke=sym-secondary; text=%../A.footprint%; floater=1; } + ha:text.19 { x1=-8000; y1=-16000; dyntext=1; stroke=sym-secondary; text=%../A.device%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2023 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=edakrill/igor2 + -symbol-generator=boxsym-rnd + device=attiny24 + footprint=so(14) + funcmap=attiny24.funcmap + name=U1 + role=symbol + } + } + ha:group.10 { + uuid=Of4kyoIScCrE774KCa4AAABi; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB6; + x=80000; y=112000; + li:objects { + ha:group.1 { + uuid=Of4kyoIScCrE774KCa4AAABj; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB7; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + drc/require_graphical_conn=1 + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-4000; y1=4000; x2=4000; y2=7000; halign=center; dyntext=0; stroke=sym-primary; text=Vcc; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:Vcc} + } + role=symbol + } + } + ha:group.11 { + uuid=Of4kyoIScCrE774KCa4AAABk; + li:objects { + ha:line.1 { x1=80000; y1=112000; x2=80000; y2=108000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.12 { + li:conn { + /2/11/1 + /2/9/15/1 + } + } + ha:connection.13 { + li:conn { + /2/11/1 + /2/10/1/1 + } + } + ha:group.17 { + uuid=Of4kyoIScCrE774KCa4AAABp; src_uuid=Of4kyoIScCrE774KCa4AAAAK; + x=136000; y=60000; + li:objects { + ha:group.1 { + uuid=Of4kyoIScCrE774KCa4AAABq; src_uuid=Of4kyoIScCrE774KCa4AAAAD; + x=-8000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=ctrl + role=terminal + } + } + ha:group.2 { + uuid=Of4kyoIScCrE774KCa4AAABr; src_uuid=Of4kyoIScCrE774KCa4AAAAD; + x=0; y=8000; rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=Vin + role=terminal + } + } + ha:polygon.3 { + li:outline { + ha:line { x1=-8000; y1=8000; x2=-8000; y2=-8000; } + ha:line { x1=-8000; y1=-8000; x2=8000; y2=-8000; } + ha:line { x1=8000; y1=-8000; x2=8000; y2=8000; } + ha:line { x1=8000; y1=8000; x2=-8000; y2=8000; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + ha:text.4 { x1=-8000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:text.5 { x1=-1000; y1=-1000; dyntext=1; stroke=sym-secondary; text=%../A.cschem/child/name%; floater=1; } + } + ha:attrib { + cschem/child/name=led + name=S2 + role=symbol + } + } + ha:group.20 { + uuid=Of4kyoIScCrE774KCa4AAAB6; src_uuid=iNOQfJpO6hT/HFDFGjoAAABv; + x=136000; y=72000; + li:objects { + ha:group.1 { + uuid=Of4kyoIScCrE774KCa4AAAB7; src_uuid=iNOQfJpO6hT/HFDFGjoAAABw; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + drc/require_graphical_conn=1 + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-6000; y1=4000; x2=6000; y2=7000; halign=center; dyntext=1; stroke=sym-primary; text=%../A.rail%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:forge { + delete,forge/tmp + scalar,forge/tmp + {sub,^,1:,forge/tmp} + suba,$,rail,forge/tmp + array,connect + append,connect,forge/tmp + } + rail=V9V + role=symbol + } + } + ha:connection.21 { + li:conn { + /2/20/1/1 + /2/17/2/1 + } + } + ha:group.22 { + uuid=Of4kyoIScCrE774KCa4AAAB8; src_uuid=iNOQfJpO6hT/HFDFGjoAAABv; + x=136000; y=104000; + li:objects { + ha:group.1 { + uuid=Of4kyoIScCrE774KCa4AAAB9; src_uuid=iNOQfJpO6hT/HFDFGjoAAABw; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + drc/require_graphical_conn=1 + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-6000; y1=4000; x2=6000; y2=7000; halign=center; dyntext=1; stroke=sym-primary; text=%../A.rail%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:forge { + delete,forge/tmp + scalar,forge/tmp + {sub,^,1:,forge/tmp} + suba,$,rail,forge/tmp + array,connect + append,connect,forge/tmp + } + rail=V9V + role=symbol + } + } + ha:connection.23 { + li:conn { + /2/22/1/1 + /2/8/2/1 + } + } + ha:group.24 { + uuid=Of4kyoIScCrE774KCa4AAACC; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=80000; y=64000; + li:objects { + ha:group.1 { + uuid=Of4kyoIScCrE774KCa4AAACD; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + drc/require_graphical_conn=1 + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:connection.25 { + li:conn { + /2/24/1/1 + /2/9/16/1 + } + } + ha:group.26 { + uuid=Of4kyoIScCrE774KCa4AAACE; + li:objects { + ha:line.1 { x1=96000; y1=76000; x2=112000; y2=76000; stroke=wire; } + ha:line.2 { x1=112000; y1=76000; x2=112000; y2=60000; stroke=wire; } + ha:line.3 { x1=112000; y1=60000; x2=124000; y2=60000; stroke=wire; } + ha:text.4 { x1=112000; y1=60000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=pwm1a + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.27 { + li:conn { + /2/26/1 + /2/9/13/1 + } + } + ha:connection.28 { + li:conn { + /2/26/3 + /2/17/1/1 + } + } + ha:group.29 { + uuid=Of4kyoIScCrE774KCa4AAACF; + li:objects { + ha:line.1 { x1=96000; y1=80000; x2=112000; y2=80000; stroke=wire; } + ha:line.2 { x1=112000; y1=80000; x2=112000; y2=92000; stroke=wire; } + ha:line.3 { x1=112000; y1=92000; x2=124000; y2=92000; stroke=wire; } + ha:text.4 { x1=112000; y1=92000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=pwm1b + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.30 { + li:conn { + /2/29/1 + /2/9/12/1 + } + } + ha:connection.31 { + li:conn { + /2/29/3 + /2/8/1/1 + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer=Tibor 'Igor2' Palinkas + page=1/1 + print_page=A/4 + title=programmable blinking LEDs + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 2 + grid = 4.0960 mm + } + } + } +} Index: tags/1.0.5/doc/examples/hierarchic/50_hlibrary/project.lht =================================================================== --- tags/1.0.5/doc/examples/hierarchic/50_hlibrary/project.lht (nonexistent) +++ tags/1.0.5/doc/examples/hierarchic/50_hlibrary/project.lht (revision 10414) @@ -0,0 +1,11 @@ +ha:coraleda-project-v1 { + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:prj { + li:root_sheets { + main.rs + } + } + } + } +} Index: tags/1.0.5/doc/examples/hierarchic/52_path/main.rs =================================================================== --- tags/1.0.5/doc/examples/hierarchic/52_path/main.rs (nonexistent) +++ tags/1.0.5/doc/examples/hierarchic/52_path/main.rs (revision 10414) @@ -0,0 +1,703 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + ha:group.1 { + uuid=Of4kyoIScCrE774KCa4AAABc; + li:objects { + ha:group.1 { + uuid=Of4kyoIScCrE774KCa4AAABd; loclib_name=attiny24.funcmap; + li:objects { + } + ha:attrib { + li:funcmap/ports { + { PB0/PB0 -> sigtype=digital; } + { PB0/PCINT8 -> sigtype=digital; dir=input } + { PB0/XTAL1 -> sigtype=analog; } + { PB1/PB1 -> sigtype=digital; } + { PB1/PCINT9 -> sigtype=digital; dir=input } + { PB1/XTAL2 -> sigtype=analog; } + { PB3/PB3 -> sigtype=digital; } + { PB3/PCINT11 -> sigtype=digital; dir=input } + { PB3/RESET -> sigtype=digital; dir=input } + { PB2/PB2 -> sigtype=digital; } + { PB2/PCINT10 -> sigtype=digital; dir=input } + { PB2/OC0A -> sigtype=digital; dir=output } + { PB2/INT0 -> sigtype=digital; dir=input } + { PA7/PA7 -> sigtype=digital; } + { PA7/PCINT7 -> sigtype=digital; dir=input } + { PA7/OC0B -> sigtype=digital; dir=output } + { PA7/ADC7 -> sigtype=digital; dir=input } + { PA6/PA6 -> sigtype=digital; } + { PA6/PCINT6 -> sigtype=digital; dir=input } + { PA6/MOSI -> sigtype=digital; } + { PA6/DI -> sigtype=digital; dir=input } + { PA6/SDA -> sigtype=digital; } + { PA6/OC1A -> sigtype=digital; dir=output } + { PA6/ADC6 -> sigtype=analog; dir=input } + { PA0/PA0 -> sigtype=digital; } + { PA0/PCINT0 -> sigtype=digital; dir=input } + { PA0/AREF+ADC0-> sigtype=analog; dir=input } + { PA1/PA1 -> sigtype=digital; } + { PA1/PCINT1 -> sigtype=digital; dir=input } + { PA1/AIN0 -> sigtype=analog; dir=input } + { PA1/ADC1 -> sigtype=analog; dir=input } + { PA2/PA2 -> sigtype=digital; } + { PA2/PCINT2 -> sigtype=digital; dir=input } + { PA2/AIN1 -> sigtype=analog; dir=input } + { PA2/ADC2 -> sigtype=analog; dir=input } + { PA3/PA3 -> sigtype=digital; } + { PA3/PCINT3 -> sigtype=digital; dir=input } + { PA3/ADC3 -> sigtype=analog; dir=input } + { PA4/PA4 -> sigtype=digital; } + { PA4/PCINT4 -> sigtype=digital; dir=input } + { PA4/SCK -> sigtype=digital; } + { PA4/SCL -> sigtype=digital; } + { PA4/ADC4 -> sigtype=analog; dir=input } + { PA5/PA5 -> sigtype=digital; } + { PA5/PCINT5 -> sigtype=digital; dir=input } + { PA5/MISO -> sigtype=digital; } + { PA5/DO -> sigtype=digital; dir=output } + { PA5/OC1B -> sigtype=digital; dir=output } + { PA5/ADC5 -> sigtype=analog; dir=input } + } + li:funcmap/strong_groups { + { SPI -> SCK, MISO, MOSI } + { I2C -> SDA, SCL } + { USI -> SCK, DI, DO } + } + li:funcmap/weak_groups { + { gpio -> PB0, PB1, PB2, PB3, PA6, PA7, PA0, PA1, PA2, PA3, PA4, PA5 } + { pcint -> PCINT8, PCINT9, PCINT11, PCINT10, PCINT7, PCINT6, PCINT0, PCINT1, PCINT2, PCINT3, PCINT4, PCINT5 } + { xtal -> XTAL1, XTAL2 } + { PWM -> OC0A, OC0B, OC1A, OC1B } + { adc -> AREF+ADC0, ADC1, ADC2, ADC3, ADC4, ADC5, ADC6, ADC7 } + { comparator -> AIN0, AIN1 } + } + } + } + } + ha:attrib { + ha:purpose = { value=funcmap; prio=0; } + } + } + } + } + ha:obj_direct.2 { + uuid=Of4kyoIScCrE774KCa4AAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.1 { + uuid=8/SYZ/pfBzxyqFA12WQAAAAC; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAg; + li:objects { + ha:polygon.11 { + li:outline { + ha:line { x1=0; y1=0; x2=80000; y2=0; } + ha:line { x1=80000; y1=0; x2=80000; y2=20000; } + ha:line { x1=80000; y1=20000; x2=0; y2=20000; } + ha:line { x1=0; y1=20000; x2=0; y2=0; } + } + stroke=titlebox-frame; + fill=titlebox-fill; + } + ha:line.12 { x1=0; y1=10000; x2=80000; y2=10000; stroke=titlebox-frame; } + ha:line.13 { x1=40000; y1=10000; x2=40000; y2=0; stroke=titlebox-frame; } + ha:text.20 { x1=1000; y1=16500; dyntext=0; stroke=titlebox-big; text=TITLE; } + ha:text.21 { x1=1000; y1=10500; x2=79000; y2=16000; dyntext=1; stroke=titlebox-big; text=%../../A.title%; } + ha:text.22 { x1=1000; y1=5500; dyntext=0; stroke=titlebox-small; text={PROJECT:}; } + ha:text.23 { x1=13000; y1=5500; x2=39000; y2=9500; dyntext=1; stroke=titlebox-big; text=%project.name%; } + ha:text.24 { x1=1000; y1=500; dyntext=0; stroke=titlebox-small; text={PAGE:}; } + ha:text.25 { x1=10000; y1=500; x2=39000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.page%; } + ha:text.26 { x1=41000; y1=5500; dyntext=0; stroke=titlebox-small; text={FILE:}; } + ha:text.27 { x1=48000; y1=5500; x2=79000; y2=9500; dyntext=1; stroke=titlebox-big; text=%filename%; } + ha:text.28 { x1=41000; y1=500; dyntext=0; stroke=titlebox-small; text={MAINTAINER:}; } + ha:text.29 { x1=55000; y1=500; x2=79000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.maintainer%; } + ha:text.30 { x1=79000; y1=16000; mirx=1; dyntext=1; stroke=sheet-decor; text=%stance.model% %stance.sub_major% %stance.sub_minor% %stance.test_bench% %view.name%; } + } + ha:attrib { + purpose=titlebox + } + } + ha:group.8 { + uuid=Of4kyoIScCrE774KCa4AAAAK; + x=136000; y=92000; + li:objects { + ha:group.1 { + uuid=Of4kyoIScCrE774KCa4AAAAL; src_uuid=Of4kyoIScCrE774KCa4AAAAD; + x=-8000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=ctrl + role=terminal + } + } + ha:group.2 { + uuid=Of4kyoIScCrE774KCa4AAAAM; src_uuid=Of4kyoIScCrE774KCa4AAAAD; + x=0; y=8000; rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=Vin + role=terminal + } + } + ha:polygon.3 { + li:outline { + ha:line { x1=-8000; y1=8000; x2=-8000; y2=-8000; } + ha:line { x1=-8000; y1=-8000; x2=8000; y2=-8000; } + ha:line { x1=8000; y1=-8000; x2=8000; y2=8000; } + ha:line { x1=8000; y1=8000; x2=-8000; y2=8000; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + ha:text.4 { x1=-8000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:text.5 { x1=-5000; y1=-1000; dyntext=1; stroke=sym-secondary; text=%../A.cschem/child/path%; floater=1; } + } + ha:attrib { + cschem/child/path=my_lib/led.rs + name=S1 + role=symbol + } + } + ha:group.9 { + uuid=Of4kyoIScCrE774KCa4AAABN; src_uuid=+oSyprNFSw9F5MMrBkcAAAAP; + x=68000; y=68000; + li:objects { + ha:text.1 { x1=-8000; y1=-4000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.2 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=36000; } + ha:line { x1=0; y1=36000; x2=24000; y2=36000; } + ha:line { x1=24000; y1=36000; x2=24000; y2=0; } + ha:line { x1=24000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + } + ha:group.3 { + uuid=Of4kyoIScCrE774KCa4AAABO; src_uuid=+oSyprNFSw9F5MMrBkcAAAAB; + x=0; y=24000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PB0 + pinnum=2 + role=terminal + } + } + ha:group.4 { + uuid=Of4kyoIScCrE774KCa4AAABP; src_uuid=+oSyprNFSw9F5MMrBkcAAAAC; + x=0; y=20000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PB1 + pinnum=3 + role=terminal + } + } + ha:group.5 { + uuid=Of4kyoIScCrE774KCa4AAABQ; src_uuid=+oSyprNFSw9F5MMrBkcAAAAD; + x=0; y=16000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PB2 + pinnum=5 + role=terminal + } + } + ha:group.6 { + uuid=Of4kyoIScCrE774KCa4AAABR; src_uuid=+oSyprNFSw9F5MMrBkcAAAAE; + x=0; y=12000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PB3 + pinnum=4 + role=terminal + } + } + ha:group.7 { + uuid=Of4kyoIScCrE774KCa4AAABS; src_uuid=+oSyprNFSw9F5MMrBkcAAAAF; + x=24000; y=32000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PA0 + pinnum=13 + role=terminal + } + } + ha:group.8 { + uuid=Of4kyoIScCrE774KCa4AAABT; src_uuid=+oSyprNFSw9F5MMrBkcAAAAG; + x=24000; y=28000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PA1 + pinnum=12 + role=terminal + } + } + ha:group.9 { + uuid=Of4kyoIScCrE774KCa4AAABU; src_uuid=+oSyprNFSw9F5MMrBkcAAAAH; + x=24000; y=24000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PA2 + pinnum=11 + role=terminal + } + } + ha:group.10 { + uuid=Of4kyoIScCrE774KCa4AAABV; src_uuid=+oSyprNFSw9F5MMrBkcAAAAI; + x=24000; y=20000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PA3 + pinnum=10 + role=terminal + } + } + ha:group.11 { + uuid=Of4kyoIScCrE774KCa4AAABW; src_uuid=+oSyprNFSw9F5MMrBkcAAAAJ; + x=24000; y=16000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + name=PA4 + pinnum=9 + role=terminal + } + } + ha:group.12 { + uuid=Of4kyoIScCrE774KCa4AAABX; src_uuid=+oSyprNFSw9F5MMrBkcAAAAK; + x=24000; y=12000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + funcmap/name=OC1B + name=PA5 + pinnum=8 + role=terminal + } + } + ha:group.13 { + uuid=Of4kyoIScCrE774KCa4AAABY; src_uuid=+oSyprNFSw9F5MMrBkcAAAAL; + x=24000; y=8000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + funcmap/name=OC1A + name=PA6 + pinnum=7 + role=terminal + } + } + ha:group.14 { + uuid=Of4kyoIScCrE774KCa4AAABZ; src_uuid=+oSyprNFSw9F5MMrBkcAAAAM; + x=24000; y=4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=1; stroke=term-secondary; text=%../a.funcmap/name%; } + } + ha:attrib { + funcmap/name=PA7 + name=PA7 + pinnum=6 + role=terminal + } + } + ha:group.15 { + uuid=Of4kyoIScCrE774KCa4AAABa; src_uuid=+oSyprNFSw9F5MMrBkcAAAAN; + x=12000; y=36000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=0; stroke=term-secondary; text=VCC; } + } + ha:attrib { + name=VCC + pinnum=1 + role=terminal + } + } + ha:group.16 { + uuid=Of4kyoIScCrE774KCa4AAABb; src_uuid=+oSyprNFSw9F5MMrBkcAAAAO; + x=12000; y=0; rot=-90.000000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:text.3 { x1=-500; y1=-2000; mirx=1; dyntext=0; stroke=term-secondary; text=GND; } + } + ha:attrib { + name=GND + pinnum=14 + role=terminal + } + } + ha:text.17 { x1=-8000; y1=-8000; dyntext=1; stroke=sym-secondary; text=%../A.funcmap%; floater=1; } + ha:text.18 { x1=-8000; y1=-12000; dyntext=1; stroke=sym-secondary; text=%../A.footprint%; floater=1; } + ha:text.19 { x1=-8000; y1=-16000; dyntext=1; stroke=sym-secondary; text=%../A.device%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2023 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=edakrill/igor2 + -symbol-generator=boxsym-rnd + device=attiny24 + footprint=so(14) + funcmap=attiny24.funcmap + name=U1 + role=symbol + } + } + ha:group.10 { + uuid=Of4kyoIScCrE774KCa4AAABi; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB6; + x=80000; y=112000; + li:objects { + ha:group.1 { + uuid=Of4kyoIScCrE774KCa4AAABj; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB7; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + drc/require_graphical_conn=1 + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-4000; y1=4000; x2=4000; y2=7000; halign=center; dyntext=0; stroke=sym-primary; text=Vcc; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:Vcc} + } + role=symbol + } + } + ha:group.11 { + uuid=Of4kyoIScCrE774KCa4AAABk; + li:objects { + ha:line.1 { x1=80000; y1=112000; x2=80000; y2=108000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.12 { + li:conn { + /2/11/1 + /2/9/15/1 + } + } + ha:connection.13 { + li:conn { + /2/11/1 + /2/10/1/1 + } + } + ha:group.17 { + uuid=Of4kyoIScCrE774KCa4AAABp; src_uuid=Of4kyoIScCrE774KCa4AAAAK; + x=136000; y=60000; + li:objects { + ha:group.1 { + uuid=Of4kyoIScCrE774KCa4AAABq; src_uuid=Of4kyoIScCrE774KCa4AAAAD; + x=-8000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=ctrl + role=terminal + } + } + ha:group.2 { + uuid=Of4kyoIScCrE774KCa4AAABr; src_uuid=Of4kyoIScCrE774KCa4AAAAD; + x=0; y=8000; rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=Vin + role=terminal + } + } + ha:polygon.3 { + li:outline { + ha:line { x1=-8000; y1=8000; x2=-8000; y2=-8000; } + ha:line { x1=-8000; y1=-8000; x2=8000; y2=-8000; } + ha:line { x1=8000; y1=-8000; x2=8000; y2=8000; } + ha:line { x1=8000; y1=8000; x2=-8000; y2=8000; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + ha:text.4 { x1=-8000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:text.5 { x1=-5000; y1=-1000; dyntext=1; stroke=sym-secondary; text=%../A.cschem/child/path%; floater=1; } + } + ha:attrib { + cschem/child/path=my_lib/led.rs + name=S2 + role=symbol + } + } + ha:group.20 { + uuid=Of4kyoIScCrE774KCa4AAAB6; src_uuid=iNOQfJpO6hT/HFDFGjoAAABv; + x=136000; y=72000; + li:objects { + ha:group.1 { + uuid=Of4kyoIScCrE774KCa4AAAB7; src_uuid=iNOQfJpO6hT/HFDFGjoAAABw; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + drc/require_graphical_conn=1 + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-6000; y1=4000; x2=6000; y2=7000; halign=center; dyntext=1; stroke=sym-primary; text=%../A.rail%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:forge { + delete,forge/tmp + scalar,forge/tmp + {sub,^,1:,forge/tmp} + suba,$,rail,forge/tmp + array,connect + append,connect,forge/tmp + } + rail=V9V + role=symbol + } + } + ha:connection.21 { + li:conn { + /2/20/1/1 + /2/17/2/1 + } + } + ha:group.22 { + uuid=Of4kyoIScCrE774KCa4AAAB8; src_uuid=iNOQfJpO6hT/HFDFGjoAAABv; + x=136000; y=104000; + li:objects { + ha:group.1 { + uuid=Of4kyoIScCrE774KCa4AAAB9; src_uuid=iNOQfJpO6hT/HFDFGjoAAABw; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + drc/require_graphical_conn=1 + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-6000; y1=4000; x2=6000; y2=7000; halign=center; dyntext=1; stroke=sym-primary; text=%../A.rail%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:forge { + delete,forge/tmp + scalar,forge/tmp + {sub,^,1:,forge/tmp} + suba,$,rail,forge/tmp + array,connect + append,connect,forge/tmp + } + rail=V9V + role=symbol + } + } + ha:connection.23 { + li:conn { + /2/22/1/1 + /2/8/2/1 + } + } + ha:group.24 { + uuid=Of4kyoIScCrE774KCa4AAACC; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=80000; y=64000; + li:objects { + ha:group.1 { + uuid=Of4kyoIScCrE774KCa4AAACD; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + drc/require_graphical_conn=1 + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:connection.25 { + li:conn { + /2/24/1/1 + /2/9/16/1 + } + } + ha:group.26 { + uuid=Of4kyoIScCrE774KCa4AAACE; + li:objects { + ha:line.1 { x1=96000; y1=76000; x2=112000; y2=76000; stroke=wire; } + ha:line.2 { x1=112000; y1=76000; x2=112000; y2=60000; stroke=wire; } + ha:line.3 { x1=112000; y1=60000; x2=124000; y2=60000; stroke=wire; } + ha:text.4 { x1=112000; y1=60000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=pwm1a + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.27 { + li:conn { + /2/26/1 + /2/9/13/1 + } + } + ha:connection.28 { + li:conn { + /2/26/3 + /2/17/1/1 + } + } + ha:group.29 { + uuid=Of4kyoIScCrE774KCa4AAACF; + li:objects { + ha:line.1 { x1=96000; y1=80000; x2=112000; y2=80000; stroke=wire; } + ha:line.2 { x1=112000; y1=80000; x2=112000; y2=92000; stroke=wire; } + ha:line.3 { x1=112000; y1=92000; x2=124000; y2=92000; stroke=wire; } + ha:text.4 { x1=112000; y1=92000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=pwm1b + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.30 { + li:conn { + /2/29/1 + /2/9/12/1 + } + } + ha:connection.31 { + li:conn { + /2/29/3 + /2/8/1/1 + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer=Tibor 'Igor2' Palinkas + page=1/2 + print_page=A/4 + title=programmable blinking LEDs + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 2 + grid = 4.0960 mm + } + } + } +} Index: tags/1.0.5/doc/examples/hierarchic/52_path/my_lib/led.rs =================================================================== --- tags/1.0.5/doc/examples/hierarchic/52_path/my_lib/led.rs (nonexistent) +++ tags/1.0.5/doc/examples/hierarchic/52_path/my_lib/led.rs (revision 10414) @@ -0,0 +1,495 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + ha:group.1 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAP; + li:objects { + ha:group.1 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAQ; loclib_name=2n7002_sot23; + li:objects { + } + ha:attrib { + device=2n7002 + footprint=SOT23 + li:portmap { + {G->pcb/pinnum=1} + {S->pcb/pinnum=2} + {D->pcb/pinnum=3} + } + } + } + ha:group.2 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAj; loclib_name=led5; + li:objects { + } + ha:attrib { + device=led5 + footprint=LED5 + li:portmap { + {C->pcb/pinnum=1} + {A->pcb/pinnum=2} + } + } + } + } + ha:attrib { + ha:purpose = { value=devmap; prio=0; } + } + } + } + } + ha:obj_direct.2 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.1 { + uuid=8/SYZ/pfBzxyqFA12WQAAAAC; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAg; + li:objects { + ha:polygon.11 { + li:outline { + ha:line { x1=0; y1=0; x2=80000; y2=0; } + ha:line { x1=80000; y1=0; x2=80000; y2=20000; } + ha:line { x1=80000; y1=20000; x2=0; y2=20000; } + ha:line { x1=0; y1=20000; x2=0; y2=0; } + } + stroke=titlebox-frame; + fill=titlebox-fill; + } + ha:line.12 { x1=0; y1=10000; x2=80000; y2=10000; stroke=titlebox-frame; } + ha:line.13 { x1=40000; y1=10000; x2=40000; y2=0; stroke=titlebox-frame; } + ha:text.20 { x1=1000; y1=16500; dyntext=0; stroke=titlebox-big; text=TITLE; } + ha:text.21 { x1=1000; y1=10500; x2=79000; y2=16000; dyntext=1; stroke=titlebox-big; text=%../../A.title%; } + ha:text.22 { x1=1000; y1=5500; dyntext=0; stroke=titlebox-small; text={PROJECT:}; } + ha:text.23 { x1=13000; y1=5500; x2=39000; y2=9500; dyntext=1; stroke=titlebox-big; text=%project.name%; } + ha:text.24 { x1=1000; y1=500; dyntext=0; stroke=titlebox-small; text={PAGE:}; } + ha:text.25 { x1=10000; y1=500; x2=39000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.page%; } + ha:text.26 { x1=41000; y1=5500; dyntext=0; stroke=titlebox-small; text={FILE:}; } + ha:text.27 { x1=48000; y1=5500; x2=79000; y2=9500; dyntext=1; stroke=titlebox-big; text=%filename%; } + ha:text.28 { x1=41000; y1=500; dyntext=0; stroke=titlebox-small; text={MAINTAINER:}; } + ha:text.29 { x1=55000; y1=500; x2=79000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.maintainer%; } + ha:text.30 { x1=79000; y1=16000; mirx=1; dyntext=1; stroke=sheet-decor; text=%stance.model% %stance.sub_major% %stance.sub_minor% %stance.test_bench% %view.name%; } + } + ha:attrib { + purpose=titlebox + } + } + ha:group.2 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAL; src_uuid=iNOQfJpO6hT/HFDFGjoAAACC; + x=96000; y=104000; + li:objects { + ha:group.1 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAM; src_uuid=iNOQfJpO6hT/HFDFGjoAAACD; + x=12000; y=12000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=D + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:group.2 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAN; src_uuid=iNOQfJpO6hT/HFDFGjoAAACE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=G + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:text.3 { x1=8000; y1=8000; rot=90.000000; dyntext=1; stroke=sym-secondary; text=%../a.devmap%; floater=1; } + ha:text.4 { x1=4000; y1=8000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:arc.5 { cx=11000; cy=3000; r=5500; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:line.6 { x1=4000; y1=0; x2=8000; y2=0; stroke=sym-decor; } + ha:line.7 { x1=9000; y1=-1000; x2=9000; y2=1000; stroke=sym-decor; } + ha:line.8 { x1=9000; y1=2000; x2=9000; y2=4000; stroke=sym-decor; } + ha:line.9 { x1=9000; y1=5000; x2=9000; y2=7000; stroke=sym-decor; } + ha:line.10 { x1=9000; y1=3000; x2=12000; y2=3000; stroke=sym-decor; } + ha:line.11 { x1=9000; y1=0; x2=12000; y2=0; stroke=sym-decor; } + ha:line.12 { x1=9000; y1=6000; x2=12000; y2=6000; stroke=sym-decor; } + ha:line.13 { x1=12000; y1=6000; x2=12000; y2=8000; stroke=sym-decor; } + ha:line.14 { x1=12000; y1=-4000; x2=12000; y2=3000; stroke=sym-decor; } + ha:line.15 { x1=13000; y1=3000; x2=15000; y2=3000; stroke=sym-decor; } + ha:line.16 { x1=15000; y1=3000; x2=14000; y2=4000; stroke=sym-decor; } + ha:line.17 { x1=14000; y1=4000; x2=13000; y2=3000; stroke=sym-decor; } + ha:line.18 { x1=13000; y1=4000; x2=15000; y2=4000; stroke=sym-decor; } + ha:line.19 { x1=12000; y1=7000; x2=14000; y2=7000; stroke=sym-decor; } + ha:line.20 { x1=14000; y1=-1000; x2=12000; y2=-1000; stroke=sym-decor; } + ha:line.21 { x1=8000; y1=7000; x2=8000; y2=0; stroke=sym-decor; } + ha:polygon.22 { + li:outline { + ha:line { x1=10000; y1=4000; x2=9000; y2=3000; } + ha:line { x1=9000; y1=3000; x2=10000; y2=2000; } + ha:line { x1=10000; y1=2000; x2=10000; y2=4000; } + } + stroke=sym-decor; + fill=sym-decor; + } + ha:group.23 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAO; src_uuid=iNOQfJpO6hT/HFDFGjoAAACF; + x=12000; y=-4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=S + role=terminal + ha:spice/pinnum = { value=3; prio=31050; } + } + } + ha:line.24 { x1=14000; y1=-1000; x2=14000; y2=3000; stroke=sym-decor; } + ha:line.25 { x1=14000; y1=4000; x2=14000; y2=7000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + devmap=2n7002_sot23 + name=./Q1 + role=symbol + ha:spice/prefix = { value=M; prio=31050; } + } + } + ha:group.3 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAX; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=108000; y=168000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAY; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAZ; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + ha:device = { value=resistor; prio=31050; } + footprint=1206 + name=./R1 + role=symbol + ha:spice/prefix = { value=R; prio=31050; } + value=510 + } + } + ha:group.4 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAg; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAQ; + x=108000; y=124000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAh; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAR; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=C + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.2 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAi; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAS; + x=-16000; y=0; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=A + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:line.3 { x1=-4000; y1=0; x2=-6000; y2=0; stroke=sym-decor; } + ha:line.4 { x1=-12000; y1=0; x2=-10000; y2=0; stroke=sym-decor; } + ha:line.5 { x1=-10000; y1=4000; x2=-6000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=-6000; y1=0; x2=-10000; y2=-4000; stroke=sym-decor; } + ha:line.7 { x1=-10000; y1=4000; x2=-10000; y2=-4000; stroke=sym-decor; } + ha:line.8 { x1=-6000; y1=4000; x2=-6000; y2=-4000; stroke=sym-decor; } + ha:text.9 { x1=-4000; y1=13000; rot=90.000000; dyntext=1; stroke=sym-secondary; text=%../a.devmap%; floater=1; } + ha:text.10 { x1=-8000; y1=13000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.11 { x1=-8000; y1=8000; x2=-6000; y2=11000; stroke=sym-decor; } + ha:line.12 { x1=-6000; y1=11000; x2=-7000; y2=10000; stroke=sym-decor; } + ha:line.13 { x1=-6000; y1=11000; x2=-6517; y2=9545; stroke=sym-decor; } + ha:line.14 { x1=-10000; y1=7000; x2=-8000; y2=10000; stroke=sym-decor; } + ha:line.15 { x1=-8000; y1=10000; x2=-8000; y2=8000; stroke=sym-decor; } + ha:line.16 { x1=-8303; y1=6354; x2=-6303; y2=9354; stroke=sym-decor; } + ha:line.17 { x1=-6303; y1=9354; x2=-7303; y2=8354; stroke=sym-decor; } + ha:line.18 { x1=-6303; y1=9354; x2=-6820; y2=7899; stroke=sym-decor; } + ha:line.19 { x1=-10303; y1=5354; x2=-8303; y2=8354; stroke=sym-decor; } + ha:line.20 { x1=-8303; y1=8354; x2=-8303; y2=6354; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + devmap=led5 + name=./D1 + role=symbol + ha:spice/prefix = { value=D; prio=31050; } + } + } + ha:group.5 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAk; + li:objects { + ha:line.1 { x1=108000; y1=116000; x2=108000; y2=124000; stroke=wire; } + ha:text.2 { x1=110000; y1=120000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=./led_fet + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.6 { + li:conn { + /2/5/1 + /2/2/1/1 + } + } + ha:connection.7 { + li:conn { + /2/5/1 + /2/4/1/1 + } + } + ha:group.8 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAl; + li:objects { + ha:line.1 { x1=108000; y1=140000; x2=108000; y2=148000; stroke=wire; } + ha:text.2 { x1=110000; y1=144000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=res_led + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.9 { + li:conn { + /2/8/1 + /2/3/1/1 + } + } + ha:connection.10 { + li:conn { + /2/8/1 + /2/4/2/1 + } + } + ha:connection.12 { + li:conn { + /2/3/2/1 + /2/14/3 + } + } + ha:group.14 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAo; + li:objects { + ha:line.1 { x1=84000; y1=176000; x2=108000; y2=176000; stroke=wire; } + ha:line.3 { x1=108000; y1=168000; x2=108000; y2=176000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.16 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAp; + li:objects { + ha:line.1 { x1=96000; y1=104000; x2=84000; y2=104000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.17 { + li:conn { + /2/16/1 + /2/2/2/1 + } + } + ha:group.20 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAs; + li:objects { + ha:line.1 { x1=108000; y1=96000; x2=108000; y2=88000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.21 { + li:conn { + /2/20/1 + /2/2/23/1 + } + } + ha:group.22 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAx; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=108000; y=88000; + li:objects { + ha:group.1 { + uuid=mPJMPTQBLMqdGSJWpRwAAAAy; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + drc/require_graphical_conn=1 + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:connection.23 { + li:conn { + /2/22/1/1 + /2/20/1 + } + } + ha:group.24 { + uuid=2SRAr8t6oTchmYmlPFsAAAA9; src_uuid=AHibvjaMiL5NH+9/wR0AAAAG; + x=84000; y=176000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-5000; y1=-1500; mirx=1; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:line.3 { x1=-4000; y1=0; x2=-5000; y2=2000; stroke=sheet-decor; } + ha:line.4 { x1=-4000; y1=0; x2=-5000; y2=-2000; stroke=sheet-decor; } + ha:line.5 { x1=-5000; y1=-2000; x2=-17000; y2=-2000; stroke=sheet-decor; } + ha:line.6 { x1=-17000; y1=2000; x2=-5000; y2=2000; stroke=sheet-decor; } + ha:line.7 { x1=-17000; y1=2000; x2=-17000; y2=-2000; stroke=sheet-decor; } + } + ha:attrib { + -sym-comment={ Sheet level terminal (not really a symbol) for subsheet input net in a hierarchy } + -sym-copyright=(C) 2024 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=Vin + role=terminal + } + } + ha:connection.25 { + li:conn { + /2/24/1 + /2/14/1 + } + } + ha:group.26 { + uuid=2SRAr8t6oTchmYmlPFsAAAA/; src_uuid=AHibvjaMiL5NH+9/wR0AAAAG; + x=84000; y=104000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-5000; y1=-1500; mirx=1; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:line.3 { x1=-4000; y1=0; x2=-5000; y2=2000; stroke=sheet-decor; } + ha:line.4 { x1=-4000; y1=0; x2=-5000; y2=-2000; stroke=sheet-decor; } + ha:line.5 { x1=-5000; y1=-2000; x2=-17000; y2=-2000; stroke=sheet-decor; } + ha:line.6 { x1=-17000; y1=2000; x2=-5000; y2=2000; stroke=sheet-decor; } + ha:line.7 { x1=-17000; y1=2000; x2=-17000; y2=-2000; stroke=sheet-decor; } + } + ha:attrib { + -sym-comment={ Sheet level terminal (not really a symbol) for subsheet input net in a hierarchy } + -sym-copyright=(C) 2024 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=ctrl + role=terminal + } + } + ha:connection.27 { + li:conn { + /2/26/1 + /2/16/1 + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer=Tibor 'Igor2' Palinkas + page=2/2 + print_page=A/4 + title=LED and driver + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 1 + grid = 2.0480 mm + } + } + } +} Index: tags/1.0.5/doc/examples/hierarchic/52_path/project.lht =================================================================== --- tags/1.0.5/doc/examples/hierarchic/52_path/project.lht (nonexistent) +++ tags/1.0.5/doc/examples/hierarchic/52_path/project.lht (revision 10414) @@ -0,0 +1,11 @@ +ha:coraleda-project-v1 { + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:prj { + li:root_sheets { + main.rs + } + } + } + } +} Index: tags/1.0.5/doc/examples/hierarchic/60_spice_unslot/60_spice_unslot.cir =================================================================== --- tags/1.0.5/doc/examples/hierarchic/60_spice_unslot/60_spice_unslot.cir (nonexistent) +++ tags/1.0.5/doc/examples/hierarchic/60_spice_unslot/60_spice_unslot.cir (revision 10414) @@ -0,0 +1,10 @@ +.title sch-rnd export using export_spice + +*** circuit *** +US1/U1__1 div1 anon_net_5 div1 Vcc 0 +US1/U1__2 div2 anon_net_7 div2 Vcc 0 +R1 Vcc anon_net_5 100k +R2 Vcc anon_net_7 100k +R3 anon_net_5 0 100k +R4 anon_net_7 0 120k +.end Index: tags/1.0.5/doc/examples/hierarchic/60_spice_unslot/dual_opamp.rs =================================================================== --- tags/1.0.5/doc/examples/hierarchic/60_spice_unslot/dual_opamp.rs (nonexistent) +++ tags/1.0.5/doc/examples/hierarchic/60_spice_unslot/dual_opamp.rs (revision 10414) @@ -0,0 +1,658 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + ha:group.1 { + uuid=edZ1ej7ECGAcPGvyn1MAAAAV; + li:objects { + ha:group.1 { + uuid=edZ1ej7ECGAcPGvyn1MAAAAW; loclib_name=lm358_so8; + li:objects { + } + ha:attrib { + device=lm358 + footprint=so(8) + li:portmap { + {1/in- -> pcb/pinnum=2} + {1/in+ -> pcb/pinnum=3} + {1/out -> pcb/pinnum=1} + {1/V+ -> pcb/pinnum=8} + {1/V- -> pcb/pinnum=4} + {2/in- -> pcb/pinnum=6} + {2/in+ -> pcb/pinnum=5} + {2/out -> pcb/pinnum=7} + {2/V+ -> pcb/pinnum=8} + {2/V- -> pcb/pinnum=4} + } + } + } + } + ha:attrib { + ha:purpose = { value=devmap; prio=0; } + } + } + } + } + ha:obj_direct.2 { + uuid=edZ1ej7ECGAcPGvyn1MAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.1 { + uuid=8/SYZ/pfBzxyqFA12WQAAAAC; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAg; + li:objects { + ha:polygon.11 { + li:outline { + ha:line { x1=0; y1=0; x2=80000; y2=0; } + ha:line { x1=80000; y1=0; x2=80000; y2=20000; } + ha:line { x1=80000; y1=20000; x2=0; y2=20000; } + ha:line { x1=0; y1=20000; x2=0; y2=0; } + } + stroke=titlebox-frame; + fill=titlebox-fill; + } + ha:line.12 { x1=0; y1=10000; x2=80000; y2=10000; stroke=titlebox-frame; } + ha:line.13 { x1=40000; y1=10000; x2=40000; y2=0; stroke=titlebox-frame; } + ha:text.20 { x1=1000; y1=16500; dyntext=0; stroke=titlebox-big; text=TITLE; } + ha:text.21 { x1=1000; y1=10500; x2=79000; y2=16000; dyntext=1; stroke=titlebox-big; text=%../../A.title%; } + ha:text.22 { x1=1000; y1=5500; dyntext=0; stroke=titlebox-small; text={PROJECT:}; } + ha:text.23 { x1=13000; y1=5500; x2=39000; y2=9500; dyntext=1; stroke=titlebox-big; text=%project.name%; } + ha:text.24 { x1=1000; y1=500; dyntext=0; stroke=titlebox-small; text={PAGE:}; } + ha:text.25 { x1=10000; y1=500; x2=39000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.page%; } + ha:text.26 { x1=41000; y1=5500; dyntext=0; stroke=titlebox-small; text={FILE:}; } + ha:text.27 { x1=48000; y1=5500; x2=79000; y2=9500; dyntext=1; stroke=titlebox-big; text=%filename%; } + ha:text.28 { x1=41000; y1=500; dyntext=0; stroke=titlebox-small; text={MAINTAINER:}; } + ha:text.29 { x1=55000; y1=500; x2=79000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.maintainer%; } + ha:text.30 { x1=79000; y1=16000; mirx=1; dyntext=1; stroke=sheet-decor; text=%stance.model% %stance.sub_major% %stance.sub_minor% %stance.test_bench% %view.name%; } + } + ha:attrib { + purpose=titlebox + } + } + ha:group.2 { + uuid=edZ1ej7ECGAcPGvyn1MAAAAP; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAH; + x=104000; y=80000; + li:objects { + ha:group.1 { + uuid=edZ1ej7ECGAcPGvyn1MAAAAQ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAI; + x=-20000; y=4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=in+ + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.2 { + uuid=edZ1ej7ECGAcPGvyn1MAAAAR; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAJ; + x=-20000; y=-4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=in- + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:group.3 { + uuid=edZ1ej7ECGAcPGvyn1MAAAAS; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAK; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=out + role=terminal + ha:spice/pinnum = { value=3; prio=31050; } + } + } + ha:line.4 { x1=-20000; y1=-8000; x2=-20000; y2=8000; stroke=sym-decor; } + ha:line.5 { x1=-20000; y1=8000; x2=-4000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=-4000; y1=0; x2=-20000; y2=-8000; stroke=sym-decor; } + ha:line.7 { x1=-18000; y1=5000; x2=-18000; y2=3000; stroke=sym-decor; } + ha:line.8 { x1=-19000; y1=4000; x2=-17000; y2=4000; stroke=sym-decor; } + ha:line.9 { x1=-19000; y1=-4000; x2=-17000; y2=-4000; stroke=sym-decor; } + ha:group.10 { + uuid=edZ1ej7ECGAcPGvyn1MAAAAT; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAL; + x=-12000; y=-4000; rot=270.000000; mirx=1; miry=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=0; y1=-1000; rot=180.000000; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=V- + role=terminal + ha:spice/pinnum = { value=5; prio=31050; } + } + } + ha:group.11 { + uuid=edZ1ej7ECGAcPGvyn1MAAAAU; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAM; + x=-12000; y=8000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=-4000; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=V+ + role=terminal + ha:spice/pinnum = { value=4; prio=31050; } + } + } + ha:text.12 { x1=-21000; y1=9000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:text.13 { x1=-15000; y1=9000; dyntext=1; stroke=sym-secondary; text=%../A.-slot%; floater=1; } + } + ha:attrib { + -slot=1 + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + devmap=lm358_so8 + name=./U1 + role=symbol + } + } + ha:group.3 { + uuid=edZ1ej7ECGAcPGvyn1MAAAAd; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAH; + x=104000; y=52000; + li:objects { + ha:group.1 { + uuid=edZ1ej7ECGAcPGvyn1MAAAAe; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAI; + x=-20000; y=4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=in+ + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.2 { + uuid=edZ1ej7ECGAcPGvyn1MAAAAf; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAJ; + x=-20000; y=-4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=in- + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:group.3 { + uuid=edZ1ej7ECGAcPGvyn1MAAAAg; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAK; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=out + role=terminal + ha:spice/pinnum = { value=3; prio=31050; } + } + } + ha:line.4 { x1=-20000; y1=-8000; x2=-20000; y2=8000; stroke=sym-decor; } + ha:line.5 { x1=-20000; y1=8000; x2=-4000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=-4000; y1=0; x2=-20000; y2=-8000; stroke=sym-decor; } + ha:line.7 { x1=-18000; y1=5000; x2=-18000; y2=3000; stroke=sym-decor; } + ha:line.8 { x1=-19000; y1=4000; x2=-17000; y2=4000; stroke=sym-decor; } + ha:line.9 { x1=-19000; y1=-4000; x2=-17000; y2=-4000; stroke=sym-decor; } + ha:group.10 { + uuid=edZ1ej7ECGAcPGvyn1MAAAAh; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAL; + x=-12000; y=-4000; rot=270.000000; mirx=1; miry=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=0; y1=-1000; rot=180.000000; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=V- + role=terminal + ha:spice/pinnum = { value=5; prio=31050; } + } + } + ha:group.11 { + uuid=edZ1ej7ECGAcPGvyn1MAAAAi; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAM; + x=-12000; y=8000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=-4000; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=V+ + role=terminal + ha:spice/pinnum = { value=4; prio=31050; } + } + } + ha:text.12 { x1=-21000; y1=9000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:text.13 { x1=-15000; y1=9000; dyntext=1; stroke=sym-secondary; text=%../A.-slot%; floater=1; } + } + ha:attrib { + -slot=1 + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + devmap=lm358_so8 + name=./U2 + role=symbol + } + } + ha:group.4 { + uuid=edZ1ej7ECGAcPGvyn1MAAAAj; + x=-28000; y=-48000; + li:objects { + ha:line.1 { x1=120000; y1=108000; x2=120000; y2=112000; stroke=wire; } + ha:line.2 { x1=120000; y1=112000; x2=156000; y2=112000; stroke=wire; } + ha:line.4 { x1=156000; y1=140000; x2=120000; y2=140000; stroke=wire; } + ha:line.5 { x1=120000; y1=140000; x2=120000; y2=136000; stroke=wire; } + ha:line.6 { x1=156000; y1=112000; x2=156000; y2=152000; stroke=wire; } + ha:line.7 { x1=156000; y1=140000; x2=156000; y2=140000; stroke=junction; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.7 { + uuid=edZ1ej7ECGAcPGvyn1MAAAAk; + x=-28000; y=-48000; + li:objects { + ha:line.1 { x1=120000; y1=92000; x2=120000; y2=88000; stroke=wire; } + ha:line.2 { x1=120000; y1=88000; x2=164000; y2=88000; stroke=wire; } + ha:line.6 { x1=164000; y1=88000; x2=164000; y2=152000; stroke=wire; } + ha:line.7 { x1=120000; y1=120000; x2=164000; y2=120000; stroke=wire; } + ha:line.8 { x1=164000; y1=120000; x2=164000; y2=120000; stroke=junction; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.10 { + uuid=edZ1ej7ECGAcPGvyn1MAAAAl; + x=-28000; y=-48000; + li:objects { + ha:line.1 { x1=132000; y1=128000; x2=176000; y2=128000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.12 { + uuid=edZ1ej7ECGAcPGvyn1MAAAAm; + x=-28000; y=-48000; + li:objects { + ha:line.1 { x1=132000; y1=100000; x2=176000; y2=100000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.14 { + uuid=edZ1ej7ECGAcPGvyn1MAAAAn; + x=-28000; y=-48000; + li:objects { + ha:line.1 { x1=108000; y1=132000; x2=96000; y2=132000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.16 { + uuid=edZ1ej7ECGAcPGvyn1MAAAAo; + x=-28000; y=-48000; + li:objects { + ha:line.1 { x1=108000; y1=124000; x2=96000; y2=124000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.18 { + uuid=edZ1ej7ECGAcPGvyn1MAAAAp; + x=-28000; y=-48000; + li:objects { + ha:line.1 { x1=108000; y1=104000; x2=96000; y2=104000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.20 { + uuid=edZ1ej7ECGAcPGvyn1MAAAAq; + x=-28000; y=-48000; + li:objects { + ha:line.1 { x1=108000; y1=96000; x2=96000; y2=96000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.23 { + uuid=edZ1ej7ECGAcPGvyn1MAAAAu; src_uuid=AHibvjaMiL5NH+9/wR0AAAAG; + x=68000; y=84000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-5000; y1=-1500; mirx=1; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:line.3 { x1=-4000; y1=0; x2=-5000; y2=2000; stroke=sheet-decor; } + ha:line.4 { x1=-4000; y1=0; x2=-5000; y2=-2000; stroke=sheet-decor; } + ha:line.5 { x1=-5000; y1=-2000; x2=-17000; y2=-2000; stroke=sheet-decor; } + ha:line.6 { x1=-17000; y1=2000; x2=-5000; y2=2000; stroke=sheet-decor; } + ha:line.7 { x1=-17000; y1=2000; x2=-17000; y2=-2000; stroke=sheet-decor; } + } + ha:attrib { + -sym-comment={ Sheet level terminal (not really a symbol) for subsheet input net in a hierarchy } + -sym-copyright=(C) 2024 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=in1p + role=terminal + } + } + ha:group.25 { + uuid=edZ1ej7ECGAcPGvyn1MAAAAw; src_uuid=AHibvjaMiL5NH+9/wR0AAAAG; + x=68000; y=76000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-5000; y1=-1500; mirx=1; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:line.3 { x1=-4000; y1=0; x2=-5000; y2=2000; stroke=sheet-decor; } + ha:line.4 { x1=-4000; y1=0; x2=-5000; y2=-2000; stroke=sheet-decor; } + ha:line.5 { x1=-5000; y1=-2000; x2=-17000; y2=-2000; stroke=sheet-decor; } + ha:line.6 { x1=-17000; y1=2000; x2=-5000; y2=2000; stroke=sheet-decor; } + ha:line.7 { x1=-17000; y1=2000; x2=-17000; y2=-2000; stroke=sheet-decor; } + } + ha:attrib { + -sym-comment={ Sheet level terminal (not really a symbol) for subsheet input net in a hierarchy } + -sym-copyright=(C) 2024 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=in1n + role=terminal + } + } + ha:group.27 { + uuid=edZ1ej7ECGAcPGvyn1MAAAAz; src_uuid=AHibvjaMiL5NH+9/wR0AAAAG; + x=68000; y=56000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-5000; y1=-1500; mirx=1; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:line.3 { x1=-4000; y1=0; x2=-5000; y2=2000; stroke=sheet-decor; } + ha:line.4 { x1=-4000; y1=0; x2=-5000; y2=-2000; stroke=sheet-decor; } + ha:line.5 { x1=-5000; y1=-2000; x2=-17000; y2=-2000; stroke=sheet-decor; } + ha:line.6 { x1=-17000; y1=2000; x2=-5000; y2=2000; stroke=sheet-decor; } + ha:line.7 { x1=-17000; y1=2000; x2=-17000; y2=-2000; stroke=sheet-decor; } + } + ha:attrib { + -sym-comment={ Sheet level terminal (not really a symbol) for subsheet input net in a hierarchy } + -sym-copyright=(C) 2024 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=in2p + role=terminal + } + } + ha:group.29 { + uuid=edZ1ej7ECGAcPGvyn1MAAAA0; src_uuid=AHibvjaMiL5NH+9/wR0AAAAG; + x=68000; y=48000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-5000; y1=-1500; mirx=1; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:line.3 { x1=-4000; y1=0; x2=-5000; y2=2000; stroke=sheet-decor; } + ha:line.4 { x1=-4000; y1=0; x2=-5000; y2=-2000; stroke=sheet-decor; } + ha:line.5 { x1=-5000; y1=-2000; x2=-17000; y2=-2000; stroke=sheet-decor; } + ha:line.6 { x1=-17000; y1=2000; x2=-5000; y2=2000; stroke=sheet-decor; } + ha:line.7 { x1=-17000; y1=2000; x2=-17000; y2=-2000; stroke=sheet-decor; } + } + ha:attrib { + -sym-comment={ Sheet level terminal (not really a symbol) for subsheet input net in a hierarchy } + -sym-copyright=(C) 2024 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=in2n + role=terminal + } + } + ha:group.31 { + uuid=edZ1ej7ECGAcPGvyn1MAAAA3; src_uuid=AHibvjaMiL5NH+9/wR0AAAAI; + x=148000; y=52000; + li:objects { + ha:line.1 { x1=4000; y1=0; x2=0; y2=0; stroke=term-decor; } + ha:text.2 { x1=4500; y1=-1500; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:line.3 { x1=17000; y1=0; x2=16000; y2=2000; stroke=sheet-decor; } + ha:line.4 { x1=17000; y1=0; x2=16000; y2=-2000; stroke=sheet-decor; } + ha:line.5 { x1=16000; y1=-2000; x2=4000; y2=-2000; stroke=sheet-decor; } + ha:line.6 { x1=4000; y1=2000; x2=16000; y2=2000; stroke=sheet-decor; } + ha:line.7 { x1=4000; y1=2000; x2=4000; y2=-2000; stroke=sheet-decor; } + } + ha:attrib { + -sym-comment={ Sheet level terminal (not really a symbol) for subsheet output net in a hierarchy } + -sym-copyright=(C) 2024 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=out2 + role=terminal + } + } + ha:group.33 { + uuid=edZ1ej7ECGAcPGvyn1MAAAA5; src_uuid=AHibvjaMiL5NH+9/wR0AAAAI; + x=148000; y=80000; + li:objects { + ha:line.1 { x1=4000; y1=0; x2=0; y2=0; stroke=term-decor; } + ha:text.2 { x1=4500; y1=-1500; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:line.3 { x1=17000; y1=0; x2=16000; y2=2000; stroke=sheet-decor; } + ha:line.4 { x1=17000; y1=0; x2=16000; y2=-2000; stroke=sheet-decor; } + ha:line.5 { x1=16000; y1=-2000; x2=4000; y2=-2000; stroke=sheet-decor; } + ha:line.6 { x1=4000; y1=2000; x2=16000; y2=2000; stroke=sheet-decor; } + ha:line.7 { x1=4000; y1=2000; x2=4000; y2=-2000; stroke=sheet-decor; } + } + ha:attrib { + -sym-comment={ Sheet level terminal (not really a symbol) for subsheet output net in a hierarchy } + -sym-copyright=(C) 2024 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=out1 + role=terminal + } + } + ha:group.35 { + uuid=edZ1ej7ECGAcPGvyn1MAAAA8; src_uuid=AHibvjaMiL5NH+9/wR0AAAAK; + x=128000; y=104000; rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-5000; y1=-1500; mirx=1; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:line.3 { x1=-4000; y1=0; x2=-5000; y2=2000; stroke=sheet-decor; } + ha:line.4 { x1=-4000; y1=0; x2=-5000; y2=-2000; stroke=sheet-decor; } + ha:line.5 { x1=-5000; y1=-2000; x2=-16000; y2=-2000; stroke=sheet-decor; } + ha:line.6 { x1=-16000; y1=2000; x2=-5000; y2=2000; stroke=sheet-decor; } + ha:line.7 { x1=-16000; y1=-2000; x2=-17000; y2=0; stroke=sheet-decor; } + ha:line.8 { x1=-17000; y1=0; x2=-16000; y2=2000; stroke=sheet-decor; } + } + ha:attrib { + -sym-comment={ Sheet level terminal (not really a symbol) for subsheet input/output net in a hierarchy } + -sym-copyright=(C) 2024 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=Vpos + role=terminal + } + } + ha:group.37 { + uuid=edZ1ej7ECGAcPGvyn1MAAAA+; src_uuid=AHibvjaMiL5NH+9/wR0AAAAK; + x=136000; y=104000; rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-5000; y1=-1500; mirx=1; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:line.3 { x1=-4000; y1=0; x2=-5000; y2=2000; stroke=sheet-decor; } + ha:line.4 { x1=-4000; y1=0; x2=-5000; y2=-2000; stroke=sheet-decor; } + ha:line.5 { x1=-5000; y1=-2000; x2=-16000; y2=-2000; stroke=sheet-decor; } + ha:line.6 { x1=-16000; y1=2000; x2=-5000; y2=2000; stroke=sheet-decor; } + ha:line.7 { x1=-16000; y1=-2000; x2=-17000; y2=0; stroke=sheet-decor; } + ha:line.8 { x1=-17000; y1=0; x2=-16000; y2=2000; stroke=sheet-decor; } + } + ha:attrib { + -sym-comment={ Sheet level terminal (not really a symbol) for subsheet input/output net in a hierarchy } + -sym-copyright=(C) 2024 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=Vneg + role=terminal + } + } + ha:connection.43 { + li:conn { + /2/4/1 + /2/3/11/1 + } + } + ha:connection.44 { + li:conn { + /2/4/5 + /2/2/11/1 + } + } + ha:connection.45 { + li:conn { + /2/7/1 + /2/3/10/1 + } + } + ha:connection.46 { + li:conn { + /2/7/7 + /2/2/10/1 + } + } + ha:connection.47 { + li:conn { + /2/10/1 + /2/2/3/1 + } + } + ha:connection.48 { + li:conn { + /2/12/1 + /2/3/3/1 + } + } + ha:connection.49 { + li:conn { + /2/14/1 + /2/2/1/1 + } + } + ha:connection.50 { + li:conn { + /2/16/1 + /2/2/2/1 + } + } + ha:connection.51 { + li:conn { + /2/18/1 + /2/3/1/1 + } + } + ha:connection.52 { + li:conn { + /2/20/1 + /2/3/2/1 + } + } + ha:connection.53 { + li:conn { + /2/23/1 + /2/14/1 + } + } + ha:connection.54 { + li:conn { + /2/25/1 + /2/16/1 + } + } + ha:connection.55 { + li:conn { + /2/27/1 + /2/18/1 + } + } + ha:connection.56 { + li:conn { + /2/29/1 + /2/20/1 + } + } + ha:connection.57 { + li:conn { + /2/31/1 + /2/12/1 + } + } + ha:connection.58 { + li:conn { + /2/33/1 + /2/10/1 + } + } + ha:connection.59 { + li:conn { + /2/35/1 + /2/4/6 + } + } + ha:connection.60 { + li:conn { + /2/37/1 + /2/7/6 + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer=Tibor 'Igor2' Palinkas + page=2/2 + print_page=A/4 + title=dual opamp split into two single opamps + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 2 + grid = 4.0960 mm + } + } + } +} Index: tags/1.0.5/doc/examples/hierarchic/60_spice_unslot/main.rs =================================================================== --- tags/1.0.5/doc/examples/hierarchic/60_spice_unslot/main.rs (nonexistent) +++ tags/1.0.5/doc/examples/hierarchic/60_spice_unslot/main.rs (revision 10414) @@ -0,0 +1,1055 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + ha:group.1 { + uuid=HV4brSYpErb7Smew8cEAAAAW; + li:objects { + ha:group.1 { + uuid=HV4brSYpErb7Smew8cEAAAAX; loclib_name=lm358_so8; + li:objects { + } + ha:attrib { + device=lm358 + footprint=so(8) + li:portmap { + {1/in- -> pcb/pinnum=2} + {1/in+ -> pcb/pinnum=3} + {1/out -> pcb/pinnum=1} + {1/V+ -> pcb/pinnum=8} + {1/V- -> pcb/pinnum=4} + {2/in- -> pcb/pinnum=6} + {2/in+ -> pcb/pinnum=5} + {2/out -> pcb/pinnum=7} + {2/V+ -> pcb/pinnum=8} + {2/V- -> pcb/pinnum=4} + } + } + } + } + ha:attrib { + ha:purpose = { value=devmap; prio=0; } + } + } + } + } + ha:obj_direct.2 { + uuid=HV4brSYpErb7Smew8cEAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.1 { + uuid=8/SYZ/pfBzxyqFA12WQAAAAC; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAg; + li:objects { + ha:polygon.11 { + li:outline { + ha:line { x1=0; y1=0; x2=80000; y2=0; } + ha:line { x1=80000; y1=0; x2=80000; y2=20000; } + ha:line { x1=80000; y1=20000; x2=0; y2=20000; } + ha:line { x1=0; y1=20000; x2=0; y2=0; } + } + stroke=titlebox-frame; + fill=titlebox-fill; + } + ha:line.12 { x1=0; y1=10000; x2=80000; y2=10000; stroke=titlebox-frame; } + ha:line.13 { x1=40000; y1=10000; x2=40000; y2=0; stroke=titlebox-frame; } + ha:text.20 { x1=1000; y1=16500; dyntext=0; stroke=titlebox-big; text=TITLE; } + ha:text.21 { x1=1000; y1=10500; x2=79000; y2=16000; dyntext=1; stroke=titlebox-big; text=%../../A.title%; } + ha:text.22 { x1=1000; y1=5500; dyntext=0; stroke=titlebox-small; text={PROJECT:}; } + ha:text.23 { x1=13000; y1=5500; x2=39000; y2=9500; dyntext=1; stroke=titlebox-big; text=%project.name%; } + ha:text.24 { x1=1000; y1=500; dyntext=0; stroke=titlebox-small; text={PAGE:}; } + ha:text.25 { x1=10000; y1=500; x2=39000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.page%; } + ha:text.26 { x1=41000; y1=5500; dyntext=0; stroke=titlebox-small; text={FILE:}; } + ha:text.27 { x1=48000; y1=5500; x2=79000; y2=9500; dyntext=1; stroke=titlebox-big; text=%filename%; } + ha:text.28 { x1=41000; y1=500; dyntext=0; stroke=titlebox-small; text={MAINTAINER:}; } + ha:text.29 { x1=55000; y1=500; x2=79000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.maintainer%; } + ha:text.30 { x1=79000; y1=16000; mirx=1; dyntext=1; stroke=sheet-decor; text=%stance.model% %stance.sub_major% %stance.sub_minor% %stance.test_bench% %view.name%; } + } + ha:attrib { + purpose=titlebox + } + } + ha:group.33 { + uuid=HV4brSYpErb7Smew8cEAAAAn; + x=156000; y=88000; + li:objects { + ha:group.1 { + uuid=HV4brSYpErb7Smew8cEAAAAo; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAI; + x=4000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=in1p + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.2 { + uuid=HV4brSYpErb7Smew8cEAAAAp; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAJ; + x=4000; y=-8000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=in1n + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:group.3 { + uuid=HV4brSYpErb7Smew8cEAAAAq; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAK; + x=24000; y=-4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=out1 + role=terminal + ha:spice/pinnum = { value=3; prio=31050; } + } + } + ha:line.4 { x1=4000; y1=-12000; x2=4000; y2=4000; stroke=sym-decor; } + ha:line.5 { x1=4000; y1=4000; x2=20000; y2=-4000; stroke=sym-decor; } + ha:line.6 { x1=20000; y1=-4000; x2=4000; y2=-12000; stroke=sym-decor; } + ha:line.7 { x1=6000; y1=1000; x2=6000; y2=-1000; stroke=sym-decor; } + ha:line.8 { x1=5000; y1=0; x2=7000; y2=0; stroke=sym-decor; } + ha:line.9 { x1=5000; y1=-8000; x2=7000; y2=-8000; stroke=sym-decor; } + ha:group.10 { + uuid=HV4brSYpErb7Smew8cEAAAAr; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAM; + x=12000; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=-4000; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=Vpos + role=terminal + ha:spice/pinnum = { value=4; prio=31050; } + } + } + ha:group.11 { + uuid=HV4brSYpErb7Smew8cEAAAAs; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAI; + x=4000; y=-16000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=in2p + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.12 { + uuid=HV4brSYpErb7Smew8cEAAAAt; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAJ; + x=4000; y=-24000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=in2n + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:group.13 { + uuid=HV4brSYpErb7Smew8cEAAAAu; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAK; + x=24000; y=-20000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=out2 + role=terminal + ha:spice/pinnum = { value=3; prio=31050; } + } + } + ha:line.14 { x1=4000; y1=-28000; x2=4000; y2=-12000; stroke=sym-decor; } + ha:line.15 { x1=4000; y1=-12000; x2=20000; y2=-20000; stroke=sym-decor; } + ha:line.16 { x1=20000; y1=-20000; x2=4000; y2=-28000; stroke=sym-decor; } + ha:line.17 { x1=6000; y1=-15000; x2=6000; y2=-17000; stroke=sym-decor; } + ha:line.18 { x1=5000; y1=-16000; x2=7000; y2=-16000; stroke=sym-decor; } + ha:line.19 { x1=5000; y1=-24000; x2=7000; y2=-24000; stroke=sym-decor; } + ha:group.20 { + uuid=HV4brSYpErb7Smew8cEAAAAv; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAL; + x=12000; y=-24000; rot=270.000000; mirx=1; miry=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=0; y1=-1000; rot=180.000000; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=Vneg + role=terminal + ha:spice/pinnum = { value=5; prio=31050; } + } + } + ha:text.21 { x1=12000; y1=-12000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:text.22 { x1=12000; y1=-16000; dyntext=1; stroke=sym-secondary; text=%../A.cschem/child/name%; floater=1; } + } + ha:attrib { + cschem/child/name=dual_opamp.rs + name=S1 + role=symbol + } + } + ha:group.34 { + uuid=HV4brSYpErb7Smew8cEAAAAw; + li:objects { + ha:line.1 { x1=156000; y1=80000; x2=140000; y2=80000; stroke=wire; } + ha:line.2 { x1=140000; y1=80000; x2=140000; y2=104000; stroke=wire; } + ha:line.3 { x1=140000; y1=104000; x2=184000; y2=104000; stroke=wire; } + ha:line.4 { x1=184000; y1=104000; x2=184000; y2=84000; stroke=wire; } + ha:line.7 { x1=184000; y1=84000; x2=184000; y2=84000; stroke=junction; } + ha:line.8 { x1=180000; y1=84000; x2=228000; y2=84000; stroke=wire; } + ha:text.9 { x1=200000; y1=84000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=div1 + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.35 { + li:conn { + /2/34/1 + /2/33/2/1 + } + } + ha:connection.36 { + li:conn { + /2/33/3/1 + /2/34/8 + } + } + ha:group.37 { + uuid=HV4brSYpErb7Smew8cEAAAAx; + li:objects { + ha:line.1 { x1=168000; y1=92000; x2=168000; y2=116000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.38 { + li:conn { + /2/37/1 + /2/33/10/1 + } + } + ha:group.39 { + uuid=HV4brSYpErb7Smew8cEAAAA2; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB6; + x=168000; y=116000; + li:objects { + ha:group.1 { + uuid=HV4brSYpErb7Smew8cEAAAA3; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB7; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + drc/require_graphical_conn=1 + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-4000; y1=4000; x2=4000; y2=7000; halign=center; dyntext=0; stroke=sym-primary; text=Vcc; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:Vcc} + } + role=symbol + } + } + ha:connection.40 { + li:conn { + /2/39/1/1 + /2/37/1 + } + } + ha:group.41 { + uuid=HV4brSYpErb7Smew8cEAAAA4; + li:objects { + ha:line.1 { x1=156000; y1=64000; x2=140000; y2=64000; stroke=wire; } + ha:line.2 { x1=140000; y1=64000; x2=140000; y2=44000; stroke=wire; } + ha:line.3 { x1=140000; y1=44000; x2=184000; y2=44000; stroke=wire; } + ha:line.5 { x1=184000; y1=44000; x2=184000; y2=68000; stroke=wire; } + ha:line.8 { x1=184000; y1=68000; x2=184000; y2=68000; stroke=junction; } + ha:line.9 { x1=180000; y1=68000; x2=216000; y2=68000; stroke=wire; } + ha:line.10 { x1=216000; y1=68000; x2=216000; y2=80000; stroke=wire; } + ha:line.11 { x1=216000; y1=80000; x2=228000; y2=80000; stroke=wire; } + ha:text.12 { x1=200000; y1=68000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=div2 + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.42 { + li:conn { + /2/41/1 + /2/33/12/1 + } + } + ha:connection.43 { + li:conn { + /2/33/13/1 + /2/41/9 + } + } + ha:group.44 { + uuid=HV4brSYpErb7Smew8cEAAAA5; + li:objects { + ha:line.1 { x1=168000; y1=60000; x2=168000; y2=28000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.45 { + li:conn { + /2/44/1 + /2/33/20/1 + } + } + ha:group.46 { + uuid=HV4brSYpErb7Smew8cEAAAA+; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=168000; y=28000; + li:objects { + ha:group.1 { + uuid=HV4brSYpErb7Smew8cEAAAA/; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + drc/require_graphical_conn=1 + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:connection.47 { + li:conn { + /2/46/1/1 + /2/44/1 + } + } + ha:group.48 { + uuid=HV4brSYpErb7Smew8cEAAABG; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=104000; y=112000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=HV4brSYpErb7Smew8cEAAABH; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=HV4brSYpErb7Smew8cEAAABI; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + ha:device = { value=resistor; prio=31050; } + name=R1 + role=symbol + ha:spice/prefix = { value=R; prio=31050; } + value=100k + } + } + ha:group.49 { + uuid=HV4brSYpErb7Smew8cEAAABM; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=116000; y=112000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=HV4brSYpErb7Smew8cEAAABN; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=HV4brSYpErb7Smew8cEAAABO; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + ha:device = { value=resistor; prio=31050; } + name=R2 + role=symbol + ha:spice/prefix = { value=R; prio=31050; } + value=100k + } + } + ha:group.50 { + uuid=HV4brSYpErb7Smew8cEAAABR; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB6; + x=104000; y=116000; + li:objects { + ha:group.1 { + uuid=HV4brSYpErb7Smew8cEAAABS; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB7; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + drc/require_graphical_conn=1 + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-4000; y1=4000; x2=4000; y2=7000; halign=center; dyntext=0; stroke=sym-primary; text=Vcc; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:Vcc} + } + role=symbol + } + } + ha:group.51 { + uuid=HV4brSYpErb7Smew8cEAAABT; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB6; + x=116000; y=116000; + li:objects { + ha:group.1 { + uuid=HV4brSYpErb7Smew8cEAAABU; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB7; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + drc/require_graphical_conn=1 + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-4000; y1=4000; x2=4000; y2=7000; halign=center; dyntext=0; stroke=sym-primary; text=Vcc; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:Vcc} + } + role=symbol + } + } + ha:group.52 { + uuid=HV4brSYpErb7Smew8cEAAABV; + li:objects { + ha:line.1 { x1=104000; y1=116000; x2=104000; y2=112000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.53 { + li:conn { + /2/52/1 + /2/48/2/1 + } + } + ha:connection.54 { + li:conn { + /2/52/1 + /2/50/1/1 + } + } + ha:group.55 { + uuid=HV4brSYpErb7Smew8cEAAABW; + li:objects { + ha:line.1 { x1=116000; y1=116000; x2=116000; y2=112000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.56 { + li:conn { + /2/55/1 + /2/49/2/1 + } + } + ha:connection.57 { + li:conn { + /2/55/1 + /2/51/1/1 + } + } + ha:group.58 { + uuid=HV4brSYpErb7Smew8cEAAABd; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=104000; y=68000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=HV4brSYpErb7Smew8cEAAABe; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=HV4brSYpErb7Smew8cEAAABf; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + ha:device = { value=resistor; prio=31050; } + name=R3 + role=symbol + ha:spice/prefix = { value=R; prio=31050; } + value=100k + } + } + ha:group.59 { + uuid=HV4brSYpErb7Smew8cEAAABg; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=116000; y=68000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=HV4brSYpErb7Smew8cEAAABh; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=HV4brSYpErb7Smew8cEAAABi; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + ha:device = { value=resistor; prio=31050; } + name=R4 + role=symbol + ha:spice/prefix = { value=R; prio=31050; } + value=120k + } + } + ha:group.60 { + uuid=HV4brSYpErb7Smew8cEAAABj; + li:objects { + ha:line.1 { x1=116000; y1=92000; x2=116000; y2=68000; stroke=wire; } + ha:line.2 { x1=156000; y1=72000; x2=116000; y2=72000; stroke=wire; } + ha:line.3 { x1=116000; y1=72000; x2=116000; y2=72000; stroke=junction; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.61 { + li:conn { + /2/60/1 + /2/49/1/1 + } + } + ha:connection.62 { + li:conn { + /2/60/1 + /2/59/2/1 + } + } + ha:group.63 { + uuid=HV4brSYpErb7Smew8cEAAABk; + li:objects { + ha:line.1 { x1=104000; y1=92000; x2=104000; y2=68000; stroke=wire; } + ha:line.2 { x1=156000; y1=88000; x2=104000; y2=88000; stroke=wire; } + ha:line.3 { x1=104000; y1=88000; x2=104000; y2=88000; stroke=junction; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.64 { + li:conn { + /2/63/1 + /2/48/1/1 + } + } + ha:connection.65 { + li:conn { + /2/63/1 + /2/58/2/1 + } + } + ha:group.66 { + uuid=HV4brSYpErb7Smew8cEAAABn; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=104000; y=44000; + li:objects { + ha:group.1 { + uuid=HV4brSYpErb7Smew8cEAAABo; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + drc/require_graphical_conn=1 + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.67 { + uuid=HV4brSYpErb7Smew8cEAAABp; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=116000; y=44000; + li:objects { + ha:group.1 { + uuid=HV4brSYpErb7Smew8cEAAABq; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + drc/require_graphical_conn=1 + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.68 { + uuid=HV4brSYpErb7Smew8cEAAABr; + li:objects { + ha:line.1 { x1=104000; y1=48000; x2=104000; y2=44000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.69 { + li:conn { + /2/68/1 + /2/58/1/1 + } + } + ha:connection.70 { + li:conn { + /2/68/1 + /2/66/1/1 + } + } + ha:group.71 { + uuid=HV4brSYpErb7Smew8cEAAABs; + li:objects { + ha:line.1 { x1=116000; y1=48000; x2=116000; y2=44000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.72 { + li:conn { + /2/71/1 + /2/59/1/1 + } + } + ha:connection.73 { + li:conn { + /2/71/1 + /2/67/1/1 + } + } + ha:connection.74 { + li:conn { + /2/60/2 + /2/33/11/1 + } + } + ha:connection.75 { + li:conn { + /2/63/2 + /2/33/1/1 + } + } + ha:group.76 { + uuid=HV4brSYpErb7Smew8cEAAAB9; src_uuid=HV4brSYpErb7Smew8cEAAAB4; + x=232000; y=76000; + li:objects { + ha:text.1 { x1=0; y1=-6000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:group.2 { + uuid=HV4brSYpErb7Smew8cEAAAB+; src_uuid=HV4brSYpErb7Smew8cEAAAB5; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:group.3 { + uuid=HV4brSYpErb7Smew8cEAAAB/; src_uuid=HV4brSYpErb7Smew8cEAAAB6; + x=0; y=4000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.4 { + uuid=HV4brSYpErb7Smew8cEAAACA; src_uuid=HV4brSYpErb7Smew8cEAAAB7; + x=0; y=8000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=3 + role=terminal + } + } + ha:group.5 { + uuid=HV4brSYpErb7Smew8cEAAACB; src_uuid=HV4brSYpErb7Smew8cEAAAB8; + x=0; y=12000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=4 + role=terminal + } + } + ha:polygon.6 { + li:outline { + ha:line { x1=0; y1=-2000; x2=0; y2=14000; } + ha:line { x1=0; y1=14000; x2=4000; y2=14000; } + ha:line { x1=4000; y1=14000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=0; y2=-2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + name=CONN1 + role=symbol + spice/omit=yes + } + } + ha:group.77 { + uuid=HV4brSYpErb7Smew8cEAAACE; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB6; + x=224000; y=92000; + li:objects { + ha:group.1 { + uuid=HV4brSYpErb7Smew8cEAAACF; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB7; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + drc/require_graphical_conn=1 + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-4000; y1=4000; x2=4000; y2=7000; halign=center; dyntext=0; stroke=sym-primary; text=Vcc; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:Vcc} + } + role=symbol + } + } + ha:group.78 { + uuid=HV4brSYpErb7Smew8cEAAACI; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=224000; y=56000; + li:objects { + ha:group.1 { + uuid=HV4brSYpErb7Smew8cEAAACJ; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + drc/require_graphical_conn=1 + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.79 { + uuid=HV4brSYpErb7Smew8cEAAACK; + li:objects { + ha:line.1 { x1=228000; y1=88000; x2=224000; y2=88000; stroke=wire; } + ha:line.2 { x1=224000; y1=88000; x2=224000; y2=92000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.80 { + li:conn { + /2/79/1 + /2/76/5/1 + } + } + ha:connection.81 { + li:conn { + /2/79/2 + /2/77/1/1 + } + } + ha:group.82 { + uuid=HV4brSYpErb7Smew8cEAAACL; + li:objects { + ha:line.1 { x1=228000; y1=76000; x2=224000; y2=76000; stroke=wire; } + ha:line.2 { x1=224000; y1=76000; x2=224000; y2=56000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.83 { + li:conn { + /2/82/1 + /2/76/2/1 + } + } + ha:connection.84 { + li:conn { + /2/82/2 + /2/78/1/1 + } + } + ha:connection.85 { + li:conn { + /2/41/11 + /2/76/3/1 + } + } + ha:connection.86 { + li:conn { + /2/34/8 + /2/76/4/1 + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer=Tibor 'Igor2' Palinkas + page=1/2 + print_page=A/4 + title=dual opamp symbol unslotted for SPICE + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 2 + grid = 4.0960 mm + } + } + } +} Index: tags/1.0.5/doc/examples/hierarchic/60_spice_unslot/project.lht =================================================================== --- tags/1.0.5/doc/examples/hierarchic/60_spice_unslot/project.lht (nonexistent) +++ tags/1.0.5/doc/examples/hierarchic/60_spice_unslot/project.lht (revision 10414) @@ -0,0 +1,14 @@ +ha:coraleda-project-v1 { + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:prj { + li:root_sheets { + main.rs + } + li:aux_sheets { + dual_opamp.rs + } + } + } + } +} Index: tags/1.0.5/doc/examples/non-graphical/README =================================================================== --- tags/1.0.5/doc/examples/non-graphical/README (nonexistent) +++ tags/1.0.5/doc/examples/non-graphical/README (revision 10414) @@ -0,0 +1,8 @@ +Non-graphical sheets are specified by text, not by a drawing. The text is +either in a declarative language (tEDAx) or in a Turing-complete language +(fawk). + +For more information, please read the documentation for non-graphical sheets: + +../../user/07_io/io_ngrp/index.html + Index: tags/1.0.5/doc/examples/non-graphical/big32.tdx =================================================================== --- tags/1.0.5/doc/examples/non-graphical/big32.tdx (nonexistent) +++ tags/1.0.5/doc/examples/non-graphical/big32.tdx (revision 10414) @@ -0,0 +1,135 @@ +tEDAx v1 + + +# Mixed: verbose components, compact, list-like networks +# +# This file combines small2.tdx and small3.tdx syntax, read those +# files for semantics +# +# Advantage: verbose syntax for components where there's likely more +# attributes, compact, table-like or netlist-like syntax for +# nets +# +# Example: imaginary CPU with two srams, an IO chip and an extension +# connector +# bypass caps and power/gnd connections are specified at components +# because they are more of a component-property than a network-property + +begin cschem_acomp U2 + footprint dip(24) + device SRAM + value TMS4016 + - 24 Vcc + - 12 gnd + - 18 CSsram1 +end cschem_acomp + +begin cschem_acomp U3 + footprint dip(24) + device SRAM + value TMS4016 + - 24 Vcc + - 12 gnd + - 18 CSsram2 +end cschem_acomp + +begin cschem_acomp U1 + footprint tqfp(32) + device CPU + - 11 Vcc + - 12 gnd + - 25 Vcc + - 27 gnd + - 28 reset +end cschem_acomp + +begin cschem_acomp U4 + footprint dip(24) + device IOports + - 22 CSio + - 23 Vcc + - 24 gnd +end cschem_acomp + +begin cschem_acomp CONN1 + footprint connector(16,2) + comment extension bus connector + - 1 Vcc + - 17 Vcc + - 2 gnd + - 18 gnd +end cschem_acomp + +# U5 is specified on a graphical sheet, it controls the chip select +# of U2, U3 and U4 using networks A11 and A12 as input, CSsram1, CSsram2 +# and CSio as output. + +begin cschem_acompact + net gnd comment=use\ poly + net vcc comment=use\ poly + + conn A0 U2=8 U3=8 U1=1 U4=11 CONN1=3 + conn A1 U2=7 U3=7 U1=2 U4=12 CONN1=4 + conn A2 U2=6 U3=6 U1=3 U4=13 CONN1=5 + conn A3 U2=5 U3=5 U1=4 U4=14 CONN1=6 + conn A4 U2=4 U3=4 U1=5 U4=15 CONN1=7 + conn A5 U2=3 U3=3 U1=6 U4=16 CONN1=8 + conn A6 U2=2 U3=2 U1=7 U4=17 CONN1=9 + conn A7 U2=1 U3=1 U1=8 U4=18 CONN1=10 + conn A8 U2=23 U3=23 U1=9 U4=19 CONN1=11 + conn A9 U2=22 U3=22 U1=10 U4=20 CONN1=12 + conn A10 U2=19 U3=19 U1=13 U4=21 CONN1=13 + conn A11 U1=14 CONN1=14 + conn A12 U1=15 CONN1=15 + conn DQ1 U2=9 U3=9 U1=16 U4=10 CONN1=19 + conn DQ2 U2=10 U3=10 U1=17 U4=9 CONN1=20 + conn DQ3 U2=11 U3=11 U1=18 U4=8 CONN1=21 + conn DQ4 U2=13 U3=13 U1=19 U4=7 CONN1=22 + conn DQ5 U2=14 U3=14 U1=20 U4=6 CONN1=23 + conn DQ6 U2=15 U3=15 U1=21 U4=5 CONN1=24 + conn DQ7 U2=16 U3=16 U1=22 U4=4 CONN1=25 + conn DQ8 U2=17 U3=17 U1=23 U4=3 CONN1=26 + conn WR U2=21 U3=21 U1=23 U4=1 CONN1=27 + conn RD U2=20 U3=20 U1=23 U4=2 CONN1=28 + conn IRQ1 U1=24 CONN1=29 + conn IRQ2 U1=29 CONN1=30 + conn IRQ3 U1=30 CONN1=31 + conn IRQ4 U1=31 CONN1=32 +end cschem_acompact + +begin cschem_acomp C1 + footprint 1206 + device capacitor + - 1 Vcc + - 2 gnd +end cschem_acomp + + +begin cschem_acomp C2 + footprint 1206 + device capacitor + - 1 Vcc + - 2 gnd +end cschem_acomp + +begin cschem_acomp C3 + footprint 1206 + device capacitor + - 1 Vcc + - 2 gnd +end cschem_acomp + +begin cschem_acomp C4 + footprint 1206 + device capacitor + - 1 Vcc + - 2 gnd +end cschem_acomp + +begin cschem_acomp C5 + footprint 1206 + device capacitor + - 1 Vcc + - 2 gnd +end cschem_acomp + Index: tags/1.0.5/doc/examples/non-graphical/r2r.fawk =================================================================== --- tags/1.0.5/doc/examples/non-graphical/r2r.fawk (nonexistent) +++ tags/1.0.5/doc/examples/non-graphical/r2r.fawk (revision 10414) @@ -0,0 +1,57 @@ +## cschem fawk sheet + +# The first line must be the above, else cschem will refuse to run the script. + +# Generate classic R2R digital-analog-converter +# +# input0 input1 input2 +# | | | +# [R1] [R3] [R5] +# | | | +# j0 -- [R2] -- j1 -- [R4] -- j2 -- ... +# | +# [R0] +# | +# gnd +# +# R0, R1, R3, R5, ... are 2*R resistors (2k0 by default) +# R2, R4, ... are 1*R resistors (1k0 by default) +# output is the last j + +function refdes(n) +{ + return "R" @ (base + n); +} + +function resistor(n, val, rfd) +{ + rfd = refdes(n); + acomp_attr(rfd, "value", val, "footprint", fp); + return rfd; +} + +function main(ARGV) +{ + bits=5; + valr = "1k0"; + valr2 = "2k0"; + base = 100; + fp = "0805"; + + # create leftmost divider + low = resistor(0, valr2); + high = resistor(1, valr2); + aconn("gnd", low, 1); + aconn("input0", high, 2); + aconn("j0", low, 2, high, 1); + + # create the rest of the ladder, piece by piece from the horizontal + # R resistor and ther vertical 2*R resistor + for(i = 1; i < bits; i++) { + horiz = resistor(i*2+0, valr); + vert = resistor(i*2+1, valr2); + aconn("j" @ (i-1), horiz, 1); + aconn("j" @ i, horiz, 2, vert, 1); + aconn("input" @ i, vert, 2); + } +} Index: tags/1.0.5/doc/examples/non-graphical/small1.tdx =================================================================== --- tags/1.0.5/doc/examples/non-graphical/small1.tdx (nonexistent) +++ tags/1.0.5/doc/examples/non-graphical/small1.tdx (revision 10414) @@ -0,0 +1,43 @@ +tEDAx v1 + +# Verbose, network based +# Advantage: no need to worry about escaping (e.g. spaces) +# Disadvantage: long, verbose files, harder to oversee + +# contains: attributes only in "key value" format +begin cschem_acomp U1 + footprint TO220 + device 7805 +end cschem_acomp + + +begin cschem_acomp C1 + footprint 1206 + device capacitor +end cschem_acomp + +begin cschem_acomp C2 + footprint 1206 + device capacitor +end cschem_acomp + +# contains: attributes in "key value" format; +# lines with first word being a dash represent a connection between +# this net and a component terminal (in component-name terminal-name +# format); terminals are created automatically +begin cschem_anet gnd + - U1 2 + - C1 2 + - C2 2 + comment use poly +end cschem_anet + +begin cschem_anet Vin + - U1 1 + - C1 1 +end cschem_anet + +begin cschem_anet Vout + - U1 3 + - C2 1 +end cschem_anet Index: tags/1.0.5/doc/examples/non-graphical/small2.tdx =================================================================== --- tags/1.0.5/doc/examples/non-graphical/small2.tdx (nonexistent) +++ tags/1.0.5/doc/examples/non-graphical/small2.tdx (revision 10414) @@ -0,0 +1,40 @@ +tEDAx v1 + + +# Verbose, component based +# Advantage: no need to worry about escaping (e.g. spaces); component-oriented +# view; useful if there's one large central component (e.g. fpga) +# Disadvantage: long, verbose files, harder to oversee + +# contains: attributes only in "key value" format +# if first word is -, make a connection from the named termina to +# the named network (networks and terminals are created automatically) +begin cschem_acomp U1 + footprint TO220 + device 7805 + - 1 Vin + - 2 gnd + - 3 Vout +end cschem_acomp + + +begin cschem_acomp C1 + footprint 1206 + device capacitor + - 1 Vin + - 2 gnd +end cschem_acomp + +begin cschem_acomp C2 + footprint 1206 + device capacitor + - 1 Vout + - 2 gnd +end cschem_acomp + +# specify net only if extra attributes are needed +begin cschem_anet gnd + comment use poly +end cschem_anet + + Index: tags/1.0.5/doc/examples/non-graphical/small21.tdx =================================================================== --- tags/1.0.5/doc/examples/non-graphical/small21.tdx (nonexistent) +++ tags/1.0.5/doc/examples/non-graphical/small21.tdx (revision 10414) @@ -0,0 +1,41 @@ +tEDAx v1 + +# Verbose, mixed network/component based +# +# This file combines small1.tdx and small2.tdx syntax, read those +# files for semantics +# +# Advantage: no need to worry about escaping (e.g. spaces) +# signals of a central component (e.g. fpga) specified at comp +# boring networks, like gnd, can be specified at the net +# Disadvantage: long, verbose files, harder to oversee + +# Components; Vin and Vout connections are specified from the components' +# point of view +begin cschem_acomp U1 + footprint TO220 + device 7805 + - 1 Vin + - 3 Vout +end cschem_acomp + + +begin cschem_acomp C1 + footprint 1206 + device capacitor + - 1 Vin +end cschem_acomp + +begin cschem_acomp C2 + footprint 1206 + device capacitor + - 1 Vout +end cschem_acomp + +# gnd is a large network, specified from the net's point of view +begin cschem_anet gnd + - U1 2 + - C1 2 + - C2 2 + comment use poly +end cschem_anet Index: tags/1.0.5/doc/examples/non-graphical/small3.tdx =================================================================== --- tags/1.0.5/doc/examples/non-graphical/small3.tdx (nonexistent) +++ tags/1.0.5/doc/examples/non-graphical/small3.tdx (revision 10414) @@ -0,0 +1,29 @@ +tEDAx v1 + +# Compact, combined list +# Advantage: brief file, almost like a table, easy to oversee +# Disadvantage: have to escape spaces; need to watch for line length limit +# when line gets longer than 510 characters, need to split +# (repeating the "comp name=..." or "conn name=..." part) + +# Each line starts with a comp, net or conn; they create a component, +# a network or make a connection respectively. First argument is always +# the name (unique identifier) of the given object. Multiple lines can have +# the same identifier, the content of those lines are merged. +# +# For comp and net lines, starting from the second argument fields are +# key=value pairs for setting attributes. +# +# For conn lines, starting from the second argument fields are +# comp-name=term-name; terminals are created automatically. + +begin cschem_acompact + comp U1 footprint=TO220 device=7805 + comp C1 footprint=1206 device=capacitor + comp C2 footprint=1206 device=capacitor + net gnd comment=use\ poly + conn Vin U1=1 C1=1 + conn gnd U1=2 C1=2 C2=2 + conn Vout U1=3 C2=1 +end cschem_acompact + Index: tags/1.0.5/doc/examples/omit_comp.rs =================================================================== --- tags/1.0.5/doc/examples/omit_comp.rs (nonexistent) +++ tags/1.0.5/doc/examples/omit_comp.rs (revision 10414) @@ -0,0 +1,852 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + ha:group.1 { + uuid=E4wBSbBPnQTyLrlukNMAAAAV; + li:objects { + ha:group.1 { + uuid=E4wBSbBPnQTyLrlukNMAAAAW; loclib_name=lm358_so8; + li:objects { + } + ha:attrib { + footprint=so(8) + li:portmap { + {1/in- -> pcb/pinnum=2} + {1/in+ -> pcb/pinnum=3} + {1/out -> pcb/pinnum=1} + {1/V+ -> pcb/pinnum=8} + {1/V- -> pcb/pinnum=4} + {2/in- -> pcb/pinnum=6} + {2/in+ -> pcb/pinnum=5} + {2/out -> pcb/pinnum=7} + {2/V+ -> pcb/pinnum=8} + {2/V- -> pcb/pinnum=4} + } + } + } + } + ha:attrib { + ha:purpose = { value=devmap; prio=0; } + } + } + } + } + ha:obj_direct.2 { + uuid=E4wBSbBPnQTyLrlukNMAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.1 { + uuid=8/SYZ/pfBzxyqFA12WQAAAAC; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAg; + li:objects { + ha:polygon.11 { + li:outline { + ha:line { x1=0; y1=0; x2=80000; y2=0; } + ha:line { x1=80000; y1=0; x2=80000; y2=20000; } + ha:line { x1=80000; y1=20000; x2=0; y2=20000; } + ha:line { x1=0; y1=20000; x2=0; y2=0; } + } + stroke=titlebox-frame; + fill=titlebox-fill; + } + ha:line.12 { x1=0; y1=10000; x2=80000; y2=10000; stroke=titlebox-frame; } + ha:line.13 { x1=40000; y1=10000; x2=40000; y2=0; stroke=titlebox-frame; } + ha:text.20 { x1=1000; y1=16500; dyntext=0; stroke=titlebox-big; text=TITLE; } + ha:text.21 { x1=1000; y1=10500; x2=79000; y2=16000; dyntext=1; stroke=titlebox-big; text=%../../A.title%; } + ha:text.22 { x1=1000; y1=5500; dyntext=0; stroke=titlebox-small; text={PROJECT:}; } + ha:text.23 { x1=13000; y1=5500; x2=39000; y2=9500; dyntext=1; stroke=titlebox-big; text=%project.name%; } + ha:text.24 { x1=1000; y1=500; dyntext=0; stroke=titlebox-small; text={PAGE:}; } + ha:text.25 { x1=10000; y1=500; x2=39000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.page%; } + ha:text.26 { x1=41000; y1=5500; dyntext=0; stroke=titlebox-small; text={FILE:}; } + ha:text.27 { x1=48000; y1=5500; x2=79000; y2=9500; dyntext=1; stroke=titlebox-big; text=%filename%; } + ha:text.28 { x1=41000; y1=500; dyntext=0; stroke=titlebox-small; text={MAINTAINER:}; } + ha:text.29 { x1=55000; y1=500; x2=79000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.maintainer%; } + ha:text.30 { x1=79000; y1=16000; mirx=1; dyntext=1; stroke=sheet-decor; text=%stance.model% %stance.sub_major% %stance.sub_minor% %stance.test_bench% %view.name%; } + } + ha:attrib { + purpose=titlebox + } + } + ha:group.16 { + uuid=E4wBSbBPnQTyLrlukNMAAABB; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAH; + x=124000; y=104000; miry=1; + li:objects { + ha:group.1 { + uuid=E4wBSbBPnQTyLrlukNMAAABC; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAI; + x=-20000; y=4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=in+ + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.2 { + uuid=E4wBSbBPnQTyLrlukNMAAABD; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAJ; + x=-20000; y=-4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=in- + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:group.3 { + uuid=E4wBSbBPnQTyLrlukNMAAABE; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAK; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=out + role=terminal + ha:spice/pinnum = { value=3; prio=31050; } + } + } + ha:line.4 { x1=-20000; y1=-8000; x2=-20000; y2=8000; stroke=sym-decor; } + ha:line.5 { x1=-20000; y1=8000; x2=-4000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=-4000; y1=0; x2=-20000; y2=-8000; stroke=sym-decor; } + ha:line.7 { x1=-18000; y1=5000; x2=-18000; y2=3000; stroke=sym-decor; } + ha:line.8 { x1=-19000; y1=4000; x2=-17000; y2=4000; stroke=sym-decor; } + ha:line.9 { x1=-19000; y1=-4000; x2=-17000; y2=-4000; stroke=sym-decor; } + ha:group.10 { + uuid=E4wBSbBPnQTyLrlukNMAAABF; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAL; + x=-12000; y=-4000; rot=270.000000; mirx=1; miry=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=0; y1=-1000; rot=180.000000; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=V- + role=terminal + ha:spice/pinnum = { value=5; prio=31050; } + } + } + ha:group.11 { + uuid=E4wBSbBPnQTyLrlukNMAAABG; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAM; + x=-12000; y=8000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=-4000; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=V+ + role=terminal + ha:spice/pinnum = { value=4; prio=31050; } + } + } + ha:text.12 { x1=-21000; y1=9000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -slot=1 + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + devmap=lm358_so8 + name=U1 + omit=1 + role=symbol + } + } + ha:group.22 { + uuid=E4wBSbBPnQTyLrlukNMAAABM; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=104000; y=136000; miry=1; + li:objects { + ha:group.1 { + uuid=E4wBSbBPnQTyLrlukNMAAABN; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=E4wBSbBPnQTyLrlukNMAAABO; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=R1 + role=symbol + ha:spice/prefix = { value=R; prio=31050; } + value=47k + } + } + ha:group.23 { + uuid=E4wBSbBPnQTyLrlukNMAAABP; src_uuid=E4wBSbBPnQTyLrlukNMAAAAp; + x=16000; y=244000; miry=1; + li:objects { + ha:line.1 { x1=84000; y1=136000; x2=76000; y2=136000; stroke=wire; } + ha:line.2 { x1=76000; y1=136000; x2=76000; y2=108000; stroke=wire; } + ha:line.4 { x1=68000; y1=108000; x2=88000; y2=108000; stroke=wire; } + ha:line.5 { x1=76000; y1=108000; x2=76000; y2=108000; stroke=junction; } + ha:text.6 { x1=76000; y1=112000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=opa_neg + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.24 { + li:conn { + /2/23/1 + /2/16/2/1 + } + } + ha:connection.25 { + li:conn { + /2/22/2/1 + /2/23/4 + } + } + ha:group.26 { + uuid=E4wBSbBPnQTyLrlukNMAAABQ; src_uuid=E4wBSbBPnQTyLrlukNMAAAAq; + x=16000; y=244000; miry=1; + li:objects { + ha:line.1 { x1=108000; y1=108000; x2=124000; y2=108000; stroke=wire; } + ha:line.2 { x1=124000; y1=108000; x2=124000; y2=140000; stroke=wire; } + ha:line.4 { x1=108000; y1=140000; x2=148000; y2=140000; stroke=wire; } + ha:line.5 { x1=124000; y1=140000; x2=124000; y2=140000; stroke=junction; } + ha:text.6 { x1=132000; y1=140000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=out + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.27 { + li:conn { + /2/26/1 + /2/22/1/1 + } + } + ha:connection.28 { + li:conn { + /2/16/3/1 + /2/26/4 + } + } + ha:group.29 { + uuid=E4wBSbBPnQTyLrlukNMAAABR; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=64000; y=136000; miry=1; + li:objects { + ha:group.1 { + uuid=E4wBSbBPnQTyLrlukNMAAABS; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=E4wBSbBPnQTyLrlukNMAAABT; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=R2 + role=symbol + ha:spice/prefix = { value=R; prio=31050; } + value=10k + } + } + ha:group.30 { + uuid=E4wBSbBPnQTyLrlukNMAAABY; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=124000; y=116000; + li:objects { + ha:group.1 { + uuid=E4wBSbBPnQTyLrlukNMAAABZ; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.31 { + uuid=E4wBSbBPnQTyLrlukNMAAABa; + li:objects { + ha:line.1 { x1=112000; y1=112000; x2=112000; y2=120000; stroke=wire; } + ha:line.2 { x1=112000; y1=120000; x2=124000; y2=120000; stroke=wire; } + ha:line.3 { x1=124000; y1=120000; x2=124000; y2=116000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.32 { + li:conn { + /2/31/1 + /2/16/10/1 + } + } + ha:connection.33 { + li:conn { + /2/31/3 + /2/30/1/1 + } + } + ha:group.34 { + uuid=E4wBSbBPnQTyLrlukNMAAABf; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB6; + x=124000; y=96000; + li:objects { + ha:group.1 { + uuid=E4wBSbBPnQTyLrlukNMAAABg; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB7; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-4000; y1=4000; x2=4000; y2=7000; halign=center; dyntext=0; stroke=sym-primary; text=Vcc; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:Vcc} + } + role=symbol + } + } + ha:group.37 { + uuid=E4wBSbBPnQTyLrlukNMAAABi; + li:objects { + ha:line.1 { x1=112000; y1=96000; x2=112000; y2=92000; stroke=wire; } + ha:line.2 { x1=112000; y1=92000; x2=124000; y2=92000; stroke=wire; } + ha:line.3 { x1=124000; y1=92000; x2=124000; y2=96000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.38 { + li:conn { + /2/37/1 + /2/16/11/1 + } + } + ha:connection.39 { + li:conn { + /2/37/3 + /2/34/1/1 + } + } + ha:group.40 { + uuid=E4wBSbBPnQTyLrlukNMAAABj; + li:objects { + ha:line.1 { x1=100000; y1=100000; x2=92000; y2=100000; stroke=wire; } + ha:line.2 { x1=92000; y1=100000; x2=92000; y2=92000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.41 { + li:conn { + /2/40/1 + /2/16/1/1 + } + } + ha:group.42 { + uuid=E4wBSbBPnQTyLrlukNMAAABm; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=92000; y=92000; + li:objects { + ha:group.1 { + uuid=E4wBSbBPnQTyLrlukNMAAABn; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:connection.43 { + li:conn { + /2/42/1/1 + /2/40/2 + } + } + ha:connection.44 { + li:conn { + /2/23/4 + /2/29/1/1 + } + } + ha:group.45 { + uuid=E4wBSbBPnQTyLrlukNMAAABo; + li:objects { + ha:line.2 { x1=48000; y1=136000; x2=64000; y2=136000; stroke=wire; } + ha:text.3 { x1=56000; y1=136000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=in + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.46 { + li:conn { + /2/29/2/1 + /2/45/2 + } + } + ha:group.47 { + uuid=E4wBSbBPnQTyLrlukNMAAABx; src_uuid=E4wBSbBPnQTyLrlukNMAAABt; + x=168000; y=100000; + li:objects { + ha:text.1 { x1=0; y1=-2000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:group.2 { + uuid=E4wBSbBPnQTyLrlukNMAAABy; src_uuid=E4wBSbBPnQTyLrlukNMAAABu; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:group.3 { + uuid=E4wBSbBPnQTyLrlukNMAAABz; src_uuid=E4wBSbBPnQTyLrlukNMAAABv; + x=0; y=4000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.4 { + uuid=E4wBSbBPnQTyLrlukNMAAAB0; src_uuid=E4wBSbBPnQTyLrlukNMAAABw; + x=0; y=8000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=3 + role=terminal + } + } + ha:polygon.5 { + li:outline { + ha:line { x1=0; y1=-2000; x2=0; y2=10000; } + ha:line { x1=0; y1=10000; x2=4000; y2=10000; } + ha:line { x1=4000; y1=10000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=0; y2=-2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + name=CONN2 + role=symbol + } + } + ha:group.48 { + uuid=E4wBSbBPnQTyLrlukNMAAAB1; src_uuid=E4wBSbBPnQTyLrlukNMAAABt; + x=44000; y=132000; mirx=1; + li:objects { + ha:text.1 { x1=0; y1=-2000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:group.2 { + uuid=E4wBSbBPnQTyLrlukNMAAAB2; src_uuid=E4wBSbBPnQTyLrlukNMAAABu; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:group.3 { + uuid=E4wBSbBPnQTyLrlukNMAAAB3; src_uuid=E4wBSbBPnQTyLrlukNMAAABv; + x=0; y=4000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.4 { + uuid=E4wBSbBPnQTyLrlukNMAAAB4; src_uuid=E4wBSbBPnQTyLrlukNMAAABw; + x=0; y=8000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=3 + role=terminal + } + } + ha:polygon.5 { + li:outline { + ha:line { x1=0; y1=-2000; x2=0; y2=10000; } + ha:line { x1=0; y1=10000; x2=4000; y2=10000; } + ha:line { x1=4000; y1=10000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=0; y2=-2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + name=CONN1 + role=symbol + } + } + ha:connection.49 { + li:conn { + /2/45/2 + /2/48/3/1 + } + } + ha:connection.50 { + li:conn { + /2/26/4 + /2/47/3/1 + } + } + ha:group.51 { + uuid=E4wBSbBPnQTyLrlukNMAAAB5; + li:objects { + ha:line.1 { x1=164000; y1=108000; x2=160000; y2=108000; stroke=wire; } + ha:line.2 { x1=160000; y1=108000; x2=160000; y2=116000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.52 { + li:conn { + /2/51/1 + /2/47/4/1 + } + } + ha:group.53 { + uuid=E4wBSbBPnQTyLrlukNMAAAB6; + li:objects { + ha:line.1 { x1=164000; y1=100000; x2=160000; y2=100000; stroke=wire; } + ha:line.2 { x1=160000; y1=100000; x2=160000; y2=92000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.54 { + li:conn { + /2/53/1 + /2/47/2/1 + } + } + ha:group.55 { + uuid=E4wBSbBPnQTyLrlukNMAAAB7; + li:objects { + ha:line.1 { x1=48000; y1=140000; x2=52000; y2=140000; stroke=wire; } + ha:line.2 { x1=52000; y1=140000; x2=52000; y2=148000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.56 { + li:conn { + /2/55/1 + /2/48/4/1 + } + } + ha:group.57 { + uuid=E4wBSbBPnQTyLrlukNMAAAB8; + li:objects { + ha:line.1 { x1=48000; y1=132000; x2=52000; y2=132000; stroke=wire; } + ha:line.2 { x1=52000; y1=132000; x2=52000; y2=124000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.58 { + li:conn { + /2/57/1 + /2/48/2/1 + } + } + ha:group.59 { + uuid=E4wBSbBPnQTyLrlukNMAAAB/; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=52000; y=124000; + li:objects { + ha:group.1 { + uuid=E4wBSbBPnQTyLrlukNMAAACA; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:connection.60 { + li:conn { + /2/59/1/1 + /2/57/2 + } + } + ha:group.61 { + uuid=E4wBSbBPnQTyLrlukNMAAACB; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=160000; y=92000; + li:objects { + ha:group.1 { + uuid=E4wBSbBPnQTyLrlukNMAAACC; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:connection.62 { + li:conn { + /2/61/1/1 + /2/53/2 + } + } + ha:group.63 { + uuid=E4wBSbBPnQTyLrlukNMAAACF; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB6; + x=160000; y=116000; + li:objects { + ha:group.1 { + uuid=E4wBSbBPnQTyLrlukNMAAACG; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB7; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-4000; y1=4000; x2=4000; y2=7000; halign=center; dyntext=0; stroke=sym-primary; text=Vcc; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:Vcc} + } + role=symbol + } + } + ha:connection.64 { + li:conn { + /2/63/1/1 + /2/51/2 + } + } + ha:group.65 { + uuid=E4wBSbBPnQTyLrlukNMAAACH; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB6; + x=52000; y=148000; + li:objects { + ha:group.1 { + uuid=E4wBSbBPnQTyLrlukNMAAACI; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB7; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-4000; y1=4000; x2=4000; y2=7000; halign=center; dyntext=0; stroke=sym-primary; text=Vcc; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:Vcc} + } + role=symbol + } + } + ha:connection.66 { + li:conn { + /2/65/1/1 + /2/55/2 + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer=Tibor 'Igor2' Palinkas + page=1 of 1 + print_page=A/4 + title=omit component U1 example + } + } +} Index: tags/1.0.5/doc/examples/omit_net.rs =================================================================== --- tags/1.0.5/doc/examples/omit_net.rs (nonexistent) +++ tags/1.0.5/doc/examples/omit_net.rs (revision 10414) @@ -0,0 +1,852 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + ha:group.1 { + uuid=E4wBSbBPnQTyLrlukNMAAAAV; + li:objects { + ha:group.1 { + uuid=E4wBSbBPnQTyLrlukNMAAAAW; loclib_name=lm358_so8; + li:objects { + } + ha:attrib { + footprint=so(8) + li:portmap { + {1/in- -> pcb/pinnum=2} + {1/in+ -> pcb/pinnum=3} + {1/out -> pcb/pinnum=1} + {1/V+ -> pcb/pinnum=8} + {1/V- -> pcb/pinnum=4} + {2/in- -> pcb/pinnum=6} + {2/in+ -> pcb/pinnum=5} + {2/out -> pcb/pinnum=7} + {2/V+ -> pcb/pinnum=8} + {2/V- -> pcb/pinnum=4} + } + } + } + } + ha:attrib { + ha:purpose = { value=devmap; prio=0; } + } + } + } + } + ha:obj_direct.2 { + uuid=E4wBSbBPnQTyLrlukNMAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.1 { + uuid=8/SYZ/pfBzxyqFA12WQAAAAC; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAg; + li:objects { + ha:polygon.11 { + li:outline { + ha:line { x1=0; y1=0; x2=80000; y2=0; } + ha:line { x1=80000; y1=0; x2=80000; y2=20000; } + ha:line { x1=80000; y1=20000; x2=0; y2=20000; } + ha:line { x1=0; y1=20000; x2=0; y2=0; } + } + stroke=titlebox-frame; + fill=titlebox-fill; + } + ha:line.12 { x1=0; y1=10000; x2=80000; y2=10000; stroke=titlebox-frame; } + ha:line.13 { x1=40000; y1=10000; x2=40000; y2=0; stroke=titlebox-frame; } + ha:text.20 { x1=1000; y1=16500; dyntext=0; stroke=titlebox-big; text=TITLE; } + ha:text.21 { x1=1000; y1=10500; x2=79000; y2=16000; dyntext=1; stroke=titlebox-big; text=%../../A.title%; } + ha:text.22 { x1=1000; y1=5500; dyntext=0; stroke=titlebox-small; text={PROJECT:}; } + ha:text.23 { x1=13000; y1=5500; x2=39000; y2=9500; dyntext=1; stroke=titlebox-big; text=%project.name%; } + ha:text.24 { x1=1000; y1=500; dyntext=0; stroke=titlebox-small; text={PAGE:}; } + ha:text.25 { x1=10000; y1=500; x2=39000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.page%; } + ha:text.26 { x1=41000; y1=5500; dyntext=0; stroke=titlebox-small; text={FILE:}; } + ha:text.27 { x1=48000; y1=5500; x2=79000; y2=9500; dyntext=1; stroke=titlebox-big; text=%filename%; } + ha:text.28 { x1=41000; y1=500; dyntext=0; stroke=titlebox-small; text={MAINTAINER:}; } + ha:text.29 { x1=55000; y1=500; x2=79000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.maintainer%; } + ha:text.30 { x1=79000; y1=16000; mirx=1; dyntext=1; stroke=sheet-decor; text=%stance.model% %stance.sub_major% %stance.sub_minor% %stance.test_bench% %view.name%; } + } + ha:attrib { + purpose=titlebox + } + } + ha:group.16 { + uuid=E4wBSbBPnQTyLrlukNMAAABB; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAH; + x=124000; y=104000; miry=1; + li:objects { + ha:group.1 { + uuid=E4wBSbBPnQTyLrlukNMAAABC; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAI; + x=-20000; y=4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=in+ + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.2 { + uuid=E4wBSbBPnQTyLrlukNMAAABD; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAJ; + x=-20000; y=-4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=in- + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:group.3 { + uuid=E4wBSbBPnQTyLrlukNMAAABE; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAK; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=out + role=terminal + ha:spice/pinnum = { value=3; prio=31050; } + } + } + ha:line.4 { x1=-20000; y1=-8000; x2=-20000; y2=8000; stroke=sym-decor; } + ha:line.5 { x1=-20000; y1=8000; x2=-4000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=-4000; y1=0; x2=-20000; y2=-8000; stroke=sym-decor; } + ha:line.7 { x1=-18000; y1=5000; x2=-18000; y2=3000; stroke=sym-decor; } + ha:line.8 { x1=-19000; y1=4000; x2=-17000; y2=4000; stroke=sym-decor; } + ha:line.9 { x1=-19000; y1=-4000; x2=-17000; y2=-4000; stroke=sym-decor; } + ha:group.10 { + uuid=E4wBSbBPnQTyLrlukNMAAABF; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAL; + x=-12000; y=-4000; rot=270.000000; mirx=1; miry=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=0; y1=-1000; rot=180.000000; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=V- + role=terminal + ha:spice/pinnum = { value=5; prio=31050; } + } + } + ha:group.11 { + uuid=E4wBSbBPnQTyLrlukNMAAABG; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAM; + x=-12000; y=8000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=-4000; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=V+ + role=terminal + ha:spice/pinnum = { value=4; prio=31050; } + } + } + ha:text.12 { x1=-21000; y1=9000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -slot=1 + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + devmap=lm358_so8 + name=U1 + role=symbol + } + } + ha:group.22 { + uuid=E4wBSbBPnQTyLrlukNMAAABM; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=104000; y=136000; miry=1; + li:objects { + ha:group.1 { + uuid=E4wBSbBPnQTyLrlukNMAAABN; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=E4wBSbBPnQTyLrlukNMAAABO; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=R1 + role=symbol + ha:spice/prefix = { value=R; prio=31050; } + value=47k + } + } + ha:group.23 { + uuid=E4wBSbBPnQTyLrlukNMAAABP; src_uuid=E4wBSbBPnQTyLrlukNMAAAAp; + x=16000; y=244000; miry=1; + li:objects { + ha:line.1 { x1=84000; y1=136000; x2=76000; y2=136000; stroke=wire; } + ha:line.2 { x1=76000; y1=136000; x2=76000; y2=108000; stroke=wire; } + ha:line.4 { x1=68000; y1=108000; x2=88000; y2=108000; stroke=wire; } + ha:line.5 { x1=76000; y1=108000; x2=76000; y2=108000; stroke=junction; } + ha:text.6 { x1=76000; y1=112000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=opa_neg + omit=1 + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.24 { + li:conn { + /2/23/1 + /2/16/2/1 + } + } + ha:connection.25 { + li:conn { + /2/22/2/1 + /2/23/4 + } + } + ha:group.26 { + uuid=E4wBSbBPnQTyLrlukNMAAABQ; src_uuid=E4wBSbBPnQTyLrlukNMAAAAq; + x=16000; y=244000; miry=1; + li:objects { + ha:line.1 { x1=108000; y1=108000; x2=124000; y2=108000; stroke=wire; } + ha:line.2 { x1=124000; y1=108000; x2=124000; y2=140000; stroke=wire; } + ha:line.4 { x1=108000; y1=140000; x2=148000; y2=140000; stroke=wire; } + ha:line.5 { x1=124000; y1=140000; x2=124000; y2=140000; stroke=junction; } + ha:text.6 { x1=132000; y1=140000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=out + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.27 { + li:conn { + /2/26/1 + /2/22/1/1 + } + } + ha:connection.28 { + li:conn { + /2/16/3/1 + /2/26/4 + } + } + ha:group.29 { + uuid=E4wBSbBPnQTyLrlukNMAAABR; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=64000; y=136000; miry=1; + li:objects { + ha:group.1 { + uuid=E4wBSbBPnQTyLrlukNMAAABS; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=E4wBSbBPnQTyLrlukNMAAABT; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=R2 + role=symbol + ha:spice/prefix = { value=R; prio=31050; } + value=10k + } + } + ha:group.30 { + uuid=E4wBSbBPnQTyLrlukNMAAABY; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=124000; y=116000; + li:objects { + ha:group.1 { + uuid=E4wBSbBPnQTyLrlukNMAAABZ; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.31 { + uuid=E4wBSbBPnQTyLrlukNMAAABa; + li:objects { + ha:line.1 { x1=112000; y1=112000; x2=112000; y2=120000; stroke=wire; } + ha:line.2 { x1=112000; y1=120000; x2=124000; y2=120000; stroke=wire; } + ha:line.3 { x1=124000; y1=120000; x2=124000; y2=116000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.32 { + li:conn { + /2/31/1 + /2/16/10/1 + } + } + ha:connection.33 { + li:conn { + /2/31/3 + /2/30/1/1 + } + } + ha:group.34 { + uuid=E4wBSbBPnQTyLrlukNMAAABf; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB6; + x=124000; y=96000; + li:objects { + ha:group.1 { + uuid=E4wBSbBPnQTyLrlukNMAAABg; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB7; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-4000; y1=4000; x2=4000; y2=7000; halign=center; dyntext=0; stroke=sym-primary; text=Vcc; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:Vcc} + } + role=symbol + } + } + ha:group.37 { + uuid=E4wBSbBPnQTyLrlukNMAAABi; + li:objects { + ha:line.1 { x1=112000; y1=96000; x2=112000; y2=92000; stroke=wire; } + ha:line.2 { x1=112000; y1=92000; x2=124000; y2=92000; stroke=wire; } + ha:line.3 { x1=124000; y1=92000; x2=124000; y2=96000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.38 { + li:conn { + /2/37/1 + /2/16/11/1 + } + } + ha:connection.39 { + li:conn { + /2/37/3 + /2/34/1/1 + } + } + ha:group.40 { + uuid=E4wBSbBPnQTyLrlukNMAAABj; + li:objects { + ha:line.1 { x1=100000; y1=100000; x2=92000; y2=100000; stroke=wire; } + ha:line.2 { x1=92000; y1=100000; x2=92000; y2=92000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.41 { + li:conn { + /2/40/1 + /2/16/1/1 + } + } + ha:group.42 { + uuid=E4wBSbBPnQTyLrlukNMAAABm; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=92000; y=92000; + li:objects { + ha:group.1 { + uuid=E4wBSbBPnQTyLrlukNMAAABn; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:connection.43 { + li:conn { + /2/42/1/1 + /2/40/2 + } + } + ha:connection.44 { + li:conn { + /2/23/4 + /2/29/1/1 + } + } + ha:group.45 { + uuid=E4wBSbBPnQTyLrlukNMAAABo; + li:objects { + ha:line.2 { x1=48000; y1=136000; x2=64000; y2=136000; stroke=wire; } + ha:text.3 { x1=56000; y1=136000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=in + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.46 { + li:conn { + /2/29/2/1 + /2/45/2 + } + } + ha:group.47 { + uuid=E4wBSbBPnQTyLrlukNMAAABx; src_uuid=E4wBSbBPnQTyLrlukNMAAABt; + x=168000; y=100000; + li:objects { + ha:text.1 { x1=0; y1=-2000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:group.2 { + uuid=E4wBSbBPnQTyLrlukNMAAABy; src_uuid=E4wBSbBPnQTyLrlukNMAAABu; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:group.3 { + uuid=E4wBSbBPnQTyLrlukNMAAABz; src_uuid=E4wBSbBPnQTyLrlukNMAAABv; + x=0; y=4000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.4 { + uuid=E4wBSbBPnQTyLrlukNMAAAB0; src_uuid=E4wBSbBPnQTyLrlukNMAAABw; + x=0; y=8000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=3 + role=terminal + } + } + ha:polygon.5 { + li:outline { + ha:line { x1=0; y1=-2000; x2=0; y2=10000; } + ha:line { x1=0; y1=10000; x2=4000; y2=10000; } + ha:line { x1=4000; y1=10000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=0; y2=-2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + name=CONN2 + role=symbol + } + } + ha:group.48 { + uuid=E4wBSbBPnQTyLrlukNMAAAB1; src_uuid=E4wBSbBPnQTyLrlukNMAAABt; + x=44000; y=132000; mirx=1; + li:objects { + ha:text.1 { x1=0; y1=-2000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:group.2 { + uuid=E4wBSbBPnQTyLrlukNMAAAB2; src_uuid=E4wBSbBPnQTyLrlukNMAAABu; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:group.3 { + uuid=E4wBSbBPnQTyLrlukNMAAAB3; src_uuid=E4wBSbBPnQTyLrlukNMAAABv; + x=0; y=4000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.4 { + uuid=E4wBSbBPnQTyLrlukNMAAAB4; src_uuid=E4wBSbBPnQTyLrlukNMAAABw; + x=0; y=8000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=3 + role=terminal + } + } + ha:polygon.5 { + li:outline { + ha:line { x1=0; y1=-2000; x2=0; y2=10000; } + ha:line { x1=0; y1=10000; x2=4000; y2=10000; } + ha:line { x1=4000; y1=10000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=0; y2=-2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + name=CONN1 + role=symbol + } + } + ha:connection.49 { + li:conn { + /2/45/2 + /2/48/3/1 + } + } + ha:connection.50 { + li:conn { + /2/26/4 + /2/47/3/1 + } + } + ha:group.51 { + uuid=E4wBSbBPnQTyLrlukNMAAAB5; + li:objects { + ha:line.1 { x1=164000; y1=108000; x2=160000; y2=108000; stroke=wire; } + ha:line.2 { x1=160000; y1=108000; x2=160000; y2=116000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.52 { + li:conn { + /2/51/1 + /2/47/4/1 + } + } + ha:group.53 { + uuid=E4wBSbBPnQTyLrlukNMAAAB6; + li:objects { + ha:line.1 { x1=164000; y1=100000; x2=160000; y2=100000; stroke=wire; } + ha:line.2 { x1=160000; y1=100000; x2=160000; y2=92000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.54 { + li:conn { + /2/53/1 + /2/47/2/1 + } + } + ha:group.55 { + uuid=E4wBSbBPnQTyLrlukNMAAAB7; + li:objects { + ha:line.1 { x1=48000; y1=140000; x2=52000; y2=140000; stroke=wire; } + ha:line.2 { x1=52000; y1=140000; x2=52000; y2=148000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.56 { + li:conn { + /2/55/1 + /2/48/4/1 + } + } + ha:group.57 { + uuid=E4wBSbBPnQTyLrlukNMAAAB8; + li:objects { + ha:line.1 { x1=48000; y1=132000; x2=52000; y2=132000; stroke=wire; } + ha:line.2 { x1=52000; y1=132000; x2=52000; y2=124000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.58 { + li:conn { + /2/57/1 + /2/48/2/1 + } + } + ha:group.59 { + uuid=E4wBSbBPnQTyLrlukNMAAAB/; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=52000; y=124000; + li:objects { + ha:group.1 { + uuid=E4wBSbBPnQTyLrlukNMAAACA; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:connection.60 { + li:conn { + /2/59/1/1 + /2/57/2 + } + } + ha:group.61 { + uuid=E4wBSbBPnQTyLrlukNMAAACB; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=160000; y=92000; + li:objects { + ha:group.1 { + uuid=E4wBSbBPnQTyLrlukNMAAACC; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:connection.62 { + li:conn { + /2/61/1/1 + /2/53/2 + } + } + ha:group.63 { + uuid=E4wBSbBPnQTyLrlukNMAAACF; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB6; + x=160000; y=116000; + li:objects { + ha:group.1 { + uuid=E4wBSbBPnQTyLrlukNMAAACG; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB7; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-4000; y1=4000; x2=4000; y2=7000; halign=center; dyntext=0; stroke=sym-primary; text=Vcc; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:Vcc} + } + role=symbol + } + } + ha:connection.64 { + li:conn { + /2/63/1/1 + /2/51/2 + } + } + ha:group.65 { + uuid=E4wBSbBPnQTyLrlukNMAAACH; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB6; + x=52000; y=148000; + li:objects { + ha:group.1 { + uuid=E4wBSbBPnQTyLrlukNMAAACI; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB7; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-4000; y1=4000; x2=4000; y2=7000; halign=center; dyntext=0; stroke=sym-primary; text=Vcc; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:Vcc} + } + role=symbol + } + } + ha:connection.66 { + li:conn { + /2/65/1/1 + /2/55/2 + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer=Tibor 'Igor2' Palinkas + page=1 of 1 + print_page=A/4 + title=omit network opa_neg example + } + } +} Index: tags/1.0.5/doc/examples/psu.rs =================================================================== --- tags/1.0.5/doc/examples/psu.rs (nonexistent) +++ tags/1.0.5/doc/examples/psu.rs (revision 10414) @@ -0,0 +1,741 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=iNOQfJpO6hT/HFDFGjoAAAGW; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAGX; + li:objects { + ha:polygon.11 { + li:outline { + ha:line { x1=0; y1=0; x2=80000; y2=0; } + ha:line { x1=80000; y1=0; x2=80000; y2=20000; } + ha:line { x1=80000; y1=20000; x2=0; y2=20000; } + ha:line { x1=0; y1=20000; x2=0; y2=0; } + } + stroke=titlebox-frame; + fill=titlebox-fill; + } + ha:line.12 { x1=0; y1=10000; x2=80000; y2=10000; stroke=titlebox-frame; } + ha:line.13 { x1=40000; y1=10000; x2=40000; y2=0; stroke=titlebox-frame; } + ha:text.20 { x1=1000; y1=16500; dyntext=0; stroke=titlebox-big; text=TITLE; } + ha:text.21 { x1=1000; y1=10500; x2=79000; y2=16000; dyntext=1; stroke=titlebox-big; text=%../../A.title%; } + ha:text.22 { x1=1000; y1=5500; dyntext=0; stroke=titlebox-small; text={PROJECT:}; } + ha:text.23 { x1=13000; y1=5500; x2=39000; y2=9500; dyntext=1; stroke=titlebox-big; text=%project.name%; } + ha:text.24 { x1=1000; y1=500; dyntext=0; stroke=titlebox-small; text={PAGE:}; } + ha:text.25 { x1=10000; y1=500; x2=39000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.page%; } + ha:text.26 { x1=41000; y1=5500; dyntext=0; stroke=titlebox-small; text={FILE:}; } + ha:text.27 { x1=48000; y1=5500; x2=79000; y2=9500; dyntext=1; stroke=titlebox-big; text=%filename%; } + ha:text.28 { x1=41000; y1=500; dyntext=0; stroke=titlebox-small; text={MAINTAINER:}; } + ha:text.29 { x1=55000; y1=500; x2=79000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.maintainer%; } + } + ha:attrib { + purpose=titlebox + } + } + ha:group.2 { + uuid=iNOQfJpO6hT/HFDFGjoAAAGY; + x=44000; y=96000; mirx=1; + li:objects { + ha:text.1 { x1=0; y1=-6000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:group.2 { + uuid=iNOQfJpO6hT/HFDFGjoAAAGZ; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; floater=1; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:group.3 { + uuid=iNOQfJpO6hT/HFDFGjoAAAGa; + x=0; y=4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; floater=1; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:polygon.4 { + li:outline { + ha:line { x1=0; y1=-2000; x2=0; y2=6000; } + ha:line { x1=0; y1=6000; x2=4000; y2=6000; } + ha:line { x1=4000; y1=6000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=0; y2=-2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + footprint=connector(2,1) + name=CONN1 + role=symbol + } + } + ha:group.4 { + uuid=iNOQfJpO6hT/HFDFGjoAAAGb; + x=92000; y=92000; + li:objects { + ha:text.1 { x1=0; y1=16000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.2 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=16000; } + ha:line { x1=0; y1=16000; x2=24000; y2=16000; } + ha:line { x1=24000; y1=16000; x2=24000; y2=0; } + ha:line { x1=24000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + } + ha:group.3 { + uuid=iNOQfJpO6hT/HFDFGjoAAAGc; + x=0; y=8000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../A.pinnum%; floater=1; } + ha:text.3 { x1=1000; y1=-2000; dyntext=1; stroke=term-secondary; text=%../A.name%; floater=1; } + } + ha:attrib { + name=in + pinnum=1 + role=terminal + } + } + ha:group.4 { + uuid=iNOQfJpO6hT/HFDFGjoAAAGd; + x=24000; y=8000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../A.pinnum%; floater=1; } + ha:text.3 { x1=2000; y1=-2000; dyntext=1; stroke=term-secondary; text=%../A.name%; floater=1; } + } + ha:attrib { + name=out + pinnum=3 + role=terminal + } + } + ha:group.5 { + uuid=iNOQfJpO6hT/HFDFGjoAAAGe; + x=12000; y=0; rot=-90.000000; miry=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../A.pinnum%; floater=1; } + ha:text.3 { x1=2000; y1=-2000; dyntext=1; stroke=term-secondary; text=%../A.name%; floater=1; } + } + ha:attrib { + name=gnd + pinnum=2 + role=terminal + } + } + } + ha:attrib { + footprint=TO220 + name=U1 + role=symbol + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + sym-license-dist=GPLv2+ + sym-license-use=Public Domain + sym-source=sch-rnd default symbol lib + symbol_generator=boxsym-rnd + } + } + ha:group.8 { + uuid=iNOQfJpO6hT/HFDFGjoAAAGf; + x=52000; y=92000; + li:objects { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAGg; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + li:connect { + {1:GND} + } + role=symbol + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + sym-license-dist=GPLv2+ + sym-license-use=Public Domain + sym-source=sch-rnd default symbol lib + } + } + ha:group.10 { + uuid=iNOQfJpO6hT/HFDFGjoAAAGh; + li:objects { + ha:line.1 { x1=48000; y1=96000; x2=52000; y2=96000; stroke=wire; } + ha:line.2 { x1=52000; y1=96000; x2=52000; y2=92000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.11 { + li:conn { + /2/10/1 + /2/2/2/1 + } + } + ha:connection.12 { + li:conn { + /2/10/2 + /2/8/1/1 + } + } + ha:group.16 { + uuid=iNOQfJpO6hT/HFDFGjoAAAGi; + x=80000; y=96000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAGj; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; floater=1; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=iNOQfJpO6hT/HFDFGjoAAAGk; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; floater=1; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=20000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=16000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.5 { x1=9000; y1=5000; x2=9000; y2=-5000; stroke=sym-decor; } + ha:line.6 { x1=11000; y1=5000; x2=11000; y2=-5000; stroke=sym-decor; } + ha:line.7 { x1=4000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.8 { x1=11000; y1=0; x2=16000; y2=0; stroke=sym-decor; } + } + ha:attrib { + footprint=1206 + name=C2 + role=symbol + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + sym-license-dist=GPLv2+ + sym-license-use=Public Domain + sym-source=sch-rnd default symbol lib + value=100n + } + } + ha:group.17 { + uuid=iNOQfJpO6hT/HFDFGjoAAAGl; + x=64000; y=96000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAGm; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; floater=1; } + } + ha:attrib { + name=N + role=terminal + } + } + ha:group.2 { + uuid=iNOQfJpO6hT/HFDFGjoAAAGn; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; floater=1; } + } + ha:attrib { + name=P + role=terminal + } + } + ha:text.3 { x1=20000; y1=-10000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=16000; y1=-6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.5 { x1=9000; y1=5000; x2=9000; y2=-5000; stroke=sym-decor; } + ha:line.6 { x1=4000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.7 { x1=11000; y1=0; x2=16000; y2=0; stroke=sym-decor; } + ha:arc.8 { cx=34000; cy=0; r=23000; sang=167.500000; dang=25.000000; stroke=sym-decor; } + ha:line.9 { x1=6000; y1=-3000; x2=8000; y2=-3000; stroke=sym-decor; } + ha:line.10 { x1=7000; y1=-4000; x2=7000; y2=-2000; stroke=sym-decor; } + } + ha:attrib { + footprint=rcy(300) + name=C1 + li:portmap { + {N->pcb/pinnum=1} + {P->pcb/pinnum=2} + } + role=symbol + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + sym-license-dist=GPLv2+ + sym-license-use=Public Domain + sym-source=sch-rnd default symbol lib + value=10u + } + } + ha:group.19 { + uuid=iNOQfJpO6hT/HFDFGjoAAAGo; + x=156000; y=96000; + li:objects { + ha:text.1 { x1=0; y1=-6000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:group.2 { + uuid=iNOQfJpO6hT/HFDFGjoAAAGp; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; floater=1; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:group.3 { + uuid=iNOQfJpO6hT/HFDFGjoAAAGq; + x=0; y=4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; floater=1; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:polygon.4 { + li:outline { + ha:line { x1=0; y1=-2000; x2=0; y2=6000; } + ha:line { x1=0; y1=6000; x2=4000; y2=6000; } + ha:line { x1=4000; y1=6000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=0; y2=-2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + footprint=connector(2,1) + name=CONN2 + role=symbol + } + } + ha:group.20 { + uuid=iNOQfJpO6hT/HFDFGjoAAAGr; + x=148000; y=92000; + li:objects { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAGs; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + li:connect { + {1:GND} + } + role=symbol + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + sym-license-dist=GPLv2+ + sym-license-use=Public Domain + sym-source=sch-rnd default symbol lib + } + } + ha:group.21 { + uuid=iNOQfJpO6hT/HFDFGjoAAAGt; + li:objects { + ha:line.1 { x1=152000; y1=96000; x2=148000; y2=96000; stroke=wire; } + ha:line.2 { x1=148000; y1=96000; x2=148000; y2=92000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.22 { + li:conn { + /2/21/1 + /2/19/2/1 + } + } + ha:connection.23 { + li:conn { + /2/21/2 + /2/20/1/1 + } + } + ha:group.24 { + uuid=iNOQfJpO6hT/HFDFGjoAAAGu; + li:objects { + ha:line.1 { x1=48000; y1=100000; x2=88000; y2=100000; stroke=wire; } + ha:line.2 { x1=64000; y1=96000; x2=64000; y2=100000; stroke=wire; } + ha:line.3 { x1=64000; y1=100000; x2=64000; y2=100000; stroke=junction; } + ha:line.4 { x1=80000; y1=96000; x2=80000; y2=100000; stroke=wire; } + ha:line.5 { x1=80000; y1=100000; x2=80000; y2=100000; stroke=junction; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.25 { + li:conn { + /2/24/1 + /2/2/3/1 + } + } + ha:connection.26 { + li:conn { + /2/24/1 + /2/4/3/1 + } + } + ha:group.27 { + uuid=iNOQfJpO6hT/HFDFGjoAAAGv; + li:objects { + ha:line.1 { x1=120000; y1=100000; x2=152000; y2=100000; stroke=wire; } + ha:line.4 { x1=128000; y1=96000; x2=128000; y2=100000; stroke=wire; } + ha:line.5 { x1=128000; y1=100000; x2=128000; y2=100000; stroke=junction; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.28 { + li:conn { + /2/27/1 + /2/4/4/1 + } + } + ha:connection.29 { + li:conn { + /2/27/1 + /2/19/3/1 + } + } + ha:connection.30 { + li:conn { + /2/24/2 + /2/17/2/1 + } + } + ha:connection.31 { + li:conn { + /2/24/4 + /2/16/2/1 + } + } + ha:group.32 { + uuid=iNOQfJpO6hT/HFDFGjoAAAGw; + x=128000; y=96000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAGx; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; floater=1; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=iNOQfJpO6hT/HFDFGjoAAAGy; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; floater=1; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=20000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=16000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.5 { x1=9000; y1=5000; x2=9000; y2=-5000; stroke=sym-decor; } + ha:line.6 { x1=11000; y1=5000; x2=11000; y2=-5000; stroke=sym-decor; } + ha:line.7 { x1=4000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.8 { x1=11000; y1=0; x2=16000; y2=0; stroke=sym-decor; } + } + ha:attrib { + footprint=1206 + name=C3 + role=symbol + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + sym-license-dist=GPLv2+ + sym-license-use=Public Domain + sym-source=sch-rnd default symbol lib + value=100n + } + } + ha:group.34 { + uuid=iNOQfJpO6hT/HFDFGjoAAAGz; + x=128000; y=64000; + li:objects { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAG0; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + li:connect { + {1:GND} + } + role=symbol + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + sym-license-dist=GPLv2+ + sym-license-use=Public Domain + sym-source=sch-rnd default symbol lib + } + } + ha:group.35 { + uuid=iNOQfJpO6hT/HFDFGjoAAAG1; + x=80000; y=64000; + li:objects { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAG2; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + li:connect { + {1:GND} + } + role=symbol + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + sym-license-dist=GPLv2+ + sym-license-use=Public Domain + sym-source=sch-rnd default symbol lib + } + } + ha:group.36 { + uuid=iNOQfJpO6hT/HFDFGjoAAAG3; + x=64000; y=64000; + li:objects { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAG4; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + li:connect { + {1:GND} + } + role=symbol + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + sym-license-dist=GPLv2+ + sym-license-use=Public Domain + sym-source=sch-rnd default symbol lib + } + } + ha:connection.37 { + li:conn { + /2/27/4 + /2/32/2/1 + } + } + ha:group.38 { + uuid=iNOQfJpO6hT/HFDFGjoAAAG5; + li:objects { + ha:line.1 { x1=128000; y1=76000; x2=128000; y2=64000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.39 { + li:conn { + /2/38/1 + /2/34/1/1 + } + } + ha:connection.40 { + li:conn { + /2/38/1 + /2/32/1/1 + } + } + ha:group.41 { + uuid=iNOQfJpO6hT/HFDFGjoAAAG6; + li:objects { + ha:line.1 { x1=80000; y1=76000; x2=80000; y2=64000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.42 { + li:conn { + /2/41/1 + /2/16/1/1 + } + } + ha:connection.43 { + li:conn { + /2/41/1 + /2/35/1/1 + } + } + ha:group.44 { + uuid=iNOQfJpO6hT/HFDFGjoAAAG7; + li:objects { + ha:line.1 { x1=64000; y1=76000; x2=64000; y2=64000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.45 { + li:conn { + /2/44/1 + /2/17/1/1 + } + } + ha:connection.46 { + li:conn { + /2/44/1 + /2/36/1/1 + } + } + ha:group.47 { + uuid=iNOQfJpO6hT/HFDFGjoAAAG8; + x=104000; y=64000; + li:objects { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAG9; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + li:connect { + {1:GND} + } + role=symbol + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + sym-license-dist=GPLv2+ + sym-license-use=Public Domain + sym-source=sch-rnd default symbol lib + } + } + ha:group.48 { + uuid=iNOQfJpO6hT/HFDFGjoAAAG+; + li:objects { + ha:line.1 { x1=104000; y1=88000; x2=104000; y2=64000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.49 { + li:conn { + /2/48/1 + /2/4/5/1 + } + } + ha:connection.50 { + li:conn { + /2/48/1 + /2/47/1/1 + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer=Tibor 'Igor2' Palinkas + page=1 of 1 + print_page=A/4 + title={simple PSU board: LDO breakout (example)} + } + } +} Index: tags/1.0.5/doc/examples/slot.rs =================================================================== --- tags/1.0.5/doc/examples/slot.rs (nonexistent) +++ tags/1.0.5/doc/examples/slot.rs (revision 10414) @@ -0,0 +1,1179 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + ha:group.1 { + uuid=bOwQFqA7m2jl+cvU6t4AAABC; + li:objects { + ha:group.1 { + uuid=bOwQFqA7m2jl+cvU6t4AAABD; loclib_name=lm358_so8; + li:objects { + } + ha:attrib { + footprint=so(8) + li:portmap { + {1/in- -> pcb/pinnum=2} + {1/in+ -> pcb/pinnum=3} + {1/out -> pcb/pinnum=1} + {1/V+ -> pcb/pinnum=8} + {1/V- -> pcb/pinnum=4} + {2/in- -> pcb/pinnum=6} + {2/in+ -> pcb/pinnum=5} + {2/out -> pcb/pinnum=7} + {2/V+ -> pcb/pinnum=8} + {2/V- -> pcb/pinnum=4} + } + } + } + ha:group.2 { + uuid=bOwQFqA7m2jl+cvU6t4AAABE; loclib_name=lm358_so8; + li:objects { + } + ha:attrib { + footprint=so(8) + li:portmap { + {1/in- -> pcb/pinnum=2} + {1/in+ -> pcb/pinnum=3} + {1/out -> pcb/pinnum=1} + {1/V+ -> pcb/pinnum=8} + {1/V- -> pcb/pinnum=4} + {2/in- -> pcb/pinnum=6} + {2/in+ -> pcb/pinnum=5} + {2/out -> pcb/pinnum=7} + {2/V+ -> pcb/pinnum=8} + {2/V- -> pcb/pinnum=4} + } + } + } + } + ha:attrib { + ha:purpose = { value=devmap; prio=0; } + } + } + } + } + ha:obj_direct.2 { + uuid=iNOQfJpO6hT/HFDFGjoAAAEl; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAEm; + li:objects { + ha:polygon.11 { + li:outline { + ha:line { x1=0; y1=0; x2=80000; y2=0; } + ha:line { x1=80000; y1=0; x2=80000; y2=20000; } + ha:line { x1=80000; y1=20000; x2=0; y2=20000; } + ha:line { x1=0; y1=20000; x2=0; y2=0; } + } + stroke=titlebox-frame; + fill=titlebox-fill; + } + ha:line.12 { x1=0; y1=10000; x2=80000; y2=10000; stroke=titlebox-frame; } + ha:line.13 { x1=40000; y1=10000; x2=40000; y2=0; stroke=titlebox-frame; } + ha:text.20 { x1=1000; y1=16500; dyntext=0; stroke=titlebox-big; text=TITLE; } + ha:text.21 { x1=1000; y1=10500; x2=79000; y2=16000; dyntext=1; stroke=titlebox-big; text=%../../A.title%; } + ha:text.22 { x1=1000; y1=5500; dyntext=0; stroke=titlebox-small; text={PROJECT:}; } + ha:text.23 { x1=13000; y1=5500; x2=39000; y2=9500; dyntext=1; stroke=titlebox-big; text=%project.name%; } + ha:text.24 { x1=1000; y1=500; dyntext=0; stroke=titlebox-small; text={PAGE:}; } + ha:text.25 { x1=10000; y1=500; x2=39000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.page%; } + ha:text.26 { x1=41000; y1=5500; dyntext=0; stroke=titlebox-small; text={FILE:}; } + ha:text.27 { x1=48000; y1=5500; x2=79000; y2=9500; dyntext=1; stroke=titlebox-big; text=%filename%; } + ha:text.28 { x1=41000; y1=500; dyntext=0; stroke=titlebox-small; text={MAINTAINER:}; } + ha:text.29 { x1=55000; y1=500; x2=79000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.maintainer%; } + } + ha:attrib { + purpose=titlebox + } + } + ha:group.4 { + uuid=iNOQfJpO6hT/HFDFGjoAAAEz; + li:objects { + ha:line.3 { x1=96000; y1=84000; x2=96000; y2=60000; stroke=wire; } + ha:line.4 { x1=96000; y1=60000; x2=56000; y2=60000; stroke=wire; } + ha:line.5 { x1=56000; y1=60000; x2=56000; y2=80000; stroke=wire; } + ha:line.8 { x1=56000; y1=80000; x2=56000; y2=80000; stroke=junction; } + ha:line.9 { x1=88000; y1=84000; x2=100000; y2=84000; stroke=wire; } + ha:line.10 { x1=96000; y1=84000; x2=96000; y2=84000; stroke=junction; } + ha:line.11 { x1=24000; y1=80000; x2=64000; y2=80000; stroke=wire; } + ha:text.12 { x1=38000; y1=80000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=in + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.10 { + uuid=iNOQfJpO6hT/HFDFGjoAAAE2; + li:objects { + ha:line.1 { x1=76000; y1=100000; x2=76000; y2=92000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.13 { + uuid=iNOQfJpO6hT/HFDFGjoAAAE3; + x=76000; y=68000; + li:objects { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAE4; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + li:connect { + {1:GND} + } + role=symbol + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + sym-license-dist=GPLv2+ + sym-license-use=Public Domain + sym-source=sch-rnd default symbol lib + } + } + ha:group.14 { + uuid=iNOQfJpO6hT/HFDFGjoAAAE5; + li:objects { + ha:line.1 { x1=76000; y1=76000; x2=76000; y2=68000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.16 { + li:conn { + /2/14/1 + /2/13/1/1 + } + } + ha:group.17 { + uuid=iNOQfJpO6hT/HFDFGjoAAAE6; + x=60000; y=88000; + li:objects { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAE7; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + li:connect { + {1:GND} + } + role=symbol + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + sym-license-dist=GPLv2+ + sym-license-use=Public Domain + sym-source=sch-rnd default symbol lib + } + } + ha:group.18 { + uuid=iNOQfJpO6hT/HFDFGjoAAAE8; + li:objects { + ha:line.1 { x1=64000; y1=88000; x2=60000; y2=88000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.20 { + li:conn { + /2/18/1 + /2/17/1/1 + } + } + ha:group.21 { + uuid=iNOQfJpO6hT/HFDFGjoAAAE9; + x=100000; y=84000; + li:objects { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAE+; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=iNOQfJpO6hT/HFDFGjoAAAE/; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.5 { x1=9000; y1=5000; x2=9000; y2=-5000; stroke=sym-decor; } + ha:line.6 { x1=11000; y1=5000; x2=11000; y2=-5000; stroke=sym-decor; } + ha:line.7 { x1=4000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.8 { x1=11000; y1=0; x2=16000; y2=0; stroke=sym-decor; } + } + ha:attrib { + name=C1 + role=symbol + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + sym-license-dist=GPLv2+ + sym-license-use=Public Domain + sym-source=sch-rnd default symbol lib + value=100n + } + } + ha:connection.22 { + li:conn { + /2/4/9 + /2/21/2/1 + } + } + ha:group.23 { + uuid=iNOQfJpO6hT/HFDFGjoAAAFA; + x=128000; y=116000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAFB; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=iNOQfJpO6hT/HFDFGjoAAAFC; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + name=R1 + role=symbol + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + sym-license-dist=GPLv2+ + sym-license-use=Public Domain + sym-source=sch-rnd default symbol lib + value=470k + } + } + ha:group.27 { + uuid=iNOQfJpO6hT/HFDFGjoAAAFD; + x=128000; y=76000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAFE; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=iNOQfJpO6hT/HFDFGjoAAAFF; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + name=R2 + role=symbol + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + sym-license-dist=GPLv2+ + sym-license-use=Public Domain + sym-source=sch-rnd default symbol lib + value=470k + } + } + ha:group.29 { + uuid=iNOQfJpO6hT/HFDFGjoAAAFG; + x=128000; y=52000; + li:objects { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAFH; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + li:connect { + {1:GND} + } + role=symbol + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + sym-license-dist=GPLv2+ + sym-license-use=Public Domain + sym-source=sch-rnd default symbol lib + } + } + ha:group.30 { + uuid=iNOQfJpO6hT/HFDFGjoAAAFI; + li:objects { + ha:line.1 { x1=128000; y1=56000; x2=128000; y2=52000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.31 { + li:conn { + /2/30/1 + /2/27/1/1 + } + } + ha:connection.32 { + li:conn { + /2/30/1 + /2/29/1/1 + } + } + ha:group.36 { + uuid=iNOQfJpO6hT/HFDFGjoAAAFJ; + x=140000; y=88000; + li:objects { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAFK; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + li:connect { + {1:GND} + } + role=symbol + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + sym-license-dist=GPLv2+ + sym-license-use=Public Domain + sym-source=sch-rnd default symbol lib + } + } + ha:group.38 { + uuid=iNOQfJpO6hT/HFDFGjoAAAFL; + li:objects { + ha:line.1 { x1=140000; y1=88000; x2=144000; y2=88000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.40 { + li:conn { + /2/38/1 + /2/36/1/1 + } + } + ha:group.60 { + uuid=iNOQfJpO6hT/HFDFGjoAAAFO; + li:objects { + ha:line.1 { x1=128000; y1=124000; x2=128000; y2=116000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.61 { + li:conn { + /2/60/1 + /2/23/2/1 + } + } + ha:group.63 { + uuid=iNOQfJpO6hT/HFDFGjoAAAFP; + x=196000; y=80000; + li:objects { + ha:text.1 { x1=10000; y1=-4000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:group.2 { + uuid=iNOQfJpO6hT/HFDFGjoAAAFQ; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:group.3 { + uuid=iNOQfJpO6hT/HFDFGjoAAAFR; + x=0; y=4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.4 { + uuid=iNOQfJpO6hT/HFDFGjoAAAFS; + x=0; y=8000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + name=3 + role=terminal + } + } + ha:polygon.5 { + li:outline { + ha:line { x1=0; y1=-2000; x2=0; y2=10000; } + ha:line { x1=0; y1=10000; x2=4000; y2=10000; } + ha:line { x1=4000; y1=10000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=0; y2=-2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + name=CONN2 + role=symbol + } + } + ha:group.67 { + uuid=iNOQfJpO6hT/HFDFGjoAAAFW; + li:objects { + ha:line.1 { x1=140000; y1=60000; x2=140000; y2=80000; stroke=wire; } + ha:line.2 { x1=176000; y1=64000; x2=176000; y2=84000; stroke=wire; } + ha:line.3 { x1=128000; y1=84000; x2=128000; y2=84000; stroke=junction; } + ha:line.4 { x1=140000; y1=60000; x2=176000; y2=60000; stroke=wire; } + ha:line.5 { x1=140000; y1=80000; x2=140000; y2=80000; stroke=junction; } + ha:line.6 { x1=128000; y1=80000; x2=128000; y2=80000; stroke=junction; } + ha:line.7 { x1=144000; y1=80000; x2=128000; y2=80000; stroke=wire; } + ha:line.8 { x1=176000; y1=84000; x2=192000; y2=84000; stroke=wire; } + ha:line.9 { x1=176000; y1=60000; x2=176000; y2=64000; stroke=wire; } + ha:line.10 { x1=176000; y1=84000; x2=176000; y2=84000; stroke=junction; } + ha:line.11 { x1=128000; y1=76000; x2=128000; y2=96000; stroke=wire; } + ha:line.12 { x1=176000; y1=84000; x2=168000; y2=84000; stroke=wire; } + ha:line.13 { x1=120000; y1=84000; x2=128000; y2=84000; stroke=wire; } + ha:text.14 { x1=178000; y1=84000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + ha:text.15 { x1=124000; y1=84000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=mid + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.69 { + li:conn { + /2/67/8 + /2/63/3/1 + } + } + ha:connection.70 { + li:conn { + /2/67/11 + /2/23/1/1 + } + } + ha:connection.71 { + li:conn { + /2/67/11 + /2/27/2/1 + } + } + ha:connection.73 { + li:conn { + /2/67/13 + /2/21/1/1 + } + } + ha:group.75 { + uuid=iNOQfJpO6hT/HFDFGjoAAAFX; + x=188000; y=76000; + li:objects { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAFY; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + li:connect { + {1:GND} + } + role=symbol + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + sym-license-dist=GPLv2+ + sym-license-use=Public Domain + sym-source=sch-rnd default symbol lib + } + } + ha:group.77 { + uuid=iNOQfJpO6hT/HFDFGjoAAAFb; + li:objects { + ha:line.1 { x1=192000; y1=80000; x2=188000; y2=80000; stroke=wire; } + ha:line.2 { x1=188000; y1=80000; x2=188000; y2=76000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.78 { + li:conn { + /2/77/1 + /2/63/2/1 + } + } + ha:connection.79 { + li:conn { + /2/77/2 + /2/75/1/1 + } + } + ha:group.80 { + uuid=iNOQfJpO6hT/HFDFGjoAAAFc; + li:objects { + ha:line.1 { x1=192000; y1=88000; x2=188000; y2=88000; stroke=wire; } + ha:line.2 { x1=188000; y1=88000; x2=188000; y2=92000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.81 { + li:conn { + /2/80/1 + /2/63/4/1 + } + } + ha:line.93 { x1=24000; y1=84000; x2=28000; y2=84000; stroke=wire; } + ha:group.95 { + uuid=iNOQfJpO6hT/HFDFGjoAAAFf; + x=20000; y=76000; mirx=1; + li:objects { + ha:text.1 { x1=10000; y1=-4000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:group.2 { + uuid=iNOQfJpO6hT/HFDFGjoAAAFg; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:group.3 { + uuid=iNOQfJpO6hT/HFDFGjoAAAFh; + x=0; y=4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.4 { + uuid=iNOQfJpO6hT/HFDFGjoAAAFi; + x=0; y=8000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + name=3 + role=terminal + } + } + ha:polygon.5 { + li:outline { + ha:line { x1=0; y1=-2000; x2=0; y2=10000; } + ha:line { x1=0; y1=10000; x2=4000; y2=10000; } + ha:line { x1=4000; y1=10000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=0; y2=-2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + name=CONN1 + role=symbol + } + } + ha:group.98 { + uuid=iNOQfJpO6hT/HFDFGjoAAAFj; + x=28000; y=72000; mirx=1; + li:objects { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAFk; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + li:connect { + {1:GND} + } + role=symbol + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + sym-license-dist=GPLv2+ + sym-license-use=Public Domain + sym-source=sch-rnd default symbol lib + } + } + ha:connection.100 { + li:conn { + /2/4/11 + /2/95/3/1 + } + } + ha:group.101 { + uuid=iNOQfJpO6hT/HFDFGjoAAAFl; + li:objects { + ha:line.1 { x1=28000; y1=84000; x2=28000; y2=88000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.103 { + uuid=iNOQfJpO6hT/HFDFGjoAAAFm; + li:objects { + ha:line.1 { x1=24000; y1=76000; x2=28000; y2=76000; stroke=wire; } + ha:line.2 { x1=28000; y1=76000; x2=28000; y2=72000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.104 { + li:conn { + /2/103/1 + /2/95/2/1 + } + } + ha:connection.105 { + li:conn { + /2/103/2 + /2/98/1/1 + } + } + ha:group.106 { + uuid=bOwQFqA7m2jl+cvU6t4AAABR; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAH; + x=88000; y=84000; + li:objects { + ha:group.1 { + uuid=bOwQFqA7m2jl+cvU6t4AAABS; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAI; + x=-20000; y=4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=in+ + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.2 { + uuid=bOwQFqA7m2jl+cvU6t4AAABT; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAJ; + x=-20000; y=-4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=in- + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:group.3 { + uuid=bOwQFqA7m2jl+cvU6t4AAABU; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAK; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=out + role=terminal + ha:spice/pinnum = { value=3; prio=31050; } + } + } + ha:line.4 { x1=-20000; y1=-8000; x2=-20000; y2=8000; stroke=sym-decor; } + ha:line.5 { x1=-20000; y1=8000; x2=-4000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=-4000; y1=0; x2=-20000; y2=-8000; stroke=sym-decor; } + ha:line.7 { x1=-18000; y1=5000; x2=-18000; y2=3000; stroke=sym-decor; } + ha:line.8 { x1=-19000; y1=4000; x2=-17000; y2=4000; stroke=sym-decor; } + ha:line.9 { x1=-19000; y1=-4000; x2=-17000; y2=-4000; stroke=sym-decor; } + ha:group.10 { + uuid=bOwQFqA7m2jl+cvU6t4AAABV; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAL; + x=-12000; y=-4000; rot=270.000000; mirx=1; miry=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=0; y1=-1000; rot=180.000000; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=V- + role=terminal + ha:spice/pinnum = { value=5; prio=31050; } + } + } + ha:group.11 { + uuid=bOwQFqA7m2jl+cvU6t4AAABW; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAM; + x=-12000; y=8000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=-4000; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=V+ + role=terminal + ha:spice/pinnum = { value=4; prio=31050; } + } + } + ha:text.12 { x1=-21000; y1=9000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:text.13 { x1=-21000; y1=12000; dyntext=1; stroke=sym-secondary; text=%../A.-slot%; floater=1; } + } + ha:attrib { + -slot=1 + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + devmap=lm358_so8 + name=U1 + role=symbol + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + sym-license-dist=GPLv2+ + sym-license-use=Public Domain + sym-source=sch-rnd default symbol lib + } + } + ha:connection.107 { + li:conn { + /2/106/1/1 + /2/18/1 + } + } + ha:connection.108 { + li:conn { + /2/106/2/1 + /2/4/11 + } + } + ha:connection.109 { + li:conn { + /2/106/3/1 + /2/4/9 + } + } + ha:connection.110 { + li:conn { + /2/106/10/1 + /2/14/1 + } + } + ha:connection.111 { + li:conn { + /2/106/11/1 + /2/10/1 + } + } + ha:group.112 { + uuid=bOwQFqA7m2jl+cvU6t4AAABX; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAH; + x=168000; y=84000; + li:objects { + ha:group.1 { + uuid=bOwQFqA7m2jl+cvU6t4AAABY; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAI; + x=-20000; y=4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=in+ + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.2 { + uuid=bOwQFqA7m2jl+cvU6t4AAABZ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAJ; + x=-20000; y=-4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=in- + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:group.3 { + uuid=bOwQFqA7m2jl+cvU6t4AAABa; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAK; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=out + role=terminal + ha:spice/pinnum = { value=3; prio=31050; } + } + } + ha:line.4 { x1=-20000; y1=-8000; x2=-20000; y2=8000; stroke=sym-decor; } + ha:line.5 { x1=-20000; y1=8000; x2=-4000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=-4000; y1=0; x2=-20000; y2=-8000; stroke=sym-decor; } + ha:line.7 { x1=-18000; y1=5000; x2=-18000; y2=3000; stroke=sym-decor; } + ha:line.8 { x1=-19000; y1=4000; x2=-17000; y2=4000; stroke=sym-decor; } + ha:line.9 { x1=-19000; y1=-4000; x2=-17000; y2=-4000; stroke=sym-decor; } + ha:group.10 { + uuid=bOwQFqA7m2jl+cvU6t4AAABb; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAL; + x=-12000; y=-4000; rot=270.000000; mirx=1; miry=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=0; y1=-1000; rot=180.000000; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=V- + role=terminal + ha:spice/pinnum = { value=5; prio=31050; } + } + } + ha:group.11 { + uuid=bOwQFqA7m2jl+cvU6t4AAABc; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAM; + x=-12000; y=8000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=-4000; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=V+ + role=terminal + ha:spice/pinnum = { value=4; prio=31050; } + } + } + ha:text.12 { x1=-21000; y1=9000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:text.13 { x1=-21000; y1=12000; dyntext=1; stroke=sym-secondary; text=%../A.-slot%; floater=1; } + } + ha:attrib { + -slot=2 + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + devmap=lm358_so8 + name=U1 + role=symbol + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + sym-license-dist=GPLv2+ + sym-license-use=Public Domain + sym-source=sch-rnd default symbol lib + } + } + ha:connection.113 { + li:conn { + /2/112/1/1 + /2/38/1 + } + } + ha:connection.114 { + li:conn { + /2/112/2/1 + /2/67/7 + } + } + ha:connection.115 { + li:conn { + /2/112/3/1 + /2/67/12 + } + } + ha:group.116 { + uuid=bOwQFqA7m2jl+cvU6t4AAABh; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB6; + x=28000; y=88000; + li:objects { + ha:group.1 { + uuid=bOwQFqA7m2jl+cvU6t4AAABi; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB7; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-4000; y1=4000; x2=4000; y2=7000; halign=center; dyntext=0; stroke=sym-primary; text=Vcc; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:Vcc} + } + role=symbol + } + } + ha:connection.117 { + li:conn { + /2/116/1/1 + /2/101/1 + } + } + ha:group.118 { + uuid=bOwQFqA7m2jl+cvU6t4AAABj; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB6; + x=76000; y=100000; + li:objects { + ha:group.1 { + uuid=bOwQFqA7m2jl+cvU6t4AAABk; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB7; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-4000; y1=4000; x2=4000; y2=7000; halign=center; dyntext=0; stroke=sym-primary; text=Vcc; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:Vcc} + } + role=symbol + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + sym-license-dist=GPLv2+ + sym-license-use=Public Domain + sym-source=sch-rnd default symbol lib + } + } + ha:connection.119 { + li:conn { + /2/118/1/1 + /2/10/1 + } + } + ha:group.120 { + uuid=bOwQFqA7m2jl+cvU6t4AAABl; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB6; + x=128000; y=124000; + li:objects { + ha:group.1 { + uuid=bOwQFqA7m2jl+cvU6t4AAABm; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB7; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-4000; y1=4000; x2=4000; y2=7000; halign=center; dyntext=0; stroke=sym-primary; text=Vcc; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:Vcc} + } + role=symbol + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + sym-license-dist=GPLv2+ + sym-license-use=Public Domain + sym-source=sch-rnd default symbol lib + } + } + ha:connection.121 { + li:conn { + /2/120/1/1 + /2/60/1 + } + } + ha:group.122 { + uuid=bOwQFqA7m2jl+cvU6t4AAABn; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB6; + x=188000; y=92000; + li:objects { + ha:group.1 { + uuid=bOwQFqA7m2jl+cvU6t4AAABo; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB7; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-4000; y1=4000; x2=4000; y2=7000; halign=center; dyntext=0; stroke=sym-primary; text=Vcc; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:Vcc} + } + role=symbol + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + sym-license-dist=GPLv2+ + sym-license-use=Public Domain + sym-source=sch-rnd default symbol lib + } + } + ha:connection.123 { + li:conn { + /2/122/1/1 + /2/80/2 + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer=Tibor 'Igor2' Palinkas + page=1 of 1 + print_page=A/4 + title=Slot + devmap example + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 1 + grid = 2.0480 mm + } + } + } +} Index: tags/1.0.5/doc/examples/slot2.rs =================================================================== --- tags/1.0.5/doc/examples/slot2.rs (nonexistent) +++ tags/1.0.5/doc/examples/slot2.rs (revision 10414) @@ -0,0 +1,1018 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=iNOQfJpO6hT/HFDFGjoAAAFn; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAFo; + li:objects { + ha:polygon.11 { + li:outline { + ha:line { x1=0; y1=0; x2=80000; y2=0; } + ha:line { x1=80000; y1=0; x2=80000; y2=20000; } + ha:line { x1=80000; y1=20000; x2=0; y2=20000; } + ha:line { x1=0; y1=20000; x2=0; y2=0; } + } + stroke=titlebox-frame; + fill=titlebox-fill; + } + ha:line.12 { x1=0; y1=10000; x2=80000; y2=10000; stroke=titlebox-frame; } + ha:line.13 { x1=40000; y1=10000; x2=40000; y2=0; stroke=titlebox-frame; } + ha:text.20 { x1=1000; y1=16500; dyntext=0; stroke=titlebox-big; text=TITLE; } + ha:text.21 { x1=1000; y1=10500; x2=79000; y2=16000; dyntext=1; stroke=titlebox-big; text=%../../A.title%; } + ha:text.22 { x1=1000; y1=5500; dyntext=0; stroke=titlebox-small; text={PROJECT:}; } + ha:text.23 { x1=13000; y1=5500; x2=39000; y2=9500; dyntext=1; stroke=titlebox-big; text=%project.name%; } + ha:text.24 { x1=1000; y1=500; dyntext=0; stroke=titlebox-small; text={PAGE:}; } + ha:text.25 { x1=10000; y1=500; x2=39000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.page%; } + ha:text.26 { x1=41000; y1=5500; dyntext=0; stroke=titlebox-small; text={FILE:}; } + ha:text.27 { x1=48000; y1=5500; x2=79000; y2=9500; dyntext=1; stroke=titlebox-big; text=%filename%; } + ha:text.28 { x1=41000; y1=500; dyntext=0; stroke=titlebox-small; text={MAINTAINER:}; } + ha:text.29 { x1=55000; y1=500; x2=79000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.maintainer%; } + } + ha:attrib { + purpose=titlebox + } + } + ha:group.2 { + uuid=iNOQfJpO6hT/HFDFGjoAAAFp; + x=104000; y=112000; + li:objects { + ha:text.1 { x1=-8000; y1=28000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.2 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=16000; } + ha:line { x1=0; y1=16000; x2=16000; y2=16000; } + ha:line { x1=16000; y1=16000; x2=16000; y2=0; } + ha:line { x1=16000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + } + ha:group.3 { + uuid=iNOQfJpO6hT/HFDFGjoAAAFq; + x=0; y=12000; + li:objects { + ha:polygon.1 { + li:outline { + ha:line { x1=1000; y1=0; x2=0; y2=1000; } + ha:line { x1=0; y1=1000; x2=0; y2=-1000; } + ha:line { x1=0; y1=-1000; x2=1000; y2=0; } + } + stroke=sym-decor; + } + ha:line.2 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.3 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; floater=1; } + ha:text.4 { x1=1000; y1=-2000; dyntext=1; stroke=term-secondary; text=%../A.name%; floater=1; } + } + ha:attrib { + name=A + pinnum=1 + role=terminal + } + } + ha:group.4 { + uuid=iNOQfJpO6hT/HFDFGjoAAAFr; + x=0; y=4000; + li:objects { + ha:polygon.1 { + li:outline { + ha:line { x1=1000; y1=0; x2=0; y2=1000; } + ha:line { x1=0; y1=1000; x2=0; y2=-1000; } + ha:line { x1=0; y1=-1000; x2=1000; y2=0; } + } + stroke=sym-decor; + } + ha:line.2 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.3 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; floater=1; } + ha:text.4 { x1=1000; y1=-2000; dyntext=1; stroke=term-secondary; text=%../A.name%; floater=1; } + } + ha:attrib { + name=B + pinnum=2 + role=terminal + } + } + ha:group.5 { + uuid=iNOQfJpO6hT/HFDFGjoAAAFs; + x=16000; y=8000; mirx=1; + li:objects { + ha:arc.1 { cx=-500; cy=0; r=500; sang=0.000000; dang=360.000000; stroke=term-decor; } + ha:polygon.2 { + li:outline { + ha:line { x1=0; y1=0; x2=1000; y2=1000; } + ha:line { x1=1000; y1=1000; x2=1000; y2=-1000; } + ha:line { x1=1000; y1=-1000; x2=0; y2=0; } + } + stroke=sym-decor; + } + ha:line.3 { x1=-1000; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.4 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; floater=1; } + ha:text.5 { x1=1000; y1=-2000; dyntext=1; stroke=term-secondary; text=%../A.name%; floater=1; } + } + ha:attrib { + name=Z + pinnum=3 + role=terminal + } + } + ha:text.6 { x1=-8000; y1=24000; dyntext=1; stroke=sym-secondary; text={slot=%../A.-slot%}; floater=1; } + ha:text.7 { x1=-8000; y1=20000; dyntext=1; stroke=sym-secondary; text=%../A.device%; floater=1; } + } + ha:attrib { + device=7400 + name=U1 + li:portmap { + {1/A -> pcb/pinnum=1} + {2/A -> pcb/pinnum=4} + {3/A -> pcb/pinnum=9} + {4/A -> pcb/pinnum=12} + {1/B -> pcb/pinnum=2} + {2/B -> pcb/pinnum=5} + {3/B -> pcb/pinnum=10} + {4/B -> pcb/pinnum=13} + {1/Z -> pcb/pinnum=3} + {2/Z -> pcb/pinnum=6} + {3/Z -> pcb/pinnum=8} + {4/Z -> pcb/pinnum=11} + } + role=symbol + -slot=1 + symbol_generator=boxsym-rnd + } + } + ha:group.3 { + uuid=iNOQfJpO6hT/HFDFGjoAAAFt; + x=136000; y=160000; + li:objects { + ha:text.1 { x1=9000; y1=10000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.2 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=24000; } + ha:line { x1=0; y1=24000; x2=8000; y2=24000; } + ha:line { x1=8000; y1=24000; x2=8000; y2=0; } + ha:line { x1=8000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + } + ha:group.3 { + uuid=iNOQfJpO6hT/HFDFGjoAAAFu; + x=4000; y=24000; rot=90.000000; miry=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; floater=1; } + ha:text.3 { x1=0; y1=-2000; dyntext=1; stroke=term-secondary; text=%../A.name%; floater=1; } + } + ha:attrib { + name=Vcc + pinnum=14 + role=terminal + } + } + ha:group.4 { + uuid=iNOQfJpO6hT/HFDFGjoAAAFv; + x=4000; y=0; rot=-90.000000; miry=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; floater=1; } + ha:text.3 { x1=0; y1=-2000; dyntext=1; stroke=term-secondary; text=%../A.name%; floater=1; } + } + ha:attrib { + name=gnd + pinnum=7 + role=terminal + } + } + } + ha:attrib { + name=U1 + role=symbol + symbol_generator=boxsym-rnd + } + } + ha:group.4 { + uuid=iNOQfJpO6hT/HFDFGjoAAAFw; + x=104000; y=64000; + li:objects { + ha:text.1 { x1=-8000; y1=-4000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.2 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=16000; } + ha:line { x1=0; y1=16000; x2=16000; y2=16000; } + ha:line { x1=16000; y1=16000; x2=16000; y2=0; } + ha:line { x1=16000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + } + ha:group.3 { + uuid=iNOQfJpO6hT/HFDFGjoAAAFx; + x=0; y=12000; + li:objects { + ha:polygon.1 { + li:outline { + ha:line { x1=1000; y1=0; x2=0; y2=1000; } + ha:line { x1=0; y1=1000; x2=0; y2=-1000; } + ha:line { x1=0; y1=-1000; x2=1000; y2=0; } + } + stroke=sym-decor; + } + ha:line.2 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.3 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; floater=1; } + ha:text.4 { x1=1000; y1=-2000; dyntext=1; stroke=term-secondary; text=%../A.name%; floater=1; } + } + ha:attrib { + name=A + pinnum=1 + role=terminal + } + } + ha:group.4 { + uuid=iNOQfJpO6hT/HFDFGjoAAAFy; + x=0; y=4000; + li:objects { + ha:polygon.1 { + li:outline { + ha:line { x1=1000; y1=0; x2=0; y2=1000; } + ha:line { x1=0; y1=1000; x2=0; y2=-1000; } + ha:line { x1=0; y1=-1000; x2=1000; y2=0; } + } + stroke=sym-decor; + } + ha:line.2 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.3 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; floater=1; } + ha:text.4 { x1=1000; y1=-2000; dyntext=1; stroke=term-secondary; text=%../A.name%; floater=1; } + } + ha:attrib { + name=B + pinnum=2 + role=terminal + } + } + ha:group.5 { + uuid=iNOQfJpO6hT/HFDFGjoAAAFz; + x=16000; y=8000; mirx=1; + li:objects { + ha:arc.1 { cx=-500; cy=0; r=500; sang=0.000000; dang=360.000000; stroke=term-decor; } + ha:polygon.2 { + li:outline { + ha:line { x1=0; y1=0; x2=1000; y2=1000; } + ha:line { x1=1000; y1=1000; x2=1000; y2=-1000; } + ha:line { x1=1000; y1=-1000; x2=0; y2=0; } + } + stroke=sym-decor; + } + ha:line.3 { x1=-1000; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.4 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; floater=1; } + ha:text.5 { x1=1000; y1=-2000; dyntext=1; stroke=term-secondary; text=%../A.name%; floater=1; } + } + ha:attrib { + name=Z + pinnum=3 + role=terminal + } + } + ha:text.6 { x1=-8000; y1=-8000; dyntext=1; stroke=sym-secondary; text={slot=%../A.-slot%}; floater=1; } + ha:text.7 { x1=-8000; y1=-12000; dyntext=1; stroke=sym-secondary; text=%../A.device%; floater=1; } + } + ha:attrib { + device=7400 + name=U1 + role=symbol + -slot=2 + symbol_generator=boxsym-rnd + } + } + ha:group.5 { + uuid=iNOQfJpO6hT/HFDFGjoAAAF0; + x=160000; y=108000; + li:objects { + ha:text.1 { x1=-8000; y1=28000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.2 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=16000; } + ha:line { x1=0; y1=16000; x2=16000; y2=16000; } + ha:line { x1=16000; y1=16000; x2=16000; y2=0; } + ha:line { x1=16000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + } + ha:group.3 { + uuid=iNOQfJpO6hT/HFDFGjoAAAF1; + x=0; y=12000; + li:objects { + ha:polygon.1 { + li:outline { + ha:line { x1=1000; y1=0; x2=0; y2=1000; } + ha:line { x1=0; y1=1000; x2=0; y2=-1000; } + ha:line { x1=0; y1=-1000; x2=1000; y2=0; } + } + stroke=sym-decor; + } + ha:line.2 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.3 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; floater=1; } + ha:text.4 { x1=1000; y1=-2000; dyntext=1; stroke=term-secondary; text=%../A.name%; floater=1; } + } + ha:attrib { + name=A + pinnum=1 + role=terminal + } + } + ha:group.4 { + uuid=iNOQfJpO6hT/HFDFGjoAAAF2; + x=0; y=4000; + li:objects { + ha:polygon.1 { + li:outline { + ha:line { x1=1000; y1=0; x2=0; y2=1000; } + ha:line { x1=0; y1=1000; x2=0; y2=-1000; } + ha:line { x1=0; y1=-1000; x2=1000; y2=0; } + } + stroke=sym-decor; + } + ha:line.2 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.3 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; floater=1; } + ha:text.4 { x1=1000; y1=-2000; dyntext=1; stroke=term-secondary; text=%../A.name%; floater=1; } + } + ha:attrib { + name=B + pinnum=2 + role=terminal + } + } + ha:group.5 { + uuid=iNOQfJpO6hT/HFDFGjoAAAF3; + x=16000; y=8000; mirx=1; + li:objects { + ha:arc.1 { cx=-500; cy=0; r=500; sang=0.000000; dang=360.000000; stroke=term-decor; } + ha:polygon.2 { + li:outline { + ha:line { x1=0; y1=0; x2=1000; y2=1000; } + ha:line { x1=1000; y1=1000; x2=1000; y2=-1000; } + ha:line { x1=1000; y1=-1000; x2=0; y2=0; } + } + stroke=sym-decor; + } + ha:line.3 { x1=-1000; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.4 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; floater=1; } + ha:text.5 { x1=1000; y1=-2000; dyntext=1; stroke=term-secondary; text=%../A.name%; floater=1; } + } + ha:attrib { + name=Z + pinnum=3 + role=terminal + } + } + ha:text.6 { x1=-8000; y1=24000; dyntext=1; stroke=sym-secondary; text={slot=%../A.-slot%}; floater=1; } + ha:text.7 { x1=-8000; y1=20000; dyntext=1; stroke=sym-secondary; text=%../A.device%; floater=1; } + } + ha:attrib { + device=7400 + name=U1 + role=symbol + -slot=3 + symbol_generator=boxsym-rnd + } + } + ha:group.6 { + uuid=iNOQfJpO6hT/HFDFGjoAAAF4; + x=160000; y=68000; + li:objects { + ha:text.1 { x1=-8000; y1=-4000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.2 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=16000; } + ha:line { x1=0; y1=16000; x2=16000; y2=16000; } + ha:line { x1=16000; y1=16000; x2=16000; y2=0; } + ha:line { x1=16000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + } + ha:group.3 { + uuid=iNOQfJpO6hT/HFDFGjoAAAF5; + x=0; y=12000; + li:objects { + ha:polygon.1 { + li:outline { + ha:line { x1=1000; y1=0; x2=0; y2=1000; } + ha:line { x1=0; y1=1000; x2=0; y2=-1000; } + ha:line { x1=0; y1=-1000; x2=1000; y2=0; } + } + stroke=sym-decor; + } + ha:line.2 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.3 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; floater=1; } + ha:text.4 { x1=1000; y1=-2000; dyntext=1; stroke=term-secondary; text=%../A.name%; floater=1; } + } + ha:attrib { + name=A + pinnum=1 + role=terminal + } + } + ha:group.4 { + uuid=iNOQfJpO6hT/HFDFGjoAAAF6; + x=0; y=4000; + li:objects { + ha:polygon.1 { + li:outline { + ha:line { x1=1000; y1=0; x2=0; y2=1000; } + ha:line { x1=0; y1=1000; x2=0; y2=-1000; } + ha:line { x1=0; y1=-1000; x2=1000; y2=0; } + } + stroke=sym-decor; + } + ha:line.2 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.3 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; floater=1; } + ha:text.4 { x1=1000; y1=-2000; dyntext=1; stroke=term-secondary; text=%../A.name%; floater=1; } + } + ha:attrib { + name=B + pinnum=2 + role=terminal + } + } + ha:group.5 { + uuid=iNOQfJpO6hT/HFDFGjoAAAF7; + x=16000; y=8000; mirx=1; + li:objects { + ha:arc.1 { cx=-500; cy=0; r=500; sang=0.000000; dang=360.000000; stroke=term-decor; } + ha:polygon.2 { + li:outline { + ha:line { x1=0; y1=0; x2=1000; y2=1000; } + ha:line { x1=1000; y1=1000; x2=1000; y2=-1000; } + ha:line { x1=1000; y1=-1000; x2=0; y2=0; } + } + stroke=sym-decor; + } + ha:line.3 { x1=-1000; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.4 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; floater=1; } + ha:text.5 { x1=1000; y1=-2000; dyntext=1; stroke=term-secondary; text=%../A.name%; floater=1; } + } + ha:attrib { + name=Z + pinnum=3 + role=terminal + } + } + ha:text.6 { x1=-8000; y1=-8000; dyntext=1; stroke=sym-secondary; text={slot=%../A.-slot%}; floater=1; } + ha:text.7 { x1=-8000; y1=-12000; dyntext=1; stroke=sym-secondary; text=%../A.device%; floater=1; } + } + ha:attrib { + device=7400 + name=U1 + role=symbol + -slot=4 + symbol_generator=boxsym-rnd + } + } + ha:group.7 { + uuid=iNOQfJpO6hT/HFDFGjoAAAF8; + li:objects { + ha:line.1 { x1=124000; y1=72000; x2=156000; y2=72000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.8 { + li:conn { + /2/7/1 + /2/6/4/2 + } + } + ha:connection.9 { + li:conn { + /2/7/1 + /2/4/5/3 + } + } + ha:group.10 { + uuid=iNOQfJpO6hT/HFDFGjoAAAF9; + li:objects { + ha:line.1 { x1=124000; y1=120000; x2=156000; y2=120000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.11 { + li:conn { + /2/10/1 + /2/2/5/3 + } + } + ha:connection.12 { + li:conn { + /2/10/1 + /2/5/3/2 + } + } + ha:group.13 { + uuid=iNOQfJpO6hT/HFDFGjoAAAF+; + li:objects { + ha:line.1 { x1=100000; y1=116000; x2=88000; y2=116000; stroke=wire; } + ha:line.3 { x1=88000; y1=76000; x2=88000; y2=116000; stroke=wire; } + ha:line.4 { x1=88000; y1=76000; x2=100000; y2=76000; stroke=wire; } + ha:line.5 { x1=60000; y1=96000; x2=88000; y2=96000; stroke=wire; } + ha:line.6 { x1=88000; y1=96000; x2=88000; y2=96000; stroke=junction; } + ha:text.7 { x1=80000; y1=96000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=clk + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.14 { + li:conn { + /2/13/1 + /2/2/4/2 + } + } + ha:connection.15 { + li:conn { + /2/13/4 + /2/4/3/2 + } + } + ha:group.20 { + uuid=iNOQfJpO6hT/HFDFGjoAAAF/; + li:objects { + ha:line.2 { x1=192000; y1=76000; x2=192000; y2=92000; stroke=wire; } + ha:line.3 { x1=192000; y1=92000; x2=144000; y2=100000; stroke=wire; } + ha:line.4 { x1=156000; y1=112000; x2=144000; y2=112000; stroke=wire; } + ha:line.5 { x1=144000; y1=100000; x2=144000; y2=112000; stroke=wire; } + ha:line.6 { x1=180000; y1=76000; x2=216000; y2=76000; stroke=wire; } + ha:line.7 { x1=192000; y1=76000; x2=192000; y2=76000; stroke=junction; } + ha:line.8 { x1=216000; y1=76000; x2=216000; y2=96000; stroke=wire; } + ha:line.9 { x1=216000; y1=96000; x2=220000; y2=96000; stroke=wire; } + ha:text.10 { x1=204000; y1=77000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=Q' + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.21 { + li:conn { + /2/6/5/3 + /2/20/6 + } + } + ha:group.22 { + uuid=iNOQfJpO6hT/HFDFGjoAAAGA; + li:objects { + ha:line.4 { x1=192000; y1=100000; x2=192000; y2=116000; stroke=wire; } + ha:line.5 { x1=192000; y1=100000; x2=144000; y2=92000; stroke=wire; } + ha:line.6 { x1=156000; y1=80000; x2=144000; y2=80000; stroke=wire; } + ha:line.7 { x1=144000; y1=80000; x2=144000; y2=92000; stroke=wire; } + ha:line.9 { x1=192000; y1=116000; x2=192000; y2=116000; stroke=junction; } + ha:line.10 { x1=180000; y1=116000; x2=216000; y2=116000; stroke=wire; } + ha:line.11 { x1=216000; y1=116000; x2=216000; y2=100000; stroke=wire; } + ha:line.12 { x1=216000; y1=100000; x2=220000; y2=100000; stroke=wire; } + ha:text.13 { x1=204000; y1=117000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=Q + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.23 { + li:conn { + /2/5/5/3 + /2/22/10 + } + } + ha:connection.24 { + li:conn { + /2/22/6 + /2/6/3/2 + } + } + ha:connection.25 { + li:conn { + /2/20/4 + /2/5/4/2 + } + } + ha:group.28 { + uuid=iNOQfJpO6hT/HFDFGjoAAAGB; + li:objects { + ha:line.1 { x1=100000; y1=68000; x2=68000; y2=68000; stroke=wire; } + ha:line.2 { x1=68000; y1=68000; x2=68000; y2=92000; stroke=wire; } + ha:line.3 { x1=68000; y1=92000; x2=60000; y2=92000; stroke=wire; } + ha:text.4 { x1=80000; y1=68000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=R + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.29 { + li:conn { + /2/28/1 + /2/4/4/2 + } + } + ha:group.30 { + uuid=iNOQfJpO6hT/HFDFGjoAAAGC; + x=140000; y=148000; + li:objects { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAGD; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + li:connect { + {1:GND} + } + role=symbol + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + sym-license-dist=GPLv2+ + sym-license-use=Public Domain + sym-source=sch-rnd default symbol lib + } + } + ha:group.31 { + uuid=iNOQfJpO6hT/HFDFGjoAAAGE; + x=140000; y=192000; + li:objects { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAGF; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-4000; y1=4000; dyntext=0; stroke=sym-primary; text=Vcc; } + } + ha:attrib { + li:connect { + {1:Vcc} + } + role=symbol + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + sym-license-dist=GPLv2+ + sym-license-use=Public Domain + sym-source=sch-rnd default symbol lib + } + } + ha:group.38 { + uuid=iNOQfJpO6hT/HFDFGjoAAAGG; + x=120000; y=168000; mirx=1; + li:objects { + ha:text.1 { x1=6000; y1=12000; rot=270.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:group.2 { + uuid=iNOQfJpO6hT/HFDFGjoAAAGH; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:group.3 { + uuid=iNOQfJpO6hT/HFDFGjoAAAGI; + x=0; y=4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:polygon.4 { + li:outline { + ha:line { x1=0; y1=-2000; x2=0; y2=6000; } + ha:line { x1=0; y1=6000; x2=4000; y2=6000; } + ha:line { x1=4000; y1=6000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=0; y2=-2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + name=CONN3 + role=symbol + } + } + ha:group.39 { + uuid=iNOQfJpO6hT/HFDFGjoAAAGJ; + x=224000; y=96000; + li:objects { + ha:text.1 { x1=10000; y1=-8000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:group.2 { + uuid=iNOQfJpO6hT/HFDFGjoAAAGK; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:group.3 { + uuid=iNOQfJpO6hT/HFDFGjoAAAGL; + x=0; y=4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:polygon.4 { + li:outline { + ha:line { x1=0; y1=-2000; x2=0; y2=6000; } + ha:line { x1=0; y1=6000; x2=4000; y2=6000; } + ha:line { x1=4000; y1=6000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=0; y2=-2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + name=CONN2 + role=symbol + } + } + ha:group.40 { + uuid=iNOQfJpO6hT/HFDFGjoAAAGM; + x=56000; y=92000; mirx=1; + li:objects { + ha:text.1 { x1=6000; y1=12000; rot=270.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:group.2 { + uuid=iNOQfJpO6hT/HFDFGjoAAAGN; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:group.3 { + uuid=iNOQfJpO6hT/HFDFGjoAAAGO; + x=0; y=4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.4 { + uuid=iNOQfJpO6hT/HFDFGjoAAAGP; + x=0; y=8000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + name=3 + role=terminal + } + } + ha:polygon.5 { + li:outline { + ha:line { x1=0; y1=-2000; x2=0; y2=10000; } + ha:line { x1=0; y1=10000; x2=4000; y2=10000; } + ha:line { x1=4000; y1=10000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=0; y2=-2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + name=CONN1 + role=symbol + } + } + ha:connection.41 { + li:conn { + /2/20/9 + /2/39/2/1 + } + } + ha:connection.42 { + li:conn { + /2/39/3/1 + /2/22/12 + } + } + ha:connection.43 { + li:conn { + /2/28/3 + /2/40/2/1 + } + } + ha:group.44 { + uuid=iNOQfJpO6hT/HFDFGjoAAAGQ; + li:objects { + ha:line.1 { x1=60000; y1=100000; x2=68000; y2=100000; stroke=wire; } + ha:line.2 { x1=100000; y1=124000; x2=68000; y2=124000; stroke=wire; } + ha:line.3 { x1=68000; y1=100000; x2=68000; y2=124000; stroke=wire; } + ha:text.4 { x1=80000; y1=124000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=S + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.45 { + li:conn { + /2/44/1 + /2/40/4/1 + } + } + ha:connection.46 { + li:conn { + /2/44/2 + /2/2/3/2 + } + } + ha:connection.47 { + li:conn { + /2/13/5 + /2/40/3/1 + } + } + ha:group.72 { + uuid=iNOQfJpO6hT/HFDFGjoAAAGR; + x=164000; y=180000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAGS; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=iNOQfJpO6hT/HFDFGjoAAAGT; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.5 { x1=9000; y1=5000; x2=9000; y2=-5000; stroke=sym-decor; } + ha:line.6 { x1=11000; y1=5000; x2=11000; y2=-5000; stroke=sym-decor; } + ha:line.7 { x1=4000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.8 { x1=11000; y1=0; x2=16000; y2=0; stroke=sym-decor; } + } + ha:attrib { + name=C1 + role=symbol + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + sym-license-dist=GPLv2+ + sym-license-use=Public Domain + sym-source=sch-rnd default symbol lib + value=100n + } + } + ha:group.77 { + uuid=iNOQfJpO6hT/HFDFGjoAAAGU; + li:objects { + ha:line.1 { x1=129000; y1=153000; x2=140000; y2=153000; stroke=wire; } + ha:line.2 { x1=140000; y1=153000; x2=140000; y2=154000; stroke=wire; } + ha:line.3 { x1=140000; y1=148000; x2=140000; y2=156000; stroke=wire; } + ha:line.4 { x1=140000; y1=153000; x2=164000; y2=153000; stroke=wire; } + ha:line.5 { x1=129000; y1=168000; x2=129000; y2=153000; stroke=wire; } + ha:line.6 { x1=164000; y1=153000; x2=164000; y2=160000; stroke=wire; } + ha:line.7 { x1=124000; y1=168000; x2=129000; y2=168000; stroke=wire; } + ha:line.8 { x1=140000; y1=153000; x2=140000; y2=153000; stroke=junction; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.78 { + li:conn { + /2/77/3 + /2/30/1/1 + } + } + ha:connection.79 { + li:conn { + /2/77/3 + /2/3/4/1 + } + } + ha:connection.80 { + li:conn { + /2/77/6 + /2/72/1/1 + } + } + ha:connection.81 { + li:conn { + /2/77/7 + /2/38/2/1 + } + } + ha:group.83 { + uuid=iNOQfJpO6hT/HFDFGjoAAAGV; + li:objects { + ha:line.1 { x1=140000; y1=189000; x2=140000; y2=189000; stroke=junction; } + ha:line.2 { x1=129000; y1=172000; x2=129000; y2=189000; stroke=wire; } + ha:line.3 { x1=140000; y1=188000; x2=140000; y2=192000; stroke=wire; } + ha:line.4 { x1=124000; y1=172000; x2=129000; y2=172000; stroke=wire; } + ha:line.5 { x1=129000; y1=189000; x2=164000; y2=189000; stroke=wire; } + ha:line.6 { x1=164000; y1=189000; x2=164000; y2=180000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.84 { + li:conn { + /2/83/3 + /2/3/3/1 + } + } + ha:connection.85 { + li:conn { + /2/83/3 + /2/31/1/1 + } + } + ha:connection.86 { + li:conn { + /2/83/4 + /2/38/3/1 + } + } + ha:connection.88 { + li:conn { + /2/83/6 + /2/72/2/1 + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer=Tibor 'Igor2' Palinkas + page=1 of 1 + print_page=A/4 + title=inhomogeneous slot example + } + } +} Index: tags/1.0.5/doc/help.html =================================================================== --- tags/1.0.5/doc/help.html (nonexistent) +++ tags/1.0.5/doc/help.html (revision 10414) @@ -0,0 +1,61 @@ + + + + sch-rnd - help wanted + + + + + + + + + + +
Main + Doc &  Knowledge pool  &  Tutorial + Current state + Events & timeline + sch-rnd [sch-rnd logo] +
+ + +

sch-rnd - help wanted

+The project is looking for volunteers for the features listed below. If +you want to contribute, you will need to have an svn client and an email +client. Furthermore an IRC client is strongly recommended. +

+You will become part of the team and get svn commit right immediately +when you start working. +

+Don't have much free time? Don't worry: the tasks below are split up in +very small (1..2 hours) chunks. Coordination is granted, the administrative +overhead is almost zero - you can focus on the task, and finish it whenever +you have a free hour. +

+Worrying about your contribution to go in /dev/null? Don't: sch-rnd +has very short loops; you start contributing and get immediate feedback. Your +work is part of the official thing immediately and revised and accepted (or +rarely refused) within hours or at most days. +There are no bitrotting branches. +

+You are not confident enough with your skills? sch-rnd is an optimal +project for learning. If you start contributing, you get support. There +are small and simple entry level tasks. Most of the tasks don't require +any programming skills. +

+Sign up by contacting the lead developer +If you want to work on a feature not listed below, feel free to drop me +a mail. +

+ +
ID skill required description +
CUCP user or dev CUCP is a flexible system for small chunks of regular contribution - pick this if you have only 1..4 hours a week for contributing; anything else below takes more time. +
doc user, html write sections of user documentation (generic) +
atest C/beginner program automated test cases +
rosetta scripting port example scripts to your favorite language (more details) +
actionw C action wrapper programming (more details) + +
+ + Index: tags/1.0.5/doc/index.html =================================================================== --- tags/1.0.5/doc/index.html (nonexistent) +++ tags/1.0.5/doc/index.html (revision 10414) @@ -0,0 +1,115 @@ + + + + sch-rnd - About + + + + + + + + + + +
Main + Doc &  Knowledge pool  &  Tutorial + Current state + Events & timeline + sch-rnd [sch-rnd logo] +
+ + +
+ + +
+

Summary

+ +
+
[sch-rnd logo]sch-rnd
+ +
+ is a simple, modular, scriptable schematics editor. +

can be used as a stand-alone schematics capture tool +

but also fits nicely in the Ringdove EDA suite +

is workflow-agnostic +

is set up in a similar manner as pcb-rnd +

is easy and fast to compile, edit and contribute to + +

+
[cschem] cschem
+ +
+ is the name of the data model that sch-rnd implements. +

cschem specification is kept generic so that other, independent implementations could be based on it. + +

Version Control svn://svn.repo.hu/sch-rnd/trunk   (mirrors) +
Download source releases | binary releases (windows) +
Comments, feedback, patches live chat with the developer
or contact the lead developer
Mailing list: pcb-rnd list.repo.hu (send a mail with subject: subscribe; does not work with gmail) (archives) (privacy policy) +
Contribution and support + How to join or contribute +
Please test and report bugs and feature requests! +
We are looking for help and sponsoration/donation. +

A major supporter is NLnet + +

Key features + schematics capture for multisheet designs +
scriptable in 10+ different scripting languages +
parametric symbols generation +
hierarchic design (since 1.0.5) +
modular code with a flexible plugin system +
fits well in a UNIXy workflow +
supports CLI and server applications +
active development, frequent releases +
friendly and efficient developer and user community +
multiple workflows from the same sheet without modification (e.g. PCB and spice) +
circuit simulation: low level (raw SPICE); high level (integrated GUI wth plots, based on ngspice) + +
predictable development cycles +
also loads gEDA/gschem, lepton-eda, tinyCAD, altium, OrCAD files + +
Supported platforms + +
+ Linux desktop (various distributions, from source) + + +
OpenBSD (Likely: any BSD not older than 25 years) +
(Likely: any 90's or newer UNIX system with motif) +
Screen resolution as small as 800x600 +
GUI options: motif/lesstif, gtk-gdk, gtk-gl +
+ + screenshot of sch-rnd running on Devuan GNU/Linux +
+
+ + +
+ + + +

What is -rnd?

+ + +
+ +

+

RiNgDove is an EDA suite that includes: +

a PCB editor: pcb-rnd +

a PCB autorouter: route-rnd +

a CAM viewer: camv-rnd +

a software lib: librnd +

or all in one: suite +

  +

user contributed addons: edakrill +

+ + +
+ + + Index: tags/1.0.5/doc/irc.html =================================================================== --- tags/1.0.5/doc/irc.html (nonexistent) +++ tags/1.0.5/doc/irc.html (revision 10414) @@ -0,0 +1,41 @@ + + + + sch-rnd - IRC + + + + + + + + + + +
Main + Doc &  Knowledge pool  &  Tutorial + Current state + Events & timeline + sch-rnd [sch-rnd logo] +
+ + +

Live support via IRC (chat)

+
Irc server: repo.hu       Port: 6667       Channel: #pcb-rnd +
  +

I'm normally online as Igor2 between 5:00 CET and 19:00 CET; on Sunday there's an AFK-window between 11:00 CET and 16:00 CET. If I don't answer in a few minutes I'm probably away doing something, please be patient; say hi before you type your long question so you see if I'm available. +


+

+Below is an iframe of +mibbit irc client configured with the above settings. +

+Using the web client: you should change your nickname (using the +/nick myname command if you are already connected); there's no password +or registration or channel key or ssl of any form. Check mibbit's page about +their privacy policy. Connecting with the web client may take some time, give it a minute. +


+ + + + + Index: tags/1.0.5/doc/keys.html =================================================================== --- tags/1.0.5/doc/keys.html (nonexistent) +++ tags/1.0.5/doc/keys.html (revision 10414) @@ -0,0 +1,645 @@ + + + + + + Key to action bindings + + + + + +

Key to action bindings

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
key action source +
+ +Zoom In 20%
Zoom(-1.2) +
menu-default.lht +
- +Zoom Out 20%
Zoom(+1.2) +
menu-default.lht +
/ +Cycle line clip/refraction (toggle)
conf(toggle, editor/line_refraction, design) +
menu-default.lht +
: +Command Entry
Command() +
menu-default.lht +
< +Previous
SwitchRelative(-1) +
menu-default.lht +
> +Next
SwitchRelative(+1) +
menu-default.lht +
[ +Previous grid
Grid(down) +
menu-default.lht +
\ +Full screen
fullscreen(toggle) +
menu-default.lht +
] +Next grid
Grid(up) +
menu-default.lht +
a
 a
+Change name (refdes)
AttributeDialog(object, name) +
menu-default.lht +
a
 c
  
+Change connections
QuickAttr(object, connect) +
menu-default.lht +
a
 d
  
+Change devmap
QuickAttr(object, devmap) +
menu-default.lht +
a
 f
+Change footprint
AttributeDialog(object, footprint) +
menu-default.lht +
a
 n
  
+Change name
AttributeDialog(object, name) +
menu-default.lht +
a
 o
  
+Change role
QuickAttr(object, role) +
menu-default.lht +
a
 p
  
+Change portmap
QuickAttr(object, portmap) +
menu-default.lht +
a
 r
+Change name (refdes)
AttributeDialog(object, name) +
menu-default.lht +
a
 s
+Change slot num
AttributeDialog(object, -slot) +
menu-default.lht +
a
 u
  
+Change funcmap
QuickAttr(object, funcmap) +
menu-default.lht +
a
 v
+Change value
AttributeDialog(object, value) +
menu-default.lht +
b
 1
  
+Select Buffer #1
BufferSwitch(1) +
menu-default.lht +
b
 2
  
+Select Buffer #2
BufferSwitch(2) +
menu-default.lht +
b
 3
  
+Select Buffer #3
BufferSwitch(3) +
menu-default.lht +
b
 4
  
+Select Buffer #4
BufferSwitch(4) +
menu-default.lht +
b
 5
  
+Select scratchpad
BufferSwitch(5) +
menu-default.lht +
b
 c
  c
   
+Clear buffer
BufferClear() +
menu-default.lht +
b
 f
  l
   
+Load buffer content from file
BufferClear(); BufferLoad(All); Tool(buffer) +
menu-default.lht +
b
 f
  s
   
+Save buffer content to file
BufferSave(All) +
menu-default.lht +
b
 l
  s
+Load buffer symbol/group from file
BufferLoad(Symbol); Tool(buffer) +
menu-default.lht +
b
 m
  l
+Mirror buffer (left/right)
Mirror(Buffer, horizontal) +
menu-default.lht +
b
 m
  u
+Mirror buffer (up/down)
Mirror(Buffer, vertical) +
menu-default.lht +
b
 r
  a
+Arbitrarily Rotate Buffer
Rotate(Buffer, ask) +
menu-default.lht +
b
 r
  l
+Rotate buffer 90 deg CCW (left)
Rotate90(Buffer, 1) +
menu-default.lht +
b
 r
  r
+Rotate buffer 90 deg CW (right)
Rotate90(Buffer, -1) +
menu-default.lht +
b
 s
  g
+Save buffer group to file
BufferSave(Group) +
menu-default.lht +
b
 s
  s
+Save buffer symbol to file
BufferSave(Symbol) +
menu-default.lht +
c-ctrl
 
+Copy selection to buffer
GetXY(Click to set the snap point for this buffer); BufferClear(Clear); BufferCopy(); Unselect(All); Tool(buffer) +
menu-default.lht +
delete +Remove object
Tool(Save); Tool(remove); GetXY(Click on object to remove); Tool(Press); Tool(Restore) +
menu-default.lht +
e
 c
+Copy selection to buffer
GetXY(Click to set the snap point for this buffer); BufferClear(Clear); BufferCopy(); Unselect(All); Tool(buffer) +
menu-default.lht +
e
 d
+Remove object
Tool(Save); Tool(remove); GetXY(Click on object to remove); Tool(Press); Tool(Restore) +
menu-default.lht +
e
 h
+Mirror object horizontally
Mirror(auto, horizontal) +
menu-default.lht +
e
 m
  r
+Renumber symbols
RenumberDialog +
menu-default.lht +
e
 p
+Object Properties...
PropEdit(selection) +
menu-default.lht +
e
 s
+Stroke
pendialog(object) +
menu-default.lht +
e
 t
+Text string
EditText(Object) +
menu-default.lht +
e
 v
+Mirror object vertically
Mirror(auto, vertical) +
menu-default.lht +
e
 w
+Whirl object (rotate 90 deg)
Rotate90(auto) +
menu-default.lht +
e
 x
+Cut selection to buffer
GetXY(Click to set the snap point for this buffer); BufferClear(Clear); BufferCut(MoveSelected); Tool(buffer) +
menu-default.lht +
escape +Cancel
Tool(escape) +
menu-default.lht +
f1 +Circle
Tool(circle) +
menu-default.lht +
f11 +Arrow
Tool(arrow) +
menu-default.lht +
f12 +Lock
Tool(lock) +
menu-default.lht +
f2 +Wirenet
Tool(wirenet) +
menu-default.lht +
f3 +Line
Tool(line) +
menu-default.lht +
f4 +Text
Tool(text) +
menu-default.lht +
f5 +Rectangle
Tool(rect) +
menu-default.lht +
f7 +Buffer
Tool(buffer) +
menu-default.lht +
f8 +Del/remove
Tool(remove) +
menu-default.lht +
f9 +Whirl (rotate 90 deg)
Tool(rotate) +
menu-default.lht +
f
 a
+Save sheet as...
SaveAs() +
menu-default.lht +
f
 e
+Export Sheet...
ExportDialog() +
menu-default.lht +
f
 j
+Export Project...
ExportProjectDialog() +
menu-default.lht +
f
 n
+New root sheet
New(@, root) +
menu-default.lht +
f
 n-shift
+New aux sheet
New(@, aux) +
menu-default.lht +
f
 o
+Load...
Load() +
menu-default.lht +
f
 p
+Print sheet...
Print() +
menu-default.lht +
f
 q
+Quit
Quit() +
menu-default.lht +
f
 r
+Revert sheet
Revert(sheet) +
menu-default.lht +
f
 s
+Save sheet...
Save() +
menu-default.lht +
f
 u
+Unload sheet
Unload(sheet) +
menu-default.lht +
g
 b
+Previous grid
Grid(down) +
menu-default.lht +
g
 c
+Custom grid
Grid(ask) +
menu-default.lht +
g
 d
+Grid *2
SetGrid(*2) +
menu-default.lht +
g
 f
+Next grid
Grid(up) +
menu-default.lht +
g
 h
+Grid /2
SetGrid(/2) +
menu-default.lht +
g
 l
+Enable local grid
conf(toggle, editor/local_grid/enable, design) +
menu-default.lht +
g
 v
+Enable visible grid
conf(toggle, editor/draw_grid, design) +
menu-default.lht +
i
 c
  d
+Re-scan the devmap library
devmaplibRehash() +
menu-default.lht +
i
 c
  i
+Data integrity check
Integrity() +
menu-default.lht +
i
 c
  p
+Preferences...
preferences +
menu-default.lht +
i
 c
  r
+Re-scan the symbol library
SymlibRehash() +
menu-default.lht +
i
 c
  u
+Re-scan the funcmap library
funcmaplibRehash() +
menu-default.lht +
l
 -
+TODO
Layer(remove) +
menu-default.lht +
l
 r
+TODO
Layer(remove) +
menu-default.lht +
m
 f
  l
+Lock floaters
ToggleFloaters(lock) +
menu-default.lht +
m
 f
  o
+Only floaters
ToggleFloaters(only) +
menu-default.lht +
m
 k
  s
+Loose symbol (no sym lock)
proptoggle(sheet, p/sheet/loose_sym) +
menu-default.lht +
m
 l
  c
+Continuous draw (toggle)
conf(toggle, editor/line_cont, design) +
menu-default.lht +
m
 l
  f
+Cycle line clip/refraction (toggle)
conf(toggle, editor/line_refraction, design) +
menu-default.lht +
m
 r
  o
+Rubber band: orthogonal lines
conf(toggle, editor/rubber_band_ortho, design) +
menu-default.lht +
m
 r
  r
+Rubber band mode
conf(toggle, editor/rubber_band_mode, design) +
menu-default.lht +
m
 s
  p
+Enable symbol auto-pasting to local lib
conf(toggle, editor/paste_to_local_lib, design) +
menu-default.lht +
n-ctrl +New root sheet
New(@, root) +
menu-default.lht +
p
 a
+place attribute text
GetXy(Click where the new attribute should be placed); PlaceAttrib() +
menu-default.lht +
p
 m
  p
   
+Manage plugins...
ManagePlugins() +
menu-default.lht +
p
 m
  s
   
+Manage scripts...
BrowseScripts() +
menu-default.lht +
p
 t
+place terminal
GetXy(Click where the new terminal should be placed); PlaceTerminal() +
menu-default.lht +
s-ctrl +Save sheet...
Save() +
menu-default.lht +
s
 a
  a
   
+Select all visible objects on sheet
Select(All) +
menu-default.lht +
s
 b
  b
+objects
Breakup(selected, any, sheet) +
menu-default.lht +
s
 b
  g
+groups
Breakup(selected, group, sheet) +
menu-default.lht +
s
 b
  p
+polygons
Breakup(selected, poly, sheet) +
menu-default.lht +
s
 c
  g
+Custom group
GetXY(Click to set origin); Convert(selected, group) +
menu-default.lht +
s
 c
  p
+Polygon
GetXY(Click to set origin); Convert(selected, polygon) +
menu-default.lht +
s
 c
  s
+Symbol
GetXY(Click to set origin); Convert(selected, symbol) +
menu-default.lht +
s
 c
  t
+Terminal
GetXY(Click to set origin); Convert(selected, terminal) +
menu-default.lht +
s
 i
  
+Invert selection on sheet
Select(Invert) +
menu-default.lht +
s
 l
  k
   
+List locked objects
query(view, "@.locked == 1") +
menu-default.lht +
s
 l
  u
   
+List unnamed symbols
query(view, '@.a.role == "sym" || @.a.name ~ "[?]$"') +
menu-default.lht +
s
 p
+Edit properties
propedit(selection) +
menu-default.lht +
s
 r
  
+Remove selected objects
RemoveSelected() +
menu-default.lht +
s
 s
  
+Advanced search and select
SearchDialog() +
menu-default.lht +
s
 t
+Testbench affiliation
TestBenchDialog(selected) +
menu-default.lht +
s
 u
  a
   
+Unselect all objects on sheet
Unselect(All) +
menu-default.lht +
s
 u
  p
   
+Unselect all objects in projet
Unselect(AllProject) +
menu-default.lht +
t
 b
+Buffer
Tool(buffer) +
menu-default.lht +
t
 c
+Circle
Tool(circle) +
menu-default.lht +
t
 d
+Del/remove
Tool(remove) +
menu-default.lht +
t
 k
+Lock
Tool(lock) +
menu-default.lht +
t
 l
+Line
Tool(line) +
menu-default.lht +
t
 m
+Move
Tool(move) +
menu-default.lht +
t
 n
+Arrow
Tool(arrow) +
menu-default.lht +
t
 o
+Whirl (rotate 90 deg)
Tool(rotate) +
menu-default.lht +
t
 p
+Change pen
Preferences(colors) +
menu-default.lht +
t
 p-shift
+Copy
Tool(copy) +
menu-default.lht +
t
 r
+Rectangle
Tool(rect) +
menu-default.lht +
t
 t
+Text
Tool(text) +
menu-default.lht +
t
 w
+Wirenet
Tool(wirenet) +
menu-default.lht +
t
 x
+xmirror
Tool(xmirror) +
menu-default.lht +
t
 y
+ymirror
Tool(ymirror) +
menu-default.lht +
u
 c
+Clear undo-buffer
Undo(ClearList) +
menu-default.lht +
u
 d
  
+Undo dialog (for debugging)
UndoDialog() +
menu-default.lht +
u
 r
+Redo last undone operation
Redo() +
menu-default.lht +
u
 u
+Undo last operation
Undo() +
menu-default.lht +
v-ctrl
 
+Paste buffer to layout
Tool(buffer) +
menu-default.lht +
v
 c
+Center cursor
Center() +
menu-default.lht +
v
 d
  n
+Next
SwitchRelative(+1) +
menu-default.lht +
v
 d
  p
+Previous
SwitchRelative(-1) +
menu-default.lht +
v
 f
+Zoom Extents
Zoom() +
menu-default.lht +
v
 r
  g
+Reset GUI
+
menu-default.lht +
v
 r
  v
+Reset View
+
menu-default.lht +
w
 a
+Abstract model
AbstractDialog() +
menu-default.lht +
w
 l
+Library
LibraryDialog(symbol, sheet) +
menu-default.lht +
w
 m
+Message Log
LogDialog() +
menu-default.lht +
w
 t
+Tree view
TreeDialog() +
menu-default.lht +
w
 w
  d
+devmaps
LibraryDialog(devmap, sheet) +
menu-default.lht +
w
 w
  s
+spice libs
LibraryDialog(spicelib, sheet) +
menu-default.lht +
w
 w
  u
+funcmaps
LibraryDialog(funcmap, sheet) +
menu-default.lht +
y-ctrl +Redo last undone operation
Redo() +
menu-default.lht +
z-ctrl +Undo last operation
Undo() +
menu-default.lht +
z
 1
  
+Zoom to 0.10k/px
Zoom(=100) +
menu-default.lht +
z
 2
  
+Zoom to 0.25k/px
Zoom(=250) +
menu-default.lht +
z
 5
  
+Zoom to 0.50k/px
Zoom(=500) +
menu-default.lht +
z
 e
  
+Zoom Extents
Zoom() +
menu-default.lht +
z
 s
  
+Zoom to selection
ZoomTo(selected) +
menu-default.lht +
z
 x
  
+Zoom Out 20%
Zoom(+1.2) +
menu-default.lht +
z
 z
  
+Zoom In 20%
Zoom(-1.2) +
menu-default.lht +
+ + Index: tags/1.0.5/doc/man/Makefile =================================================================== --- tags/1.0.5/doc/man/Makefile (nonexistent) +++ tags/1.0.5/doc/man/Makefile (revision 10414) @@ -0,0 +1,60 @@ +# This Makefile is a plain old hand written one; all configuration settings +# are included from $(ROOT)/Makefile.conf which is scconfig generated +ROOT=../.. + +IN=sch-rnd.1.mml boxsym-rnd.1.mml boxsym-rnd.5.mml +OUT_HTML = sch-rnd.1.html boxsym-rnd.1.html boxsym-rnd.5.html +OUT_MAN1 = sch-rnd.1 boxsym-rnd.1 boxsym-rnd.5 +OUT_LINT = sch-rnd.1.lint boxsym-rnd.1.lint boxsym-rnd.5.lint + +OUTPUT = $(OUT_HTML) $(OUT_MAN1) index.html +MML = mml + +all: $(OUTPUT) + +lint: $(OUT_LINT) + +.SUFFIXES: .html .mml .lint + +.mml.html: .mml_linkmap + $(MML) -i copyright.mml -f html $< > $@ + +.mml: + $(MML) -i copyright.mml -f man $< > $@ + +.mml_linkmap: + $(MML) -i copyright.mml -f linkmap $(IN) > $@ + +index.html: $(IN) + @echo '' > $@ + @echo 'man page index - sch-rnd
    ' >> $@ + $(MML) -i copyright.mml -f indexhtml $(IN) >> $@ + @echo "
" >> $@ + +clean: + +distclean: + +genclean: + rm $(OUTPUT) 2>/dev/null ; true + +.mml.lint: + $(MML) -i copyright.mml -f lint $< + +install_all: + $(SCCBOX) mkdir -p "$(MAN1DIR)" "$(MAN5DIR)" + $(SCCBOX) $(HOW) "sch-rnd.1" "$(MAN1DIR)/sch-rnd.1" + $(SCCBOX) $(HOW) "boxsym-rnd.1" "$(MAN1DIR)/boxsym-rnd.1" + $(SCCBOX) $(HOW) "boxsym-rnd.5" "$(MAN5DIR)/boxsym-rnd.5" + +install: + $(MAKE) install_all HOW="install -f" + +linstall: + $(MAKE) install_all HOW="linstall -f" + +uninstall: + $(MAKE) install_all HOW="uninstall" + +include $(ROOT)/Makefile.conf + Index: tags/1.0.5/doc/man/README =================================================================== --- tags/1.0.5/doc/man/README (nonexistent) +++ tags/1.0.5/doc/man/README (revision 10414) @@ -0,0 +1,17 @@ +Manual pages are written in the manual markup format and are compiled into +manual and html using mml. Do not edit the generated manual or html pages. + +The generated files are commited in the repository so dependencies are not +required for casual users to build the project. + +The required tools and dependencies is the fawkml project's manmarkup util: + svn://svn.repo.hu/fawkml/trunk + +Installation procedure: + +1. svn checkout svn://svn.repo.hu/fawkml/trunk fawkml/trunk + +2. ./configure; optionally edit Makefile.conf; make; make install + +3. make install in trunk/util/manmarkup + Index: tags/1.0.5/doc/man/boxsym-rnd.1 =================================================================== --- tags/1.0.5/doc/man/boxsym-rnd.1 (nonexistent) +++ tags/1.0.5/doc/man/boxsym-rnd.1 (revision 10414) @@ -0,0 +1,31 @@ +.\" sch-rnd - manual\\n Copyright (C) 2022 Tibor 'Igor2' Palinkas\\n +.\"\\n +.\"This program is free software; you can redistribute it and/or modify\\n +.\"it under the terms of the GNU General Public License as published by\\n +.\"the Free Software Foundation; either version 2 of the License, or\\n +.\"(at your option) any later version.\\n +.\"\\n +.\"This program is distributed in the hope that it will be useful,\\n +.\"but WITHOUT ANY WARRANTY; without even the implied warranty of\\n +.\"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n +.\"GNU General Public License for more details.\\n +.\"\\n +.\"You should have received a copy of the GNU General Public License along\\n +.\"with this program; if not, write to the Free Software Foundation, Inc.,\\n +.\"51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\\n +.\"\\n +.\"Contact: sch-rnd-man[removethis]@igor2.repo.hu +.TH boxsym-rnd 1 2022-03-28 "" "sch-rnd manual" + +.SH NAME +boxsym-rnd - generate box shaped symbol(s) +.SH SYNPOSIS +.nf +.sp +\fBboxsym-rnd < \fIinfile.bs\fB > +.fi +.SH DESCRIPTION + +.BR boxsym-rnd +reads a boxsym description text file from the user specified path \fIinfile.bs\fR and generates one or more sch-rnd symbols in the same directory as the infile is in, named +infile.sym and infile-*.sym (for slotted boxsyms).boxsym-rnd(5) Index: tags/1.0.5/doc/man/boxsym-rnd.1.html =================================================================== --- tags/1.0.5/doc/man/boxsym-rnd.1.html (nonexistent) +++ tags/1.0.5/doc/man/boxsym-rnd.1.html (revision 10414) @@ -0,0 +1,64 @@ + + + +boxsym-rnd - sch-rnd manual + + + + +
boxsym-rnd 1 + 2022-03-28 + sch-rnd manual +
+ + + + +

NAME

+
+boxsym-rnd - generate box shaped symbol(s) +
+ +

SYNPOSIS

+
+

+boxsym-rnd &lt; infile.bs &gt; + + + +

+ +

DESCRIPTION

+
+boxsym-rnd reads a boxsym description text file from the user specified path infile.bs and generates one or more sch-rnd symbols in the same directory as the infile is in, named +infile.sym and infile-*.sym (for slotted boxsyms).boxsym-rnd(5) +
+

+ + +
boxsym-rnd 1 + 2022-03-28 + sch-rnd manual +
+ + + + Index: tags/1.0.5/doc/man/boxsym-rnd.1.mml =================================================================== --- tags/1.0.5/doc/man/boxsym-rnd.1.mml (nonexistent) +++ tags/1.0.5/doc/man/boxsym-rnd.1.mml (revision 10414) @@ -0,0 +1,15 @@ +boxsym-rnd +1 +2022-03-28 + + boxsym-rnd - generate box shaped symbol(s) + boxsym-rnd < infile.bs > + + +boxsym-rnd reads a boxsym description text file from +the user specified path infile.bs and generates +one or more sch-rnd symbols in the same directory as the infile is in, named +infile.sym and infile-*.sym (for slotted boxsyms). + +boxsym-rnd(5) + Index: tags/1.0.5/doc/man/boxsym-rnd.5 =================================================================== --- tags/1.0.5/doc/man/boxsym-rnd.5 (nonexistent) +++ tags/1.0.5/doc/man/boxsym-rnd.5 (revision 10414) @@ -0,0 +1,277 @@ +.\" sch-rnd - manual\\n Copyright (C) 2022 Tibor 'Igor2' Palinkas\\n +.\"\\n +.\"This program is free software; you can redistribute it and/or modify\\n +.\"it under the terms of the GNU General Public License as published by\\n +.\"the Free Software Foundation; either version 2 of the License, or\\n +.\"(at your option) any later version.\\n +.\"\\n +.\"This program is distributed in the hope that it will be useful,\\n +.\"but WITHOUT ANY WARRANTY; without even the implied warranty of\\n +.\"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n +.\"GNU General Public License for more details.\\n +.\"\\n +.\"You should have received a copy of the GNU General Public License along\\n +.\"with this program; if not, write to the Free Software Foundation, Inc.,\\n +.\"51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\\n +.\"\\n +.\"Contact: sch-rnd-man[removethis]@igor2.repo.hu +.TH boxsym-rnd 5 2022-03-28 "" "sch-rnd manual" + +.SH NAME +boxsym-rnd - boxsym description syntax +.SH DESCRIPTION +A boxsym file specifies symbol attributes and pins (terminals) for a single box symbol or for a set of inhomogenousely slotted box symbols. +When slotted symbols are generated, one symbol file is generated for each +slot containing only the pins defined for the given slot (file name +suffixed with slot name) and a monolith symbol is generated (using the +original file name) with all pins in one large box. +.SS Syntax + +.PP +The boxsym syntax is a plain text, line based, hierarchical file format with a syntax similar to tEDAx. Leading whitespace in lines are ignored. +Empty lines and lines starting with a hashmark (#) are ignored. The first +word of a line is a command. + +.PP +If the command is +.BR begin +, the rest of the lines until the matching +.BR end +line are read as a nested level of hierarchy. The syntax allows "begin in begin" (nesting to any depth). The second +word of begin and end are the type of the nested subtree. + +.PP +Commands issued outside of any begin-end blocks are said to be made in global scope. + +.SS Refdes + +.PP +There can be only one refdes line, in global scope. The argument is a single word, the refdes attribute. If no refdes is specified, the +default refdes is used. + +.SS Attributes + +.PP +Attributes are symbol attributes. Attributes specified in the global scope will be present in every symbol generated from the file. Attributes specified +for a slot will be present in the slot's symbol and in the monolith symbol. + +.PP +An attribute is defined in the following form: +.PP + +.BR attr +\fIkey\fR \fIvalue\fR +.PP +Key is a single word, value is anything up to the end of the line. This defintion creates the attribute and places a dyntext+floater text object +printing the value of the attribute. If command is +.BR attr_both +, the text object is created to print key=value. If command is + +.BR attr_invis +the attribute is still created but no text object is made. + +.SS Other global settings + +.PP +A line starting with text_size_mult followed by a decimal number (greater than zero) changes text pixel length allocation factor. Increasing values +will allocate more pixels to each text in length (text height is not affected). + + +.SS Defining pins + +.PP +Pins are defined using a pin subtree: begin pin pinname, then lines defining pin properties and then an end pin. Pinname should be the textual, human +readable name of the pin (also used as an input for the optional devmap), +not the physical pin number. + +.PP +For example: +.PP +.nf + +begin pin Vcc + num 14 + loc top +end pin +begin pin B + num 2:5:10:13 + loc left + dir in + invcirc + funcmap +end pin + +.fi + +.PP +Within the pin block the +.BR num +line specifies the physical footprint pin number; for a pin participating in a slot this should be +a colon separated list of pin number per slot. + +.PP +The mandatory +.BR loc +line specifies the location of the pin, the side of the box on which it should be placed, one of: left, right, +top or bottom. + +.PP +If a +.BR dir +line is present, extra "pin direction" graphics is drawn for the pin inside of the box. Values are in or out + +.PP +If +.BR invcirc +is present, the pin will have a small circle near the box to indicate the pin is inverted. + +.PP +If +.BR label +is present its value (anything written after "label") is printed within the box next to the pin instead of the pin name. + +.PP +If +.BR funcmap +is present, the label is replaced with a dyntext that prints abstract attribute funcmap/name. This is useful for symbols +that are going to use a funcmap (alternate pin function mapping). The +funcmap file is normally also referenced from the component, setting +the funcmap attribute to the funcmap file name. + +.SS Arranging pins + +.PP +By default pins are listed per side (loc), tightly packed, in order of appearance in the file from the start of the side. This can be changed +using pinalign lines in global or slot scope: + +.PP +.nf + +pinalign left center + +.fi + +.PP +will arrange left side pins on the center (vertically). +.SS Defining a single box symbol +The simplest form of box symbols emit a single file that has a single large box with all pins. The boxsym definition for such symbols contain +the above described constructs and no "begin slot" subtrees. + +.SS Defining inhomogenous slot symbol +In an multi-box, inhomogenous slot symbol there are different symbols representing different sections of the component. + +.PP +The typical example is an MCU which is split up into a couple of boxes: a few boxes per port groups and another few per peripheral +types. Each box represents a slot that appears only once in the MCU. + +.PP +Another typical example is logic ICs, e.g. 7400 implemented in two different slot symbols: one for power (Vcc and gnd), presents once +in the component, and one for a 3 pin gate, same box used 4 times +for 4 different slots. + +.PP +An inhomogenous slot symbol does not have any pin in global scope, but defines one or more "begin slot slotname" subtrees for all the different +type of slots. If the same slot appears multiple times in the component, +it needs to be defined only once (and multiple pin numbers assigned +in pin definitions.) + +.SH EXAMPLE + +.SS Single box LDO + +.PP +.nf + +refdes U?? +attr_invis sym-source sch-rnd default symbol lib +attr_invis sym-copyright (C) 2022 Tibor 'Igor2' Palinkas +attr_invis sym-license-dist GPLv2+ +attr_invis sym-license-use Public Domain + +pinalign bottom center +pinalign left center +pinalign right center + +shape box +shape_fill yes +begin pin in + num 1 + loc left +end pin + +begin pin gnd + num 2 + loc bottom +end pin + +begin pin out + num 3 + loc right +end pin + + + +.fi + +.SS Inhomogenous slot 7400 + +.PP +.nf + +refdes U?? + +pinalign right center +pinalign bottom center +pinalign top center +attr device 7400 + +begin slot power + shape box + shape_fill yes + begin pin Vcc + num 14 + loc top + end pin + begin pin gnd + num 7 + loc bottom + end pin + pinalign top center + pinalign bottom center +end slot + + +begin slot logic + attr device 7400 + attr_both slot 1 + + begin pin A + num 1:4:9:12 + loc left + dir in + end pin + + begin pin B + num 2:5:10:13 + loc left + dir in + end pin + + begin pin Z + num 3:6:8:11 + loc right + dir out + invcirc + end pin + + pinalign left center + pinalign right center +end slot + + + +.fi + + +.SH SEE ALSO +boxsym-rnd(1) Index: tags/1.0.5/doc/man/boxsym-rnd.5.html =================================================================== --- tags/1.0.5/doc/man/boxsym-rnd.5.html (nonexistent) +++ tags/1.0.5/doc/man/boxsym-rnd.5.html (revision 10414) @@ -0,0 +1,303 @@ + + + +boxsym-rnd - sch-rnd manual + + + + +
boxsym-rnd 5 + 2022-03-28 + sch-rnd manual +
+ + + + +

NAME

+
+boxsym-rnd - boxsym description syntax +
+ + +

DESCRIPTION

+
+A boxsym file specifies symbol attributes and pins (terminals) for a single box symbol or for a set of inhomogenousely slotted box symbols. +When slotted symbols are generated, one symbol file is generated for each +slot containing only the pins defined for the given slot (file name +suffixed with slot name) and a monolith symbol is generated (using the +original file name) with all pins in one large box. +

Syntax

+ +

+The boxsym syntax is a plain text, line based, hierarchical file format with a syntax similar to tEDAx. Leading whitespace in lines are ignored. +Empty lines and lines starting with a hashmark (#) are ignored. The first +word of a line is a command. + + +

+If the command is begin, the rest of the lines until the matching end line are read as a nested level of hierarchy. The syntax allows "begin in begin" (nesting to any depth). The second +word of begin and end are the type of the nested subtree. + + +

+Commands issued outside of any begin-end blocks are said to be made in global scope. + + +

Refdes

+ +

+There can be only one refdes line, in global scope. The argument is a single word, the refdes attribute. If no refdes is specified, the +default refdes is used. + + +

Attributes

+ +

+Attributes are symbol attributes. Attributes specified in the global scope will be present in every symbol generated from the file. Attributes specified +for a slot will be present in the slot's symbol and in the monolith symbol. + + +

+An attribute is defined in the following form: + +

+attr key value + +

+Key is a single word, value is anything up to the end of the line. This defintion creates the attribute and places a dyntext+floater text object +printing the value of the attribute. If command is attr_both, the text object is created to print key=value. If command is +attr_invis the attribute is still created but no text object is made. + + +

Other global settings

+ +

+A line starting with text_size_mult followed by a decimal number (greater than zero) changes text pixel length allocation factor. Increasing values +will allocate more pixels to each text in length (text height is not affected). + + + +

Defining pins

+ +

+Pins are defined using a pin subtree: begin pin pinname, then lines defining pin properties and then an end pin. Pinname should be the textual, human +readable name of the pin (also used as an input for the optional devmap), +not the physical pin number. + + +

+For example: +

 
+begin pin Vcc
+	num 14
+	loc top
+end pin
+begin pin B
+	num 2:5:10:13
+	loc left
+	dir in
+	invcirc
+	funcmap
+end pin
+	
+ + +

+Within the pin block the num line specifies the physical footprint pin number; for a pin participating in a slot this should be +a colon separated list of pin number per slot. + + +

+The mandatory loc line specifies the location of the pin, the side of the box on which it should be placed, one of: left, right, +top or bottom. + + +

+If a dir line is present, extra "pin direction" graphics is drawn for the pin inside of the box. Values are in or out + + +

+If invcirc is present, the pin will have a small circle near the box to indicate the pin is inverted. + + +

+If label is present its value (anything written after "label") is printed within the box next to the pin instead of the pin name. + + +

+If funcmap is present, the label is replaced with a dyntext that prints abstract attribute funcmap/name. This is useful for symbols +that are going to use a funcmap (alternate pin function mapping). The +funcmap file is normally also referenced from the component, setting +the funcmap attribute to the funcmap file name. + + +

Arranging pins

+ +

+By default pins are listed per side (loc), tightly packed, in order of appearance in the file from the start of the side. This can be changed +using pinalign lines in global or slot scope: + +

 
+pinalign left center
+	
+ + +

+will arrange left side pins on the center (vertically). + +

Defining a single box symbol

+The simplest form of box symbols emit a single file that has a single large box with all pins. The boxsym definition for such symbols contain +the above described constructs and no "begin slot" subtrees. + +

Defining inhomogenous slot symbol

+In an multi-box, inhomogenous slot symbol there are different symbols representing different sections of the component. + +

+The typical example is an MCU which is split up into a couple of boxes: a few boxes per port groups and another few per peripheral +types. Each box represents a slot that appears only once in the MCU. + + +

+Another typical example is logic ICs, e.g. 7400 implemented in two different slot symbols: one for power (Vcc and gnd), presents once +in the component, and one for a 3 pin gate, same box used 4 times +for 4 different slots. + + +

+An inhomogenous slot symbol does not have any pin in global scope, but defines one or more "begin slot slotname" subtrees for all the different +type of slots. If the same slot appears multiple times in the component, +it needs to be defined only once (and multiple pin numbers assigned +in pin definitions.) + + +

+ + +

EXAMPLE

+
+ +

Single box LDO

+ +
 
+refdes U??
+attr_invis sym-source       sch-rnd default symbol lib
+attr_invis sym-copyright    (C) 2022 Tibor 'Igor2' Palinkas
+attr_invis sym-license-dist GPLv2+
+attr_invis sym-license-use  Public Domain
+
+pinalign bottom center
+pinalign left center
+pinalign right center
+
+shape box
+shape_fill yes
+begin pin in
+	num 1
+	loc left
+end pin
+
+begin pin gnd
+	num 2
+	loc bottom
+end pin
+
+begin pin out
+	num 3
+	loc right
+end pin
+
+
+
+ +

Inhomogenous slot 7400

+ +
 
+refdes U??
+
+pinalign right center
+pinalign bottom center
+pinalign top center
+attr device 7400
+
+begin slot power
+	shape box
+	shape_fill yes
+	begin pin Vcc
+		num 14
+		loc top
+	end pin
+	begin pin gnd
+		num 7
+		loc bottom
+	end pin
+	pinalign top center
+	pinalign bottom center
+end slot
+
+
+begin slot logic
+	attr device 7400
+	attr_both slot 1
+
+	begin pin A
+		num 1:4:9:12
+		loc left
+		dir in
+	end pin
+
+	begin pin B
+		num 2:5:10:13
+		loc left
+		dir in
+	end pin
+
+	begin pin Z
+		num 3:6:8:11
+		loc right
+		dir out
+		invcirc
+	end pin
+
+	pinalign left center
+	pinalign right center
+end slot
+
+
+
+ +
+ +

SEE ALSO

+
    +
  • boxsym-rnd(1) +
+

+ + +
boxsym-rnd 5 + 2022-03-28 + sch-rnd manual +
+ + + + Index: tags/1.0.5/doc/man/boxsym-rnd.5.mml =================================================================== --- tags/1.0.5/doc/man/boxsym-rnd.5.mml (nonexistent) +++ tags/1.0.5/doc/man/boxsym-rnd.5.mml (revision 10414) @@ -0,0 +1,273 @@ +boxsym-rnd +5 +2022-03-28 + + boxsym-rnd - boxsym description syntax + + +A boxsym file specifies symbol attributes and pins (terminals) for a +single box symbol or for a set of inhomogenousely slotted box symbols. +When slotted symbols are generated, one symbol file is generated for each +slot containing only the pins defined for the given slot (file name +suffixed with slot name) and a monolith symbol is generated (using the +original file name) with all pins in one large box. + + + Syntax + +

+ The boxsym syntax is a plain text, line based, hierarchical file format + with a syntax similar to tEDAx. Leading whitespace in lines are ignored. + Empty lines and lines starting with a hashmark (#) are ignored. The first + word of a line is a command. +

+ If the command is begin, the rest of the lines until the + matching end line are read as a nested level of hierarchy. + The syntax allows "begin in begin" (nesting to any depth). The second + word of begin and end are the type of the nested subtree. +

+ Commands issued outside of any begin-end blocks are said to be made in + global scope. + + + + + Refdes + +

+ There can be only one refdes line, in global scope. The argument is + a single word, the refdes attribute. If no refdes is specified, the + default refdes is used. + + + + + + Attributes + +

+ Attributes are symbol attributes. Attributes specified in the global scope + will be present in every symbol generated from the file. Attributes specified + for a slot will be present in the slot's symbol and in the monolith symbol. +

+ An attribute is defined in the following form: +

+ attr key value +

+ Key is a single word, value is anything up to the end of the line. This + defintion creates the attribute and places a dyntext+floater text object + printing the value of the attribute. If command is attr_both, + the text object is created to print key=value. If command is + attr_invis the attribute is still created but no text object + is made. + + + + + Other global settings + +

+ A line starting with text_size_mult followed by a decimal number (greater + than zero) changes text pixel length allocation factor. Increasing values + will allocate more pixels to each text in length (text height is not affected). + + + + + + Defining pins + +

+ Pins are defined using a pin subtree: begin pin pinname, then lines defining + pin properties and then an end pin. Pinname should be the textual, human + readable name of the pin (also used as an input for the optional devmap), + not the physical pin number. +

For example: +

+begin pin Vcc
+	num 14
+	loc top
+end pin
+begin pin B
+	num 2:5:10:13
+	loc left
+	dir in
+	invcirc
+	funcmap
+end pin
+	
+

+ Within the pin block the num line specifies the physical + footprint pin number; for a pin participating in a slot this should be + a colon separated list of pin number per slot. +

+ The mandatory loc line specifies the location of the pin, + the side of the box on which it should be placed, one of: left, right, + top or bottom. +

+ If a dir line is present, extra "pin direction" graphics is + drawn for the pin inside of the box. Values are in or out +

+ If invcirc is present, the pin will have a small circle + near the box to indicate the pin is inverted. +

+ If label is present its value (anything written after "label") + is printed within the box next to the pin instead of the pin name. +

+ If funcmap is present, the label is replaced with a dyntext + that prints abstract attribute funcmap/name. This is useful for symbols + that are going to use a funcmap (alternate pin function mapping). The + funcmap file is normally also referenced from the component, setting + the funcmap attribute to the funcmap file name. + + + + + Arranging pins + +

+ By default pins are listed per side (loc), tightly packed, in order of + appearance in the file from the start of the side. This can be changed + using pinalign lines in global or slot scope: +

+pinalign left center
+	
+

+ will arrange left side pins on the center (vertically). + + + + + Defining a single box symbol + + The simplest form of box symbols emit a single file that has a single + large box with all pins. The boxsym definition for such symbols contain + the above described constructs and no "begin slot" subtrees. + + + + + Defining inhomogenous slot symbol + + In an multi-box, inhomogenous slot symbol there are different symbols + representing different sections of the component. +

+ The typical example is an MCU which is split up into a couple of + boxes: a few boxes per port groups and another few per peripheral + types. Each box represents a slot that appears only once in the MCU. +

+ Another typical example is logic ICs, e.g. 7400 implemented in two + different slot symbols: one for power (Vcc and gnd), presents once + in the component, and one for a 3 pin gate, same box used 4 times + for 4 different slots. +

+ An inhomogenous slot symbol does not have any pin in global scope, but + defines one or more "begin slot slotname" subtrees for all the different + type of slots. If the same slot appears multiple times in the component, + it needs to be defined only once (and multiple pin numbers assigned + in pin definitions.) + + + + + + + + Single box LDO + +

+refdes U??
+attr_invis sym-source       sch-rnd default symbol lib
+attr_invis sym-copyright    (C) 2022 Tibor 'Igor2' Palinkas
+attr_invis sym-license-dist GPLv2+
+attr_invis sym-license-use  Public Domain
+
+pinalign bottom center
+pinalign left center
+pinalign right center
+
+shape box
+shape_fill yes
+begin pin in
+	num 1
+	loc left
+end pin
+
+begin pin gnd
+	num 2
+	loc bottom
+end pin
+
+begin pin out
+	num 3
+	loc right
+end pin
+
+
+
+ + + + + Inhomogenous slot 7400 + +
+refdes U??
+
+pinalign right center
+pinalign bottom center
+pinalign top center
+attr device 7400
+
+begin slot power
+	shape box
+	shape_fill yes
+	begin pin Vcc
+		num 14
+		loc top
+	end pin
+	begin pin gnd
+		num 7
+		loc bottom
+	end pin
+	pinalign top center
+	pinalign bottom center
+end slot
+
+
+begin slot logic
+	attr device 7400
+	attr_both slot 1
+
+	begin pin A
+		num 1:4:9:12
+		loc left
+		dir in
+	end pin
+
+	begin pin B
+		num 2:5:10:13
+		loc left
+		dir in
+	end pin
+
+	begin pin Z
+		num 3:6:8:11
+		loc right
+		dir out
+		invcirc
+	end pin
+
+	pinalign left center
+	pinalign right center
+end slot
+
+
+
+
+
+ + + +boxsym-rnd(1) + Index: tags/1.0.5/doc/man/copyright.mml =================================================================== --- tags/1.0.5/doc/man/copyright.mml (nonexistent) +++ tags/1.0.5/doc/man/copyright.mml (revision 10414) @@ -0,0 +1,21 @@ + +sch-rnd - manual\n +Copyright (C) 2022 Tibor 'Igor2' Palinkas\n +\n +This program is free software; you can redistribute it and/or modify\n +it under the terms of the GNU General Public License as published by\n +the Free Software Foundation; either version 2 of the License, or\n +(at your option) any later version.\n +\n +This program is distributed in the hope that it will be useful,\n +but WITHOUT ANY WARRANTY; without even the implied warranty of\n +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n +GNU General Public License for more details.\n +\n +You should have received a copy of the GNU General Public License along\n +with this program; if not, write to the Free Software Foundation, Inc.,\n +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n +\n +Contact: sch-rnd-man[removethis]@igor2.repo.hu + +sch-rnd manual Index: tags/1.0.5/doc/man/index.html =================================================================== --- tags/1.0.5/doc/man/index.html (nonexistent) +++ tags/1.0.5/doc/man/index.html (revision 10414) @@ -0,0 +1,6 @@ + +man page index - sch-rnd
    +
  • sch-rnd (1) -- sch-rnd - Schematics editor +
  • boxsym-rnd (1) -- boxsym-rnd - generate box shaped symbol(s) +
  • boxsym-rnd (5) -- boxsym-rnd - boxsym description syntax +
Index: tags/1.0.5/doc/man/sch-rnd.1 =================================================================== --- tags/1.0.5/doc/man/sch-rnd.1 (nonexistent) +++ tags/1.0.5/doc/man/sch-rnd.1 (revision 10414) @@ -0,0 +1,55 @@ +.\" sch-rnd - manual\\n Copyright (C) 2022 Tibor 'Igor2' Palinkas\\n +.\"\\n +.\"This program is free software; you can redistribute it and/or modify\\n +.\"it under the terms of the GNU General Public License as published by\\n +.\"the Free Software Foundation; either version 2 of the License, or\\n +.\"(at your option) any later version.\\n +.\"\\n +.\"This program is distributed in the hope that it will be useful,\\n +.\"but WITHOUT ANY WARRANTY; without even the implied warranty of\\n +.\"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n +.\"GNU General Public License for more details.\\n +.\"\\n +.\"You should have received a copy of the GNU General Public License along\\n +.\"with this program; if not, write to the Free Software Foundation, Inc.,\\n +.\"51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\\n +.\"\\n +.\"Contact: sch-rnd-man[removethis]@igor2.repo.hu +.TH sch-rnd 1 2022-09-29 "" "sch-rnd manual" + +.SH NAME +sch-rnd - Schematics editor +.SH SYNPOSIS +.nf +.sp +\fBsch-rnd [\fIoptions\fB] [\fIinputfile\fB] +.fi +.SH DESCRIPTION + +.BR sch-rnd +is a modular schematics capture (editor). The main use is interactive editing. If no \fI-x\fR is specified on the command line, the graphical editor mode is initiated. +Automated, headless processing is also possible with \fI-x\fR or\fI--gui batch\fR\&. +.SH OPTIONS + + +.TP + +.B --help \fItopic\fR +Print help about \fItopic\fR and exit; if no topic is specified, print available topics. + +.TP + +.B -x \fIexporter\fR [\fIexportflags] \fIinputfile\fR\fR +Instead of interactive editing, export the design (loaded from \fIinputfile\fR) to a file using the specified \fIexporter\fR plugin. A list of exporter-specific parameters may follow to control the details of the process. +.TP + +.B --gui \fIhid\fR +Use the \fIhid\fR plugin for the "gui" frontend. Common choices are "gtk2_gdk" or "lesstif" for graphical user interfaces +and "batch" for a headless command-line interface (or automated +batch processing). +.TP + +.B -c \fIpath=val\fR +Set a config node in role CFR_CLI. The path of the node is \fIpath\fR (e.g. editor/grid) and the new value is \fIval\fR (e.g. 5mm). +.PP + Index: tags/1.0.5/doc/man/sch-rnd.1.html =================================================================== --- tags/1.0.5/doc/man/sch-rnd.1.html (nonexistent) +++ tags/1.0.5/doc/man/sch-rnd.1.html (revision 10414) @@ -0,0 +1,92 @@ + + + +sch-rnd - sch-rnd manual + + + + +
sch-rnd 1 + 2022-09-29 + sch-rnd manual +
+ + + + +

NAME

+
+sch-rnd - Schematics editor +
+ +

SYNPOSIS

+
+

+sch-rnd [options] [inputfile] + + + +

+ +

DESCRIPTION

+
+sch-rnd is a modular schematics capture (editor). The main use is interactive editing. If no -x is specified on the command line, the graphical editor mode is initiated. +Automated, headless processing is also possible with -x or--gui batch. +
+ + +

OPTIONS

+
+ + + + + + + + + + + +
--help topic + Print help about topic and exit; if no topic is specified, print available topics. + +
-x exporter [exportflags] inputfile + Instead of interactive editing, export the design (loaded from inputfile) to a file using the specified exporter plugin. A list of exporter-specific parameters may follow to control the details of the process. +
--gui hid + Use the hid plugin for the "gui" frontend. Common choices are "gtk2_gdk" or "lesstif" for graphical user interfaces +and "batch" for a headless command-line interface (or automated +batch processing). +
-c path=val + Set a config node in role CFR_CLI. The path of the node is path (e.g. editor/grid) and the new value is val (e.g. 5mm). +
+
+

+ + +
sch-rnd 1 + 2022-09-29 + sch-rnd manual +
+ + + + Index: tags/1.0.5/doc/man/sch-rnd.1.mml =================================================================== --- tags/1.0.5/doc/man/sch-rnd.1.mml (nonexistent) +++ tags/1.0.5/doc/man/sch-rnd.1.mml (revision 10414) @@ -0,0 +1,44 @@ +sch-rnd +1 +2022-09-29 + + sch-rnd - Schematics editor + sch-rnd [options] [inputfile] + + +sch-rnd is a modular schematics capture (editor). +The main use is interactive editing. If no -x is +specified on the command line, the graphical editor mode is initiated. +Automated, headless processing is also possible with -x or +--gui batch. + + + + + + --help topic + Print help about topic and exit; if no topic is + specified, print available topics. + + + -x exporter [exportflags] inputfile + Instead of interactive editing, export the design (loaded from + inputfile) to a file using the specified + exporter plugin. A list of exporter-specific parameters + may follow to control the details of the process. + + + --gui hid + Use the hid plugin for the "gui" frontend. Common + choices are "gtk2_gdk" or "lesstif" for graphical user interfaces + and "batch" for a headless command-line interface (or automated + batch processing). + + + -c path=val + Set a config node in role CFR_CLI. The path of the node is + path (e.g. editor/grid) and the new value is + val (e.g. 5mm). + + + Index: tags/1.0.5/doc/mirrors.html =================================================================== --- tags/1.0.5/doc/mirrors.html (nonexistent) +++ tags/1.0.5/doc/mirrors.html (revision 10414) @@ -0,0 +1,74 @@ + + + + sch-rnd - main + + + + + + + + + + +
Main + Doc &  Knowledge pool  &  Tutorial + Current state + Events & timeline + sch-rnd [sch-rnd logo] +
+ + +
+ + +

Master read-write repository

+

+svn://svn.repo.hu/sch-rnd +

+Use only this one for commiting changes. + +

Real-time read-only svn mirrors

+

+These repositories are mirroring the master repo in real-time. That means +seconds after a commit to the master repository the synchronization takes +place and the mirror should be up to date. Use these mirrors if you +never commit and the master repository feels slow. +

+ +
url + location +
svn://us.repo.hu/sch-rnd + U.S., west coast +
+ +

Periodic read-only svn mirrors

+

+These mirrors upgrade periodically, thus they are lagging behind the main +repositories above. Do not use them unless none of the above repositries +are accessible. +

+ +
url + update frequency location +
svn://igor3.repo.hu/sch-rnd + manual/random (every few days) + Budapest, Hungary +
+

+Note: svn mirrors are always read-only and lag behind the master +repository. The latest commits are often accessible only in the master +repo, until mirrors sync, which may take anything between minutes and +days. You should almost always use the master repository. +There are situations when using a mirror may help, tho: +

    +
  • if you need to do a lot of checkouts of past revisions, e.g. for + bisecting an old bug, you should pick the mirror that is fastest + for you +
  • the master repositry is not accessible for some reason and your + svn access can not wait until it is restored +
+ + + Index: tags/1.0.5/doc/resources/Makefile =================================================================== --- tags/1.0.5/doc/resources/Makefile (nonexistent) +++ tags/1.0.5/doc/resources/Makefile (revision 10414) @@ -0,0 +1,24 @@ +ROOT=../.. +RESDIR=$(DOCDIR)/resources + +all: + +install_all: + $(SCCBOX) mkdir -p $(RESDIR) + $(SCCBOX) $(HOW) -d *.png *.svg *.eps *.jpg $(RESDIR) + +install: + $(MAKE) install_all HOW="install -f -d" + +linstall: + $(MAKE) install_all HOW="install -f -l -d" + +uninstall: + $(MAKE) install_all HOW="install -u" + +clean: + +distclean: + + +include $(ROOT)/Makefile.conf Index: tags/1.0.5/doc/resources/at.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/1.0.5/doc/resources/at.png =================================================================== --- tags/1.0.5/doc/resources/at.png (nonexistent) +++ tags/1.0.5/doc/resources/at.png (revision 10414) Property changes on: tags/1.0.5/doc/resources/at.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/1.0.5/doc/resources/cschem_logo.eps =================================================================== --- tags/1.0.5/doc/resources/cschem_logo.eps (nonexistent) +++ tags/1.0.5/doc/resources/cschem_logo.eps (revision 10414) @@ -0,0 +1,179 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%Creator: cairo 1.12.14 (http://cairographics.org) +%%CreationDate: Sun Dec 10 03:21:32 2017 +%%Pages: 1 +%%DocumentData: Clean7Bit +%%LanguageLevel: 2 +%%BoundingBox: 0 -1 820 820 +%%EndComments +%%BeginProlog +save +50 dict begin +/q { gsave } bind def +/Q { grestore } bind def +/cm { 6 array astore concat } bind def +/w { setlinewidth } bind def +/J { setlinecap } bind def +/j { setlinejoin } bind def +/M { setmiterlimit } bind def +/d { setdash } bind def +/m { moveto } bind def +/l { lineto } bind def +/c { curveto } bind def +/h { closepath } bind def +/re { exch dup neg 3 1 roll 5 3 roll moveto 0 rlineto + 0 exch rlineto 0 rlineto closepath } bind def +/S { stroke } bind def +/f { fill } bind def +/f* { eofill } bind def +/n { newpath } bind def +/W { clip } bind def +/W* { eoclip } bind def +/BT { } bind def +/ET { } bind def +/pdfmark where { pop globaldict /?pdfmark /exec load put } + { globaldict begin /?pdfmark /pop load def /pdfmark + /cleartomark load def end } ifelse +/BDC { mark 3 1 roll /BDC pdfmark } bind def +/EMC { mark /EMC pdfmark } bind def +/cairo_store_point { /cairo_point_y exch def /cairo_point_x exch def } def +/Tj { show currentpoint cairo_store_point } bind def +/TJ { + { + dup + type /stringtype eq + { show } { -0.001 mul 0 cairo_font_matrix dtransform rmoveto } ifelse + } forall + currentpoint cairo_store_point +} bind def +/cairo_selectfont { cairo_font_matrix aload pop pop pop 0 0 6 array astore + cairo_font exch selectfont cairo_point_x cairo_point_y moveto } bind def +/Tf { pop /cairo_font exch def /cairo_font_matrix where + { pop cairo_selectfont } if } bind def +/Td { matrix translate cairo_font_matrix matrix concatmatrix dup + /cairo_font_matrix exch def dup 4 get exch 5 get cairo_store_point + /cairo_font where { pop cairo_selectfont } if } bind def +/Tm { 2 copy 8 2 roll 6 array astore /cairo_font_matrix exch def + cairo_store_point /cairo_font where { pop cairo_selectfont } if } bind def +/g { setgray } bind def +/rg { setrgbcolor } bind def +/d1 { setcachedevice } bind def +%%EndProlog +%%Page: 1 1 +%%BeginPageSetup +%%PageBoundingBox: 0 -1 820 820 +%%EndPageSetup +q 0 -1 820 821 rectclip q +0.847059 0.968627 0.984314 rg +4.516 820.001 m 815.484 820.001 l 817.984 820.001 820 817.985 820 815.485 + c 820 4.516 l 820 2.013 817.984 0.001 815.484 0.001 c 4.516 0.001 l 2.016 + 0.001 0 2.013 0 4.516 c 0 815.485 l 0 817.985 2.016 820.001 4.516 820.001 + c h +f +0.00784314 g +120 136.001 m 120 122.747 109.254 112.001 96 112.001 c 82.746 112.001 72 + 122.747 72 136.001 c 72 149.255 82.746 160.001 96 160.001 c 109.254 160.001 + 120 149.255 120 136.001 c h +f +0 g +0.32 w +1 J +0 j +[] 0.0 d +4 M q 1 0 0 -1 0 819.200012 cm +120 683.199 m 120 696.453 109.254 707.199 96 707.199 c 82.746 707.199 72 + 696.453 72 683.199 c 72 669.945 82.746 659.199 96 659.199 c 109.254 659.199 + 120 669.945 120 683.199 c h +S Q +0.00784314 g +120 696.001 m 120 682.747 109.254 672.001 96 672.001 c 82.746 672.001 72 + 682.747 72 696.001 c 72 709.255 82.746 720.001 96 720.001 c 109.254 720.001 + 120 709.255 120 696.001 c h +f +0 g +q 1 0 0 -1 0 819.200012 cm +120 123.199 m 120 136.453 109.254 147.199 96 147.199 c 82.746 147.199 72 + 136.453 72 123.199 c 72 109.945 82.746 99.199 96 99.199 c 109.254 99.199 + 120 109.945 120 123.199 c h +S Q +0.00784314 g +744 144.001 m 744 130.747 733.254 120.001 720 120.001 c 706.746 120.001 + 696 130.747 696 144.001 c 696 157.255 706.746 168.001 720 168.001 c 733.254 + 168.001 744 157.255 744 144.001 c h +f +0 g +q 1 0 0 -1 0 819.200012 cm +744 675.199 m 744 688.453 733.254 699.199 720 699.199 c 706.746 699.199 + 696 688.453 696 675.199 c 696 661.945 706.746 651.199 720 651.199 c 733.254 + 651.199 744 661.945 744 675.199 c h +S Q +0.00784314 g +744 696.001 m 744 682.747 733.254 672.001 720 672.001 c 706.746 672.001 + 696 682.747 696 696.001 c 696 709.255 706.746 720.001 720 720.001 c 733.254 + 720.001 744 709.255 744 696.001 c h +f +0 g +q 1 0 0 -1 0 819.200012 cm +744 123.199 m 744 136.453 733.254 147.199 720 147.199 c 706.746 147.199 + 696 136.453 696 123.199 c 696 109.945 706.746 99.199 720 99.199 c 733.254 + 99.199 744 109.945 744 123.199 c h +S Q +24 w +q 1 0 0 -1 0 819.200012 cm +656 123.199 m 720 123.199 l 176 123.199 m 96 123.199 l 656 123.199 m 608 + 195.199 l 512 51.199 m 608 195.199 l 512 51.199 m 416 195.199 l 320 51.199 + m 416 195.199 l 320 51.199 m 224 195.199 l 176 123.199 m 224 195.199 l S Q +q 1 0 0 -1 0 819.200012 cm +96 123.199 m 96 375.199 l 20 375.199 m 172 375.199 l S Q +q 1 0 0 -1 0 819.200012 cm +96 683.199 m 96 439.199 l 20 439.199 m 172 439.199 l S Q +q 1 0 0 -1 0 819.200012 cm +528 675.199 m 576 611.199 584 611.199 600 675.199 c 720 675.199 l 232 683.199 + m 96 683.199 l 424 683.199 m 496 595.199 488 611.199 520 683.199 c 592 +811.199 424 795.199 528 675.199 c 328 683.199 m 400 595.199 392 611.199 +424 683.199 c 496 811.199 328 795.199 432 675.199 c 232 683.199 m 304 595.199 + 296 611.199 328 683.199 c 400 811.199 232 795.199 336 675.199 c S Q +0.00784314 g +752 320.001 m 752 302.325 737.672 288.001 720 288.001 c 702.328 288.001 + 688 302.325 688 320.001 c 688 337.673 702.328 352.001 720 352.001 c 737.672 + 352.001 752 337.673 752 320.001 c h +f +0 g +0.426667 w +q 1 0 0 -1 0 819.200012 cm +752 499.199 m 752 516.875 737.672 531.199 720 531.199 c 702.328 531.199 + 688 516.875 688 499.199 c 688 481.527 702.328 467.199 720 467.199 c 737.672 + 467.199 752 481.527 752 499.199 c h +S Q +0.0666667 0.584314 0.662745 rg +32 w +1 M q 1 0 0 -1 0 819.200012 cm +528 285.352 m 501.824 264 468.41 251.199 432 251.199 c 348.051 251.199 +280 319.254 280 403.199 c 280 487.148 348.051 555.199 432 555.199 c 468.41 + 555.199 501.824 542.398 528 521.051 c S Q +588 496.001 m 458.25 501.282 l 494.25 557.282 l 588 496.001 m 530.25 609.282 + l 494.25 557.282 l f +0 g +24 w +4 M q 1 0 0 -1 0 819.200012 cm +720 675.199 m 720 499.199 l S Q +0.00784314 g +752 500.001 m 752 517.673 737.672 532.001 720 532.001 c 702.328 532.001 + 688 517.673 688 500.001 c 688 482.325 702.328 468.001 720 468.001 c 737.672 + 468.001 752 482.325 752 500.001 c h +f +0 g +0.426667 w +q 1 0 0 1 0 819.200012 cm +752 -319.199 m 752 -301.527 737.672 -287.199 720 -287.199 c 702.328 -287.199 + 688 -301.527 688 -319.199 c 688 -336.875 702.328 -351.199 720 -351.199 +c 737.672 -351.199 752 -336.875 752 -319.199 c h +S Q +24 w +q 1 0 0 -1 0 819.200012 cm +720 123.199 m 720 319.199 l S Q +Q Q +showpage +%%Trailer +end restore +%%EOF Index: tags/1.0.5/doc/resources/cschem_logo.svg =================================================================== --- tags/1.0.5/doc/resources/cschem_logo.svg (nonexistent) +++ tags/1.0.5/doc/resources/cschem_logo.svg (revision 10414) @@ -0,0 +1,36 @@ + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file Index: tags/1.0.5/doc/resources/cschem_logo128.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/1.0.5/doc/resources/cschem_logo128.png =================================================================== --- tags/1.0.5/doc/resources/cschem_logo128.png (nonexistent) +++ tags/1.0.5/doc/resources/cschem_logo128.png (revision 10414) Property changes on: tags/1.0.5/doc/resources/cschem_logo128.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/1.0.5/doc/resources/cschem_logo16.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/1.0.5/doc/resources/cschem_logo16.png =================================================================== --- tags/1.0.5/doc/resources/cschem_logo16.png (nonexistent) +++ tags/1.0.5/doc/resources/cschem_logo16.png (revision 10414) Property changes on: tags/1.0.5/doc/resources/cschem_logo16.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/1.0.5/doc/resources/cschem_logo16.svg =================================================================== --- tags/1.0.5/doc/resources/cschem_logo16.svg (nonexistent) +++ tags/1.0.5/doc/resources/cschem_logo16.svg (revision 10414) @@ -0,0 +1,195 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/1.0.5/doc/resources/cschem_logo32.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/1.0.5/doc/resources/cschem_logo32.png =================================================================== --- tags/1.0.5/doc/resources/cschem_logo32.png (nonexistent) +++ tags/1.0.5/doc/resources/cschem_logo32.png (revision 10414) Property changes on: tags/1.0.5/doc/resources/cschem_logo32.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/1.0.5/doc/resources/cschem_logo64.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/1.0.5/doc/resources/cschem_logo64.png =================================================================== --- tags/1.0.5/doc/resources/cschem_logo64.png (nonexistent) +++ tags/1.0.5/doc/resources/cschem_logo64.png (revision 10414) Property changes on: tags/1.0.5/doc/resources/cschem_logo64.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/1.0.5/doc/resources/cschem_logo_full.svg =================================================================== --- tags/1.0.5/doc/resources/cschem_logo_full.svg (nonexistent) +++ tags/1.0.5/doc/resources/cschem_logo_full.svg (revision 10414) @@ -0,0 +1,230 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + schem + + Index: tags/1.0.5/doc/resources/cschem_logo_full_128.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/1.0.5/doc/resources/cschem_logo_full_128.png =================================================================== --- tags/1.0.5/doc/resources/cschem_logo_full_128.png (nonexistent) +++ tags/1.0.5/doc/resources/cschem_logo_full_128.png (revision 10414) Property changes on: tags/1.0.5/doc/resources/cschem_logo_full_128.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/1.0.5/doc/resources/cschem_logo_full_32.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/1.0.5/doc/resources/cschem_logo_full_32.png =================================================================== --- tags/1.0.5/doc/resources/cschem_logo_full_32.png (nonexistent) +++ tags/1.0.5/doc/resources/cschem_logo_full_32.png (revision 10414) Property changes on: tags/1.0.5/doc/resources/cschem_logo_full_32.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/1.0.5/doc/resources/cschem_logo_full_64.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/1.0.5/doc/resources/cschem_logo_full_64.png =================================================================== --- tags/1.0.5/doc/resources/cschem_logo_full_64.png (nonexistent) +++ tags/1.0.5/doc/resources/cschem_logo_full_64.png (revision 10414) Property changes on: tags/1.0.5/doc/resources/cschem_logo_full_64.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/1.0.5/doc/resources/cschem_logo_small.eps =================================================================== --- tags/1.0.5/doc/resources/cschem_logo_small.eps (nonexistent) +++ tags/1.0.5/doc/resources/cschem_logo_small.eps (revision 10414) @@ -0,0 +1,154 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%Creator: cairo 1.12.14 (http://cairographics.org) +%%CreationDate: Sun Dec 10 03:23:33 2017 +%%Pages: 1 +%%DocumentData: Clean7Bit +%%LanguageLevel: 2 +%%BoundingBox: 0 -1 103 103 +%%EndComments +%%BeginProlog +save +50 dict begin +/q { gsave } bind def +/Q { grestore } bind def +/cm { 6 array astore concat } bind def +/w { setlinewidth } bind def +/J { setlinecap } bind def +/j { setlinejoin } bind def +/M { setmiterlimit } bind def +/d { setdash } bind def +/m { moveto } bind def +/l { lineto } bind def +/c { curveto } bind def +/h { closepath } bind def +/re { exch dup neg 3 1 roll 5 3 roll moveto 0 rlineto + 0 exch rlineto 0 rlineto closepath } bind def +/S { stroke } bind def +/f { fill } bind def +/f* { eofill } bind def +/n { newpath } bind def +/W { clip } bind def +/W* { eoclip } bind def +/BT { } bind def +/ET { } bind def +/pdfmark where { pop globaldict /?pdfmark /exec load put } + { globaldict begin /?pdfmark /pop load def /pdfmark + /cleartomark load def end } ifelse +/BDC { mark 3 1 roll /BDC pdfmark } bind def +/EMC { mark /EMC pdfmark } bind def +/cairo_store_point { /cairo_point_y exch def /cairo_point_x exch def } def +/Tj { show currentpoint cairo_store_point } bind def +/TJ { + { + dup + type /stringtype eq + { show } { -0.001 mul 0 cairo_font_matrix dtransform rmoveto } ifelse + } forall + currentpoint cairo_store_point +} bind def +/cairo_selectfont { cairo_font_matrix aload pop pop pop 0 0 6 array astore + cairo_font exch selectfont cairo_point_x cairo_point_y moveto } bind def +/Tf { pop /cairo_font exch def /cairo_font_matrix where + { pop cairo_selectfont } if } bind def +/Td { matrix translate cairo_font_matrix matrix concatmatrix dup + /cairo_font_matrix exch def dup 4 get exch 5 get cairo_store_point + /cairo_font where { pop cairo_selectfont } if } bind def +/Tm { 2 copy 8 2 roll 6 array astore /cairo_font_matrix exch def + cairo_store_point /cairo_font where { pop cairo_selectfont } if } bind def +/g { setgray } bind def +/rg { setrgbcolor } bind def +/d1 { setcachedevice } bind def +%%EndProlog +%%Page: 1 1 +%%BeginPageSetup +%%PageBoundingBox: 0 -1 103 103 +%%EndPageSetup +q 0 -1 103 104 rectclip q +0.847059 0.968627 0.984314 rg +0.562 102.4 m 101.836 102.4 l 102.148 102.4 102.398 102.15 102.398 101.838 + c 102.398 0.564 l 102.398 0.252 102.148 0.002 101.836 0.002 c 0.562 0.002 + l 0.25 0.002 0 0.252 0 0.564 c 0 101.838 l 0 102.15 0.25 102.4 0.562 102.4 + c h +f +0.00784314 g +14.984 16.982 m 14.984 15.33 13.645 13.986 11.988 13.986 c 10.332 13.986 + 8.992 15.33 8.992 16.982 c 8.992 18.638 10.332 19.982 11.988 19.982 c 13.645 + 19.982 14.984 18.638 14.984 16.982 c h +f +14.984 86.916 m 14.984 85.259 13.645 83.92 11.988 83.92 c 10.332 83.92 +8.992 85.259 8.992 86.916 c 8.992 88.572 10.332 89.912 11.988 89.912 c 13.645 + 89.912 14.984 88.572 14.984 86.916 c h +f +92.91 17.982 m 92.91 16.326 91.566 14.986 89.914 14.986 c 88.258 14.986 + 86.914 16.326 86.914 17.982 c 86.914 19.638 88.258 20.978 89.914 20.978 + c 91.566 20.978 92.91 19.638 92.91 17.982 c h +f +92.91 86.916 m 92.91 85.259 91.566 83.92 89.914 83.92 c 88.258 83.92 86.914 + 85.259 86.914 86.916 c 86.914 88.572 88.258 89.912 89.914 89.912 c 91.566 + 89.912 92.91 88.572 92.91 86.916 c h +f +0 g +2.997073 w +1 J +0 j +[] 0.0 d +4 M q 1 0 0 -1 0 102.400002 cm +81.922 15.484 m 89.914 15.484 l 21.98 15.484 m 11.988 15.484 l 81.922 15.484 + m 75.926 24.477 l 63.938 6.492 m 75.926 24.477 l 63.938 6.492 m 51.949 +24.477 l 39.961 6.492 m 51.949 24.477 l 39.961 6.492 m 27.973 24.477 l 21.98 + 15.484 m 27.973 24.477 l S Q +q 1 0 0 -1 0 102.400002 cm +11.988 15.484 m 11.988 46.953 l 2.496 46.953 m 21.48 46.953 l S Q +q 1 0 0 -1 0 102.400002 cm +11.988 85.418 m 11.988 54.945 l 2.496 54.945 m 21.48 54.945 l S Q +q 1 0 0 -1 0 102.400002 cm +65.938 84.418 m 71.93 76.426 72.93 76.426 74.926 84.418 c 89.914 84.418 + l 28.973 85.418 m 11.988 85.418 l 52.949 85.418 m 61.941 74.426 60.941 +76.426 64.938 85.418 c 73.93 101.402 52.949 99.402 65.938 84.418 c 40.961 + 85.418 m 49.953 74.426 48.953 76.426 52.949 85.418 c 61.941 101.402 40.961 + 99.402 53.949 84.418 c 28.973 85.418 m 37.965 74.426 36.965 76.426 40.961 + 85.418 c 49.953 101.402 28.973 99.402 41.961 84.418 c S Q +0.00784314 g +93.91 39.963 m 93.91 37.755 92.121 35.966 89.914 35.966 c 87.707 35.966 + 85.918 37.755 85.918 39.963 c 85.918 42.17 87.707 43.959 89.914 43.959 +c 92.121 43.959 93.91 42.17 93.91 39.963 c h +f +0 g +0.0532813 w +q 1 0 0 -1 0 102.400002 cm +93.91 62.438 m 93.91 64.645 92.121 66.434 89.914 66.434 c 87.707 66.434 + 85.918 64.645 85.918 62.438 c 85.918 60.23 87.707 58.441 89.914 58.441 +c 92.121 58.441 93.91 60.23 93.91 62.438 c h +S Q +0.0666667 0.584314 0.662745 rg +3.996098 w +1 M q 1 0 0 -1 0 102.400002 cm +65.938 35.734 m 62.668 33.066 58.496 31.469 53.949 31.469 c 43.465 31.469 + 34.965 39.969 34.965 50.449 c 34.965 60.934 43.465 69.434 53.949 69.434 + c 58.496 69.434 62.668 67.832 65.938 65.168 c S Q +73.43 61.939 m 57.227 62.599 l 61.723 69.591 l 73.43 61.939 m 66.219 76.088 + l 61.723 69.591 l f +0 g +2.997073 w +4 M q 1 0 0 -1 0 102.400002 cm +89.914 84.418 m 89.914 62.438 l S Q +0.00784314 g +93.91 62.439 m 93.91 64.646 92.121 66.435 89.914 66.435 c 87.707 66.435 + 85.918 64.646 85.918 62.439 c 85.918 60.232 87.707 58.443 89.914 58.443 + c 92.121 58.443 93.91 60.232 93.91 62.439 c h +f +0 g +0.0532813 w +q 1 0 0 1 0 102.400002 cm +93.91 -39.961 m 93.91 -37.754 92.121 -35.965 89.914 -35.965 c 87.707 -35.965 + 85.918 -37.754 85.918 -39.961 c 85.918 -42.168 87.707 -43.957 89.914 -43.957 + c 92.121 -43.957 93.91 -42.168 93.91 -39.961 c h +S Q +2.997073 w +q 1 0 0 -1 0 102.400002 cm +89.914 15.484 m 89.914 39.961 l S Q +Q Q +showpage +%%Trailer +end restore +%%EOF Index: tags/1.0.5/doc/resources/cschem_logo_small.svg =================================================================== --- tags/1.0.5/doc/resources/cschem_logo_small.svg (nonexistent) +++ tags/1.0.5/doc/resources/cschem_logo_small.svg (revision 10414) @@ -0,0 +1,192 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/1.0.5/doc/resources/logo.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/1.0.5/doc/resources/logo.png =================================================================== --- tags/1.0.5/doc/resources/logo.png (nonexistent) +++ tags/1.0.5/doc/resources/logo.png (revision 10414) Property changes on: tags/1.0.5/doc/resources/logo.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/1.0.5/doc/resources/logo.rs =================================================================== --- tags/1.0.5/doc/resources/logo.rs (nonexistent) +++ tags/1.0.5/doc/resources/logo.rs (revision 10414) @@ -0,0 +1,109 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=xsOiQL0BalAZ8gK7fkMAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=12000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.2 { + uuid=xsOiQL0BalAZ8gK7fkMAAAAP; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAw; + x=0; y=16000; + li:objects { + ha:group.1 { + uuid=xsOiQL0BalAZ8gK7fkMAAAAQ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAx; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=xsOiQL0BalAZ8gK7fkMAAAAR; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAy; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.4 { x1=3500; y1=-15000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:arc.5 { cx=7000; cy=0; r=2000; sang=-40.000000; dang=220.000000; stroke=sym-decor; } + ha:arc.6 { cx=13000; cy=0; r=2000; sang=0.000000; dang=220.000000; stroke=sym-decor; } + ha:arc.7 { cx=10000; cy=0; r=2000; sang=-40.000000; dang=260.000000; stroke=sym-decor; } + ha:line.8 { x1=4000; y1=0; x2=5000; y2=0; stroke=sym-decor; } + ha:line.9 { x1=15000; y1=0; x2=16000; y2=0; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=rnd + role=symbol + value= + } + } + ha:group.3 { + uuid=xsOiQL0BalAZ8gK7fkMAAAAS; + li:objects { + ha:line.1 { x1=0; y1=16000; x2=0; y2=0; stroke=wire; } + ha:line.4 { x1=0; y1=0; x2=20000; y2=0; stroke=wire; } + ha:line.5 { x1=20000; y1=0; x2=20000; y2=16000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.11 { + li:conn { + /2/3/1 + /2/2/2/1 + } + } + ha:connection.12 { + li:conn { + /2/3/5 + /2/2/1/1 + } + } + } + ha:attrib { + maintainer= + page= + print_page=A/4 + title= + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 2 + grid = 4.0960 mm + } + } + } +} Index: tags/1.0.5/doc/resources/logo.svg =================================================================== --- tags/1.0.5/doc/resources/logo.svg (nonexistent) +++ tags/1.0.5/doc/resources/logo.svg (revision 10414) @@ -0,0 +1,215 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/1.0.5/doc/resources/logo128.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/1.0.5/doc/resources/logo128.png =================================================================== --- tags/1.0.5/doc/resources/logo128.png (nonexistent) +++ tags/1.0.5/doc/resources/logo128.png (revision 10414) Property changes on: tags/1.0.5/doc/resources/logo128.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/1.0.5/doc/resources/logo256.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/1.0.5/doc/resources/logo256.png =================================================================== --- tags/1.0.5/doc/resources/logo256.png (nonexistent) +++ tags/1.0.5/doc/resources/logo256.png (revision 10414) Property changes on: tags/1.0.5/doc/resources/logo256.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/1.0.5/doc/resources/logo32.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/1.0.5/doc/resources/logo32.png =================================================================== --- tags/1.0.5/doc/resources/logo32.png (nonexistent) +++ tags/1.0.5/doc/resources/logo32.png (revision 10414) Property changes on: tags/1.0.5/doc/resources/logo32.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/1.0.5/doc/resources/logo64.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/1.0.5/doc/resources/logo64.png =================================================================== --- tags/1.0.5/doc/resources/logo64.png (nonexistent) +++ tags/1.0.5/doc/resources/logo64.png (revision 10414) Property changes on: tags/1.0.5/doc/resources/logo64.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/1.0.5/doc/resources/logo_nlnet.svg =================================================================== --- tags/1.0.5/doc/resources/logo_nlnet.svg (nonexistent) +++ tags/1.0.5/doc/resources/logo_nlnet.svg (revision 10414) @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/1.0.5/doc/resources/logo_small.svg =================================================================== --- tags/1.0.5/doc/resources/logo_small.svg (nonexistent) +++ tags/1.0.5/doc/resources/logo_small.svg (revision 10414) @@ -0,0 +1,210 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/1.0.5/doc/resources/ringdove2.svg =================================================================== --- tags/1.0.5/doc/resources/ringdove2.svg (nonexistent) +++ tags/1.0.5/doc/resources/ringdove2.svg (revision 10414) @@ -0,0 +1,144 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/1.0.5/doc/resources/screenshot.jpg =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/1.0.5/doc/resources/screenshot.jpg =================================================================== --- tags/1.0.5/doc/resources/screenshot.jpg (nonexistent) +++ tags/1.0.5/doc/resources/screenshot.jpg (revision 10414) Property changes on: tags/1.0.5/doc/resources/screenshot.jpg ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/1.0.5/doc/state.html =================================================================== --- tags/1.0.5/doc/state.html (nonexistent) +++ tags/1.0.5/doc/state.html (revision 10414) @@ -0,0 +1,52 @@ + + + + sch-rnd - State + + + + + + + + + + +
Main + Doc &  Knowledge pool  &  Tutorial + Current state + Events & timeline + sch-rnd [sch-rnd logo] +
+ + +

sch-rnd - current state

+

+Current stable version: 1.0.4. +

+With the release of sch-rnd 1.0.0, +in May 2023, sch-rnd is now considered stable and ready for production usage. +

+(The road that led to 1.0.0 is shown in the archived +older verison of the current page.) + +

sch-rnd - plans for 2023 (archive)

+ +

+With the support of nlnet, the following +features are going to be implemented in 2023 and 2024: +

    +
  • hierarchic design (sheets referencing other sheets as "subsheets" for repetitive parts) +
+

+Features already done as part of the 2023/2024 nlnet effort: +

    +
  • alien file format: load sheets of tinycad and altium and orcad +
  • non-graphical sheets (data or scripted) +
  • raw spice target and export (ngspice and gnucap) +
  • simulation target (SPICE) [1.0.2] +
  • symbol attribute based build options and DNP for the PCB workflow [1.0.2] +
  • symbol editor mode (directly opening a symbol file for interative edit) [1.0.3] +
  • back annotation upgade from pcb-rnd [1.0.3] +
  • symbol attribute based alternate MCU pin function system [1.0.3] +
Index: tags/1.0.5/doc/state.old.html =================================================================== --- tags/1.0.5/doc/state.old.html (nonexistent) +++ tags/1.0.5/doc/state.old.html (revision 10414) @@ -0,0 +1,65 @@ + + + + sch-rnd - State history + + + + + + + + + + +
Main + Doc &  Knowledge pool  &  Tutorial + Current state + Events & timeline + sch-rnd [sch-rnd logo] +
+ + +

sch-rnd - state history

+

+This page is the archived variant of state.html, showing how we reached +our first stable release. +

+This closes the initial intensive development phase (sponsored by nlnet/NGI0). +

+Dates are in yyyy-mm-dd form. + + +
date event/phase + +
Plans for future events +
2023 May First sable release: 1.0.0 + +
Current phase, recent events +
2022-08-18 Beta testing phase starts for simple PCB workflows with pcb-rnd +
2022-09-21 released 0.9.2 (beta testing) +
2022-11-09 released 0.9.3 (beta testing) +
2023-02-08 released 0.9.4 (beta testing) +
2023-03-29 released 0.9.5 (beta testing) + +
Past events +
2017-06-30 Announcement, call for contributors +
2017-07-20 discussion: design process +
2017-07-26 discussion: main components:
system overview draft
implementation details and rationale +
2017-07-29 discussion: schematics data:
spec
implementation details and rationale +
2017-08-23 discussion: drawing primitives:
spec
implementation details and rationale +
2017-09-08 discussion: attributes:
spec
implementation details and rationale +
2017-09-22 discussion: netlist
spec
(no implementation details and rationale) +
2017-10-10 discussion: hierarchic schematics
spec
implementation details and rationale +
2017-11-02 discussion: device mapping - slotting, the transistor problem, heavy vs. light symbols
spec
implementation details and rationale +
2017-11-27 discussion: ripple annotation
spec
implementation details and rationale +
2018-02-19 discussion: bus support - conventions and pseudo-hierarchy (mostly already convered by chapter 2)
spec
implementation details and rationale +
2018-03-05 discussion: is anything left out, not addressed? +
2022-01-12 Initial development to reach beta testing state by end of October 2022 +
2022-03-28 Upcoming alpha release +
2022-05-06 0.8.1: second alpha release +
2022-06-08 0.8.2-alpha: third alpha release +
2022-06-18 0.8.3-alpha: fourth alpha release +
2022-07-16 0.8.4-alpha: fifth alpha release + +
Index: tags/1.0.5/doc/tutorial/Makefile =================================================================== --- tags/1.0.5/doc/tutorial/Makefile (nonexistent) +++ tags/1.0.5/doc/tutorial/Makefile (revision 10414) @@ -0,0 +1,24 @@ +ROOT=../.. +TUTDIR=$(DOCDIR)/tutorial + +all: + +install_all: + $(SCCBOX) mkdir -p $(TUTDIR) + $(SCCBOX) $(HOW) -d *.html $(TUTDIR) + +install: + $(MAKE) install_all HOW="install -f -d" + +linstall: + $(MAKE) install_all HOW="install -f -l -d" + +uninstall: + $(MAKE) install_all HOW="install -u" + +clean: + +distclean: + + +include $(ROOT)/Makefile.conf Index: tags/1.0.5/doc/tutorial/done.txt =================================================================== --- tags/1.0.5/doc/tutorial/done.txt (nonexistent) +++ tags/1.0.5/doc/tutorial/done.txt (revision 10414) @@ -0,0 +1,447 @@ +Tutorial videos done: + ++ getting started (~15..20 minutes) + (single sheet only) + (default lib only) + (blinking LEDs, 2 transistors, PCB workflow) + - setup: + - sheet attributes for the titlebox + - save + -place + - library window, place symbols + - arrange symbols + - draw nets + - shift + - {/} + - endpoint drag for draeing the crossing + - connection indication (layer toggle) + - metadata + - {a a} name symbols (all!) + - {a v} change value: res, cap + - {a f} change footprint on resistors + - (explain devmap) + - {a d} on NPNs + - {a d} on leds and caps + - place floater on devmap + - {a a} name nets + * this can be done more efficiently, shown in another video + - battery portmap + - save + - create/arrange floaters for net names + - abstract model & netlist + - inspect the abstract model with {w a} + - explain abstract/concrete models and terminology + - export tEDAx netlist + - export ps + + ++ arbitrary grouping sheet decoration + - draw an arrow + - box-select + - convert to group + - group origin + - select, move it around, transform, copy in group + - save/load menu + ++ selections and locking + - click-select + - click-away to unselect + - beware of clicking within symbols + - only on wirenet: double selection means select wirenet + - shift+click to add selection + - shift+click to remove from selection + - positive selection box + - do not start on an existing object, that's drag&drop move + - negative selction box + - layer visibility + - lock object so it can not be selectd + - unlock is the only tool that works on locked objects + ++ constructing an arbitrary polygon + - draw lines and arcs + - make sure endpoints connect + - select all + - select menu, convert to polygon + - propedit: + - fill color + - stroke color + - has_fill + - has_stroke + - clicking works only on the contour! + - break up, edit, convert again + - won't remember stroke and fill + ++ operations on object vs. selected + - object: + - right click context menu + - {e s}, {a a} and alike + - transformations (mirror, rotate) + - invoke from menu -> no cursor -> ask for obj (rotate) + - drag&drop endpoint move is nothing is selected + - drag&drop object move is nothing is selected + - selection: + - drag&drop move if anything is selected + - convert hotkeys + - select menu + ++ paste buffers + - open with 2 sheets + - copy with ctrl+c + - cut with ctrl+x + - paste with the buffer tool + - while the buffer tool is active: + - rotate buffer with {e w}, + - mirror with {e v} for vertical or {e h} for horizontal + - {b r a} for arbitrary rotation + - multi-sheet: buffer is cross-sheet + - undo effects sheet part (e.g. paste or cut) but not buffer contents + - multiple buffers + - buffer saves/load + - full content + - group/symbol + ++ backann + ++ how to use the crosshair + ++ how to use propedit for multi-object editing + ++ how to construct a symbol + - symbol: piezo-electric buzzer + - draw decoration + - use {p t} to place terminals + - mention standard grid (4k) + - arrange everything + - name terminals using {a a} + - select, convert to symbol + - save symbol + - move symbol to lib + - refresh lib + ++ undo/redo + - open with two sheets + - line, circle, move + - open the undo dialog + - undo with {u u}, redo with {u r} + - undo/redo from the dialog + - explain the undo list (list of operations) + - it is not saved + - it is per sheet + - demonstrate multisheet + ++ custom pinout with devmap (how to create devmap) + (do the same as in "custom pinout with portmap" above) + - enable autocompile + - copy one of the existing files + - open datasheet, open the symbol in raw mode + - fill in the pinout + - place transistor symbol + - change devmap attribute (context menu or hotkey {a d}) + ++ custom pinout with converting to heavy symbol + (need the datasheet of some old device) + - enable autocompile + - place transistor symbol + - attribute editor + -remove devmap attribute + - add the footprint attribute + - close editor + - remove the devmap floater leftover + - {a a} over each term label + ++ custom pinout with portmap + (need the datasheet of some old device) + - enable autocompile + - place transistor symbol + - attribute editor, remove devmap attribute + - add the footprint attribute + - add portmap attribute, convert to array + - assisted edit portmap + ++ text edit: tools and basic properties + - place text + - use {e t} to edit ot + - use {e s} to change pen + - change rotation + - no mirror + - show bbox with (....) + ++ dyntext text object edit: dyntext + - place text + - use {e t} to edit text + - propedit + - edit text, add %../A.title% + - enable dyntext + - invoke the tree to show why this works, explain the .. part + - edit sheet attribute title to show it is the same thing + - show 3-field {e t} + - demonstrate how refdes is the same thing + - demonstrate how any other attribute can be printed + - quicker path is 'add floater' + - demonstrate how term label is the same thing, explain the 'a' vs 'A' part + +-- attribute editor: basics + - enable autocompile + (- place a symbol: npn transistor) + - opening symbol attributes + - context menu + - {a a} + - using the attribute editor + - left side concrete, right side abstract + - edit value of existing string attributes: name + - see how it changes on the right side + - add custom attribute: product_id (shows up on the right) + - edit name of existing attribute (product_id to prod_id) + - create a floater for prod_id + - del attribute (prod_id) + - delete floater + +-- attribute editor: array editing and assisted editing + (- place a symbol: npn transistors) + - open attribute editor + - remove the devmap attribute + - create portmap attribute + - change it to array + - use assisted edit for mapping 2 pins + - fill in the 3d pin using raw array edit + +-- using pens + - place text, draw a rectangle around it and place a symbol + - choose different stroke pen for the text - use menu + - choose different stroke pen for the rect - use {e s} + - choose different fill pen for rect + - explain where pens are stored and how they are defined for purpose not looks + - demonstrate this on sym-decor + - create a new pen called error + - change text and rectangle to error pen + +-- text: alignment, bbox-defined text + - origin + - place text object (looong text) + - text size: pen {e s} (refer to the pen video) + - enable text meta layer -> bbox shown + - change font size -> bbox grows + - change text -> bbox grows + - explain the origin of the text object, "grows away" + - horizontal-mirror text to show the grow-away effect + - (there's no real mirror: pixels are not mirrored) + - bbox based + - property editor, enable has_bbox + - edit text to longer -> bbox remains, text size shrinks: width-constraint + - edit text to shorter -> bbox remains: height-constraint + - propedit, different halign values + - mirror: origin and halign matter together + +-- how to connect things (net) + - wire: draw net + - wires + net names + - wire stub + net names + - connect symbol attribute + - vcc, gnd + - generic rail symbol + +-- tree view: + - 2 sheets + - window menu, show both sheets + - navigate to object + - mention preview + - select/unselect + - propedit, attr edit + - del -> pending update + - right click invocation + +-- propedit dialog (multi is already covered) + - right click propedit on a symbol + - close subtrees + - explain p/ and a/ + - reopen subtrees + - a/ + - open a/, open attr dialog, compare + - a/role: edit as string, edit with assisted edit + - p/ + - explain generic flags + - explain grp/ + - change rot by abs value + - step rot + - change rot by rel value + - open a new propedit on a text object + - explain there's no a/ + - show the different p/text subtree + - change rot + +-- navigating the abstract model (tracing back sources) + - use the slot2 example + - find objects: + - U1 sources + - explain multisheet case + - U1's 1/A port source + - net/clk sources + - attribute history: + - U1, 3/Z + - pcb/pinnum attribute + - history src (tooltip!) -> U1 portmap + - history src -> attr edit -> change to 87 + - tree view to abstract + - right click on the terminal for 87 + - left side: no 87; right side: 87 + - history src twice + ++ how to speed up setting symbol attributes + - show the manual way + - make one right, copy that + - select + :propedit -> quick edit button on the bottom right! + * multi on arc is already shown in another video + - renumber plugin + ++ symbol terminal: + - text alignment on terminals + - turn on text meta + - mirroring terminals instead of just moving + - text alignment inside the body + - same as terminals, just align the other way around + - how to make terminal longer (sloped, opamp example) + - cheat with an extra line + - create the terminal by converting a line + ++ export sheet + - graphical export from menu or keyboard (single sheet, png, svg) + - automated export using -x (single sheet, png, svg) + - default output file name: generated from sheet name + - override default output file name + ++ export project + - graphical export from menu or keyboard (multi-page ps, multi-file svg) + - automated export using -x project.lht (multi-page ps, multi-file svg) + -> all pages listeed are exported + - automated export using -x doc.lht MCU.lht (multi-page ps) + -> only pages named are exported + - default output file name depends on project.lht + - override default output file name + ++ flat multisheet with implicit project file listing + - start sch-rnd with multiple sheets from cli + - show that project is marked [i] in the sheetsel + - explain implicit projects + - sheet files are in the same directory, that's how they are an implicit project + - if there's project file, it holds cfg, no sheet list + - does not matter if project file exists or not, but whether sheet list is empty or not + - implicit project files work from the command line: + - when sch-rnd is started for editing + - or for export + - explain implicit projects + - disadvantage: sch-rnd is not aware of the file names + - advantage: no extra project file list (e.g. compared to Makefile) + - show a makefile!!! + - creating new sheet + - CLI: name it on the command line + - GUI: menu: new unlisted sheet + - load the file from the GUI + ++ flat multisheet with explicit project file listing + - mkdir from the shell + - run sch-rnd, menu for create new project + - create three types of new sheets plus one extra + - quit and start sch-rnd then load the project file + - quit and start sch-rnd with the project file + - quit and export the project with -x + - show [e] for explicit project + - load partial projects: + - start sch-rnd with not all sheets + - start sch-rnd on the project file but unload sheet + - show the menu for loading missing sheets + - show project properties, change the type of the extra sheet + ++ multiple pins per terminal + - (explain the so(8) mosfet problem) + - draw mostfet, 3 resistors + - remove devmap from the mosfet, add portmap + - fill in portmap: S=1 2 3; G=4; D=5 6 7 8 + - add footprint + - export to tedax, show the result + ++ how to use the preferences window, part 1 + - load a sheet so that we have a project file + - invoke from file menu + - navigate to the color tab + - set role!!! to project + - change generic color for "beyond drawing area", explain it's a frame/indication + - exit, restart -> no frame; load -> frame; show a differnt project has no frame + - redo the whole thing on user role + - restart; show it's not project dependent + ++ how to use the preferences window, part 2 + - load a sheet so that we have a project file, from part 1 + - invoke from file menu + - tree tab + - show the left side tree and search for color; off_limit is ours + - explain the right side (top is input, bottom is conclusion) + - (show this in the project file) + - remove selected on project level + - add a different one on project level + - explain read-only levels + ++ attribute editor: overriding footprint attribute using prio + - place a symbol: nfet + - devmap is 2n7002_sot23 + - open attribute editor + - show footprint on the right side + - show history of footprint attribute on the right side -> it's from devmap + - add footprint to sot23_bigpad + - show history of footprint attribute on the right side -> it's overridden + - change attribute prio to 31050 + - show history of footprint attribute on the right side -> it's devmap again + - show how devmap prio is calculated (engine list) + - show the table for default prios + ++ drawing sheet decoration + - lines + - line tool vs. wire tool + - anydir vs. orthogonal + - top level objects vs. wirenet group (show tree on right click) + - juntions made (draw junctions) + - move at once - no select + - grab endpoint - no select + - move selected + - stroke {e s} + - rectangles + - stroke {e s} + - fill + - text + - stroke {e s} changes font + ++ local lib support for devmaps + - empty sheet, place fet and an npn + - show devmap attributes + - open the {w w d} dialog from menu + - show , lm358 inserted + - show "count" + - show refresh button, explain it is for edited + - turn off compilation + - mass version: maintenance menu, clean + - compile + - show these buttons are not present in other parts of the lib + - show lib refresh doesn't work in + ++ local lib support for symbols, part 1 + - (turn off autocompile, save, set up terminal with watch ls -l) + - save sheet with a single resistor, show size + - show how file size is growing with 4 copies of the same resistor + - show propedit: grp type + - delete all resistors, save + - enable lolib: mode menu, symbol libraries + - place a resistor, save, show file size + - place a 4 copies, save, show file size + - show propedit: grp_ref type + - explain how shared attributes are not accessible + - open attribute editor + - show the two sections + - add new, value, show it is added to the local section + - edit value, show how it is copied + - open library window, show local lib section + - show the # button + - edit value in loclib, show how all changes... + - ... except for the one with local deviation + - refresh: overwrites our value change + - remove and unembed + -> show file size + Index: tags/1.0.5/doc/tutorial/index.html =================================================================== --- tags/1.0.5/doc/tutorial/index.html (nonexistent) +++ tags/1.0.5/doc/tutorial/index.html (revision 10414) @@ -0,0 +1,135 @@ + + + + sch-rnd - Tutorial + + + + + + + + + + +
Main + Doc &  Knowledge pool  &  Tutorial + Current state + Events & timeline + sch-rnd [sch-rnd logo] +
+ + +

sch-rnd tutorial

+

+The official sch-rnd video tutorial consists of three chapters: +

    +
  • a longer "getting started" episode which serves as the backbone +
  • a series of short episodes that assume the base episodes and previos eposides has been watched +
  • a collection of independent episodes, each demonstrating a set of features, assuming only chapter 1 and 2 are watched +
+

+After watching all episodes of chapter 1, you will be able to use sch-rnd on +beginner level, for drawing simple circuits for the PCB workflow. After +watching chapter 2 you will be able to use sch-rnd in intermediate level, +much more efficiently, for more complex designs for the PCB workflow. Advanced +topics and non-PCB workflows are covered in chapter 3, which should be watched +selectively, on a per topic basis. + +

Chapter 1: getting started

+

+(18 minutes) +

+ Blinking LED board (also on youtube) +

+Topics covered: +

    +
  • symbol placement, +
  • wiring, +
  • attributes, +
  • devmaps for pinout, +
  • export netlist, +
  • export to postscript and png. +
+ +

Chapter 2: using sch-rnd

+

+(1..5 minutes each) +

+

    +
  1. using the crosshair to line things up (also on youtube) +
  2. using undo and redo, undo list (also on youtube) +
  3. Selections & layers (also on youtube) +
  4. Operations on objects vs. selection (also on youtube) +
  5. Paste buffers (also on youtube) +
  6. Sheet decorations +
  7. Text + +
  8. Custom groups (also on youtube) +
  9. Drawing polygons: polygon conversion from objects (also on youtube) +
  10. Networks, wiring + +
  11. Handling pinouts with generic symbols (the "transistor problem") + +
  12. Editing metadata + +
  13. Pens (color & font) (also on youtube) +
  14. Creating new symbols (GUI) (also on youtube) +
  15. Creating symbol terminals (GUI) (also on youtube) +
  16. Exporting data + +
  17. Multisheet projects + + +
+ +

Chapter 3: advanced topics

+

+

+ +

Chapter 4: Multipart, written tutorials

+

+

+ + + Index: tags/1.0.5/doc/tutorial/plan.txt =================================================================== --- tags/1.0.5/doc/tutorial/plan.txt (nonexistent) +++ tags/1.0.5/doc/tutorial/plan.txt (revision 10414) @@ -0,0 +1,29 @@ +Tutorial videos in production or planned: + +- local lib support for symbols, part 2 + - explain the scope of embedding and local libbing: + - symbol attributes + - terminal attributes + - graphics + TODO: check if these are undoable + - right click context menu for embed + - right click context menu for unembed + - maintenance menu for upgrading all symbols + +TODO: +- advanced search & query +- a devmap/portmap part 2 video for slotting [report: SnakesAndStuff] +- a video on search paths: [report: SnakesAndStuff] + - default project locals + - default user local in ~/.sch-rnd, including symlinking + - advanced conf usage with append/prepend and a text editor + + +TODO later: +- printing U1A for slot (for name=U1 slot=A) +- build options: stances with omit and dnp +- sheet decoration advanced: arc; draw circle, propedit, (TODO: grab endpoint) +- loose sym: behaves as if every object of every symbol was a floater; loclib: does per instance child xform (same as with floaters) +- polyedit (+with ctrl) +- rubber band mode (+rubber band ortho) +- funcmap Index: tags/1.0.5/doc/tutorial/simulation/index.html =================================================================== --- tags/1.0.5/doc/tutorial/simulation/index.html (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/index.html (revision 10414) @@ -0,0 +1,159 @@ + + + +

sch-rnd simulation (SPICE) tutorial

+

+This tutorial goes through the topic of Circuit Simulation with sch-rnd. +More specifically: lumped element simulation using SPICE (various implementations). +Since sch-rnd itself does not contain any simulation code, all the +methods described here rely on external SPICE simulation software. +

+As of writing (2023), there are a bunch of proprietary SPICE implementations +and a few open source alternatives. This tutorial is focusing on the open +source implementations. There are three main open source alternatives: +

    +
  • ngspice: derived from the traditional Berkely SPICE, upgraded with + additional extras (such as mixed analog-digital and behavioral + simulation by merging xspice and CIDER). +
  • gnucap: independent implementation; may run faster than ngspice; + no mixed analog/digital support in sch-rnd. Not recommended + because of various problems in compatibility and stability. +
  • xyce: should work but is not tested with sch-rnd at the moment. +
+

+At the moment sch-rnd recommends using ngspice because that implementation +has the most complete support and is the most well-tested with sch-rnd. + + +

Two levels of simulation

+

+Sch-rnd is designed to allow single schematics to be used for different +workflows, e.g. both spice simulation and PCB layout. There are various +(sometimes optional) abstractions over spice to make this possible. +

+The low level of simulation are: +

    +
  • The raw spice approach; + this assumes the user speaks spice and wants to run the simulator + by hand, outside of sch-rnd (e.g. from a shell or Makefile). When + using this method, the schematics will likely end up with spice + commands and parameters that depend on a spice implementation. + That is, "this sheet is for ngspice" or "this sheet is for gnucap". +
  • The more generic simulation approach, + which introduces a higher abstraction layer over spice. The advantages + are that the user does not need to know as much about spice, the + same sheet can be used with different spice implementations and + sch-rnd can coordinate executing the simulation and can provide a GUI + for visualizing the results. It is possible to keep a plot window open, + make changes on the sheet (e.g. tune resistor values) and rerun the + simulation getting the plot updated with a single click. + Simulator execution and GUI are optional, + the abstraction itself can be used from command line too. The drawback + is that the user needs to learn an abstraction that is specific to + sch-rnd, while some minimal spice knowledge (for the models) is still + required. +
+

+For new users the recommendation is: unless you already have a lot of +experience with spice, it is better to go for the simulation approach. +

+The user manual contains +a section on simulation. + +

Tutorial

+

+The tutorial is a system of smallish examples. Each new example adds something +and assumes previous examples are understood. The recommended way of +reading the tutorial is to pick one of the raw +simulator or the high level sim target and click through the examples for +that column. +

+Note: the raw examples are always written for ngspice with considerations +for other spice implementations mentioned at the end of each example. The high +level simulation works only with ngspice at the moment. +

+ + + + + + + + + + + +
title + raw ngspice + raw gnucap + high level sim + concepts + +
01_dc + yes + yes + yes + sch-rnd: sheet setup +
sim: dc operating point + +
04_passive_tr + yes + yes + yes + sim: transient (time domain) analysis, voltage source (pulsed) + + +
06_passive_ac + yes + yes + yes + sim: ac (frequency domain) analysis + + +
10_bjt_amp_tr + yes + yes + yes + sch-rnd: spice model, spice pinout +
sim: time domain sim and SINE() source + +
12_bjt_amp_ac + yes + yes + yes + sch-rnd: spice pinout with portmap +
sim: ac analysis + + +
16_opamp_dc + yes + error + yes + sim: dc sweep + +
18_opamp_ac + yes + error + yes + sch-rnd: 2-slot opamp + +
22_custom_sym + yes + yes + yes + sch-rnd: symbol inline model card, spice/prefix + +
30_mixed + yes + N/S + TODO + sch-rnd: ADC/DAC bridging from terminal attributes +
sim: mixed analog+digital +
+

+Legend: +

    +
  • error: supported in theory, but the simulation fails with an error +
  • N/S: not supported +
  • TODO: sch-rnd code missing or example not yet developed +
Index: tags/1.0.5/doc/tutorial/simulation/raw/01_dc.html =================================================================== --- tags/1.0.5/doc/tutorial/simulation/raw/01_dc.html (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/raw/01_dc.html (revision 10414) @@ -0,0 +1,164 @@ + + +

01_dc: sheet preparation and DC op point

+ +

Scope

+

+In this simulation we are going to calculate the DC operating point of a +simple voltage divider. This is also an introduction to setting up a +sheet for circuit simulation. This tutorial deals with differences between +spice implementations by describing the process for ngspice and then any +differences for other implementations are described at the bottom. + + +

The schematics

+

+The single-sheet schematic contains the voltage divider with all networks +named and two extra symbols for the simulation: +

    +
  • a 5V voltage source, V1 +
  • a spice command symbol +
+

+Note: these symbols do not have a footprint attribute so they are not exported +in the PCB workflow. +

+

+ +
Click the image to get the sch-rnd sheet
+

+ +

SPICE: what is a DC op point

+

+In SPICE simulation there are different analysis options available: these +are different simulation actions or operations or modes. Basically each +analysis is a different algorithm to run on the circuit. The simplest +analysis is called the "DC operating point analysis". +

+In the op point analysis, the simulator will apply all sources, assume +all inductors are shorted and assume all capacitors are open and then calculate +the voltage for all nodes. (Node is the spice terminology for an equipotential +electrical network.) This simulation is not time or frequency dependent, and +represents a single DC operating point once the circuit has already stabilized. +

+In our example, this means V1's 5V is applied and the voltages at in, out1 and +out2 are calculated. Since V1 is an ideal voltage source capable of supplying +any amount of current, the voltage on the in network will be 5V; but the +voltages on out1 and out2 will depend on the resistor values of R1, R2 and R3. + + +

Preparing for simulation

+ +

Symbols and nets

+

+Draw the schematics as usual; make sure there is a gnd network, spice won't +work without that. Ideally, use the stock gnd symbol for that. Make sure +all resistors have a unique name and a value. Spice understands the normal +SI suffixes such as k for kilo, but as it is generally not case sensitive, +m and M are both milli, so you will need to write meg to get mega. +

+Your symbols also need to have the proper spice pin numbers. First switch +your view from the default pcb to spice_raw: there's a button for this on +the top right part of the main window, on the left of the help/support button. +This pops up a view selector; click raw_spice twice and the selector will close +and the view will change. The new view will show pin numbers as seen by the +spice target. For plain resistors, pin ordering does not matter, but it is +important for polarized parts like diodes, transistors, and sources. The +stock library has spice pin numbers set up and should work without +modification. Later chapters of this tutorial will explain how to deal with +spice pin numbers in symbols. + + +

V1

+

+In the raw spice approach, the voltage source needs to be specified in the +concrete model. The easiest way is to place a source-DC symbol from the +stock library in between the in network and the ground. The name +of the symbol does not matter; as we are using it as a voltage source, +it is best to name it V1. To make it produce a steady 5V output, create +an attribute called spice/params and set it to DC 5V. It is +also a good idea to make this visible in the form of a floater. +

+External resource: +ngspice manual on voltage and current sources explains all the different parameter options; spice/params is the part that gets written after N-; later chapters will demonstrate using more complex waveforms than plain flat DC. +For a DC operating point we are only interested in the DC component, tho. + +

Raw spice commands

+

+The circuit is complete. It could be exported and the simulator could read it, +but command to start any simulation would need to be specified by hand, on the +simulator's command line. It is more convenient for now to specify these +commands in the schematics. For that, the spice_command symbol is placed from +the stock library. The actual spice commands are stored in the spice/command +attribute. This is typically a multiline string attribute. Use the attribute +editor (accessible from the right click menu over the symbol), select the +attribute and click on the "edit multiline" button. +

+It contains two lines: +

+op
+print v(out1) v(out2)
+
+

+The first line instructs spice to do the "DC operating point analysis", +the second tells it to print the voltage of out1 and the voltage of out2 +(each measured to ground) on stdout. You can list more voltages here by +v(netname) and it is possible to print currents and other properties, +as will be shown in later chapters of this tutorial. +

+Note: this symbol has no name attribute, so it is not exported as a normal +component. + + +

Export the netlist

+

+GUI export: make sure your view is set to spice_raw, as it affects not only +how the circuit is displayed on the GUI but also how it is exported. Open +the file menu, click on export project (hotkey: {f j}). Select spice in +the export dialog, verify the file name and click the export button. +

+CLI export: +

+sch-rnd -x spice --view spice_raw 01_dc.rs
+
+

+ +

Run ngspice

+

+From a shell run this command (assuming the exported netlist is called 01_dc.cir): +

+ngspice 01_dc.cir
+
+

+This will print a lot of noise and these two lines: +

+v(out1) = 2.380952e+00
+v(out2) = 1.190476e+00
+
+

+These are the voltages (in V) measured on the networks out1 and out2 in +steady state. Type quit to exit the spice prompt. + + +

Using other implementations

+

gnucap

+

+Gnucap uses a different command syntax. Modify the spice command symbol's +spice/command attribute to: +

+print dc v(out1) v(out2)
+dc
+
+

+This tells gnucap what to print after a dc simulation then runs the dc simulation. +

+After the export, write the single word spice in the first line of the +file (e.g. using a text editor), otherwise gnucap won't know the file is in spice +syntax. Then run gnucap 01_dc.cir and it will print (among tons of +noise) the two voltages. +

+The gnucap-modified schematic is also available. + +

xyce

+

+TODO Index: tags/1.0.5/doc/tutorial/simulation/raw/01_dc.rs =================================================================== --- tags/1.0.5/doc/tutorial/simulation/raw/01_dc.rs (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/raw/01_dc.rs (revision 10414) @@ -0,0 +1,478 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.1 { + uuid=8/SYZ/pfBzxyqFA12WQAAAAC; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAg; + li:objects { + ha:polygon.11 { + li:outline { + ha:line { x1=0; y1=0; x2=80000; y2=0; } + ha:line { x1=80000; y1=0; x2=80000; y2=20000; } + ha:line { x1=80000; y1=20000; x2=0; y2=20000; } + ha:line { x1=0; y1=20000; x2=0; y2=0; } + } + stroke=titlebox-frame; + fill=titlebox-fill; + } + ha:line.12 { x1=0; y1=10000; x2=80000; y2=10000; stroke=titlebox-frame; } + ha:line.13 { x1=40000; y1=10000; x2=40000; y2=0; stroke=titlebox-frame; } + ha:text.20 { x1=1000; y1=16500; dyntext=0; stroke=titlebox-big; text=TITLE; } + ha:text.21 { x1=1000; y1=10500; x2=79000; y2=16000; dyntext=1; stroke=titlebox-big; text=%../../A.title%; } + ha:text.22 { x1=1000; y1=5500; dyntext=0; stroke=titlebox-small; text={PROJECT:}; } + ha:text.23 { x1=13000; y1=5500; x2=39000; y2=9500; dyntext=1; stroke=titlebox-big; text=%project.name%; } + ha:text.24 { x1=1000; y1=500; dyntext=0; stroke=titlebox-small; text={PAGE:}; } + ha:text.25 { x1=10000; y1=500; x2=39000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.page%; } + ha:text.26 { x1=41000; y1=5500; dyntext=0; stroke=titlebox-small; text={FILE:}; } + ha:text.27 { x1=48000; y1=5500; x2=79000; y2=9500; dyntext=1; stroke=titlebox-big; text=%filename%; } + ha:text.28 { x1=41000; y1=500; dyntext=0; stroke=titlebox-small; text={MAINTAINER:}; } + ha:text.29 { x1=55000; y1=500; x2=79000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.maintainer%; } + } + ha:attrib { + purpose=titlebox + } + } + ha:group.3 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAY; + x=-24000; y=-12000; + li:objects { + ha:line.1 { x1=36000; y1=116000; x2=52000; y2=116000; stroke=wire; } + ha:line.2 { x1=44000; y1=108000; x2=44000; y2=116000; stroke=wire; } + ha:line.3 { x1=44000; y1=116000; x2=44000; y2=116000; stroke=junction; } + ha:text.4 { x1=36000; y1=116000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=in + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.6 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAZ; + x=-20000; y=-12000; + li:objects { + ha:line.1 { x1=40000; y1=88000; x2=40000; y2=60000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.8 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAg; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=28000; y=104000; + li:objects { + ha:group.1 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAh; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAi; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=R1 + role=symbol + spice/prefix=R + value=2.2k + } + } + ha:group.14 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAz; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=52000; y=100000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=LnNTcUkV1CIzG7F2EXUAAAA0; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=LnNTcUkV1CIzG7F2EXUAAAA1; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=R2 + role=symbol + spice/prefix=R + value=1k + } + } + ha:group.24 { + uuid=LnNTcUkV1CIzG7F2EXUAAABA; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=20000; y=48000; + li:objects { + ha:group.1 { + uuid=LnNTcUkV1CIzG7F2EXUAAABB; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.33 { + uuid=F3n6uHwVbWw4HTjelNgAAAAf; src_uuid=TeGEOMuew6iCb2kzckAAAAAD; + x=16000; y=136000; + li:objects { + ha:text.1 { x1=2000; y1=-4000; dyntext=0; stroke=sym-decor; text=raw spice; } + ha:text.2 { x1=2000; y1=-8000; dyntext=0; stroke=sym-decor; text=command; } + ha:polygon.3 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=-10000; } + ha:line { x1=0; y1=-10000; x2=12000; y2=-10000; } + ha:line { x1=12000; y1=-10000; x2=12000; y2=0; } + ha:line { x1=12000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + } + ha:attrib { + -sym-comment={ Fill in spice/command and use export_spice (e.g. the spice_raw view) to get that string exported at the end of the spice netlist file. } + -sym-copyright=(C) 2023 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + role=symbol + spice/command={op +print v(out1) v(out2) +} + } + } + ha:group.34 { + uuid=XkMAnbHX1rIO2D9kjFAAAAAk; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB0; + x=20000; y=96000; rot=270.000000; mirx=1; + li:objects { + ha:group.1 { + uuid=XkMAnbHX1rIO2D9kjFAAAAAl; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB1; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=N + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.2 { + uuid=XkMAnbHX1rIO2D9kjFAAAAAm; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB2; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=P + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:arc.3 { cx=10000; cy=0; r=6000; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:line.4 { x1=7000; y1=2000; x2=7000; y2=-2000; stroke=sym-decor; } + ha:line.5 { x1=5000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=11000; y1=0; x2=15000; y2=0; stroke=sym-decor; } + ha:text.7 { x1=0; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:text.8 { x1=0; y1=4000; dyntext=1; stroke=sym-secondary; text=%../A.spice/params%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=V1 + role=symbol + spice/params=DC 5V + } + } + ha:group.37 { + uuid=XkMAnbHX1rIO2D9kjFAAAAAn; + x=-24000; y=-12000; + li:objects { + ha:line.1 { x1=72000; y1=116000; x2=84000; y2=116000; stroke=wire; } + ha:line.2 { x1=76000; y1=112000; x2=76000; y2=116000; stroke=wire; } + ha:line.3 { x1=76000; y1=116000; x2=76000; y2=116000; stroke=junction; } + ha:text.4 { x1=84000; y1=116000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=out1 + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.40 { + uuid=XkMAnbHX1rIO2D9kjFAAAAAr; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=52000; y=72000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=XkMAnbHX1rIO2D9kjFAAAAAs; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=XkMAnbHX1rIO2D9kjFAAAAAt; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=R3 + role=symbol + spice/prefix=R + value=1k + } + } + ha:group.42 { + uuid=XkMAnbHX1rIO2D9kjFAAAAAw; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=52000; y=48000; + li:objects { + ha:group.1 { + uuid=XkMAnbHX1rIO2D9kjFAAAAAx; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.43 { + uuid=XkMAnbHX1rIO2D9kjFAAAAAy; + x=-24000; y=-16000; + li:objects { + ha:line.1 { x1=76000; y1=64000; x2=76000; y2=68000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.49 { + uuid=XkMAnbHX1rIO2D9kjFAAAAAz; + x=-24000; y=-12000; + li:objects { + ha:line.1 { x1=76000; y1=84000; x2=76000; y2=92000; stroke=wire; } + ha:line.2 { x1=76000; y1=88000; x2=84000; y2=88000; stroke=wire; } + ha:line.3 { x1=76000; y1=88000; x2=76000; y2=88000; stroke=junction; } + ha:text.4 { x1=84000; y1=88000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=out2 + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.53 { + li:conn { + /2/8/2/1 + /2/3/1 + } + } + ha:connection.54 { + li:conn { + /2/24/1/1 + /2/6/1 + } + } + ha:connection.55 { + li:conn { + /2/34/1/1 + /2/6/1 + } + } + ha:connection.56 { + li:conn { + /2/34/2/1 + /2/3/2 + } + } + ha:connection.57 { + li:conn { + /2/37/1 + /2/8/1/1 + } + } + ha:connection.58 { + li:conn { + /2/37/2 + /2/14/2/1 + } + } + ha:connection.59 { + li:conn { + /2/43/1 + /2/40/1/1 + } + } + ha:connection.60 { + li:conn { + /2/43/1 + /2/42/1/1 + } + } + ha:connection.61 { + li:conn { + /2/49/1 + /2/14/1/1 + } + } + ha:connection.62 { + li:conn { + /2/49/1 + /2/40/2/1 + } + } + } + ha:attrib { + maintainer=Tibor 'Igor2' Palinkas + page=1 of 1 + print_page=A/4 + title={SIM raw spice: DC operating point} + } + } +} Index: tags/1.0.5/doc/tutorial/simulation/raw/01_dc.svg =================================================================== --- tags/1.0.5/doc/tutorial/simulation/raw/01_dc.svg (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/raw/01_dc.svg (revision 10414) @@ -0,0 +1,634 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/1.0.5/doc/tutorial/simulation/raw/04_passive_tr.html =================================================================== --- tags/1.0.5/doc/tutorial/simulation/raw/04_passive_tr.html (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/raw/04_passive_tr.html (revision 10414) @@ -0,0 +1,104 @@ + + +

04_passive_tr: time domain simulation: tran

+ +

Scope

+

+In this simulation we are going to look at how a multi-stage RC filter behaves +when the input voltage is switched from 0 to 5V. + +

The schematics

+

+The single-sheet schematic contains the filter, the voltage source and +the spice command symbol. +

+

+ +
Click the image to get the sch-rnd sheet
+

+ +

SPICE: what a tran simulation is

+

+In the tran(sient) analysis a DC solution is calculated first +then a simulation is run with a fixed time stepping, updating the internal +states of components (e.g. capacitor charges) and networks (voltages). The +result is typically a graph with time along the X axis and voltages/currents on +the Y axis. + +

Preparing for simulation

+ +

V1

+

+In our example, V1 uses a PULSE wave form as the stimulus on the in network. +The SPICE syntax of PULSE is: +

+PULSE(V1 V2 TD TR TF PW PER NP)
+
+

+Voltage is changed from V1 to V2 after a delay of TD with a rising time of TR. +Later the output will fall back to V1 with the falling time of TF. Pulse width +is PW. All the T's and P's are in seconds. The process is repeated NP times +and the period of the wignal is PER (in seconds). The last few parameters +are optional. +

+In our example we are only interested in a sharp rising edge: +

+spice/params=PULSE (0 5 1u 1u 1u 1 1)
+
+

+Initial delay and rise time are set very short (1 microsec) then the pulse width +and period are set to 1s. The circuit will reach its steady state in a fraction +of a second, so this means we are really doing only a rising edge +from 0 to 5V. + +

Raw spice commands

+

+It contains two lines: +

+tran 0.1ms 200ms
+plot v(in) v(mid) v(out) xlimit 0 200ms
+
+

+The first line instructs spice to do the "transient analysis" with 0.1ms +time stepping up to 200ms. +The second tells it plot (draw) three voltages; our X axis is time (because +of tran), and to display the plot between 0 and 200ms. + + +

Export and run ngspice

+

+Because of the plot command the output is a drawing (if ngspice is run +on X), consisting of a graph with three curves. Fastest is v(in), a +slower, curvy trace is mid's voltage and the slowest to follow is v(out). +

+ + + +

Using other implementations

+

gnucap

+

+Gnucap uses a different command syntax. Modify the spice command symbol's +spice/command attribute to: +

+print tran v(in) v(mid) v(out)
+tran 0.1ms 200ms > plot.txt
+
+

+This tells gnucap what to print after a tran simulation then runs the tran +simulation, redirecting the printout to a file called plot.txt. +

+After the export, write the single word spice in the first line of the +file (e.g. using a text editor), otherwise gnucap won't know the file is in +spice syntax. Then run gnucap 04_passive_tr.cir and it will dump a text +table to plot.txt. Run gnuplot and type the following command: +

+plot "plot.txt" using 1:2 with lines title "v(in)", \
+ "plot.txt" using 1:3 with lines title "v(mid)", \
+ "plot.txt" using 1:4 with lines title "v(out)";
+
+

+The gnucap-modified schematic is also available. + +

xyce

+

+TODO Index: tags/1.0.5/doc/tutorial/simulation/raw/04_passive_tr.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/1.0.5/doc/tutorial/simulation/raw/04_passive_tr.png =================================================================== --- tags/1.0.5/doc/tutorial/simulation/raw/04_passive_tr.png (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/raw/04_passive_tr.png (revision 10414) Property changes on: tags/1.0.5/doc/tutorial/simulation/raw/04_passive_tr.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/1.0.5/doc/tutorial/simulation/raw/04_passive_tr.rs =================================================================== --- tags/1.0.5/doc/tutorial/simulation/raw/04_passive_tr.rs (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/raw/04_passive_tr.rs (revision 10414) @@ -0,0 +1,578 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.1 { + uuid=8/SYZ/pfBzxyqFA12WQAAAAC; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAg; + li:objects { + ha:polygon.11 { + li:outline { + ha:line { x1=0; y1=0; x2=80000; y2=0; } + ha:line { x1=80000; y1=0; x2=80000; y2=20000; } + ha:line { x1=80000; y1=20000; x2=0; y2=20000; } + ha:line { x1=0; y1=20000; x2=0; y2=0; } + } + stroke=titlebox-frame; + fill=titlebox-fill; + } + ha:line.12 { x1=0; y1=10000; x2=80000; y2=10000; stroke=titlebox-frame; } + ha:line.13 { x1=40000; y1=10000; x2=40000; y2=0; stroke=titlebox-frame; } + ha:text.20 { x1=1000; y1=16500; dyntext=0; stroke=titlebox-big; text=TITLE; } + ha:text.21 { x1=1000; y1=10500; x2=79000; y2=16000; dyntext=1; stroke=titlebox-big; text=%../../A.title%; } + ha:text.22 { x1=1000; y1=5500; dyntext=0; stroke=titlebox-small; text={PROJECT:}; } + ha:text.23 { x1=13000; y1=5500; x2=39000; y2=9500; dyntext=1; stroke=titlebox-big; text=%project.name%; } + ha:text.24 { x1=1000; y1=500; dyntext=0; stroke=titlebox-small; text={PAGE:}; } + ha:text.25 { x1=10000; y1=500; x2=39000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.page%; } + ha:text.26 { x1=41000; y1=5500; dyntext=0; stroke=titlebox-small; text={FILE:}; } + ha:text.27 { x1=48000; y1=5500; x2=79000; y2=9500; dyntext=1; stroke=titlebox-big; text=%filename%; } + ha:text.28 { x1=41000; y1=500; dyntext=0; stroke=titlebox-small; text={MAINTAINER:}; } + ha:text.29 { x1=55000; y1=500; x2=79000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.maintainer%; } + } + ha:attrib { + purpose=titlebox + } + } + ha:group.2 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAV; src_uuid=iNOQfJpO6hT/HFDFGjoAAABx; + x=16000; y=76000; rot=270.000000; mirx=1; + li:objects { + ha:arc.1 { cx=10000; cy=0; r=6000; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:arc.2 { cx=8000; cy=0; r=2000; sang=0.000000; dang=180.000000; stroke=sym-decor; } + ha:arc.3 { cx=12000; cy=0; r=2000; sang=180.000000; dang=180.000000; stroke=sym-decor; } + ha:group.4 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAW; src_uuid=iNOQfJpO6hT/HFDFGjoAAABy; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=N + role=terminal + } + } + ha:group.5 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAX; src_uuid=iNOQfJpO6hT/HFDFGjoAAABz; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=P + role=terminal + } + } + ha:text.6 { x1=8000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:text.8 { x1=-2000; y1=6000; dyntext=1; stroke=sym-secondary; text=%../A.spice/params%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=V1 + li:portmap { + {P->spice/pinnum=1} + {N->spice/pinnum=2} + } + role=symbol + spice/params=PULSE (0 5 1u 1u 1u 1 1) + spice/prefix=V + } + } + ha:group.3 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAY; + x=-28000; y=-32000; + li:objects { + ha:line.1 { x1=36000; y1=116000; x2=52000; y2=116000; stroke=wire; } + ha:line.2 { x1=44000; y1=108000; x2=44000; y2=116000; stroke=wire; } + ha:line.3 { x1=44000; y1=116000; x2=44000; y2=116000; stroke=junction; } + ha:text.4 { x1=36000; y1=116000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=in + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.6 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAZ; + x=-24000; y=-32000; + li:objects { + ha:line.1 { x1=40000; y1=88000; x2=40000; y2=80000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.8 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAg; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=24000; y=84000; + li:objects { + ha:group.1 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAh; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAi; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=R1 + role=symbol + spice/prefix=R + value=10k + } + } + ha:group.10 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAp; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAh; + x=52000; y=76000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAq; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAi; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAr; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAj; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.5 { x1=9000; y1=5000; x2=9000; y2=-5000; stroke=sym-decor; } + ha:line.6 { x1=11000; y1=5000; x2=11000; y2=-5000; stroke=sym-decor; } + ha:line.7 { x1=4000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.8 { x1=11000; y1=0; x2=16000; y2=0; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=C1 + role=symbol + spice/prefix=C + value=1u + } + } + ha:group.11 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAs; + x=-28000; y=-32000; + li:objects { + ha:line.2 { x1=80000; y1=116000; x2=80000; y2=108000; stroke=wire; } + ha:line.3 { x1=72000; y1=116000; x2=88000; y2=116000; stroke=wire; } + ha:line.4 { x1=80000; y1=116000; x2=80000; y2=116000; stroke=junction; } + ha:text.5 { x1=84000; y1=116000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=mid + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.14 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAz; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=60000; y=84000; + li:objects { + ha:group.1 { + uuid=LnNTcUkV1CIzG7F2EXUAAAA0; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=LnNTcUkV1CIzG7F2EXUAAAA1; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=R2 + role=symbol + spice/prefix=R + value=15k + } + } + ha:group.16 { + uuid=LnNTcUkV1CIzG7F2EXUAAAA2; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAh; + x=88000; y=76000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=LnNTcUkV1CIzG7F2EXUAAAA3; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAi; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=LnNTcUkV1CIzG7F2EXUAAAA4; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAj; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.5 { x1=9000; y1=5000; x2=9000; y2=-5000; stroke=sym-decor; } + ha:line.6 { x1=11000; y1=5000; x2=11000; y2=-5000; stroke=sym-decor; } + ha:line.7 { x1=4000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.8 { x1=11000; y1=0; x2=16000; y2=0; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=C2 + role=symbol + spice/prefix=C + value=1.2u + } + } + ha:group.17 { + uuid=LnNTcUkV1CIzG7F2EXUAAAA5; + x=-28000; y=-32000; + li:objects { + ha:line.2 { x1=116000; y1=116000; x2=116000; y2=108000; stroke=wire; } + ha:line.3 { x1=108000; y1=116000; x2=132000; y2=116000; stroke=wire; } + ha:line.4 { x1=116000; y1=116000; x2=116000; y2=116000; stroke=junction; } + ha:text.5 { x1=128000; y1=116000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=out + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.20 { + uuid=LnNTcUkV1CIzG7F2EXUAAAA6; + x=-28000; y=-32000; + li:objects { + ha:line.1 { x1=80000; y1=88000; x2=80000; y2=80000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.22 { + uuid=LnNTcUkV1CIzG7F2EXUAAAA7; + x=-28000; y=-32000; + li:objects { + ha:line.1 { x1=116000; y1=88000; x2=116000; y2=80000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.24 { + uuid=LnNTcUkV1CIzG7F2EXUAAABA; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=16000; y=48000; + li:objects { + ha:group.1 { + uuid=LnNTcUkV1CIzG7F2EXUAAABB; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.26 { + uuid=LnNTcUkV1CIzG7F2EXUAAABC; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=52000; y=48000; + li:objects { + ha:group.1 { + uuid=LnNTcUkV1CIzG7F2EXUAAABD; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.28 { + uuid=LnNTcUkV1CIzG7F2EXUAAABE; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=88000; y=48000; + li:objects { + ha:group.1 { + uuid=LnNTcUkV1CIzG7F2EXUAAABF; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.33 { + uuid=F3n6uHwVbWw4HTjelNgAAAAf; src_uuid=TeGEOMuew6iCb2kzckAAAAAD; + x=16000; y=136000; + li:objects { + ha:text.1 { x1=2000; y1=-4000; dyntext=0; stroke=sym-decor; text=raw spice; } + ha:text.2 { x1=2000; y1=-8000; dyntext=0; stroke=sym-decor; text=command; } + ha:polygon.3 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=-10000; } + ha:line { x1=0; y1=-10000; x2=12000; y2=-10000; } + ha:line { x1=12000; y1=-10000; x2=12000; y2=0; } + ha:line { x1=12000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + } + ha:attrib { + -sym-comment={ Fill in spice/command and use export_spice (e.g. the spice_raw view) to get that string exported at the end of the spice netlist file. } + -sym-copyright=(C) 2023 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + role=symbol + spice/command={tran 0.1ms 200ms +plot v(in) v(mid) v(out) xlimit 0 200ms} + } + } + ha:connection.34 { + li:conn { + /2/3/2 + /2/2/5/1 + } + } + ha:connection.35 { + li:conn { + /2/6/1 + /2/2/4/1 + } + } + ha:connection.36 { + li:conn { + /2/8/2/1 + /2/3/1 + } + } + ha:connection.37 { + li:conn { + /2/11/2 + /2/10/2/1 + } + } + ha:connection.38 { + li:conn { + /2/11/3 + /2/8/1/1 + } + } + ha:connection.40 { + li:conn { + /2/14/2/1 + /2/11/3 + } + } + ha:connection.41 { + li:conn { + /2/17/2 + /2/16/2/1 + } + } + ha:connection.42 { + li:conn { + /2/17/3 + /2/14/1/1 + } + } + ha:connection.43 { + li:conn { + /2/20/1 + /2/10/1/1 + } + } + ha:connection.44 { + li:conn { + /2/22/1 + /2/16/1/1 + } + } + ha:connection.45 { + li:conn { + /2/24/1/1 + /2/6/1 + } + } + ha:connection.46 { + li:conn { + /2/26/1/1 + /2/20/1 + } + } + ha:connection.47 { + li:conn { + /2/28/1/1 + /2/22/1 + } + } + } + ha:attrib { + maintainer=Tibor 'Igor2' Palinkas + page=1 of 1 + print_page=A/4 + title={SIM raw spice: passives, tran} + } + } +} Index: tags/1.0.5/doc/tutorial/simulation/raw/04_passive_tr.svg =================================================================== --- tags/1.0.5/doc/tutorial/simulation/raw/04_passive_tr.svg (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/raw/04_passive_tr.svg (revision 10414) @@ -0,0 +1,737 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/1.0.5/doc/tutorial/simulation/raw/06_passive_ac.html =================================================================== --- tags/1.0.5/doc/tutorial/simulation/raw/06_passive_ac.html (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/raw/06_passive_ac.html (revision 10414) @@ -0,0 +1,101 @@ + + +

06_passive_ac: freqency domain simulation: ac

+ +

Scope

+

+In this simulation we are going to look at how a multi-stage RC filter behaves +when stimulated with sine waves of various frequencies. + +

The schematics

+

+The single-sheet schematic contains the filter, the voltage source and +the spice command symbol. +

+

+ +
Click the image to get the sch-rnd sheet
+

+ +

SPICE: what an ac simulation is

+

+In the ac analysis simulation a DC solution is calculated first +and then a small signal sinusoidal stimulus is applied over a range of +frequencies. The result is typically a graph with frequency on the X axis +and gain or phase on the Y axis. The AC analysis is often used to get +a transfer function. + +

Preparing for simulation

+ +

V1

+

+In our example, V1 specifies a 1V AC signal with a DC component of 0V +on the in network. The syntax for this is (see in V1's spice/params): +

+dc 0 ac 1
+
+

+The frequency of the ac component is not specified because that will be +varied over a range by the analysis command. + +

Raw spice commands

+

+It contains the following script: +

+ac dec 10 1 100k
+
+settype decibel out
+plot vdb(out) xlimit 1 100k ylabel 'small signal gain'
+
+settype phase out
+plot cph(out) xlimit 1 100k ylabel 'phase (in rad)'
+
+let outd = 180/PI*cph(out)
+settype phase outd
+plot outd xlimit 1 100k ylabel 'phase (in deg)'
+
+

+The first line instructs spice to do the "ac analysis" in decade variation +mode (dec 10), to get a decade logarithmic output with 10 points in each +decade. It then specifies the range of interest for the frequencies: +anything between 1 Hz and 100 kHz. +

+Then come three plots. The first is the output voltage in decibels, on +a logarithmic Y scale, then the phase shift of the circuit, both in radians +and in degrees. + +

Export and run ngspice

+

+Because of the plot commands the output is a set of drawings (if ngspice is run +on X): three graphs with one curve each. +

+ +

+ +

+ + + +

Using other implementations

+

gnucap

+

+Gnucap uses a different command syntax. Modify the spice command symbol's +spice/command attribute to: +

+print ac vdb(out) zp(out)
+op
+ac dec 10 1 1000k > plot.txt
+
+

+After the export, write the single word spice in the first line of the +file (e.g. using a text editor), otherwise gnucap won't know the file is in spice +syntax. Then run gnucap 06_passive_ac.cir and it will dump a text +table to plot.txt that can be plotted using a suitable utility, e.g. gnuplot. +

+The gnucap-modified schematic is also available. + + + +

xyce

+

+TODO Index: tags/1.0.5/doc/tutorial/simulation/raw/06_passive_ac.rs =================================================================== --- tags/1.0.5/doc/tutorial/simulation/raw/06_passive_ac.rs (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/raw/06_passive_ac.rs (revision 10414) @@ -0,0 +1,585 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.1 { + uuid=8/SYZ/pfBzxyqFA12WQAAAAC; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAg; + li:objects { + ha:polygon.11 { + li:outline { + ha:line { x1=0; y1=0; x2=80000; y2=0; } + ha:line { x1=80000; y1=0; x2=80000; y2=20000; } + ha:line { x1=80000; y1=20000; x2=0; y2=20000; } + ha:line { x1=0; y1=20000; x2=0; y2=0; } + } + stroke=titlebox-frame; + fill=titlebox-fill; + } + ha:line.12 { x1=0; y1=10000; x2=80000; y2=10000; stroke=titlebox-frame; } + ha:line.13 { x1=40000; y1=10000; x2=40000; y2=0; stroke=titlebox-frame; } + ha:text.20 { x1=1000; y1=16500; dyntext=0; stroke=titlebox-big; text=TITLE; } + ha:text.21 { x1=1000; y1=10500; x2=79000; y2=16000; dyntext=1; stroke=titlebox-big; text=%../../A.title%; } + ha:text.22 { x1=1000; y1=5500; dyntext=0; stroke=titlebox-small; text={PROJECT:}; } + ha:text.23 { x1=13000; y1=5500; x2=39000; y2=9500; dyntext=1; stroke=titlebox-big; text=%project.name%; } + ha:text.24 { x1=1000; y1=500; dyntext=0; stroke=titlebox-small; text={PAGE:}; } + ha:text.25 { x1=10000; y1=500; x2=39000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.page%; } + ha:text.26 { x1=41000; y1=5500; dyntext=0; stroke=titlebox-small; text={FILE:}; } + ha:text.27 { x1=48000; y1=5500; x2=79000; y2=9500; dyntext=1; stroke=titlebox-big; text=%filename%; } + ha:text.28 { x1=41000; y1=500; dyntext=0; stroke=titlebox-small; text={MAINTAINER:}; } + ha:text.29 { x1=55000; y1=500; x2=79000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.maintainer%; } + } + ha:attrib { + purpose=titlebox + } + } + ha:group.2 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAV; src_uuid=iNOQfJpO6hT/HFDFGjoAAABx; + x=12000; y=72000; rot=270.000000; mirx=1; + li:objects { + ha:arc.1 { cx=10000; cy=0; r=6000; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:arc.2 { cx=8000; cy=0; r=2000; sang=0.000000; dang=180.000000; stroke=sym-decor; } + ha:arc.3 { cx=12000; cy=0; r=2000; sang=180.000000; dang=180.000000; stroke=sym-decor; } + ha:group.4 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAW; src_uuid=iNOQfJpO6hT/HFDFGjoAAABy; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=N + role=terminal + } + } + ha:group.5 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAX; src_uuid=iNOQfJpO6hT/HFDFGjoAAABz; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=P + role=terminal + } + } + ha:text.6 { x1=8000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=V1 + li:portmap { + {P->spice/pinnum=1} + {N->spice/pinnum=2} + } + role=symbol + spice/params=dc 0 ac 1 + spice/prefix=V + } + } + ha:group.3 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAY; + x=-32000; y=-36000; + li:objects { + ha:line.1 { x1=36000; y1=116000; x2=52000; y2=116000; stroke=wire; } + ha:line.2 { x1=44000; y1=108000; x2=44000; y2=116000; stroke=wire; } + ha:line.3 { x1=44000; y1=116000; x2=44000; y2=116000; stroke=junction; } + ha:text.4 { x1=36000; y1=116000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=in + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.6 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAZ; + x=-28000; y=-36000; + li:objects { + ha:line.1 { x1=40000; y1=88000; x2=40000; y2=80000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.8 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAg; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=20000; y=80000; + li:objects { + ha:group.1 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAh; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAi; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=R1 + role=symbol + spice/prefix=R + value=10k + } + } + ha:group.10 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAp; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAh; + x=48000; y=72000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAq; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAi; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAr; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAj; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.5 { x1=9000; y1=5000; x2=9000; y2=-5000; stroke=sym-decor; } + ha:line.6 { x1=11000; y1=5000; x2=11000; y2=-5000; stroke=sym-decor; } + ha:line.7 { x1=4000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.8 { x1=11000; y1=0; x2=16000; y2=0; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=C1 + role=symbol + spice/prefix=C + value=1u + } + } + ha:group.11 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAs; + x=-32000; y=-36000; + li:objects { + ha:line.2 { x1=80000; y1=116000; x2=80000; y2=108000; stroke=wire; } + ha:line.3 { x1=72000; y1=116000; x2=88000; y2=116000; stroke=wire; } + ha:line.4 { x1=80000; y1=116000; x2=80000; y2=116000; stroke=junction; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.14 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAz; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=56000; y=80000; + li:objects { + ha:group.1 { + uuid=LnNTcUkV1CIzG7F2EXUAAAA0; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=LnNTcUkV1CIzG7F2EXUAAAA1; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=R2 + role=symbol + spice/prefix=R + value=1k + } + } + ha:group.16 { + uuid=LnNTcUkV1CIzG7F2EXUAAAA2; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAh; + x=84000; y=72000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=LnNTcUkV1CIzG7F2EXUAAAA3; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAi; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=LnNTcUkV1CIzG7F2EXUAAAA4; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAj; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.5 { x1=9000; y1=5000; x2=9000; y2=-5000; stroke=sym-decor; } + ha:line.6 { x1=11000; y1=5000; x2=11000; y2=-5000; stroke=sym-decor; } + ha:line.7 { x1=4000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.8 { x1=11000; y1=0; x2=16000; y2=0; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=C2 + role=symbol + spice/prefix=C + value=100n + } + } + ha:group.17 { + uuid=LnNTcUkV1CIzG7F2EXUAAAA5; + x=-32000; y=-36000; + li:objects { + ha:line.2 { x1=116000; y1=116000; x2=116000; y2=108000; stroke=wire; } + ha:line.3 { x1=108000; y1=116000; x2=132000; y2=116000; stroke=wire; } + ha:line.4 { x1=116000; y1=116000; x2=116000; y2=116000; stroke=junction; } + ha:text.5 { x1=128000; y1=116000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=out + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.20 { + uuid=LnNTcUkV1CIzG7F2EXUAAAA6; + x=-32000; y=-36000; + li:objects { + ha:line.1 { x1=80000; y1=88000; x2=80000; y2=80000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.22 { + uuid=LnNTcUkV1CIzG7F2EXUAAAA7; + x=-32000; y=-36000; + li:objects { + ha:line.1 { x1=116000; y1=88000; x2=116000; y2=80000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.24 { + uuid=LnNTcUkV1CIzG7F2EXUAAABA; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=12000; y=44000; + li:objects { + ha:group.1 { + uuid=LnNTcUkV1CIzG7F2EXUAAABB; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.26 { + uuid=LnNTcUkV1CIzG7F2EXUAAABC; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=48000; y=44000; + li:objects { + ha:group.1 { + uuid=LnNTcUkV1CIzG7F2EXUAAABD; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.28 { + uuid=LnNTcUkV1CIzG7F2EXUAAABE; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=84000; y=44000; + li:objects { + ha:group.1 { + uuid=LnNTcUkV1CIzG7F2EXUAAABF; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.33 { + uuid=F3n6uHwVbWw4HTjelNgAAAAf; src_uuid=TeGEOMuew6iCb2kzckAAAAAD; + x=4000; y=100000; + li:objects { + ha:text.1 { x1=2000; y1=-4000; dyntext=0; stroke=sym-decor; text=raw spice; } + ha:text.2 { x1=2000; y1=-8000; dyntext=0; stroke=sym-decor; text=command; } + ha:polygon.3 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=-10000; } + ha:line { x1=0; y1=-10000; x2=12000; y2=-10000; } + ha:line { x1=12000; y1=-10000; x2=12000; y2=0; } + ha:line { x1=12000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + } + ha:attrib { + -sym-comment={ Fill in spice/command and use export_spice (e.g. the spice_raw view) to get that string exported at the end of the spice netlist file. } + -sym-copyright=(C) 2023 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + role=symbol + spice/command={ac dec 10 1 100k + +settype decibel out +plot vdb(out) xlimit 1 100k ylabel 'small signal gain' + +settype phase out +plot cph(out) xlimit 1 100k ylabel 'phase (in rad)' + +let outd = 180/PI*cph(out) +settype phase outd +plot outd xlimit 1 100k ylabel 'phase (in deg)' +} + } + } + ha:connection.34 { + li:conn { + /2/3/2 + /2/2/5/1 + } + } + ha:connection.35 { + li:conn { + /2/6/1 + /2/2/4/1 + } + } + ha:connection.36 { + li:conn { + /2/8/2/1 + /2/3/1 + } + } + ha:connection.37 { + li:conn { + /2/11/2 + /2/10/2/1 + } + } + ha:connection.39 { + li:conn { + /2/11/3 + /2/8/1/1 + } + } + ha:connection.40 { + li:conn { + /2/14/2/1 + /2/11/3 + } + } + ha:connection.41 { + li:conn { + /2/17/2 + /2/16/2/1 + } + } + ha:connection.43 { + li:conn { + /2/17/3 + /2/14/1/1 + } + } + ha:connection.44 { + li:conn { + /2/20/1 + /2/10/1/1 + } + } + ha:connection.45 { + li:conn { + /2/22/1 + /2/16/1/1 + } + } + ha:connection.46 { + li:conn { + /2/24/1/1 + /2/6/1 + } + } + ha:connection.47 { + li:conn { + /2/26/1/1 + /2/20/1 + } + } + ha:connection.48 { + li:conn { + /2/28/1/1 + /2/22/1 + } + } + } + ha:attrib { + maintainer=Tibor 'Igor2' Palinkas + page=1 of 1 + print_page=A/4 + title={SIM raw spice: passives, ac} + } + } +} Index: tags/1.0.5/doc/tutorial/simulation/raw/06_passive_ac.svg =================================================================== --- tags/1.0.5/doc/tutorial/simulation/raw/06_passive_ac.svg (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/raw/06_passive_ac.svg (revision 10414) @@ -0,0 +1,670 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/1.0.5/doc/tutorial/simulation/raw/06_passive_ac1.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/1.0.5/doc/tutorial/simulation/raw/06_passive_ac1.png =================================================================== --- tags/1.0.5/doc/tutorial/simulation/raw/06_passive_ac1.png (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/raw/06_passive_ac1.png (revision 10414) Property changes on: tags/1.0.5/doc/tutorial/simulation/raw/06_passive_ac1.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/1.0.5/doc/tutorial/simulation/raw/06_passive_ac2.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/1.0.5/doc/tutorial/simulation/raw/06_passive_ac2.png =================================================================== --- tags/1.0.5/doc/tutorial/simulation/raw/06_passive_ac2.png (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/raw/06_passive_ac2.png (revision 10414) Property changes on: tags/1.0.5/doc/tutorial/simulation/raw/06_passive_ac2.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/1.0.5/doc/tutorial/simulation/raw/06_passive_ac3.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/1.0.5/doc/tutorial/simulation/raw/06_passive_ac3.png =================================================================== --- tags/1.0.5/doc/tutorial/simulation/raw/06_passive_ac3.png (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/raw/06_passive_ac3.png (revision 10414) Property changes on: tags/1.0.5/doc/tutorial/simulation/raw/06_passive_ac3.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/1.0.5/doc/tutorial/simulation/raw/10_bjt_amp_tr.html =================================================================== --- tags/1.0.5/doc/tutorial/simulation/raw/10_bjt_amp_tr.html (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/raw/10_bjt_amp_tr.html (revision 10414) @@ -0,0 +1,140 @@ + + +

10_bjt_amp_tr: model from the library

+ +

Scope

+

+In this simulation we are going to look at a single-transistor amplifier +in the time domain to verify how it amplifies a sine wave. + +

The schematics

+

+The single-sheet schematic contains the amplifier, the voltage sources and +the spice command symbol. +

+

+ +
Click the image to get the sch-rnd sheet
+

+ +

How to specify the model

+

+In the previous examples all components used were ideal: simple +resistors, capacitors and sources, without any special characteristics +or side effects. More complex components such as transistors typically +have a large set of parameters that differ by device type. Spice addresses +this by using models. +

+A model in spice is really two things: +

    +
  • the code that implements how to simulate the given thing (e.g. an npn transistor) +
  • a set of parameters for this model which make the behavior match a specific real world device +
+

+The first of these, the code, is typically provided as part of the simulator software, +at least for the most common, basic component types. The second of these, the set of +model parameters, is specified by the user (normally acquired from the device +vendor or derived from the datasheet or actual measurements). +

+In sch-rnd these models are kept in the spice library, which is very much like +the symbol or devmap library: a directory tree that holds spice models, +one model per file, with models identified by file name. Spice export files +are self-contained and do not rely on external model files. This is achieved +by sch-rnd copying the content of these spice model files from the library +into the output file. +

+Furthermore there's a sheet-local library, just like with devmap (and +optionally with symbols), so that any spice model used by the sheet is +also saved within the sheet, keeping the sheet self-contained and portable. + +

Preparing for simulation

+ +

Q1

+

+This is the usual npn symbol from the stock symbol library shipped with +sch-rnd. The devmap has been set to bc817_sot23 so that the sheet can also +be used in a PCB workflow with a sot23 footprint as well. +

+The spice-specific aspects are the model and the spice pinout. The model +is specified using the spice/model attribute, with value bc817. +There is a file in the spice model library shipped with sch-rnd called +bc817.prm. The pinout is set by the spice/pinnum terminal attributes. +For the BJT spice model the pinout is always the same, so the stock +library symbol has this attribute hardwired in terminals with a low priority +(so that it can be overridden by other mechanisms). +

+The devmap file could contain the symbol's spice/model and portmap to set +spice/pinnum for each terminal, but this is not a good idea because there may be +different spice models for different complexities of simulation. Simple models, +like bc817.prm, concentrate only on the core of the functionality, while +more complex models implemented as "subcircuits" (subckt in spice slang) may +add parasitic effects, such as pin inductances and pin/package +related stray capacitances. Such complex models run slower, but may be +more accurate in some cases, while the simpler model would cover most of the +normal use cases. The user needs to decide which model to use for the given +circuit or even the given simulation; accordingly, this should not be defined +in the devmap. +

+Specifying the spice pinout from the devmap is unnecessary if both the model +and the symbol use the standard spice BJT pinout that matches the model code +in spice. However, for subcircuit models the pinout may differ, and sch-rnd +offers multiple mechanisms +to deal with different spice pinouts. + + +

V1

+

+V1 is generating the input sine wave on the in network. +The syntax for this is (see in V1's spice/params): +

+SINE(0 0.01 1k)
+
+

+The first parameter is the (dc) voltage offset, the second is the +AC amplitude voltage and the third is the frequency in Hz. + +

V2

+

+V2 is an 5V DC power supply for Vcc: +

+dc 5
+
+ + +

Raw spice commands

+

+It contains the following script: +

+tran 1u 10m
+plot v(out) v(in)
+
+

+which runs the simulation for 10 mS, sampling it once a microsecond. At +the end we are plotting the input and output voltages. + +

Export and run ngspice

+

+Running ngspice the usual way on the export yields the following graph: +

+ + +

Using other implementations

+

gnucap

+

+Gnucap uses a different command syntax. Modify the spice command symbol's +spice/command attribute to: +

+print tran v(out) v(in)
+tran 1u 10m > plot.txt
+
+

+After the export, write the single word spice in the first line of the +file (e.g. using a text editor), otherwise gnucap won't know the file is in spice +syntax. Then run gnucap 10_btj_amp_tr.cir and it will dump a text +table to plot.txt that can be plotted using a suitable utility, e.g. gnuplot. +

+The gnucap-modified schematic is also available. + +

xyce

+

+TODO Index: tags/1.0.5/doc/tutorial/simulation/raw/10_bjt_amp_tr.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/1.0.5/doc/tutorial/simulation/raw/10_bjt_amp_tr.png =================================================================== --- tags/1.0.5/doc/tutorial/simulation/raw/10_bjt_amp_tr.png (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/raw/10_bjt_amp_tr.png (revision 10414) Property changes on: tags/1.0.5/doc/tutorial/simulation/raw/10_bjt_amp_tr.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/1.0.5/doc/tutorial/simulation/raw/10_bjt_amp_tr.rs =================================================================== --- tags/1.0.5/doc/tutorial/simulation/raw/10_bjt_amp_tr.rs (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/raw/10_bjt_amp_tr.rs (revision 10414) @@ -0,0 +1,1143 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAp; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAq; loclib_name=bc817_sot23; + li:objects { + } + ha:attrib { + footprint=SOT23 + li:portmap { + {B->pcb/pinnum=1} + {E->pcb/pinnum=2} + {C->pcb/pinnum=3} + } + } + } + } + ha:attrib { + ha:purpose = { value=devmap; prio=0; } + } + } + ha:group.2 { + uuid=mpbUxZA3TcX63n9yc2EAAAA9; + li:objects { + ha:group.1 { + uuid=mpbUxZA3TcX63n9yc2EAAAA+; loclib_name=bc817; + li:objects { + } + ha:attrib { + spice/model_card={* (C) 2023 Tibor 'Igor2' Palinkas +* License: CC0 (no rights reserved): https://creativecommons.org/publicdomain/zero/1.0/ +* Source: based on Vishay's datasheet: https://archive.org/details/bc817_spice_vishay +* +.model BC817 npn ( ++ IS=2.43485e-13 VAF=10 BF=270 IKF=1.12487 NE=1.84302 ISE=7.17747e-12 ++ IKR=0.149889 ISC=2.42047e-12 NC=3.94859 NR=1.04566 BR=2.51332 RC=0.407107 ++ CJC=5.516e-11 FC=0.8 MJC=0.529364 VJC=0.4 CJE=5.10473e-11 MJE=0.412728 ++ VJE=0.561234 TF=7.1424e-10 ITF=0.175457 VTF=1.86025 XTF=1.09929 RB=6.50128 ++ IRB=0.1 RBM=0.1 RE=0.0814215 TR=1e-07 ++ ) + +} + } + } + } + ha:attrib { + ha:purpose = { value=spicelib; prio=0; } + } + } + } + } + ha:obj_direct.2 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.1 { + uuid=8/SYZ/pfBzxyqFA12WQAAAAC; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAg; + li:objects { + ha:polygon.11 { + li:outline { + ha:line { x1=0; y1=0; x2=80000; y2=0; } + ha:line { x1=80000; y1=0; x2=80000; y2=20000; } + ha:line { x1=80000; y1=20000; x2=0; y2=20000; } + ha:line { x1=0; y1=20000; x2=0; y2=0; } + } + stroke=titlebox-frame; + fill=titlebox-fill; + } + ha:line.12 { x1=0; y1=10000; x2=80000; y2=10000; stroke=titlebox-frame; } + ha:line.13 { x1=40000; y1=10000; x2=40000; y2=0; stroke=titlebox-frame; } + ha:text.20 { x1=1000; y1=16500; dyntext=0; stroke=titlebox-big; text=TITLE; } + ha:text.21 { x1=1000; y1=10500; x2=79000; y2=16000; dyntext=1; stroke=titlebox-big; text=%../../A.title%; } + ha:text.22 { x1=1000; y1=5500; dyntext=0; stroke=titlebox-small; text={PROJECT:}; } + ha:text.23 { x1=13000; y1=5500; x2=39000; y2=9500; dyntext=1; stroke=titlebox-big; text=%project.name%; } + ha:text.24 { x1=1000; y1=500; dyntext=0; stroke=titlebox-small; text={PAGE:}; } + ha:text.25 { x1=10000; y1=500; x2=39000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.page%; } + ha:text.26 { x1=41000; y1=5500; dyntext=0; stroke=titlebox-small; text={FILE:}; } + ha:text.27 { x1=48000; y1=5500; x2=79000; y2=9500; dyntext=1; stroke=titlebox-big; text=%filename%; } + ha:text.28 { x1=41000; y1=500; dyntext=0; stroke=titlebox-small; text={MAINTAINER:}; } + ha:text.29 { x1=55000; y1=500; x2=79000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.maintainer%; } + } + ha:attrib { + purpose=titlebox + } + } + ha:group.2 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAJ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAh; + x=20000; y=100000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAK; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAi; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAL; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAj; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.5 { x1=9000; y1=5000; x2=9000; y2=-5000; stroke=sym-decor; } + ha:line.6 { x1=11000; y1=5000; x2=11000; y2=-5000; stroke=sym-decor; } + ha:line.7 { x1=4000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.8 { x1=11000; y1=0; x2=16000; y2=0; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=C1 + role=symbol + value=10u + } + } + ha:group.3 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAM; + x=-20000; y=-20000; + li:objects { + ha:line.1 { x1=40000; y1=120000; x2=32000; y2=120000; stroke=wire; } + ha:text.2 { x1=33000; y1=120000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + ha:line.3 { x1=32000; y1=84000; x2=32000; y2=120000; stroke=wire; } + } + ha:attrib { + name=in + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.5 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAN; + x=-20000; y=-20000; + li:objects { + ha:line.1 { x1=60000; y1=120000; x2=76000; y2=120000; stroke=wire; } + ha:line.3 { x1=64000; y1=120000; x2=64000; y2=120000; stroke=junction; } + ha:line.4 { x1=64000; y1=100000; x2=64000; y2=140000; stroke=wire; } + ha:text.5 { x1=66000; y1=120000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=int_b + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.7 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAU; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=44000; y=140000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAV; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAW; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=R1 + role=symbol + value=87k + } + } + ha:group.9 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAa; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=44000; y=80000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAb; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAc; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=R2 + role=symbol + value=10k + } + } + ha:group.14 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAr; + x=-52000; y=-20000; + li:objects { + ha:line.1 { x1=120000; y1=112000; x2=120000; y2=56000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.16 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAs; + x=-40000; y=-20000; + li:objects { + ha:line.1 { x1=84000; y1=80000; x2=84000; y2=56000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.18 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAw; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=68000; y=140000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAx; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAy; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=R3 + role=symbol + value=33k + } + } + ha:group.19 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAz; + x=-52000; y=-20000; + li:objects { + ha:line.1 { x1=120000; y1=128000; x2=120000; y2=140000; stroke=wire; } + ha:line.2 { x1=120000; y1=132000; x2=132000; y2=132000; stroke=wire; } + ha:line.3 { x1=120000; y1=132000; x2=120000; y2=132000; stroke=junction; } + ha:text.4 { x1=122000; y1=132000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=int_c + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.22 { + uuid=60PZRPnx0Y9mYJZvZgYAAAA0; + x=-40000; y=-20000; + li:objects { + ha:line.1 { x1=84000; y1=160000; x2=84000; y2=172000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.24 { + uuid=60PZRPnx0Y9mYJZvZgYAAAA1; + x=-52000; y=-20000; + li:objects { + ha:line.1 { x1=120000; y1=160000; x2=120000; y2=172000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.26 { + uuid=60PZRPnx0Y9mYJZvZgYAAAA5; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAh; + x=80000; y=112000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAA6; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAi; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=60PZRPnx0Y9mYJZvZgYAAAA7; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAj; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.5 { x1=9000; y1=5000; x2=9000; y2=-5000; stroke=sym-decor; } + ha:line.6 { x1=11000; y1=5000; x2=11000; y2=-5000; stroke=sym-decor; } + ha:line.7 { x1=4000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.8 { x1=11000; y1=0; x2=16000; y2=0; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=C2 + role=symbol + value=10u + } + } + ha:group.28 { + uuid=60PZRPnx0Y9mYJZvZgYAAAA/; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=108000; y=100000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAABA; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=60PZRPnx0Y9mYJZvZgYAAABB; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=R4 + role=symbol + value=100k + } + } + ha:group.29 { + uuid=60PZRPnx0Y9mYJZvZgYAAABC; + x=-60000; y=-20000; + li:objects { + ha:line.1 { x1=160000; y1=132000; x2=176000; y2=132000; stroke=wire; } + ha:line.2 { x1=168000; y1=120000; x2=168000; y2=132000; stroke=wire; } + ha:line.3 { x1=168000; y1=132000; x2=168000; y2=132000; stroke=junction; } + ha:text.4 { x1=173000; y1=132000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=out + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.32 { + uuid=60PZRPnx0Y9mYJZvZgYAAABD; + x=-60000; y=-20000; + li:objects { + ha:line.2 { x1=168000; y1=100000; x2=168000; y2=56000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.34 { + uuid=60PZRPnx0Y9mYJZvZgYAAABi; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB0; + x=128000; y=64000; rot=270.000000; mirx=1; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAABj; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB1; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=N + role=terminal + } + } + ha:group.2 { + uuid=60PZRPnx0Y9mYJZvZgYAAABk; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB2; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=P + role=terminal + } + } + ha:arc.3 { cx=10000; cy=0; r=6000; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:line.4 { x1=7000; y1=2000; x2=7000; y2=-2000; stroke=sym-decor; } + ha:line.5 { x1=5000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=11000; y1=0; x2=15000; y2=0; stroke=sym-decor; } + ha:text.7 { x1=0; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:text.8 { x1=8000; y1=-10000; dyntext=1; stroke=sym-secondary; text=%../A.spice/params%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=V2 + role=symbol + spice/params=dc 5 + li:spice/portmap { + {P->spice/pinnum=1} + {N->spice/pinnum=2} + } + } + } + ha:group.35 { + uuid=60PZRPnx0Y9mYJZvZgYAAABo; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB0; + x=12000; y=64000; rot=270.000000; mirx=1; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAABp; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB1; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=N + role=terminal + } + } + ha:group.2 { + uuid=60PZRPnx0Y9mYJZvZgYAAABq; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB2; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=P + role=terminal + } + } + ha:arc.3 { cx=10000; cy=0; r=6000; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:line.4 { x1=7000; y1=2000; x2=7000; y2=-2000; stroke=sym-decor; } + ha:line.5 { x1=5000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=11000; y1=0; x2=15000; y2=0; stroke=sym-decor; } + ha:text.7 { x1=0; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:text.8 { x1=6000; y1=-9000; dyntext=1; stroke=sym-secondary; text=%../A.spice/params%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=V1 + role=symbol + spice/params=SINE(0 0.01 1k) + li:spice/portmap { + {P->spice/pinnum=1} + {N->spice/pinnum=2} + } + } + } + ha:group.36 { + uuid=60PZRPnx0Y9mYJZvZgYAAABr; + x=-80000; y=-20000; + li:objects { + ha:line.1 { x1=208000; y1=64000; x2=208000; y2=56000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.38 { + uuid=60PZRPnx0Y9mYJZvZgYAAABs; + x=-232000; y=-20000; + li:objects { + ha:line.1 { x1=244000; y1=64000; x2=244000; y2=56000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.40 { + uuid=60PZRPnx0Y9mYJZvZgYAAABt; + x=-80000; y=-20000; + li:objects { + ha:line.1 { x1=208000; y1=84000; x2=208000; y2=92000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.46 { + uuid=60PZRPnx0Y9mYJZvZgYAAABz; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=12000; y=36000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAB0; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.48 { + uuid=60PZRPnx0Y9mYJZvZgYAAAB1; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=44000; y=36000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAB2; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.50 { + uuid=60PZRPnx0Y9mYJZvZgYAAAB3; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=68000; y=36000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAB4; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.52 { + uuid=60PZRPnx0Y9mYJZvZgYAAAB5; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=108000; y=36000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAB6; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.54 { + uuid=60PZRPnx0Y9mYJZvZgYAAAB7; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=128000; y=36000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAB8; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.56 { + uuid=60PZRPnx0Y9mYJZvZgYAAACB; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB6; + x=128000; y=72000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAACC; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB7; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-4000; y1=4000; x2=4000; y2=7000; halign=center; dyntext=0; stroke=sym-primary; text=Vcc; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:Vcc} + } + role=symbol + } + } + ha:group.58 { + uuid=60PZRPnx0Y9mYJZvZgYAAACD; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB6; + x=68000; y=152000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAACE; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB7; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-4000; y1=4000; x2=4000; y2=7000; halign=center; dyntext=0; stroke=sym-primary; text=Vcc; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:Vcc} + } + role=symbol + } + } + ha:group.60 { + uuid=60PZRPnx0Y9mYJZvZgYAAACF; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB6; + x=44000; y=152000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAACG; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB7; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-4000; y1=4000; x2=4000; y2=7000; halign=center; dyntext=0; stroke=sym-primary; text=Vcc; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:Vcc} + } + role=symbol + } + } + ha:group.62 { + uuid=uo/hkCCyjHkmVGRW0F0AAAA+; src_uuid=TeGEOMuew6iCb2kzckAAAAAD; + x=9000; y=124000; + li:objects { + ha:text.1 { x1=2000; y1=-4000; dyntext=0; stroke=sym-decor; text=raw spice; } + ha:text.2 { x1=2000; y1=-8000; dyntext=0; stroke=sym-decor; text=command; } + ha:polygon.3 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=-10000; } + ha:line { x1=0; y1=-10000; x2=12000; y2=-10000; } + ha:line { x1=12000; y1=-10000; x2=12000; y2=0; } + ha:line { x1=12000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + } + ha:attrib { + -sym-comment={ Fill in spice/command and use export_spice (e.g. the spice_raw view) to get that string exported at the end of the spice netlist file. } + -sym-copyright=(C) 2023 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + role=symbol + spice/command={tran 1u 10m +plot v(out) v(in)} + } + } + ha:group.70 { + uuid=emEhKEkrgdRFzXxchToAAABZ; src_uuid=iNOQfJpO6hT/HFDFGjoAAACK; + x=56000; y=100000; + li:objects { + ha:polygon.1 { + li:outline { + ha:line { x1=10266; y1=-1780; x2=9224; y2=-3517; } + ha:line { x1=9224; y1=-3517; x2=10935; y2=-3368; } + ha:line { x1=10935; y1=-3368; x2=10266; y2=-1780; } + } + stroke=sym-decor; + fill=sym-decor; + } + ha:group.2 { + uuid=emEhKEkrgdRFzXxchToAAABa; src_uuid=iNOQfJpO6hT/HFDFGjoAAACL; + x=12000; y=8000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=-4000; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=C + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:group.3 { + uuid=emEhKEkrgdRFzXxchToAAABb; src_uuid=iNOQfJpO6hT/HFDFGjoAAACM; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=B + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.4 { + uuid=emEhKEkrgdRFzXxchToAAABc; src_uuid=iNOQfJpO6hT/HFDFGjoAAACN; + x=12000; y=-4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=-4000; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=E + role=terminal + ha:spice/pinnum = { value=3; prio=31050; } + } + } + ha:text.5 { x1=8000; y1=8000; rot=90.000000; dyntext=1; stroke=sym-secondary; text=%../a.devmap%; floater=1; } + ha:text.6 { x1=4000; y1=8000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:arc.7 { cx=9000; cy=0; r=5500; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:line.8 { x1=7000; y1=4000; x2=7000; y2=-4000; stroke=sym-decor; } + ha:line.9 { x1=4000; y1=0; x2=7000; y2=0; stroke=sym-decor; } + ha:line.10 { x1=7000; y1=-1000; x2=12000; y2=-4000; stroke=sym-decor; } + ha:line.11 { x1=7000; y1=1000; x2=12000; y2=4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + devmap=bc817_sot23 + name=Q1 + role=symbol + spice/model=bc817 + } + } + ha:connection.74 { + li:conn { + /2/3/1 + /2/2/2/1 + } + } + ha:connection.75 { + li:conn { + /2/5/1 + /2/2/1/1 + } + } + ha:connection.87 { + li:conn { + /2/35/2/1 + /2/3/3 + } + } + ha:connection.89 { + li:conn { + /2/38/1 + /2/35/1/1 + } + } + ha:connection.91 { + li:conn { + /2/46/1/1 + /2/38/1 + } + } + ha:connection.102 { + li:conn { + /2/7/1/1 + /2/5/4 + } + } + ha:connection.103 { + li:conn { + /2/9/2/1 + /2/5/4 + } + } + ha:connection.104 { + li:conn { + /2/16/1 + /2/9/1/1 + } + } + ha:connection.105 { + li:conn { + /2/22/1 + /2/7/2/1 + } + } + ha:connection.106 { + li:conn { + /2/48/1/1 + /2/16/1 + } + } + ha:connection.107 { + li:conn { + /2/60/1/1 + /2/22/1 + } + } + ha:connection.108 { + li:conn { + /2/19/1 + /2/18/1/1 + } + } + ha:connection.109 { + li:conn { + /2/24/1 + /2/18/2/1 + } + } + ha:connection.116 { + li:conn { + /2/50/1/1 + /2/14/1 + } + } + ha:connection.120 { + li:conn { + /2/58/1/1 + /2/24/1 + } + } + ha:connection.121 { + li:conn { + /2/70/2/1 + /2/19/1 + } + } + ha:connection.122 { + li:conn { + /2/70/3/1 + /2/5/1 + } + } + ha:connection.123 { + li:conn { + /2/70/4/1 + /2/14/1 + } + } + ha:connection.124 { + li:conn { + /2/26/2/1 + /2/19/2 + } + } + ha:connection.125 { + li:conn { + /2/29/1 + /2/26/1/1 + } + } + ha:connection.126 { + li:conn { + /2/29/2 + /2/28/2/1 + } + } + ha:connection.127 { + li:conn { + /2/32/2 + /2/28/1/1 + } + } + ha:connection.130 { + li:conn { + /2/52/1/1 + /2/32/2 + } + } + ha:connection.133 { + li:conn { + /2/36/1 + /2/34/1/1 + } + } + ha:connection.134 { + li:conn { + /2/40/1 + /2/34/2/1 + } + } + ha:connection.135 { + li:conn { + /2/54/1/1 + /2/36/1 + } + } + ha:connection.136 { + li:conn { + /2/56/1/1 + /2/40/1 + } + } + } + ha:attrib { + maintainer=Tibor 'Igor2' Palinkas + page=1 of 1 + print_page=A/4 + title={SIM raw spice: BJT amplifier, tran} + } + } +} Index: tags/1.0.5/doc/tutorial/simulation/raw/10_bjt_amp_tr.svg =================================================================== --- tags/1.0.5/doc/tutorial/simulation/raw/10_bjt_amp_tr.svg (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/raw/10_bjt_amp_tr.svg (revision 10414) @@ -0,0 +1,1046 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/1.0.5/doc/tutorial/simulation/raw/12_bjt_amp_ac.html =================================================================== --- tags/1.0.5/doc/tutorial/simulation/raw/12_bjt_amp_ac.html (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/raw/12_bjt_amp_ac.html (revision 10414) @@ -0,0 +1,98 @@ + + +

12_bjt_amp_ac: pinout with spice/portmap

+ +

Scope

+

+In this simulation we are going to look at a single-transistor amplifier +in frequency domain to verify how it amplifies a sine waves. Compared to +the trans variant the only difference is +how we specify the transistor pinout and what spice commands we use for the +AC simulatuin + +

The schematics

+

+Largely the same as trans variant. +

+

+ +
Click the image to get the sch-rnd sheet; NOTE: the actual value of V1 +has been changed from SINE() to a dc/ac combo.
+

+ +

Preparing for simulation

+ +

Q1

+

+This example demonstrates using spice/portmap to set the pinout: the +stock spice/pinnum attributes has been manually removed from Q1 terminals and +a portmap attribute, array type, added to the Q1 symbol. The portmap is: +

+{C->spice/pinnum=1}
+{B->spice/pinnum=2}
+{E->spice/pinnum=3}
+
+

+Since the attribute is called spice/portmap, it does not interfere with +the normal portmap attribute (installed by devmap in our example) and it +affects the spice workflow only. + +

V1

+

+V1 is generating the input sine wave on the in network. +The simulator will reconfigure it while sweeping the frequency for the +ac analysis. + +

V2

+

+V2 is an 5V DC power supply for Vcc: +

+dc 5
+
+ + +

Raw spice commands

+

+It contains the following script: +

+ac dec 10 1 1000k
+settype decibel out
+plot vdb(out) xlimit 1 1000k ylabel 'small signal gain'
+settype phase out
+plot cph(out) xlimit 1 1000k ylabel 'phase (in rad)'
+

+This runs an ac analysis between 1 Hz and 1 MHz with 10 points in every decade, +then plot gain and phase. + +

Export and run ngspice

+

+Running ngspice the usual way on the export yields the following graph: +

+ +

+ + +

Using other implementations

+

gnucap

+

+This may not work with gnucap; error message: open circuit: internal node 2 +

+Gnucap uses a different command syntax. Modify the spice command symbol's +spice/command attribute to: +

+print ac vdb(out) zp(out)
+op
+ac dec 10 1 1000k > plot.txt
+
+

+After the export, write a single word spice in the first line of the +file (e.g. using a text editor), else gnucap won't know the file is in spice +syntax. Then run gnucap 12_btj_amp_ac.cir and it will dump a text +table to plot.txt that can be plotted using e.g. gnuplot. Both traces are +included in the same file. +

+The gnucap-modified schematics is also available. + +

xyce

+

+TODO Index: tags/1.0.5/doc/tutorial/simulation/raw/12_bjt_amp_ac.rs =================================================================== --- tags/1.0.5/doc/tutorial/simulation/raw/12_bjt_amp_ac.rs (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/raw/12_bjt_amp_ac.rs (revision 10414) @@ -0,0 +1,1149 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAp; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAq; loclib_name=bc817_sot23; + li:objects { + } + ha:attrib { + footprint=SOT23 + li:portmap { + {B->pcb/pinnum=1} + {E->pcb/pinnum=2} + {C->pcb/pinnum=3} + } + } + } + } + ha:attrib { + ha:purpose = { value=devmap; prio=0; } + } + } + ha:group.2 { + uuid=ocyrXFXWgSsRrvvVMDcAAAA9; + li:objects { + ha:group.1 { + uuid=ocyrXFXWgSsRrvvVMDcAAAA+; loclib_name=bc817; + li:objects { + } + ha:attrib { + spice/model_card={* (C) 2023 Tibor 'Igor2' Palinkas +* License: CC0 (no rights reserved): https://creativecommons.org/publicdomain/zero/1.0/ +* Source: based on Vishay's datasheet: https://archive.org/details/bc817_spice_vishay +* +.model BC817 npn ( ++ IS=2.43485e-13 VAF=10 BF=270 IKF=1.12487 NE=1.84302 ISE=7.17747e-12 ++ IKR=0.149889 ISC=2.42047e-12 NC=3.94859 NR=1.04566 BR=2.51332 RC=0.407107 ++ CJC=5.516e-11 FC=0.8 MJC=0.529364 VJC=0.4 CJE=5.10473e-11 MJE=0.412728 ++ VJE=0.561234 TF=7.1424e-10 ITF=0.175457 VTF=1.86025 XTF=1.09929 RB=6.50128 ++ IRB=0.1 RBM=0.1 RE=0.0814215 TR=1e-07 ++ ) + +} + } + } + } + ha:attrib { + ha:purpose = { value=spicelib; prio=0; } + } + } + } + } + ha:obj_direct.2 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.1 { + uuid=8/SYZ/pfBzxyqFA12WQAAAAC; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAg; + li:objects { + ha:polygon.11 { + li:outline { + ha:line { x1=0; y1=0; x2=80000; y2=0; } + ha:line { x1=80000; y1=0; x2=80000; y2=20000; } + ha:line { x1=80000; y1=20000; x2=0; y2=20000; } + ha:line { x1=0; y1=20000; x2=0; y2=0; } + } + stroke=titlebox-frame; + fill=titlebox-fill; + } + ha:line.12 { x1=0; y1=10000; x2=80000; y2=10000; stroke=titlebox-frame; } + ha:line.13 { x1=40000; y1=10000; x2=40000; y2=0; stroke=titlebox-frame; } + ha:text.20 { x1=1000; y1=16500; dyntext=0; stroke=titlebox-big; text=TITLE; } + ha:text.21 { x1=1000; y1=10500; x2=79000; y2=16000; dyntext=1; stroke=titlebox-big; text=%../../A.title%; } + ha:text.22 { x1=1000; y1=5500; dyntext=0; stroke=titlebox-small; text={PROJECT:}; } + ha:text.23 { x1=13000; y1=5500; x2=39000; y2=9500; dyntext=1; stroke=titlebox-big; text=%project.name%; } + ha:text.24 { x1=1000; y1=500; dyntext=0; stroke=titlebox-small; text={PAGE:}; } + ha:text.25 { x1=10000; y1=500; x2=39000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.page%; } + ha:text.26 { x1=41000; y1=5500; dyntext=0; stroke=titlebox-small; text={FILE:}; } + ha:text.27 { x1=48000; y1=5500; x2=79000; y2=9500; dyntext=1; stroke=titlebox-big; text=%filename%; } + ha:text.28 { x1=41000; y1=500; dyntext=0; stroke=titlebox-small; text={MAINTAINER:}; } + ha:text.29 { x1=55000; y1=500; x2=79000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.maintainer%; } + } + ha:attrib { + purpose=titlebox + } + } + ha:group.2 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAJ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAh; + x=20000; y=100000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAK; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAi; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAL; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAj; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.5 { x1=9000; y1=5000; x2=9000; y2=-5000; stroke=sym-decor; } + ha:line.6 { x1=11000; y1=5000; x2=11000; y2=-5000; stroke=sym-decor; } + ha:line.7 { x1=4000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.8 { x1=11000; y1=0; x2=16000; y2=0; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=C1 + role=symbol + value=10u + } + } + ha:group.3 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAM; + x=-20000; y=-20000; + li:objects { + ha:line.1 { x1=40000; y1=120000; x2=32000; y2=120000; stroke=wire; } + ha:text.2 { x1=33000; y1=120000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + ha:line.3 { x1=32000; y1=84000; x2=32000; y2=120000; stroke=wire; } + } + ha:attrib { + name=in + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.5 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAN; + x=-20000; y=-20000; + li:objects { + ha:line.1 { x1=60000; y1=120000; x2=76000; y2=120000; stroke=wire; } + ha:line.3 { x1=64000; y1=120000; x2=64000; y2=120000; stroke=junction; } + ha:line.4 { x1=64000; y1=100000; x2=64000; y2=140000; stroke=wire; } + ha:text.5 { x1=66000; y1=120000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=int_b + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.7 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAU; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=44000; y=140000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAV; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAW; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=R1 + role=symbol + value=87k + } + } + ha:group.9 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAa; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=44000; y=80000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAb; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAc; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=R2 + role=symbol + value=10k + } + } + ha:group.14 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAr; + x=-52000; y=-20000; + li:objects { + ha:line.1 { x1=120000; y1=112000; x2=120000; y2=56000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.16 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAs; + x=-40000; y=-20000; + li:objects { + ha:line.1 { x1=84000; y1=80000; x2=84000; y2=56000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.18 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAw; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=68000; y=140000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAx; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAy; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=R3 + role=symbol + value=33k + } + } + ha:group.19 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAz; + x=-52000; y=-20000; + li:objects { + ha:line.1 { x1=120000; y1=128000; x2=120000; y2=140000; stroke=wire; } + ha:line.2 { x1=120000; y1=132000; x2=132000; y2=132000; stroke=wire; } + ha:line.3 { x1=120000; y1=132000; x2=120000; y2=132000; stroke=junction; } + ha:text.4 { x1=122000; y1=132000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=int_c + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.22 { + uuid=60PZRPnx0Y9mYJZvZgYAAAA0; + x=-40000; y=-20000; + li:objects { + ha:line.1 { x1=84000; y1=160000; x2=84000; y2=172000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.24 { + uuid=60PZRPnx0Y9mYJZvZgYAAAA1; + x=-52000; y=-20000; + li:objects { + ha:line.1 { x1=120000; y1=160000; x2=120000; y2=172000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.26 { + uuid=60PZRPnx0Y9mYJZvZgYAAAA5; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAh; + x=80000; y=112000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAA6; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAi; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=60PZRPnx0Y9mYJZvZgYAAAA7; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAj; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.5 { x1=9000; y1=5000; x2=9000; y2=-5000; stroke=sym-decor; } + ha:line.6 { x1=11000; y1=5000; x2=11000; y2=-5000; stroke=sym-decor; } + ha:line.7 { x1=4000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.8 { x1=11000; y1=0; x2=16000; y2=0; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=C2 + role=symbol + value=10u + } + } + ha:group.28 { + uuid=60PZRPnx0Y9mYJZvZgYAAAA/; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=108000; y=100000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAABA; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=60PZRPnx0Y9mYJZvZgYAAABB; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=R4 + role=symbol + value=100k + } + } + ha:group.29 { + uuid=60PZRPnx0Y9mYJZvZgYAAABC; + x=-60000; y=-20000; + li:objects { + ha:line.1 { x1=160000; y1=132000; x2=176000; y2=132000; stroke=wire; } + ha:line.2 { x1=168000; y1=120000; x2=168000; y2=132000; stroke=wire; } + ha:line.3 { x1=168000; y1=132000; x2=168000; y2=132000; stroke=junction; } + ha:text.4 { x1=173000; y1=132000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=out + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.32 { + uuid=60PZRPnx0Y9mYJZvZgYAAABD; + x=-60000; y=-20000; + li:objects { + ha:line.2 { x1=168000; y1=100000; x2=168000; y2=56000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.34 { + uuid=60PZRPnx0Y9mYJZvZgYAAABi; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB0; + x=128000; y=64000; rot=270.000000; mirx=1; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAABj; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB1; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=N + role=terminal + } + } + ha:group.2 { + uuid=60PZRPnx0Y9mYJZvZgYAAABk; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB2; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=P + role=terminal + } + } + ha:arc.3 { cx=10000; cy=0; r=6000; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:line.4 { x1=7000; y1=2000; x2=7000; y2=-2000; stroke=sym-decor; } + ha:line.5 { x1=5000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=11000; y1=0; x2=15000; y2=0; stroke=sym-decor; } + ha:text.7 { x1=0; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:text.8 { x1=8000; y1=-10000; dyntext=1; stroke=sym-secondary; text=%../A.spice/params%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=V2 + role=symbol + spice/params=dc 5 + li:spice/portmap { + {P->spice/pinnum=1} + {N->spice/pinnum=2} + } + } + } + ha:group.35 { + uuid=60PZRPnx0Y9mYJZvZgYAAABo; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB0; + x=12000; y=64000; rot=270.000000; mirx=1; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAABp; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB1; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=N + role=terminal + } + } + ha:group.2 { + uuid=60PZRPnx0Y9mYJZvZgYAAABq; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB2; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=P + role=terminal + } + } + ha:arc.3 { cx=10000; cy=0; r=6000; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:line.4 { x1=7000; y1=2000; x2=7000; y2=-2000; stroke=sym-decor; } + ha:line.5 { x1=5000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=11000; y1=0; x2=15000; y2=0; stroke=sym-decor; } + ha:text.7 { x1=0; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:text.8 { x1=6000; y1=-9000; dyntext=1; stroke=sym-secondary; text=%../A.spice/params%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=V1 + role=symbol + spice/params=dc 0 ac 0.1 + li:spice/portmap { + {P->spice/pinnum=1} + {N->spice/pinnum=2} + } + } + } + ha:group.36 { + uuid=60PZRPnx0Y9mYJZvZgYAAABr; + x=-80000; y=-20000; + li:objects { + ha:line.1 { x1=208000; y1=64000; x2=208000; y2=56000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.38 { + uuid=60PZRPnx0Y9mYJZvZgYAAABs; + x=-232000; y=-20000; + li:objects { + ha:line.1 { x1=244000; y1=64000; x2=244000; y2=56000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.40 { + uuid=60PZRPnx0Y9mYJZvZgYAAABt; + x=-80000; y=-20000; + li:objects { + ha:line.1 { x1=208000; y1=84000; x2=208000; y2=92000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.46 { + uuid=60PZRPnx0Y9mYJZvZgYAAABz; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=12000; y=36000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAB0; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.48 { + uuid=60PZRPnx0Y9mYJZvZgYAAAB1; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=44000; y=36000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAB2; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.50 { + uuid=60PZRPnx0Y9mYJZvZgYAAAB3; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=68000; y=36000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAB4; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.52 { + uuid=60PZRPnx0Y9mYJZvZgYAAAB5; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=108000; y=36000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAB6; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.54 { + uuid=60PZRPnx0Y9mYJZvZgYAAAB7; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=128000; y=36000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAB8; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.56 { + uuid=60PZRPnx0Y9mYJZvZgYAAACB; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB6; + x=128000; y=72000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAACC; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB7; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-4000; y1=4000; x2=4000; y2=7000; halign=center; dyntext=0; stroke=sym-primary; text=Vcc; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:Vcc} + } + role=symbol + } + } + ha:group.58 { + uuid=60PZRPnx0Y9mYJZvZgYAAACD; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB6; + x=68000; y=152000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAACE; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB7; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-4000; y1=4000; x2=4000; y2=7000; halign=center; dyntext=0; stroke=sym-primary; text=Vcc; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:Vcc} + } + role=symbol + } + } + ha:group.60 { + uuid=60PZRPnx0Y9mYJZvZgYAAACF; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB6; + x=44000; y=152000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAACG; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB7; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-4000; y1=4000; x2=4000; y2=7000; halign=center; dyntext=0; stroke=sym-primary; text=Vcc; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:Vcc} + } + role=symbol + } + } + ha:group.62 { + uuid=uo/hkCCyjHkmVGRW0F0AAAA+; src_uuid=TeGEOMuew6iCb2kzckAAAAAD; + x=9000; y=124000; + li:objects { + ha:text.1 { x1=2000; y1=-4000; dyntext=0; stroke=sym-decor; text=raw spice; } + ha:text.2 { x1=2000; y1=-8000; dyntext=0; stroke=sym-decor; text=command; } + ha:polygon.3 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=-10000; } + ha:line { x1=0; y1=-10000; x2=12000; y2=-10000; } + ha:line { x1=12000; y1=-10000; x2=12000; y2=0; } + ha:line { x1=12000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + } + ha:attrib { + -sym-comment={ Fill in spice/command and use export_spice (e.g. the spice_raw view) to get that string exported at the end of the spice netlist file. } + -sym-copyright=(C) 2023 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + role=symbol + spice/command={ac dec 10 1 1000k +settype decibel out +plot vdb(out) xlimit 1 1000k ylabel 'small signal gain' +settype phase out +plot cph(out) xlimit 1 1000k ylabel 'phase (in rad)' +} + } + } + ha:group.70 { + uuid=emEhKEkrgdRFzXxchToAAABZ; src_uuid=iNOQfJpO6hT/HFDFGjoAAACK; + x=56000; y=100000; + li:objects { + ha:polygon.1 { + li:outline { + ha:line { x1=10266; y1=-1780; x2=9224; y2=-3517; } + ha:line { x1=9224; y1=-3517; x2=10935; y2=-3368; } + ha:line { x1=10935; y1=-3368; x2=10266; y2=-1780; } + } + stroke=sym-decor; + fill=sym-decor; + } + ha:group.2 { + uuid=emEhKEkrgdRFzXxchToAAABa; src_uuid=iNOQfJpO6hT/HFDFGjoAAACL; + x=12000; y=8000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=-4000; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=C + role=terminal + } + } + ha:group.3 { + uuid=emEhKEkrgdRFzXxchToAAABb; src_uuid=iNOQfJpO6hT/HFDFGjoAAACM; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=B + role=terminal + } + } + ha:group.4 { + uuid=emEhKEkrgdRFzXxchToAAABc; src_uuid=iNOQfJpO6hT/HFDFGjoAAACN; + x=12000; y=-4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=-4000; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=E + role=terminal + } + } + ha:text.5 { x1=8000; y1=8000; rot=90.000000; dyntext=1; stroke=sym-secondary; text=%../a.devmap%; floater=1; } + ha:text.6 { x1=4000; y1=8000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:arc.7 { cx=9000; cy=0; r=5500; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:line.8 { x1=7000; y1=4000; x2=7000; y2=-4000; stroke=sym-decor; } + ha:line.9 { x1=4000; y1=0; x2=7000; y2=0; stroke=sym-decor; } + ha:line.10 { x1=7000; y1=-1000; x2=12000; y2=-4000; stroke=sym-decor; } + ha:line.11 { x1=7000; y1=1000; x2=12000; y2=4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + devmap=bc817_sot23 + name=Q1 + li:portmap { + {C->spice/pinnum=1} + {B->spice/pinnum=2} + {E->spice/pinnum=3} + } + role=symbol + spice/model=bc817 + } + } + ha:connection.74 { + li:conn { + /2/3/1 + /2/2/2/1 + } + } + ha:connection.75 { + li:conn { + /2/5/1 + /2/2/1/1 + } + } + ha:connection.87 { + li:conn { + /2/35/2/1 + /2/3/3 + } + } + ha:connection.89 { + li:conn { + /2/38/1 + /2/35/1/1 + } + } + ha:connection.91 { + li:conn { + /2/46/1/1 + /2/38/1 + } + } + ha:connection.102 { + li:conn { + /2/7/1/1 + /2/5/4 + } + } + ha:connection.103 { + li:conn { + /2/9/2/1 + /2/5/4 + } + } + ha:connection.104 { + li:conn { + /2/16/1 + /2/9/1/1 + } + } + ha:connection.105 { + li:conn { + /2/22/1 + /2/7/2/1 + } + } + ha:connection.106 { + li:conn { + /2/48/1/1 + /2/16/1 + } + } + ha:connection.107 { + li:conn { + /2/60/1/1 + /2/22/1 + } + } + ha:connection.108 { + li:conn { + /2/19/1 + /2/18/1/1 + } + } + ha:connection.109 { + li:conn { + /2/24/1 + /2/18/2/1 + } + } + ha:connection.116 { + li:conn { + /2/50/1/1 + /2/14/1 + } + } + ha:connection.120 { + li:conn { + /2/58/1/1 + /2/24/1 + } + } + ha:connection.121 { + li:conn { + /2/70/2/1 + /2/19/1 + } + } + ha:connection.122 { + li:conn { + /2/70/3/1 + /2/5/1 + } + } + ha:connection.123 { + li:conn { + /2/70/4/1 + /2/14/1 + } + } + ha:connection.124 { + li:conn { + /2/26/2/1 + /2/19/2 + } + } + ha:connection.125 { + li:conn { + /2/29/1 + /2/26/1/1 + } + } + ha:connection.126 { + li:conn { + /2/29/2 + /2/28/2/1 + } + } + ha:connection.127 { + li:conn { + /2/32/2 + /2/28/1/1 + } + } + ha:connection.130 { + li:conn { + /2/52/1/1 + /2/32/2 + } + } + ha:connection.133 { + li:conn { + /2/36/1 + /2/34/1/1 + } + } + ha:connection.134 { + li:conn { + /2/40/1 + /2/34/2/1 + } + } + ha:connection.135 { + li:conn { + /2/54/1/1 + /2/36/1 + } + } + ha:connection.136 { + li:conn { + /2/56/1/1 + /2/40/1 + } + } + } + ha:attrib { + maintainer=Tibor 'Igor2' Palinkas + page=1 of 1 + print_page=A/4 + title={SIM raw spice: BJT amplifier, ac} + } + } +} Index: tags/1.0.5/doc/tutorial/simulation/raw/12_bjt_amp_ac1.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/1.0.5/doc/tutorial/simulation/raw/12_bjt_amp_ac1.png =================================================================== --- tags/1.0.5/doc/tutorial/simulation/raw/12_bjt_amp_ac1.png (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/raw/12_bjt_amp_ac1.png (revision 10414) Property changes on: tags/1.0.5/doc/tutorial/simulation/raw/12_bjt_amp_ac1.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/1.0.5/doc/tutorial/simulation/raw/12_bjt_amp_ac2.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/1.0.5/doc/tutorial/simulation/raw/12_bjt_amp_ac2.png =================================================================== --- tags/1.0.5/doc/tutorial/simulation/raw/12_bjt_amp_ac2.png (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/raw/12_bjt_amp_ac2.png (revision 10414) Property changes on: tags/1.0.5/doc/tutorial/simulation/raw/12_bjt_amp_ac2.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/1.0.5/doc/tutorial/simulation/raw/16_opamp_dc.html =================================================================== --- tags/1.0.5/doc/tutorial/simulation/raw/16_opamp_dc.html (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/raw/16_opamp_dc.html (revision 10414) @@ -0,0 +1,84 @@ + + +

16_opamp_dc: dc sweep

+ +

Scope

+

+In this simulation we are going to map a simple opamp circuit's gain +at different voltages (dc sweep). + +

The schematics

+

+The single-sheet schematic contains the opamp, the voltage sources for +input and two more voltage sources for the power supply (positive and +negative) for the opamp and spice command symbol. +

+

+ +
Click the image to get the sch-rnd sheet
+

+ +

Opamp model

+

+This example uses the lm358 macromodel from sch-rnd's stock spice +library. This model is a subcircuit of the amplifier and simulates a +lot of limiters and parasitics. + +

Preparing for simulation

+ +

Q1

+

+The model uses the standard opamp pinout so the hardwired spice/pinnum +attributes on the terminals will simply work. + + +

V1

+

+V1 is generating the input dc voltage. We can leave it 0 here, since +the dc sweep command for the analysis will provide the change over time + +

V2 and V3

+

+Both are 5V DC rails for powering the opamp with the required positive +and negative supplies. + +

Raw spice commands

+

+It contains the following script: +

+dc V1 -50m 60m 2m
+plot v(in) v(out)
+
+

+which runs a DC sweep analysis from -50mV to +60mV on the input, increasing +voltage by 2 mV steps. At the end the input and output voltages +are plotted. + +

Export and run ngspice

+

+Running ngspice the usual way on the export yields the following graph: +

+ + +

Using other implementations

+

gnucap

+

+Gnucap throws an error: open circuit: internal node 14 +

+Gnucap uses a different command syntax. Modify the spice command symbol's +spice/command attribute to: +

+print dc v(in) v(out)
+dc V1 -50m 60m 2m > plot.txt
+
+

+After the export, write the single word spice in the first line of the +file (e.g. using a text editor), otherwise gnucap won't know the file is in spice +syntax. Then run gnucap 16_omapm_dc.cir and it will dump a text +table to plot.txt that can be plotted using a suitable utility, e.g. gnuplot. +

+The gnucap-modified schematic is also available. + +

xyce

+

+TODO Index: tags/1.0.5/doc/tutorial/simulation/raw/16_opamp_dc.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/1.0.5/doc/tutorial/simulation/raw/16_opamp_dc.png =================================================================== --- tags/1.0.5/doc/tutorial/simulation/raw/16_opamp_dc.png (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/raw/16_opamp_dc.png (revision 10414) Property changes on: tags/1.0.5/doc/tutorial/simulation/raw/16_opamp_dc.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/1.0.5/doc/tutorial/simulation/raw/16_opamp_dc.rs =================================================================== --- tags/1.0.5/doc/tutorial/simulation/raw/16_opamp_dc.rs (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/raw/16_opamp_dc.rs (revision 10414) @@ -0,0 +1,1042 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + ha:group.1 { + uuid=Hif/m8o2mo/CrYnTszoAAAAV; + li:objects { + ha:group.1 { + uuid=Hif/m8o2mo/CrYnTszoAAAAW; loclib_name=lm358_so8; + li:objects { + } + ha:attrib { + footprint=so(8) + li:portmap { + {1/in- -> pcb/pinnum=2} + {1/in+ -> pcb/pinnum=3} + {1/out -> pcb/pinnum=1} + {1/V+ -> pcb/pinnum=8} + {1/V- -> pcb/pinnum=4} + {2/in- -> pcb/pinnum=6} + {2/in+ -> pcb/pinnum=5} + {2/out -> pcb/pinnum=7} + {2/V+ -> pcb/pinnum=8} + {2/V- -> pcb/pinnum=4} + } + } + } + } + ha:attrib { + ha:purpose = { value=devmap; prio=0; } + } + } + ha:group.2 { + uuid=y4qxH+ae2qngQHst1jcAAAA1; + li:objects { + ha:group.1 { + uuid=y4qxH+ae2qngQHst1jcAAAA2; loclib_name=lm358; + li:objects { + } + ha:attrib { + spice/model_card={* lm358 - low power opamp model (single slot) +* +* (C) 2023 Tibor 'Igor2' Palinkas +* License: CC0 (no rights reserved): https://creativecommons.org/publicdomain/zero/1.0/ +* Source: from ST's datasheet: https://archive.org/details/st-ts321 +* (st321 is reasonably close to lm358 for simple simulation cases; see +* warnings on page 7) +* +* +** CONNECTIONS: +* 1 inverting input +* 2 non-inverting INPUT +* 3 output +* 4 positive power supply +* 5 negative power supply +.SUBCKT LM358 1 2 3 4 5 + +.MODEL MDTH D IS=1E-8 KF=3.104131E-15 CJO=10F + +* INPUT STAGE +CIP 2 5 1.000000E-12 +CIN 1 5 1.000000E-12 +EIP 10 5 2 5 1 +EIN 16 5 1 5 1 +RIP 10 11 2.600000E+01 +RIN 15 16 2.600000E+01 +RIS 11 15 2.003862E+02 +DIP 11 12 MDTH 400E-12 +DIN 15 14 MDTH 400E-12 +VOFP 12 13 DC 0 +VOFN 13 14 DC 0 +IPOL 13 5 1.000000E-05 +CPS 11 15 3.783376E-09 +DINN 17 13 MDTH 400E-12 +VIN 17 5 0.000000e+00 +DINR 15 18 MDTH 400E-12 +VIP 4 18 2.000000E+00 +FCP 4 5 VOFP 3.400000E+01 +FCN 5 4 VOFN 3.400000E+01 +FIBP 2 5 VOFN 2.000000E-03 +FIBN 5 1 VOFP 2.000000E-03 + +* AMPLIFYING STAGE +FIP 5 19 VOFP 3.600000E+02 +FIN 5 19 VOFN 3.600000E+02 +RG1 19 5 3.652997E+06 +RG2 19 4 3.652997E+06 +CC 19 5 6.000000E-09 +DOPM 19 22 MDTH 400E-12 +DONM 21 19 MDTH 400E-12 +HOPM 22 28 VOUT 7.500000E+03 +VIPM 28 4 1.500000E+02 +HONM 21 27 VOUT 7.500000E+03 +VINM 5 27 1.500000E+02 +EOUT 26 23 19 5 1 +VOUT 23 5 0 +ROUT 26 3 20 +COUT 3 5 1.000000E-12 +DOP 19 25 MDTH 400E-12 +VOP 4 25 2.242230E+00 +DON 24 19 MDTH 400E-12 +VON 24 5 7.922301E-01 +.ENDS +} + } + } + } + ha:attrib { + ha:purpose = { value=spicelib; prio=0; } + } + } + } + } + ha:obj_direct.2 { + uuid=Hif/m8o2mo/CrYnTszoAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.1 { + uuid=8/SYZ/pfBzxyqFA12WQAAAAC; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAg; + li:objects { + ha:polygon.11 { + li:outline { + ha:line { x1=0; y1=0; x2=80000; y2=0; } + ha:line { x1=80000; y1=0; x2=80000; y2=20000; } + ha:line { x1=80000; y1=20000; x2=0; y2=20000; } + ha:line { x1=0; y1=20000; x2=0; y2=0; } + } + stroke=titlebox-frame; + fill=titlebox-fill; + } + ha:line.12 { x1=0; y1=10000; x2=80000; y2=10000; stroke=titlebox-frame; } + ha:line.13 { x1=40000; y1=10000; x2=40000; y2=0; stroke=titlebox-frame; } + ha:text.20 { x1=1000; y1=16500; dyntext=0; stroke=titlebox-big; text=TITLE; } + ha:text.21 { x1=1000; y1=10500; x2=79000; y2=16000; dyntext=1; stroke=titlebox-big; text=%../../A.title%; } + ha:text.22 { x1=1000; y1=5500; dyntext=0; stroke=titlebox-small; text={PROJECT:}; } + ha:text.23 { x1=13000; y1=5500; x2=39000; y2=9500; dyntext=1; stroke=titlebox-big; text=%project.name%; } + ha:text.24 { x1=1000; y1=500; dyntext=0; stroke=titlebox-small; text={PAGE:}; } + ha:text.25 { x1=10000; y1=500; x2=39000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.page%; } + ha:text.26 { x1=41000; y1=5500; dyntext=0; stroke=titlebox-small; text={FILE:}; } + ha:text.27 { x1=48000; y1=5500; x2=79000; y2=9500; dyntext=1; stroke=titlebox-big; text=%filename%; } + ha:text.28 { x1=41000; y1=500; dyntext=0; stroke=titlebox-small; text={MAINTAINER:}; } + ha:text.29 { x1=55000; y1=500; x2=79000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.maintainer%; } + } + ha:attrib { + purpose=titlebox + } + } + ha:group.2 { + uuid=Hif/m8o2mo/CrYnTszoAAAAP; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAH; + x=80000; y=116000; + li:objects { + ha:group.1 { + uuid=Hif/m8o2mo/CrYnTszoAAAAQ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAI; + x=-20000; y=4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=in+ + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.2 { + uuid=Hif/m8o2mo/CrYnTszoAAAAR; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAJ; + x=-20000; y=-4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=in- + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:group.3 { + uuid=Hif/m8o2mo/CrYnTszoAAAAS; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAK; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=out + role=terminal + ha:spice/pinnum = { value=3; prio=31050; } + } + } + ha:line.4 { x1=-20000; y1=-8000; x2=-20000; y2=8000; stroke=sym-decor; } + ha:line.5 { x1=-20000; y1=8000; x2=-4000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=-4000; y1=0; x2=-20000; y2=-8000; stroke=sym-decor; } + ha:line.7 { x1=-18000; y1=5000; x2=-18000; y2=3000; stroke=sym-decor; } + ha:line.8 { x1=-19000; y1=4000; x2=-17000; y2=4000; stroke=sym-decor; } + ha:line.9 { x1=-19000; y1=-4000; x2=-17000; y2=-4000; stroke=sym-decor; } + ha:group.10 { + uuid=Hif/m8o2mo/CrYnTszoAAAAT; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAL; + x=-12000; y=-4000; rot=270.000000; mirx=1; miry=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=0; y1=-1000; rot=180.000000; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=V- + role=terminal + ha:spice/pinnum = { value=5; prio=31050; } + } + } + ha:group.11 { + uuid=Hif/m8o2mo/CrYnTszoAAAAU; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAM; + x=-12000; y=8000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=-4000; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=V+ + role=terminal + ha:spice/pinnum = { value=4; prio=31050; } + } + } + ha:text.12 { x1=-21000; y1=9000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -slot=1 + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + devmap=lm358_so8 + name=U1 + role=symbol + spice/model=lm358 + } + } + ha:group.3 { + uuid=Hif/m8o2mo/CrYnTszoAAAAd; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=24000; y=112000; + li:objects { + ha:group.1 { + uuid=Hif/m8o2mo/CrYnTszoAAAAe; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=Hif/m8o2mo/CrYnTszoAAAAf; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=R1 + role=symbol + value=1k + } + } + ha:group.4 { + uuid=Hif/m8o2mo/CrYnTszoAAAAg; + x=-20000; y=0; + li:objects { + ha:line.1 { x1=64000; y1=112000; x2=76000; y2=112000; stroke=wire; } + ha:line.2 { x1=72000; y1=112000; x2=72000; y2=84000; stroke=wire; } + ha:line.3 { x1=72000; y1=112000; x2=72000; y2=112000; stroke=junction; } + ha:line.4 { x1=72000; y1=84000; x2=84000; y2=84000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.5 { + li:conn { + /2/4/1 + /2/2/2/1 + } + } + ha:group.7 { + uuid=Hif/m8o2mo/CrYnTszoAAAAk; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=64000; y=84000; + li:objects { + ha:group.1 { + uuid=Hif/m8o2mo/CrYnTszoAAAAl; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=Hif/m8o2mo/CrYnTszoAAAAm; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=R2 + role=symbol + value=100k + } + } + ha:group.9 { + uuid=Hif/m8o2mo/CrYnTszoAAAAn; + x=-20000; y=0; + li:objects { + ha:line.1 { x1=104000; y1=84000; x2=112000; y2=84000; stroke=wire; } + ha:line.2 { x1=112000; y1=84000; x2=112000; y2=116000; stroke=wire; } + ha:line.3 { x1=100000; y1=116000; x2=116000; y2=116000; stroke=wire; } + ha:line.4 { x1=112000; y1=116000; x2=112000; y2=116000; stroke=junction; } + ha:text.5 { x1=112000; y1=116000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=out + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.12 { + uuid=Hif/m8o2mo/CrYnTszoAAAAo; + x=-12000; y=0; + li:objects { + ha:line.1 { x1=36000; y1=112000; x2=24000; y2=112000; stroke=wire; } + ha:text.2 { x1=28000; y1=112000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + ha:line.3 { x1=24000; y1=104000; x2=24000; y2=112000; stroke=wire; } + } + ha:attrib { + name=in + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.14 { + uuid=Hif/m8o2mo/CrYnTszoAAAAt; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=48000; y=120000; + li:objects { + ha:group.1 { + uuid=Hif/m8o2mo/CrYnTszoAAAAu; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.15 { + uuid=Hif/m8o2mo/CrYnTszoAAAAv; + x=-20000; y=0; + li:objects { + ha:line.1 { x1=68000; y1=120000; x2=76000; y2=120000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.16 { + li:conn { + /2/15/1 + /2/2/1/1 + } + } + ha:group.18 { + uuid=Hif/m8o2mo/CrYnTszoAAAA8; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB6; + x=68000; y=128000; + li:objects { + ha:group.1 { + uuid=Hif/m8o2mo/CrYnTszoAAAA9; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB7; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-4000; y1=4000; x2=4000; y2=7000; halign=center; dyntext=0; stroke=sym-primary; text=Vcc; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:Vcc} + } + role=symbol + } + } + ha:group.19 { + uuid=Hif/m8o2mo/CrYnTszoAAAA+; + x=-20000; y=0; + li:objects { + ha:line.1 { x1=88000; y1=124000; x2=88000; y2=128000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.22 { + uuid=Hif/m8o2mo/CrYnTszoAAABH; src_uuid=iNOQfJpO6hT/HFDFGjoAAABv; + x=68000; y=104000; rot=180.000000; + li:objects { + ha:group.1 { + uuid=Hif/m8o2mo/CrYnTszoAAABI; src_uuid=iNOQfJpO6hT/HFDFGjoAAABw; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=6000; y1=7000; x2=18000; y2=10000; rot=180.000000; halign=center; dyntext=1; stroke=sym-primary; text=%../A.rail%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:forge { + delete,forge/tmp + scalar,forge/tmp + {sub,^,1:,forge/tmp} + suba,$,rail,forge/tmp + array,connect + append,connect,forge/tmp + } + rail=Vneg + role=symbol + } + } + ha:group.23 { + uuid=Hif/m8o2mo/CrYnTszoAAABJ; + x=-20000; y=0; + li:objects { + ha:line.1 { x1=88000; y1=104000; x2=88000; y2=108000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.28 { + uuid=Hif/m8o2mo/CrYnTszoAAABh; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=12000; y=80000; + li:objects { + ha:group.1 { + uuid=Hif/m8o2mo/CrYnTszoAAABi; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.29 { + uuid=Hif/m8o2mo/CrYnTszoAAABj; + x=-12000; y=0; + li:objects { + ha:line.1 { x1=24000; y1=80000; x2=24000; y2=84000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.33 { + uuid=Hif/m8o2mo/CrYnTszoAAABs; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB6; + x=56000; y=68000; + li:objects { + ha:group.1 { + uuid=Hif/m8o2mo/CrYnTszoAAABt; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB7; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-4000; y1=4000; x2=4000; y2=7000; halign=center; dyntext=0; stroke=sym-primary; text=Vcc; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:Vcc} + } + role=symbol + } + } + ha:group.34 { + uuid=Hif/m8o2mo/CrYnTszoAAABw; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=56000; y=40000; + li:objects { + ha:group.1 { + uuid=Hif/m8o2mo/CrYnTszoAAABx; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.35 { + uuid=Hif/m8o2mo/CrYnTszoAAABy; + x=-104000; y=-28000; + li:objects { + ha:line.1 { x1=160000; y1=92000; x2=160000; y2=96000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.38 { + uuid=Hif/m8o2mo/CrYnTszoAAABz; + x=-104000; y=-28000; + li:objects { + ha:line.1 { x1=160000; y1=68000; x2=160000; y2=72000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.42 { + uuid=Hif/m8o2mo/CrYnTszoAAAB8; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=92000; y=68000; + li:objects { + ha:group.1 { + uuid=Hif/m8o2mo/CrYnTszoAAAB9; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.43 { + uuid=Hif/m8o2mo/CrYnTszoAAAB+; + x=-104000; y=-28000; + li:objects { + ha:line.1 { x1=184000; y1=92000; x2=184000; y2=104000; stroke=wire; } + ha:line.2 { x1=184000; y1=104000; x2=196000; y2=104000; stroke=wire; } + ha:line.3 { x1=196000; y1=104000; x2=196000; y2=96000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.46 { + uuid=Hif/m8o2mo/CrYnTszoAAACB; src_uuid=iNOQfJpO6hT/HFDFGjoAAABv; + x=80000; y=40000; rot=180.000000; + li:objects { + ha:group.1 { + uuid=Hif/m8o2mo/CrYnTszoAAACC; src_uuid=iNOQfJpO6hT/HFDFGjoAAABw; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=6000; y1=7000; x2=18000; y2=10000; rot=180.000000; halign=center; dyntext=1; stroke=sym-primary; text=%../A.rail%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:forge { + delete,forge/tmp + scalar,forge/tmp + {sub,^,1:,forge/tmp} + suba,$,rail,forge/tmp + array,connect + append,connect,forge/tmp + } + rail=Vneg + role=symbol + } + } + ha:group.47 { + uuid=Hif/m8o2mo/CrYnTszoAAACD; + x=-104000; y=-28000; + li:objects { + ha:line.1 { x1=184000; y1=72000; x2=184000; y2=68000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.50 { + uuid=guptF1eHUCXR7MoVgJUAAAA2; src_uuid=TeGEOMuew6iCb2kzckAAAAAD; + x=8000; y=56000; + li:objects { + ha:text.1 { x1=2000; y1=-4000; dyntext=0; stroke=sym-decor; text=raw spice; } + ha:text.2 { x1=2000; y1=-8000; dyntext=0; stroke=sym-decor; text=command; } + ha:polygon.3 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=-10000; } + ha:line { x1=0; y1=-10000; x2=12000; y2=-10000; } + ha:line { x1=12000; y1=-10000; x2=12000; y2=0; } + ha:line { x1=12000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + } + ha:attrib { + -sym-comment={ Fill in spice/command and use export_spice (e.g. the spice_raw view) to get that string exported at the end of the spice netlist file. } + -sym-copyright=(C) 2023 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + role=symbol + spice/command={ dc V1 -50m 60m 2m +plot v(in) v(out)} + } + } + ha:group.51 { + uuid=XFxbV/afs+qvJqWppTgAAABB; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB0; + x=12000; y=104000; rot=270.000000; mirx=1; + li:objects { + ha:group.1 { + uuid=XFxbV/afs+qvJqWppTgAAABC; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB1; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=N + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.2 { + uuid=XFxbV/afs+qvJqWppTgAAABD; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB2; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=P + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:arc.3 { cx=10000; cy=0; r=6000; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:line.4 { x1=7000; y1=2000; x2=7000; y2=-2000; stroke=sym-decor; } + ha:line.5 { x1=5000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=11000; y1=0; x2=15000; y2=0; stroke=sym-decor; } + ha:text.7 { x1=0; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:text.8 { x1=0; y1=4000; dyntext=1; stroke=sym-secondary; text=%../A.spice/params%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=V1 + role=symbol + spice/params=dc 0 + } + } + ha:group.54 { + uuid=XFxbV/afs+qvJqWppTgAAABE; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB0; + x=56000; y=64000; rot=270.000000; mirx=1; + li:objects { + ha:group.1 { + uuid=XFxbV/afs+qvJqWppTgAAABF; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB1; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=N + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.2 { + uuid=XFxbV/afs+qvJqWppTgAAABG; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB2; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=P + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:arc.3 { cx=10000; cy=0; r=6000; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:line.4 { x1=7000; y1=2000; x2=7000; y2=-2000; stroke=sym-decor; } + ha:line.5 { x1=5000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=11000; y1=0; x2=15000; y2=0; stroke=sym-decor; } + ha:text.7 { x1=0; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:text.8 { x1=0; y1=4000; dyntext=1; stroke=sym-secondary; text=%../A.spice/params%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=V2 + role=symbol + spice/params=dc 5 + } + } + ha:group.57 { + uuid=XFxbV/afs+qvJqWppTgAAABH; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB0; + x=80000; y=64000; rot=270.000000; mirx=1; + li:objects { + ha:group.1 { + uuid=XFxbV/afs+qvJqWppTgAAABI; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB1; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=N + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.2 { + uuid=XFxbV/afs+qvJqWppTgAAABJ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB2; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=P + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:arc.3 { cx=10000; cy=0; r=6000; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:line.4 { x1=7000; y1=2000; x2=7000; y2=-2000; stroke=sym-decor; } + ha:line.5 { x1=5000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=11000; y1=0; x2=15000; y2=0; stroke=sym-decor; } + ha:text.7 { x1=0; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:text.8 { x1=0; y1=4000; dyntext=1; stroke=sym-secondary; text=%../A.spice/params%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=V3 + role=symbol + spice/params=dc 5 + } + } + ha:connection.89 { + li:conn { + /2/29/1 + /2/28/1/1 + } + } + ha:connection.90 { + li:conn { + /2/35/1 + /2/33/1/1 + } + } + ha:connection.91 { + li:conn { + /2/38/1 + /2/34/1/1 + } + } + ha:connection.93 { + li:conn { + /2/43/3 + /2/42/1/1 + } + } + ha:connection.94 { + li:conn { + /2/47/1 + /2/46/1/1 + } + } + ha:connection.95 { + li:conn { + /2/51/1/1 + /2/29/1 + } + } + ha:connection.96 { + li:conn { + /2/51/2/1 + /2/12/3 + } + } + ha:connection.97 { + li:conn { + /2/54/1/1 + /2/38/1 + } + } + ha:connection.98 { + li:conn { + /2/54/2/1 + /2/35/1 + } + } + ha:connection.99 { + li:conn { + /2/57/1/1 + /2/47/1 + } + } + ha:connection.100 { + li:conn { + /2/57/2/1 + /2/43/1 + } + } + ha:connection.102 { + li:conn { + /2/3/2/1 + /2/12/1 + } + } + ha:connection.103 { + li:conn { + /2/4/1 + /2/3/1/1 + } + } + ha:connection.104 { + li:conn { + /2/7/2/1 + /2/4/4 + } + } + ha:connection.105 { + li:conn { + /2/9/1 + /2/7/1/1 + } + } + ha:connection.106 { + li:conn { + /2/9/3 + /2/2/3/1 + } + } + ha:connection.107 { + li:conn { + /2/15/1 + /2/14/1/1 + } + } + ha:connection.108 { + li:conn { + /2/19/1 + /2/18/1/1 + } + } + ha:connection.109 { + li:conn { + /2/19/1 + /2/2/11/1 + } + } + ha:connection.110 { + li:conn { + /2/23/1 + /2/2/10/1 + } + } + ha:connection.111 { + li:conn { + /2/23/1 + /2/22/1/1 + } + } + } + ha:attrib { + maintainer=Tibor 'Igor2' Palinkas + page=1 of 1 + print_page=A/4 + title={SIM raw spice: ompamp circuit, dc gain} + } + } +} Index: tags/1.0.5/doc/tutorial/simulation/raw/16_opamp_dc.svg =================================================================== --- tags/1.0.5/doc/tutorial/simulation/raw/16_opamp_dc.svg (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/raw/16_opamp_dc.svg (revision 10414) @@ -0,0 +1,856 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/1.0.5/doc/tutorial/simulation/raw/18_opamp_ac.html =================================================================== --- tags/1.0.5/doc/tutorial/simulation/raw/18_opamp_ac.html (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/raw/18_opamp_ac.html (revision 10414) @@ -0,0 +1,67 @@ + + +

18_opamp_ac: 2 slot opamp

+ +

Scope

+

+A notch filter built with two opamps: this filter passes signals between DC +and 100 kHz but filters out 1 kHz signals. Demonstrated using a slotted +opamp with simulation. + +

The schematics

+

+

+ +
Click the image to get the sch-rnd sheet
+

+More info on the circuit: www.electronics-tutorials.ws + +

Preparing for simulation

+

+The lm358 contains two opamps in a single physical package. For the PCB +workflow this is going to be a single footprint with 8 pins. For spice +simulation, two separate components are exported, one per slot. The problem is: +only slot 1's power terminals are connected! This is no problem for the +PCB workflow, where a physical connection between slots exists within the package. +For simulation, the trick is to set spice/shared on the power terminals on both +slots (4 terminals total). This tells sch-rnd to share the connection between +the same numbered terminals of different slots of the same symbol. +

+Other than this, everything else is pretty much the same as in +12_bjt_amp_ac. + +

Raw spice commands

+

+Same as in 12_bjt_amp_ac. + +

Export and run ngspice

+

+Running ngspice the usual way on the export yields the following graphs: +

+ +

+ + +

Using other implementations

+

gnucap

+

+Gnucap throws errors: open circuit: internal node ... +

+Gnucap uses a different command syntax. Modify the spice command symbol's +spice/command attribute to: +

+print ac vdb(out) zp(out)
+op
+ac dec 10 1 1000k > plot.txt
+
+

+After the export, write the single word spice in the first line of the +file (e.g. using a text editor), otherwise gnucap won't know the file is in spice +syntax. Then run gnucap 16_omapm_dc.cir and it will dump a text +table to plot.txt that can be plotted using a suitable utility, e.g. gnuplot. +

+The gnucap-modified schematic is also available. + +

xyce

+

+TODO Index: tags/1.0.5/doc/tutorial/simulation/raw/18_opamp_ac.rs =================================================================== --- tags/1.0.5/doc/tutorial/simulation/raw/18_opamp_ac.rs (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/raw/18_opamp_ac.rs (revision 10414) @@ -0,0 +1,1560 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + ha:group.1 { + uuid=Hif/m8o2mo/CrYnTszoAAAAV; + li:objects { + ha:group.1 { + uuid=Hif/m8o2mo/CrYnTszoAAAAW; loclib_name=lm358_so8; + li:objects { + } + ha:attrib { + footprint=so(8) + li:portmap { + {1/in- -> pcb/pinnum=2} + {1/in+ -> pcb/pinnum=3} + {1/out -> pcb/pinnum=1} + {1/V+ -> pcb/pinnum=8} + {1/V- -> pcb/pinnum=4} + {2/in- -> pcb/pinnum=6} + {2/in+ -> pcb/pinnum=5} + {2/out -> pcb/pinnum=7} + {2/V+ -> pcb/pinnum=8} + {2/V- -> pcb/pinnum=4} + } + } + } + } + ha:attrib { + ha:purpose = { value=devmap; prio=0; } + } + } + ha:group.2 { + uuid=mWD+aTBiBXTjVEOQC6IAAABQ; + li:objects { + ha:group.1 { + uuid=mWD+aTBiBXTjVEOQC6IAAABR; loclib_name=lm358; + li:objects { + } + ha:attrib { + spice/model_card={* lm358 - low power opamp model (single slot) +* +* (C) 2023 Tibor 'Igor2' Palinkas +* License: CC0 (no rights reserved): https://creativecommons.org/publicdomain/zero/1.0/ +* Source: from ST's datasheet: https://archive.org/details/st-ts321 +* (st321 is reasonably close to lm358 for simple simulation cases; see +* warnings on page 7) +* +* +** CONNECTIONS: +* 1 inverting input +* 2 non-inverting INPUT +* 3 output +* 4 positive power supply +* 5 negative power supply +.SUBCKT LM358 1 2 3 4 5 + +.MODEL MDTH D IS=1E-8 KF=3.104131E-15 CJO=10F + +* INPUT STAGE +CIP 2 5 1.000000E-12 +CIN 1 5 1.000000E-12 +EIP 10 5 2 5 1 +EIN 16 5 1 5 1 +RIP 10 11 2.600000E+01 +RIN 15 16 2.600000E+01 +RIS 11 15 2.003862E+02 +DIP 11 12 MDTH 400E-12 +DIN 15 14 MDTH 400E-12 +VOFP 12 13 DC 0 +VOFN 13 14 DC 0 +IPOL 13 5 1.000000E-05 +CPS 11 15 3.783376E-09 +DINN 17 13 MDTH 400E-12 +VIN 17 5 0.000000e+00 +DINR 15 18 MDTH 400E-12 +VIP 4 18 2.000000E+00 +FCP 4 5 VOFP 3.400000E+01 +FCN 5 4 VOFN 3.400000E+01 +FIBP 2 5 VOFN 2.000000E-03 +FIBN 5 1 VOFP 2.000000E-03 + +* AMPLIFYING STAGE +FIP 5 19 VOFP 3.600000E+02 +FIN 5 19 VOFN 3.600000E+02 +RG1 19 5 3.652997E+06 +RG2 19 4 3.652997E+06 +CC 19 5 6.000000E-09 +DOPM 19 22 MDTH 400E-12 +DONM 21 19 MDTH 400E-12 +HOPM 22 28 VOUT 7.500000E+03 +VIPM 28 4 1.500000E+02 +HONM 21 27 VOUT 7.500000E+03 +VINM 5 27 1.500000E+02 +EOUT 26 23 19 5 1 +VOUT 23 5 0 +ROUT 26 3 20 +COUT 3 5 1.000000E-12 +DOP 19 25 MDTH 400E-12 +VOP 4 25 2.242230E+00 +DON 24 19 MDTH 400E-12 +VON 24 5 7.922301E-01 +.ENDS +} + } + } + } + ha:attrib { + ha:purpose = { value=spicelib; prio=0; } + } + } + } + } + ha:obj_direct.2 { + uuid=Hif/m8o2mo/CrYnTszoAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.1 { + uuid=8/SYZ/pfBzxyqFA12WQAAAAC; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAg; + li:objects { + ha:polygon.11 { + li:outline { + ha:line { x1=0; y1=0; x2=80000; y2=0; } + ha:line { x1=80000; y1=0; x2=80000; y2=20000; } + ha:line { x1=80000; y1=20000; x2=0; y2=20000; } + ha:line { x1=0; y1=20000; x2=0; y2=0; } + } + stroke=titlebox-frame; + fill=titlebox-fill; + } + ha:line.12 { x1=0; y1=10000; x2=80000; y2=10000; stroke=titlebox-frame; } + ha:line.13 { x1=40000; y1=10000; x2=40000; y2=0; stroke=titlebox-frame; } + ha:text.20 { x1=1000; y1=16500; dyntext=0; stroke=titlebox-big; text=TITLE; } + ha:text.21 { x1=1000; y1=10500; x2=79000; y2=16000; dyntext=1; stroke=titlebox-big; text=%../../A.title%; } + ha:text.22 { x1=1000; y1=5500; dyntext=0; stroke=titlebox-small; text={PROJECT:}; } + ha:text.23 { x1=13000; y1=5500; x2=39000; y2=9500; dyntext=1; stroke=titlebox-big; text=%project.name%; } + ha:text.24 { x1=1000; y1=500; dyntext=0; stroke=titlebox-small; text={PAGE:}; } + ha:text.25 { x1=10000; y1=500; x2=39000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.page%; } + ha:text.26 { x1=41000; y1=5500; dyntext=0; stroke=titlebox-small; text={FILE:}; } + ha:text.27 { x1=48000; y1=5500; x2=79000; y2=9500; dyntext=1; stroke=titlebox-big; text=%filename%; } + ha:text.28 { x1=41000; y1=500; dyntext=0; stroke=titlebox-small; text={MAINTAINER:}; } + ha:text.29 { x1=55000; y1=500; x2=79000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.maintainer%; } + } + ha:attrib { + purpose=titlebox + } + } + ha:group.2 { + uuid=Hif/m8o2mo/CrYnTszoAAAAP; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAH; + x=116000; y=116000; + li:objects { + ha:group.1 { + uuid=Hif/m8o2mo/CrYnTszoAAAAQ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAI; + x=-20000; y=4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=in+ + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.2 { + uuid=Hif/m8o2mo/CrYnTszoAAAAR; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAJ; + x=-20000; y=-4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=in- + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:group.3 { + uuid=Hif/m8o2mo/CrYnTszoAAAAS; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAK; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=out + role=terminal + ha:spice/pinnum = { value=3; prio=31050; } + } + } + ha:line.4 { x1=-20000; y1=-8000; x2=-20000; y2=8000; stroke=sym-decor; } + ha:line.5 { x1=-20000; y1=8000; x2=-4000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=-4000; y1=0; x2=-20000; y2=-8000; stroke=sym-decor; } + ha:line.7 { x1=-18000; y1=5000; x2=-18000; y2=3000; stroke=sym-decor; } + ha:line.8 { x1=-19000; y1=4000; x2=-17000; y2=4000; stroke=sym-decor; } + ha:line.9 { x1=-19000; y1=-4000; x2=-17000; y2=-4000; stroke=sym-decor; } + ha:group.10 { + uuid=Hif/m8o2mo/CrYnTszoAAAAT; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAL; + x=-12000; y=-4000; rot=270.000000; mirx=1; miry=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=0; y1=-1000; rot=180.000000; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=V- + role=terminal + ha:spice/pinnum = { value=5; prio=31050; } + spice/shared=yes + } + } + ha:group.11 { + uuid=Hif/m8o2mo/CrYnTszoAAAAU; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAM; + x=-12000; y=8000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=-4000; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=V+ + role=terminal + ha:spice/pinnum = { value=4; prio=31050; } + spice/shared=yes + } + } + ha:text.12 { x1=-21000; y1=9000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:text.13 { x1=-17000; y1=9000; dyntext=1; stroke=sym-secondary; text=%../A.-slot%; floater=1; } + ha:text.14 { x1=-8000; y1=4000; dyntext=1; stroke=sym-secondary; text=%../A.devmap%; floater=1; } + } + ha:attrib { + -slot=1 + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + devmap=lm358_so8 + name=U1 + role=symbol + spice/model=lm358 + } + } + ha:group.3 { + uuid=Hif/m8o2mo/CrYnTszoAAAAd; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=60000; y=120000; + li:objects { + ha:group.1 { + uuid=Hif/m8o2mo/CrYnTszoAAAAe; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=Hif/m8o2mo/CrYnTszoAAAAf; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=R2 + role=symbol + value=1600 + } + } + ha:group.7 { + uuid=Hif/m8o2mo/CrYnTszoAAAAk; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=48000; y=104000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=Hif/m8o2mo/CrYnTszoAAAAl; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=Hif/m8o2mo/CrYnTszoAAAAm; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=-6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=-6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=R3 + role=symbol + value=800 + } + } + ha:group.12 { + uuid=Hif/m8o2mo/CrYnTszoAAAAo; + x=-12000; y=0; + li:objects { + ha:line.1 { x1=36000; y1=120000; x2=24000; y2=120000; stroke=wire; } + ha:text.2 { x1=28000; y1=120000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + ha:line.5 { x1=24000; y1=108000; x2=36000; y2=108000; stroke=wire; } + ha:line.6 { x1=24000; y1=108000; x2=24000; y2=108000; stroke=junction; } + ha:line.7 { x1=24000; y1=68000; x2=24000; y2=120000; stroke=wire; } + } + ha:attrib { + name=in + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.18 { + uuid=Hif/m8o2mo/CrYnTszoAAAA8; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB6; + x=104000; y=128000; + li:objects { + ha:group.1 { + uuid=Hif/m8o2mo/CrYnTszoAAAA9; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB7; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-4000; y1=4000; x2=4000; y2=7000; halign=center; dyntext=0; stroke=sym-primary; text=Vcc; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:Vcc} + } + role=symbol + } + } + ha:group.19 { + uuid=Hif/m8o2mo/CrYnTszoAAAA+; + x=16000; y=0; + li:objects { + ha:line.1 { x1=88000; y1=124000; x2=88000; y2=128000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.22 { + uuid=Hif/m8o2mo/CrYnTszoAAABH; src_uuid=iNOQfJpO6hT/HFDFGjoAAABv; + x=104000; y=104000; rot=180.000000; + li:objects { + ha:group.1 { + uuid=Hif/m8o2mo/CrYnTszoAAABI; src_uuid=iNOQfJpO6hT/HFDFGjoAAABw; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=6000; y1=7000; x2=18000; y2=10000; rot=180.000000; halign=center; dyntext=1; stroke=sym-primary; text=%../A.rail%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:forge { + delete,forge/tmp + scalar,forge/tmp + {sub,^,1:,forge/tmp} + suba,$,rail,forge/tmp + array,connect + append,connect,forge/tmp + } + rail=Vneg + role=symbol + } + } + ha:group.23 { + uuid=Hif/m8o2mo/CrYnTszoAAABJ; + x=16000; y=0; + li:objects { + ha:line.1 { x1=88000; y1=104000; x2=88000; y2=108000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.28 { + uuid=Hif/m8o2mo/CrYnTszoAAABh; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=12000; y=44000; + li:objects { + ha:group.1 { + uuid=Hif/m8o2mo/CrYnTszoAAABi; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.29 { + uuid=Hif/m8o2mo/CrYnTszoAAABj; + x=-12000; y=-36000; + li:objects { + ha:line.1 { x1=24000; y1=80000; x2=24000; y2=84000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.33 { + uuid=Hif/m8o2mo/CrYnTszoAAABs; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB6; + x=92000; y=36000; + li:objects { + ha:group.1 { + uuid=Hif/m8o2mo/CrYnTszoAAABt; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB7; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-4000; y1=4000; x2=4000; y2=7000; halign=center; dyntext=0; stroke=sym-primary; text=Vcc; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:Vcc} + } + role=symbol + } + } + ha:group.34 { + uuid=Hif/m8o2mo/CrYnTszoAAABw; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=92000; y=8000; + li:objects { + ha:group.1 { + uuid=Hif/m8o2mo/CrYnTszoAAABx; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.35 { + uuid=Hif/m8o2mo/CrYnTszoAAABy; + x=-68000; y=-60000; + li:objects { + ha:line.1 { x1=160000; y1=92000; x2=160000; y2=96000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.38 { + uuid=Hif/m8o2mo/CrYnTszoAAABz; + x=-68000; y=-60000; + li:objects { + ha:line.1 { x1=160000; y1=68000; x2=160000; y2=72000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.42 { + uuid=Hif/m8o2mo/CrYnTszoAAAB8; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=128000; y=36000; + li:objects { + ha:group.1 { + uuid=Hif/m8o2mo/CrYnTszoAAAB9; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.43 { + uuid=Hif/m8o2mo/CrYnTszoAAAB+; + x=-68000; y=-60000; + li:objects { + ha:line.1 { x1=184000; y1=92000; x2=184000; y2=100000; stroke=wire; } + ha:line.2 { x1=184000; y1=100000; x2=196000; y2=100000; stroke=wire; } + ha:line.3 { x1=196000; y1=100000; x2=196000; y2=96000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.46 { + uuid=Hif/m8o2mo/CrYnTszoAAACB; src_uuid=iNOQfJpO6hT/HFDFGjoAAABv; + x=116000; y=8000; rot=180.000000; + li:objects { + ha:group.1 { + uuid=Hif/m8o2mo/CrYnTszoAAACC; src_uuid=iNOQfJpO6hT/HFDFGjoAAABw; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=6000; y1=7000; x2=18000; y2=10000; rot=180.000000; halign=center; dyntext=1; stroke=sym-primary; text=%../A.rail%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:forge { + delete,forge/tmp + scalar,forge/tmp + {sub,^,1:,forge/tmp} + suba,$,rail,forge/tmp + array,connect + append,connect,forge/tmp + } + rail=Vneg + role=symbol + } + } + ha:group.47 { + uuid=Hif/m8o2mo/CrYnTszoAAACD; + x=-68000; y=-60000; + li:objects { + ha:line.1 { x1=184000; y1=72000; x2=184000; y2=68000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.50 { + uuid=guptF1eHUCXR7MoVgJUAAAA2; src_uuid=TeGEOMuew6iCb2kzckAAAAAD; + x=36000; y=40000; + li:objects { + ha:text.1 { x1=2000; y1=-4000; dyntext=0; stroke=sym-decor; text=raw spice; } + ha:text.2 { x1=2000; y1=-8000; dyntext=0; stroke=sym-decor; text=command; } + ha:polygon.3 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=-10000; } + ha:line { x1=0; y1=-10000; x2=12000; y2=-10000; } + ha:line { x1=12000; y1=-10000; x2=12000; y2=0; } + ha:line { x1=12000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + } + ha:attrib { + -sym-comment={ Fill in spice/command and use export_spice (e.g. the spice_raw view) to get that string exported at the end of the spice netlist file. } + -sym-copyright=(C) 2023 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + role=symbol + spice/command={ac dec 10 1 1000k +settype decibel out +plot vdb(out) xlimit 1 1000k ylabel 'small signal gain' +settype phase out +plot cph(out) xlimit 1 1000k ylabel 'phase (in rad)'} + } + } + ha:group.51 { + uuid=XFxbV/afs+qvJqWppTgAAABB; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB0; + x=12000; y=68000; rot=270.000000; mirx=1; + li:objects { + ha:group.1 { + uuid=XFxbV/afs+qvJqWppTgAAABC; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB1; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=N + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.2 { + uuid=XFxbV/afs+qvJqWppTgAAABD; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB2; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=P + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:arc.3 { cx=10000; cy=0; r=6000; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:line.4 { x1=7000; y1=2000; x2=7000; y2=-2000; stroke=sym-decor; } + ha:line.5 { x1=5000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=11000; y1=0; x2=15000; y2=0; stroke=sym-decor; } + ha:text.7 { x1=0; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:text.8 { x1=0; y1=4000; dyntext=1; stroke=sym-secondary; text=%../A.spice/params%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=V1 + role=symbol + spice/params=dc 0 ac 0.1 + } + } + ha:group.54 { + uuid=XFxbV/afs+qvJqWppTgAAABE; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB0; + x=92000; y=32000; rot=270.000000; mirx=1; + li:objects { + ha:group.1 { + uuid=XFxbV/afs+qvJqWppTgAAABF; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB1; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=N + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.2 { + uuid=XFxbV/afs+qvJqWppTgAAABG; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB2; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=P + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:arc.3 { cx=10000; cy=0; r=6000; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:line.4 { x1=7000; y1=2000; x2=7000; y2=-2000; stroke=sym-decor; } + ha:line.5 { x1=5000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=11000; y1=0; x2=15000; y2=0; stroke=sym-decor; } + ha:text.7 { x1=0; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:text.8 { x1=0; y1=4000; dyntext=1; stroke=sym-secondary; text=%../A.spice/params%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=V2 + role=symbol + spice/params=dc 5 + } + } + ha:group.57 { + uuid=XFxbV/afs+qvJqWppTgAAABH; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB0; + x=116000; y=32000; rot=270.000000; mirx=1; + li:objects { + ha:group.1 { + uuid=XFxbV/afs+qvJqWppTgAAABI; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB1; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=N + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.2 { + uuid=XFxbV/afs+qvJqWppTgAAABJ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB2; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=P + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:arc.3 { cx=10000; cy=0; r=6000; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:line.4 { x1=7000; y1=2000; x2=7000; y2=-2000; stroke=sym-decor; } + ha:line.5 { x1=5000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=11000; y1=0; x2=15000; y2=0; stroke=sym-decor; } + ha:text.7 { x1=0; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:text.8 { x1=0; y1=4000; dyntext=1; stroke=sym-secondary; text=%../A.spice/params%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=V3 + role=symbol + spice/params=dc 5 + } + } + ha:connection.125 { + li:conn { + /2/3/1/1 + /2/197/2 + } + } + ha:group.132 { + uuid=GePylIY1T4cR3zcyR1kAAAA7; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=24000; y=120000; + li:objects { + ha:group.1 { + uuid=GePylIY1T4cR3zcyR1kAAAA8; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=GePylIY1T4cR3zcyR1kAAAA9; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=R1 + role=symbol + value=1600 + } + } + ha:group.142 { + uuid=GePylIY1T4cR3zcyR1kAAABQ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAH; + x=92000; y=72000; mirx=1; + li:objects { + ha:group.1 { + uuid=GePylIY1T4cR3zcyR1kAAABR; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAI; + x=-20000; y=4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=in+ + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.2 { + uuid=GePylIY1T4cR3zcyR1kAAABS; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAJ; + x=-20000; y=-4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=in- + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:group.3 { + uuid=GePylIY1T4cR3zcyR1kAAABT; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAK; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=out + role=terminal + ha:spice/pinnum = { value=3; prio=31050; } + } + } + ha:line.4 { x1=-20000; y1=-8000; x2=-20000; y2=8000; stroke=sym-decor; } + ha:line.5 { x1=-20000; y1=8000; x2=-4000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=-4000; y1=0; x2=-20000; y2=-8000; stroke=sym-decor; } + ha:line.7 { x1=-18000; y1=5000; x2=-18000; y2=3000; stroke=sym-decor; } + ha:line.8 { x1=-19000; y1=4000; x2=-17000; y2=4000; stroke=sym-decor; } + ha:line.9 { x1=-19000; y1=-4000; x2=-17000; y2=-4000; stroke=sym-decor; } + ha:group.10 { + uuid=GePylIY1T4cR3zcyR1kAAABU; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAL; + x=-12000; y=-4000; rot=270.000000; mirx=1; miry=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=0; y1=-1000; rot=180.000000; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=V- + role=terminal + ha:spice/pinnum = { value=5; prio=31050; } + spice/shared=yes + } + } + ha:group.11 { + uuid=GePylIY1T4cR3zcyR1kAAABV; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAM; + x=-12000; y=8000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=-4000; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=V+ + role=terminal + ha:spice/pinnum = { value=4; prio=31050; } + spice/shared=yes + } + } + ha:text.12 { x1=-21000; y1=9000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:text.13 { x1=-17000; y1=9000; dyntext=1; stroke=sym-secondary; text=%../A.-slot%; floater=1; } + ha:text.14 { x1=-10000; y1=6000; dyntext=1; stroke=sym-secondary; text=%../A.devmap%; floater=1; } + } + ha:attrib { + -slot=2 + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + devmap=lm358_so8 + name=U1 + role=symbol + spice/model=lm358 + } + } + ha:group.146 { + uuid=GePylIY1T4cR3zcyR1kAAABX; + x=4000; y=0; + li:objects { + ha:line.1 { x1=112000; y1=76000; x2=124000; y2=76000; stroke=wire; } + ha:line.2 { x1=124000; y1=84000; x2=124000; y2=72000; stroke=wire; } + ha:line.3 { x1=124000; y1=76000; x2=124000; y2=76000; stroke=junction; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.147 { + li:conn { + /2/146/1 + /2/142/1/1 + } + } + ha:group.148 { + uuid=GePylIY1T4cR3zcyR1kAAABb; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=128000; y=104000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=GePylIY1T4cR3zcyR1kAAABc; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=GePylIY1T4cR3zcyR1kAAABd; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=R4 + role=symbol + value=250 + } + } + ha:group.149 { + uuid=GePylIY1T4cR3zcyR1kAAABh; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=128000; y=72000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=GePylIY1T4cR3zcyR1kAAABi; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=GePylIY1T4cR3zcyR1kAAABj; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=R5 + role=symbol + value=10k + } + } + ha:group.157 { + uuid=GePylIY1T4cR3zcyR1kAAABm; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=128000; y=52000; + li:objects { + ha:group.1 { + uuid=GePylIY1T4cR3zcyR1kAAABn; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.161 { + uuid=GePylIY1T4cR3zcyR1kAAABu; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAh; + x=24000; y=108000; + li:objects { + ha:group.1 { + uuid=GePylIY1T4cR3zcyR1kAAABv; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAi; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=GePylIY1T4cR3zcyR1kAAABw; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAj; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=16000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.5 { x1=9000; y1=5000; x2=9000; y2=-5000; stroke=sym-decor; } + ha:line.6 { x1=11000; y1=5000; x2=11000; y2=-5000; stroke=sym-decor; } + ha:line.7 { x1=4000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.8 { x1=11000; y1=0; x2=16000; y2=0; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=C1 + role=symbol + value=100n + } + } + ha:connection.162 { + li:conn { + /2/12/5 + /2/161/2/1 + } + } + ha:connection.163 { + li:conn { + /2/12/1 + /2/132/2/1 + } + } + ha:group.164 { + uuid=GePylIY1T4cR3zcyR1kAAABx; + li:objects { + ha:line.1 { x1=44000; y1=108000; x2=60000; y2=108000; stroke=wire; } + ha:line.2 { x1=48000; y1=108000; x2=48000; y2=104000; stroke=wire; } + ha:line.3 { x1=48000; y1=108000; x2=48000; y2=108000; stroke=junction; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.165 { + li:conn { + /2/164/1 + /2/161/1/1 + } + } + ha:group.166 { + uuid=GePylIY1T4cR3zcyR1kAAAB1; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAh; + x=60000; y=108000; + li:objects { + ha:group.1 { + uuid=GePylIY1T4cR3zcyR1kAAAB2; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAi; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=GePylIY1T4cR3zcyR1kAAAB3; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAj; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=16000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.5 { x1=9000; y1=5000; x2=9000; y2=-5000; stroke=sym-decor; } + ha:line.6 { x1=11000; y1=5000; x2=11000; y2=-5000; stroke=sym-decor; } + ha:line.7 { x1=4000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.8 { x1=11000; y1=0; x2=16000; y2=0; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=C2 + role=symbol + value=100n + } + } + ha:group.168 { + uuid=GePylIY1T4cR3zcyR1kAAAB7; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAh; + x=56000; y=104000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=GePylIY1T4cR3zcyR1kAAAB8; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAi; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=GePylIY1T4cR3zcyR1kAAAB9; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAj; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=16000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.5 { x1=9000; y1=5000; x2=9000; y2=-5000; stroke=sym-decor; } + ha:line.6 { x1=11000; y1=5000; x2=11000; y2=-5000; stroke=sym-decor; } + ha:line.7 { x1=4000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.8 { x1=11000; y1=0; x2=16000; y2=0; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=C3 + role=symbol + value=200n + } + } + ha:connection.170 { + li:conn { + /2/2/1/1 + /2/197/2 + } + } + ha:connection.171 { + li:conn { + /2/19/1 + /2/2/11/1 + } + } + ha:connection.172 { + li:conn { + /2/19/1 + /2/18/1/1 + } + } + ha:connection.173 { + li:conn { + /2/23/1 + /2/2/10/1 + } + } + ha:connection.174 { + li:conn { + /2/23/1 + /2/22/1/1 + } + } + ha:connection.176 { + li:conn { + /2/142/3/1 + /2/189/6 + } + } + ha:connection.177 { + li:conn { + /2/148/1/1 + /2/146/2 + } + } + ha:connection.178 { + li:conn { + /2/149/2/1 + /2/146/2 + } + } + ha:connection.179 { + li:conn { + /2/157/1/1 + /2/149/1/1 + } + } + ha:connection.180 { + li:conn { + /2/164/1 + /2/166/2/1 + } + } + ha:group.181 { + uuid=GePylIY1T4cR3zcyR1kAAAB+; + li:objects { + ha:line.1 { x1=44000; y1=120000; x2=60000; y2=120000; stroke=wire; } + ha:line.2 { x1=56000; y1=104000; x2=56000; y2=120000; stroke=wire; } + ha:line.3 { x1=56000; y1=120000; x2=56000; y2=120000; stroke=junction; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.182 { + li:conn { + /2/181/1 + /2/132/1/1 + } + } + ha:connection.183 { + li:conn { + /2/181/1 + /2/3/2/1 + } + } + ha:connection.184 { + li:conn { + /2/181/2 + /2/168/2/1 + } + } + ha:connection.185 { + li:conn { + /2/164/2 + /2/7/2/1 + } + } + ha:connection.187 { + li:conn { + /2/7/1/1 + /2/189/5 + } + } + ha:connection.188 { + li:conn { + /2/168/1/1 + /2/189/7 + } + } + ha:group.189 { + uuid=GePylIY1T4cR3zcyR1kAAACA; + li:objects { + ha:line.1 { x1=120000; y1=68000; x2=116000; y2=68000; stroke=wire; } + ha:line.2 { x1=120000; y1=56000; x2=120000; y2=68000; stroke=wire; } + ha:line.4 { x1=88000; y1=56000; x2=120000; y2=56000; stroke=wire; } + ha:line.5 { x1=48000; y1=84000; x2=48000; y2=72000; stroke=wire; } + ha:line.6 { x1=48000; y1=72000; x2=92000; y2=72000; stroke=wire; } + ha:line.7 { x1=56000; y1=84000; x2=56000; y2=72000; stroke=wire; } + ha:line.8 { x1=56000; y1=72000; x2=56000; y2=72000; stroke=junction; } + ha:line.9 { x1=88000; y1=56000; x2=88000; y2=72000; stroke=wire; } + ha:line.10 { x1=88000; y1=72000; x2=88000; y2=72000; stroke=junction; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.190 { + li:conn { + /2/189/1 + /2/142/2/1 + } + } + ha:group.197 { + uuid=GePylIY1T4cR3zcyR1kAAACD; + li:objects { + ha:line.1 { x1=80000; y1=108000; x2=84000; y2=108000; stroke=wire; } + ha:line.2 { x1=80000; y1=120000; x2=92000; y2=120000; stroke=wire; } + ha:line.3 { x1=84000; y1=108000; x2=84000; y2=120000; stroke=wire; } + ha:line.4 { x1=84000; y1=120000; x2=84000; y2=120000; stroke=junction; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.198 { + li:conn { + /2/197/1 + /2/166/1/1 + } + } + ha:group.199 { + uuid=GePylIY1T4cR3zcyR1kAAACE; + li:objects { + ha:line.1 { x1=128000; y1=116000; x2=128000; y2=116000; stroke=junction; } + ha:line.2 { x1=92000; y1=92000; x2=120000; y2=92000; stroke=wire; } + ha:line.3 { x1=128000; y1=104000; x2=128000; y2=116000; stroke=wire; } + ha:line.4 { x1=116000; y1=116000; x2=136000; y2=116000; stroke=wire; } + ha:line.5 { x1=120000; y1=92000; x2=120000; y2=116000; stroke=wire; } + ha:line.6 { x1=120000; y1=116000; x2=120000; y2=116000; stroke=junction; } + ha:line.7 { x1=92000; y1=112000; x2=92000; y2=92000; stroke=wire; } + ha:text.8 { x1=131000; y1=116000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=out + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.200 { + li:conn { + /2/199/3 + /2/148/2/1 + } + } + ha:connection.201 { + li:conn { + /2/199/4 + /2/2/3/1 + } + } + ha:connection.202 { + li:conn { + /2/199/7 + /2/2/2/1 + } + } + ha:connection.203 { + li:conn { + /2/35/1 + /2/33/1/1 + } + } + ha:connection.204 { + li:conn { + /2/38/1 + /2/34/1/1 + } + } + ha:connection.205 { + li:conn { + /2/43/3 + /2/42/1/1 + } + } + ha:connection.206 { + li:conn { + /2/47/1 + /2/46/1/1 + } + } + ha:connection.207 { + li:conn { + /2/54/1/1 + /2/38/1 + } + } + ha:connection.208 { + li:conn { + /2/54/2/1 + /2/35/1 + } + } + ha:connection.209 { + li:conn { + /2/57/1/1 + /2/47/1 + } + } + ha:connection.210 { + li:conn { + /2/57/2/1 + /2/43/1 + } + } + ha:connection.219 { + li:conn { + /2/29/1 + /2/28/1/1 + } + } + ha:connection.220 { + li:conn { + /2/51/1/1 + /2/29/1 + } + } + ha:connection.221 { + li:conn { + /2/12/7 + /2/51/2/1 + } + } + } + ha:attrib { + maintainer=Tibor 'Igor2' Palinkas + page=1 of 1 + print_page=A/4 + title={SIM raw spice: notch filter with opamps, ac} + } + } +} Index: tags/1.0.5/doc/tutorial/simulation/raw/18_opamp_ac.svg =================================================================== --- tags/1.0.5/doc/tutorial/simulation/raw/18_opamp_ac.svg (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/raw/18_opamp_ac.svg (revision 10414) @@ -0,0 +1,1424 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/1.0.5/doc/tutorial/simulation/raw/18_opamp_ac1.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/1.0.5/doc/tutorial/simulation/raw/18_opamp_ac1.png =================================================================== --- tags/1.0.5/doc/tutorial/simulation/raw/18_opamp_ac1.png (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/raw/18_opamp_ac1.png (revision 10414) Property changes on: tags/1.0.5/doc/tutorial/simulation/raw/18_opamp_ac1.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/1.0.5/doc/tutorial/simulation/raw/18_opamp_ac2.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/1.0.5/doc/tutorial/simulation/raw/18_opamp_ac2.png =================================================================== --- tags/1.0.5/doc/tutorial/simulation/raw/18_opamp_ac2.png (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/raw/18_opamp_ac2.png (revision 10414) Property changes on: tags/1.0.5/doc/tutorial/simulation/raw/18_opamp_ac2.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/1.0.5/doc/tutorial/simulation/raw/22_custom_sym.html =================================================================== --- tags/1.0.5/doc/tutorial/simulation/raw/22_custom_sym.html (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/raw/22_custom_sym.html (revision 10414) @@ -0,0 +1,67 @@ + + +

22_custom_sym: creating a custom symbol

+ +

Scope

+

+Create a custom diode symbol with an embedded (inline) model card. + +

The schematics

+

+

+ +
Click the image to get the sch-rnd sheet
+ + +

Preparing for simulation

+

+Draw the symbol the usual way, using lines, rectangles and {p t} +for placing terminals; select the objects, convert selection to symbol; +set the usual attributes (e.g. name on the symbol and on the terminals). +

+For spice simulation, set the following attributes: +

    +
  • symbol attribute spice/prefix to D: for the simulation + this is a diode; this attribute lets the sheet name the symbol U1 + still show spice a D component by prefixing the name with D_. +
  • symbol attribute spice/model_card to + .MODEL my_diode D (IS=2f RS=3.4 N=2.2): + this is how the model is specified inline, within the symbol, not + relying on external libs +
  • terminal attribute spice/pinnum; the positive (anode) terminal + should be 1, the negative (cathode) should be 2. +
+

+The inline model card option is useful for one-off symbols or for an easy +and quick way of tuning model parameters in test-bench schematics. + +

Raw spice commands

+

+Similar to those used in 10_bjt_amp_tr. + +

Export and run ngspice

+

+Running ngspice the usual way on the export yields the following graphs: +

+ + +

Using other implementations

+

gnucap

+

+Gnucap uses a different command syntax. Modify the spice command symbol's +spice/command attribute to: +

+print tran v(out) v(in)
+tran 1u 4m > plot.txt
+
+

+After the export, write the single word spice in the first line of the +file (e.g. using a text editor), otherwise gnucap won't know that the file is +in spice syntax. Then run gnucap 22_custom_sym.cir and it will dump a text +table to plot.txt that can be plotted using a suitable utility, e.g. gnuplot. +

+The gnucap-modified schematic is also available. + +

xyce

+

+TODO Index: tags/1.0.5/doc/tutorial/simulation/raw/22_custom_sym.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/1.0.5/doc/tutorial/simulation/raw/22_custom_sym.png =================================================================== --- tags/1.0.5/doc/tutorial/simulation/raw/22_custom_sym.png (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/raw/22_custom_sym.png (revision 10414) Property changes on: tags/1.0.5/doc/tutorial/simulation/raw/22_custom_sym.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/1.0.5/doc/tutorial/simulation/raw/22_custom_sym.rs =================================================================== --- tags/1.0.5/doc/tutorial/simulation/raw/22_custom_sym.rs (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/raw/22_custom_sym.rs (revision 10414) @@ -0,0 +1,399 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=k5U87rmc6yaL/+FNsFAAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.1 { + uuid=8/SYZ/pfBzxyqFA12WQAAAAC; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAg; + li:objects { + ha:polygon.11 { + li:outline { + ha:line { x1=0; y1=0; x2=80000; y2=0; } + ha:line { x1=80000; y1=0; x2=80000; y2=20000; } + ha:line { x1=80000; y1=20000; x2=0; y2=20000; } + ha:line { x1=0; y1=20000; x2=0; y2=0; } + } + stroke=titlebox-frame; + fill=titlebox-fill; + } + ha:line.12 { x1=0; y1=10000; x2=80000; y2=10000; stroke=titlebox-frame; } + ha:line.13 { x1=40000; y1=10000; x2=40000; y2=0; stroke=titlebox-frame; } + ha:text.20 { x1=1000; y1=16500; dyntext=0; stroke=titlebox-big; text=TITLE; } + ha:text.21 { x1=1000; y1=10500; x2=79000; y2=16000; dyntext=1; stroke=titlebox-big; text=%../../A.title%; } + ha:text.22 { x1=1000; y1=5500; dyntext=0; stroke=titlebox-small; text={PROJECT:}; } + ha:text.23 { x1=13000; y1=5500; x2=39000; y2=9500; dyntext=1; stroke=titlebox-big; text=%project.name%; } + ha:text.24 { x1=1000; y1=500; dyntext=0; stroke=titlebox-small; text={PAGE:}; } + ha:text.25 { x1=10000; y1=500; x2=39000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.page%; } + ha:text.26 { x1=41000; y1=5500; dyntext=0; stroke=titlebox-small; text={FILE:}; } + ha:text.27 { x1=48000; y1=5500; x2=79000; y2=9500; dyntext=1; stroke=titlebox-big; text=%filename%; } + ha:text.28 { x1=41000; y1=500; dyntext=0; stroke=titlebox-small; text={MAINTAINER:}; } + ha:text.29 { x1=55000; y1=500; x2=79000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.maintainer%; } + } + ha:attrib { + purpose=titlebox + } + } + ha:group.10 { + uuid=k5U87rmc6yaL/+FNsFAAAAAR; + x=56000; y=60000; + li:objects { + ha:line.1 { x1=0; y1=-4000; x2=-4000; y2=-16000; stroke=sym-decor; } + ha:line.2 { x1=-4000; y1=-16000; x2=4000; y2=-16000; stroke=sym-decor; } + ha:line.3 { x1=4000; y1=-16000; x2=0; y2=-4000; stroke=sym-decor; } + ha:line.4 { x1=-4000; y1=-4000; x2=4000; y2=-4000; stroke=sym-decor; } + ha:group.5 { + uuid=k5U87rmc6yaL/+FNsFAAAAAS; src_uuid=k5U87rmc6yaL/+FNsFAAAAAD; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=C + role=terminal + spice/pinnum=2 + } + } + ha:group.6 { + uuid=k5U87rmc6yaL/+FNsFAAAAAT; src_uuid=k5U87rmc6yaL/+FNsFAAAAAD; + x=0; y=-20000; rot=270.000000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=A + role=terminal + spice/pinnum=1 + } + } + ha:polygon.7 { + li:outline { + ha:line { x1=-6000; y1=-2000; x2=-6000; y2=-18000; } + ha:line { x1=-6000; y1=-18000; x2=6000; y2=-18000; } + ha:line { x1=6000; y1=-18000; x2=6000; y2=-2000; } + ha:line { x1=6000; y1=-2000; x2=-6000; y2=-2000; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + ha:text.8 { x1=-6000; y1=-2000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + name=U1 + role=symbol + spice/model_card={.MODEL my_diode D (IS=2f RS=3.4 N=2.2)} + spice/prefix=D + } + } + ha:group.11 { + uuid=k5U87rmc6yaL/+FNsFAAAAAa; src_uuid=iNOQfJpO6hT/HFDFGjoAAABx; + x=20000; y=60000; rot=270.000000; mirx=1; + li:objects { + ha:arc.1 { cx=10000; cy=0; r=6000; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:arc.2 { cx=8000; cy=0; r=2000; sang=0.000000; dang=180.000000; stroke=sym-decor; } + ha:arc.3 { cx=12000; cy=0; r=2000; sang=180.000000; dang=180.000000; stroke=sym-decor; } + ha:group.4 { + uuid=k5U87rmc6yaL/+FNsFAAAAAb; src_uuid=iNOQfJpO6hT/HFDFGjoAAABy; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=N + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.5 { + uuid=k5U87rmc6yaL/+FNsFAAAAAc; src_uuid=iNOQfJpO6hT/HFDFGjoAAABz; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=P + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:text.6 { x1=0; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=V1 + role=symbol + spice/params=SINE(0 20 1k) + } + } + ha:group.12 { + uuid=k5U87rmc6yaL/+FNsFAAAAAd; + x=-8000; y=-32000; + li:objects { + ha:line.1 { x1=28000; y1=92000; x2=28000; y2=104000; stroke=wire; } + ha:line.3 { x1=28000; y1=104000; x2=32000; y2=104000; stroke=wire; } + ha:text.4 { x1=28000; y1=104000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=in + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.14 { + uuid=k5U87rmc6yaL/+FNsFAAAAAk; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=24000; y=72000; + li:objects { + ha:group.1 { + uuid=k5U87rmc6yaL/+FNsFAAAAAl; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=k5U87rmc6yaL/+FNsFAAAAAm; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=R1 + role=symbol + ha:spice/prefix = { value=R; prio=31050; } + value=100 + } + } + ha:group.16 { + uuid=k5U87rmc6yaL/+FNsFAAAAAn; + x=-8000; y=-32000; + li:objects { + ha:line.2 { x1=64000; y1=104000; x2=64000; y2=92000; stroke=wire; } + ha:line.3 { x1=52000; y1=104000; x2=76000; y2=104000; stroke=wire; } + ha:line.4 { x1=64000; y1=104000; x2=64000; y2=104000; stroke=junction; } + ha:text.5 { x1=72000; y1=104000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=out + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.19 { + uuid=k5U87rmc6yaL/+FNsFAAAAAs; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=20000; y=36000; + li:objects { + ha:group.1 { + uuid=k5U87rmc6yaL/+FNsFAAAAAt; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.20 { + uuid=k5U87rmc6yaL/+FNsFAAAAAu; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=56000; y=36000; + li:objects { + ha:group.1 { + uuid=k5U87rmc6yaL/+FNsFAAAAAv; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.21 { + uuid=k5U87rmc6yaL/+FNsFAAAAAw; + x=-8000; y=-32000; + li:objects { + ha:line.1 { x1=28000; y1=72000; x2=28000; y2=68000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.24 { + uuid=k5U87rmc6yaL/+FNsFAAAAAx; + x=-8000; y=-32000; + li:objects { + ha:line.1 { x1=64000; y1=72000; x2=64000; y2=68000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.27 { + li:conn { + /2/12/1 + /2/11/5/1 + } + } + ha:connection.29 { + li:conn { + /2/14/2/1 + /2/12/3 + } + } + ha:connection.30 { + li:conn { + /2/16/2 + /2/10/5/1 + } + } + ha:connection.31 { + li:conn { + /2/16/3 + /2/14/1/1 + } + } + ha:connection.32 { + li:conn { + /2/21/1 + /2/11/4/1 + } + } + ha:connection.33 { + li:conn { + /2/21/1 + /2/19/1/1 + } + } + ha:connection.34 { + li:conn { + /2/24/1 + /2/10/6/1 + } + } + ha:connection.35 { + li:conn { + /2/24/1 + /2/20/1/1 + } + } + ha:group.36 { + uuid=k5U87rmc6yaL/+FNsFAAAAA0; src_uuid=TeGEOMuew6iCb2kzckAAAAAD; + x=12000; y=96000; + li:objects { + ha:text.1 { x1=2000; y1=-4000; dyntext=0; stroke=sym-decor; text=raw spice; } + ha:text.2 { x1=2000; y1=-8000; dyntext=0; stroke=sym-decor; text=command; } + ha:polygon.3 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=-10000; } + ha:line { x1=0; y1=-10000; x2=12000; y2=-10000; } + ha:line { x1=12000; y1=-10000; x2=12000; y2=0; } + ha:line { x1=12000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + } + ha:attrib { + -sym-comment={ Fill in spice/command and use export_spice (e.g. the spice_raw view) to get that string exported at the end of the spice netlist file. } + -sym-copyright=(C) 2023 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + role=symbol + spice/command={tran 1u 4m +plot v(out) v(in)} + } + } + } + ha:attrib { + maintainer=Tibor 'Igor2' Palinkas + page=1/1 + print_page=A/4 + title={raw spice: custom symbol} + } + } +} Index: tags/1.0.5/doc/tutorial/simulation/raw/22_custom_sym.svg =================================================================== --- tags/1.0.5/doc/tutorial/simulation/raw/22_custom_sym.svg (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/raw/22_custom_sym.svg (revision 10414) @@ -0,0 +1,554 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/1.0.5/doc/tutorial/simulation/raw/30_mixed.html =================================================================== --- tags/1.0.5/doc/tutorial/simulation/raw/30_mixed.html (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/raw/30_mixed.html (revision 10414) @@ -0,0 +1,84 @@ + + +

30_mixed: analog+digital mixed sim

+ +

Scope

+

+Mixed mode (analog + digital) simulation in the time domain. + +

The schematics

+

+The input and the output of the circuit are analog, but there is a +section of digital circuitry inbetween (a XOR gate). The simulator +runs the analog sections in the normal fixed time stepping manner +while the digital section is simulated based on events. This makes +large digital circuits simulate much faster at the expense of tracking +digital lines only using low/high/unknown states, rather than simulating +transitions in detail (rising/falling edges). +

+There are DAC and ADC converters inserted on the boundary of the +analog and digital systems, using terminal attributes. +

+

+ +
Click the image to get the sch-rnd sheet
+

+More info on the circuit: www.electronics-tutorials.ws + +

Preparing for simulation

+

+The XOR gate is going to use ngspice's internal model called d_xor. The whole +model card is specified within the symbol, using the +spice/model_card +symbol attribute. The spice instance name must start with an 'A' for d_xor, +while for other workflows the name U1 is more practical. This is dealt with +by using the spice/prefix=A attribute. +

+ADC converters are installed on the input terminals of the XOR gate by +setting the terminal attribute spice/bridge/model to bridge_adc_ttl, which +is a sch-rnd stock spice model for TTL levels. Whenever spice/bridge/model +is set on a terminal, target_spice will cut the original network connection +of the terminal to insert a bridge component there. This component is +not visible on the schematics, as it's specified in an attribute, but shows +up in the abstract model for any view using target_spice. +

+In the case of ngspice, only one bridge component is placed per model, because +ngspice's bridge components can handle multiple inputs and outputs in a 1:1 +mapping. +

+(The sch-rnd user manual has more +details on bridging) +

+The same bridging is done on the output terminal with model bridge_dac_ttl. +

+On the input, two pulses V1 and V2 are installed to generate trapezoid +signals with slow rising and falling edges. This is to demonstrate how ADC +goes from low to undefined to high. On the output a resistor is used +to provide a DC path from the terminal to the ground - spice usually +requires a DC path to the ground. + +

Raw spice commands

+

+This example executes a normal transient simulation. Since most signals +are either low or high most of the time, they would overlap on the plot. +To avoid confusion, slight y offsets are introduced using an arithmetic +expression, +0.0n. +

+tran 10ms 6s
+plot v(input1)+0.04 v(input2)+0.08 v(output) xlimit 0 6s
+
+ +

Export and run ngspice

+

+Running ngspice the usual way on the export yields the following graphs: +

+ + +

Using other implementations

+

gnucap

+

+Mixed mode simulation is not supported with gnucap. + +

xyce

+

+TODO Index: tags/1.0.5/doc/tutorial/simulation/raw/30_mixed.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/1.0.5/doc/tutorial/simulation/raw/30_mixed.png =================================================================== --- tags/1.0.5/doc/tutorial/simulation/raw/30_mixed.png (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/raw/30_mixed.png (revision 10414) Property changes on: tags/1.0.5/doc/tutorial/simulation/raw/30_mixed.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/1.0.5/doc/tutorial/simulation/raw/30_mixed.rs =================================================================== --- tags/1.0.5/doc/tutorial/simulation/raw/30_mixed.rs (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/raw/30_mixed.rs (revision 10414) @@ -0,0 +1,534 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=9bwyX4hVlbhQseMSDAAAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.1 { + uuid=8/SYZ/pfBzxyqFA12WQAAAAC; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAg; + li:objects { + ha:polygon.11 { + li:outline { + ha:line { x1=0; y1=0; x2=80000; y2=0; } + ha:line { x1=80000; y1=0; x2=80000; y2=20000; } + ha:line { x1=80000; y1=20000; x2=0; y2=20000; } + ha:line { x1=0; y1=20000; x2=0; y2=0; } + } + stroke=titlebox-frame; + fill=titlebox-fill; + } + ha:line.12 { x1=0; y1=10000; x2=80000; y2=10000; stroke=titlebox-frame; } + ha:line.13 { x1=40000; y1=10000; x2=40000; y2=0; stroke=titlebox-frame; } + ha:text.20 { x1=1000; y1=16500; dyntext=0; stroke=titlebox-big; text=TITLE; } + ha:text.21 { x1=1000; y1=10500; x2=79000; y2=16000; dyntext=1; stroke=titlebox-big; text=%../../A.title%; } + ha:text.22 { x1=1000; y1=5500; dyntext=0; stroke=titlebox-small; text={PROJECT:}; } + ha:text.23 { x1=13000; y1=5500; x2=39000; y2=9500; dyntext=1; stroke=titlebox-big; text=%project.name%; } + ha:text.24 { x1=1000; y1=500; dyntext=0; stroke=titlebox-small; text={PAGE:}; } + ha:text.25 { x1=10000; y1=500; x2=39000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.page%; } + ha:text.26 { x1=41000; y1=5500; dyntext=0; stroke=titlebox-small; text={FILE:}; } + ha:text.27 { x1=48000; y1=5500; x2=79000; y2=9500; dyntext=1; stroke=titlebox-big; text=%filename%; } + ha:text.28 { x1=41000; y1=500; dyntext=0; stroke=titlebox-small; text={MAINTAINER:}; } + ha:text.29 { x1=55000; y1=500; x2=79000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.maintainer%; } + } + ha:attrib { + purpose=titlebox + } + } + ha:group.13 { + uuid=39gOSGd8aSMOm1wdWfIAAAAF; + x=44000; y=96000; + li:objects { + ha:group.1 { + uuid=39gOSGd8aSMOm1wdWfIAAAAG; src_uuid=9bwyX4hVlbhQseMSDAAAAAAD; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-8000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=in1 + role=terminal + spice/bridge/model=bridge_adc_ttl + spice/pinnum=[1] + } + } + ha:group.2 { + uuid=39gOSGd8aSMOm1wdWfIAAAAH; src_uuid=9bwyX4hVlbhQseMSDAAAAAAE; + x=0; y=-8000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-8000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=in2 + role=terminal + spice/bridge/model=bridge_adc_ttl + spice/pinnum=[1] + } + } + ha:group.3 { + uuid=39gOSGd8aSMOm1wdWfIAAAAI; src_uuid=9bwyX4hVlbhQseMSDAAAAAAF; + x=24000; y=-4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=out + role=terminal + spice/bridge/model=bridge_dac_ttl + spice/pinnum=2 + } + } + ha:arc.4 { cx=1000; cy=-4000; r=8000; sang=-38.500000; dang=77.000000; stroke=sym-decor; } + ha:line.5 { x1=7250; y1=1000; x2=16000; y2=1000; stroke=sym-decor; } + ha:arc.6 { cx=2500; cy=-13750; r=20000; sang=29.200000; dang=18.300000; stroke=sym-decor; } + ha:line.7 { x1=7250; y1=-9000; x2=16000; y2=-9000; stroke=sym-decor; } + ha:arc.8 { cx=2500; cy=5750; r=20000; sang=-29.200000; dang=-18.300000; stroke=sym-decor; } + ha:arc.9 { cx=0; cy=-4000; r=8000; sang=-38.500000; dang=77.000000; stroke=sym-decor; } + ha:text.10 { x1=8000; y1=2000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + device=xor + name=U1 + role=symbol + spice/model_card={.model d_xor1 d_xor (rise_delay=1.0e-6 fall_delay=2.0e-6 ++ input_load=1.0e-12) } + spice/prefix=A + } + } + ha:group.14 { + uuid=mHn79ppCTFm1QBmauQ0AAAAp; src_uuid=iNOQfJpO6hT/HFDFGjoAAABx; + x=16000; y=80000; rot=270.000000; mirx=1; + li:objects { + ha:arc.1 { cx=10000; cy=0; r=6000; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:arc.2 { cx=8000; cy=0; r=2000; sang=0.000000; dang=180.000000; stroke=sym-decor; } + ha:arc.3 { cx=12000; cy=0; r=2000; sang=180.000000; dang=180.000000; stroke=sym-decor; } + ha:group.4 { + uuid=mHn79ppCTFm1QBmauQ0AAAAq; src_uuid=iNOQfJpO6hT/HFDFGjoAAABy; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=N + role=terminal + } + } + ha:group.5 { + uuid=mHn79ppCTFm1QBmauQ0AAAAr; src_uuid=iNOQfJpO6hT/HFDFGjoAAABz; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=P + role=terminal + } + } + ha:text.6 { x1=8000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=V1 + li:portmap { + {P->spice/pinnum=1} + {N->spice/pinnum=2} + } + role=symbol + spice/params=PULSE (0 5 1 0.3 0.3 2 10) + spice/prefix=V + } + } + ha:group.15 { + uuid=mHn79ppCTFm1QBmauQ0AAAAs; src_uuid=LnNTcUkV1CIzG7F2EXUAAAAZ; + x=-24000; y=-28000; + li:objects { + ha:line.1 { x1=40000; y1=88000; x2=40000; y2=80000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.17 { + uuid=mHn79ppCTFm1QBmauQ0AAAAt; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=16000; y=52000; + li:objects { + ha:group.1 { + uuid=mHn79ppCTFm1QBmauQ0AAAAu; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.19 { + uuid=mHn79ppCTFm1QBmauQ0AAAAv; src_uuid=iNOQfJpO6hT/HFDFGjoAAABx; + x=36000; y=80000; rot=270.000000; mirx=1; + li:objects { + ha:arc.1 { cx=10000; cy=0; r=6000; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:arc.2 { cx=8000; cy=0; r=2000; sang=0.000000; dang=180.000000; stroke=sym-decor; } + ha:arc.3 { cx=12000; cy=0; r=2000; sang=180.000000; dang=180.000000; stroke=sym-decor; } + ha:group.4 { + uuid=mHn79ppCTFm1QBmauQ0AAAAw; src_uuid=iNOQfJpO6hT/HFDFGjoAAABy; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=N + role=terminal + } + } + ha:group.5 { + uuid=mHn79ppCTFm1QBmauQ0AAAAx; src_uuid=iNOQfJpO6hT/HFDFGjoAAABz; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=P + role=terminal + } + } + ha:text.6 { x1=8000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=V2 + li:portmap { + {P->spice/pinnum=1} + {N->spice/pinnum=2} + } + role=symbol + spice/params=PULSE (0 5 2 0.3 0.3 2 4) + spice/prefix=V + } + } + ha:group.20 { + uuid=mHn79ppCTFm1QBmauQ0AAAAy; src_uuid=LnNTcUkV1CIzG7F2EXUAAAAZ; + x=-4000; y=-28000; + li:objects { + ha:line.1 { x1=40000; y1=88000; x2=40000; y2=80000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.22 { + uuid=mHn79ppCTFm1QBmauQ0AAAAz; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=36000; y=52000; + li:objects { + ha:group.1 { + uuid=mHn79ppCTFm1QBmauQ0AAAA0; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.24 { + uuid=mHn79ppCTFm1QBmauQ0AAAA1; + x=-40000; y=-28000; + li:objects { + ha:line.1 { x1=76000; y1=108000; x2=76000; y2=116000; stroke=wire; } + ha:line.2 { x1=76000; y1=116000; x2=84000; y2=116000; stroke=wire; } + ha:text.3 { x1=76000; y1=116000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=input2 + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.27 { + uuid=mHn79ppCTFm1QBmauQ0AAAA2; + x=-40000; y=-28000; + li:objects { + ha:line.1 { x1=56000; y1=108000; x2=56000; y2=124000; stroke=wire; } + ha:line.2 { x1=56000; y1=124000; x2=84000; y2=124000; stroke=wire; } + ha:text.3 { x1=76000; y1=124000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=input1 + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.30 { + uuid=mHn79ppCTFm1QBmauQ0AAAA3; + x=-52000; y=-28000; + li:objects { + ha:line.1 { x1=120000; y1=120000; x2=124000; y2=120000; stroke=wire; } + ha:text.2 { x1=124000; y1=120000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=output + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.32 { + uuid=Xb4Ih/E1Q5gK2yySOvUAAAAz; src_uuid=TeGEOMuew6iCb2kzckAAAAAD; + x=16000; y=116000; + li:objects { + ha:text.1 { x1=2000; y1=-4000; dyntext=0; stroke=sym-decor; text=raw spice; } + ha:text.2 { x1=2000; y1=-8000; dyntext=0; stroke=sym-decor; text=command; } + ha:polygon.3 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=-10000; } + ha:line { x1=0; y1=-10000; x2=12000; y2=-10000; } + ha:line { x1=12000; y1=-10000; x2=12000; y2=0; } + ha:line { x1=12000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + } + ha:attrib { + -sym-comment={ Fill in spice/command and use export_spice (e.g. the spice_raw view) to get that string exported at the end of the spice netlist file. } + -sym-copyright=(C) 2023 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + role=symbol + spice/command={tran 10ms 6s +plot v(input1)+0.04 v(input2)+0.08 v(output) xlimit 0 6s} + } + } + ha:group.33 { + uuid=GtwUPhB2CW+7+ykXMBQAAAAc; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=72000; y=92000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=GtwUPhB2CW+7+ykXMBQAAAAd; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=GtwUPhB2CW+7+ykXMBQAAAAe; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=R1 + role=symbol + value=100k + } + } + ha:group.35 { + uuid=GtwUPhB2CW+7+ykXMBQAAAAh; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=72000; y=52000; + li:objects { + ha:group.1 { + uuid=GtwUPhB2CW+7+ykXMBQAAAAi; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.36 { + uuid=GtwUPhB2CW+7+ykXMBQAAAAj; + x=-60000; y=-28000; + li:objects { + ha:line.1 { x1=132000; y1=100000; x2=132000; y2=80000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.42 { + li:conn { + /2/15/1 + /2/14/4/1 + } + } + ha:connection.43 { + li:conn { + /2/17/1/1 + /2/15/1 + } + } + ha:connection.44 { + li:conn { + /2/20/1 + /2/19/4/1 + } + } + ha:connection.45 { + li:conn { + /2/22/1/1 + /2/20/1 + } + } + ha:connection.46 { + li:conn { + /2/24/1 + /2/19/5/1 + } + } + ha:connection.48 { + li:conn { + /2/27/1 + /2/14/5/1 + } + } + ha:connection.54 { + li:conn { + /2/13/1/1 + /2/27/2 + } + } + ha:connection.55 { + li:conn { + /2/13/2/1 + /2/24/2 + } + } + ha:connection.60 { + li:conn { + /2/30/1 + /2/13/3/1 + } + } + ha:connection.61 { + li:conn { + /2/33/2/1 + /2/30/1 + } + } + ha:connection.62 { + li:conn { + /2/36/1 + /2/33/1/1 + } + } + ha:connection.63 { + li:conn { + /2/36/1 + /2/35/1/1 + } + } + } + ha:attrib { + maintainer=Tibor 'Igor2' Palinkas + page=1 of 1 + print_page=A/4 + title={SIM raw spice: mixed digital+analog} + } + } +} Index: tags/1.0.5/doc/tutorial/simulation/raw/30_mixed.svg =================================================================== --- tags/1.0.5/doc/tutorial/simulation/raw/30_mixed.svg (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/raw/30_mixed.svg (revision 10414) @@ -0,0 +1,686 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/1.0.5/doc/tutorial/simulation/raw/gnucap/01_dc.rs =================================================================== --- tags/1.0.5/doc/tutorial/simulation/raw/gnucap/01_dc.rs (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/raw/gnucap/01_dc.rs (revision 10414) @@ -0,0 +1,479 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.1 { + uuid=8/SYZ/pfBzxyqFA12WQAAAAC; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAg; + li:objects { + ha:polygon.11 { + li:outline { + ha:line { x1=0; y1=0; x2=80000; y2=0; } + ha:line { x1=80000; y1=0; x2=80000; y2=20000; } + ha:line { x1=80000; y1=20000; x2=0; y2=20000; } + ha:line { x1=0; y1=20000; x2=0; y2=0; } + } + stroke=titlebox-frame; + fill=titlebox-fill; + } + ha:line.12 { x1=0; y1=10000; x2=80000; y2=10000; stroke=titlebox-frame; } + ha:line.13 { x1=40000; y1=10000; x2=40000; y2=0; stroke=titlebox-frame; } + ha:text.20 { x1=1000; y1=16500; dyntext=0; stroke=titlebox-big; text=TITLE; } + ha:text.21 { x1=1000; y1=10500; x2=79000; y2=16000; dyntext=1; stroke=titlebox-big; text=%../../A.title%; } + ha:text.22 { x1=1000; y1=5500; dyntext=0; stroke=titlebox-small; text={PROJECT:}; } + ha:text.23 { x1=13000; y1=5500; x2=39000; y2=9500; dyntext=1; stroke=titlebox-big; text=%project.name%; } + ha:text.24 { x1=1000; y1=500; dyntext=0; stroke=titlebox-small; text={PAGE:}; } + ha:text.25 { x1=10000; y1=500; x2=39000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.page%; } + ha:text.26 { x1=41000; y1=5500; dyntext=0; stroke=titlebox-small; text={FILE:}; } + ha:text.27 { x1=48000; y1=5500; x2=79000; y2=9500; dyntext=1; stroke=titlebox-big; text=%filename%; } + ha:text.28 { x1=41000; y1=500; dyntext=0; stroke=titlebox-small; text={MAINTAINER:}; } + ha:text.29 { x1=55000; y1=500; x2=79000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.maintainer%; } + } + ha:attrib { + purpose=titlebox + } + } + ha:group.3 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAY; + x=-24000; y=-12000; + li:objects { + ha:line.1 { x1=36000; y1=116000; x2=52000; y2=116000; stroke=wire; } + ha:line.2 { x1=44000; y1=108000; x2=44000; y2=116000; stroke=wire; } + ha:line.3 { x1=44000; y1=116000; x2=44000; y2=116000; stroke=junction; } + ha:text.4 { x1=36000; y1=116000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=in + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.6 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAZ; + x=-20000; y=-12000; + li:objects { + ha:line.1 { x1=40000; y1=88000; x2=40000; y2=60000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.8 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAg; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=28000; y=104000; + li:objects { + ha:group.1 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAh; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAi; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=R1 + role=symbol + spice/prefix=R + value=2.2k + } + } + ha:group.14 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAz; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=52000; y=100000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=LnNTcUkV1CIzG7F2EXUAAAA0; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=LnNTcUkV1CIzG7F2EXUAAAA1; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=R2 + role=symbol + spice/prefix=R + value=1k + } + } + ha:group.24 { + uuid=LnNTcUkV1CIzG7F2EXUAAABA; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=20000; y=48000; + li:objects { + ha:group.1 { + uuid=LnNTcUkV1CIzG7F2EXUAAABB; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.33 { + uuid=F3n6uHwVbWw4HTjelNgAAAAf; src_uuid=TeGEOMuew6iCb2kzckAAAAAD; + x=16000; y=136000; + li:objects { + ha:text.1 { x1=2000; y1=-4000; dyntext=0; stroke=sym-decor; text=raw spice; } + ha:text.2 { x1=2000; y1=-8000; dyntext=0; stroke=sym-decor; text=command; } + ha:polygon.3 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=-10000; } + ha:line { x1=0; y1=-10000; x2=12000; y2=-10000; } + ha:line { x1=12000; y1=-10000; x2=12000; y2=0; } + ha:line { x1=12000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + } + ha:attrib { + -sym-comment={ Fill in spice/command and use export_spice (e.g. the spice_raw view) to get that string exported at the end of the spice netlist file. } + -sym-copyright=(C) 2023 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + role=symbol + spice/command={ +print dc v(out1) v(out2) +dc +} + } + } + ha:group.34 { + uuid=XkMAnbHX1rIO2D9kjFAAAAAk; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB0; + x=20000; y=96000; rot=270.000000; mirx=1; + li:objects { + ha:group.1 { + uuid=XkMAnbHX1rIO2D9kjFAAAAAl; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB1; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=N + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.2 { + uuid=XkMAnbHX1rIO2D9kjFAAAAAm; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB2; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=P + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:arc.3 { cx=10000; cy=0; r=6000; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:line.4 { x1=7000; y1=2000; x2=7000; y2=-2000; stroke=sym-decor; } + ha:line.5 { x1=5000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=11000; y1=0; x2=15000; y2=0; stroke=sym-decor; } + ha:text.7 { x1=0; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:text.8 { x1=0; y1=4000; dyntext=1; stroke=sym-secondary; text=%../A.spice/params%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=V1 + role=symbol + spice/params=DC 5V + } + } + ha:group.37 { + uuid=XkMAnbHX1rIO2D9kjFAAAAAn; + x=-24000; y=-12000; + li:objects { + ha:line.1 { x1=72000; y1=116000; x2=84000; y2=116000; stroke=wire; } + ha:line.2 { x1=76000; y1=112000; x2=76000; y2=116000; stroke=wire; } + ha:line.3 { x1=76000; y1=116000; x2=76000; y2=116000; stroke=junction; } + ha:text.4 { x1=84000; y1=116000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=out1 + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.40 { + uuid=XkMAnbHX1rIO2D9kjFAAAAAr; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=52000; y=72000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=XkMAnbHX1rIO2D9kjFAAAAAs; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=XkMAnbHX1rIO2D9kjFAAAAAt; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=R3 + role=symbol + spice/prefix=R + value=1k + } + } + ha:group.42 { + uuid=XkMAnbHX1rIO2D9kjFAAAAAw; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=52000; y=48000; + li:objects { + ha:group.1 { + uuid=XkMAnbHX1rIO2D9kjFAAAAAx; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.43 { + uuid=XkMAnbHX1rIO2D9kjFAAAAAy; + x=-24000; y=-16000; + li:objects { + ha:line.1 { x1=76000; y1=64000; x2=76000; y2=68000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.49 { + uuid=XkMAnbHX1rIO2D9kjFAAAAAz; + x=-24000; y=-12000; + li:objects { + ha:line.1 { x1=76000; y1=84000; x2=76000; y2=92000; stroke=wire; } + ha:line.2 { x1=76000; y1=88000; x2=84000; y2=88000; stroke=wire; } + ha:line.3 { x1=76000; y1=88000; x2=76000; y2=88000; stroke=junction; } + ha:text.4 { x1=84000; y1=88000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=out2 + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.53 { + li:conn { + /2/8/2/1 + /2/3/1 + } + } + ha:connection.54 { + li:conn { + /2/24/1/1 + /2/6/1 + } + } + ha:connection.55 { + li:conn { + /2/34/1/1 + /2/6/1 + } + } + ha:connection.56 { + li:conn { + /2/34/2/1 + /2/3/2 + } + } + ha:connection.57 { + li:conn { + /2/37/1 + /2/8/1/1 + } + } + ha:connection.58 { + li:conn { + /2/37/2 + /2/14/2/1 + } + } + ha:connection.59 { + li:conn { + /2/43/1 + /2/40/1/1 + } + } + ha:connection.60 { + li:conn { + /2/43/1 + /2/42/1/1 + } + } + ha:connection.61 { + li:conn { + /2/49/1 + /2/14/1/1 + } + } + ha:connection.62 { + li:conn { + /2/49/1 + /2/40/2/1 + } + } + } + ha:attrib { + maintainer=Tibor 'Igor2' Palinkas + page=1 of 1 + print_page=A/4 + title={SIM raw spice: DC operating point (for gnucap)} + } + } +} Index: tags/1.0.5/doc/tutorial/simulation/raw/gnucap/04_passive_tr.rs =================================================================== --- tags/1.0.5/doc/tutorial/simulation/raw/gnucap/04_passive_tr.rs (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/raw/gnucap/04_passive_tr.rs (revision 10414) @@ -0,0 +1,578 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.1 { + uuid=8/SYZ/pfBzxyqFA12WQAAAAC; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAg; + li:objects { + ha:polygon.11 { + li:outline { + ha:line { x1=0; y1=0; x2=80000; y2=0; } + ha:line { x1=80000; y1=0; x2=80000; y2=20000; } + ha:line { x1=80000; y1=20000; x2=0; y2=20000; } + ha:line { x1=0; y1=20000; x2=0; y2=0; } + } + stroke=titlebox-frame; + fill=titlebox-fill; + } + ha:line.12 { x1=0; y1=10000; x2=80000; y2=10000; stroke=titlebox-frame; } + ha:line.13 { x1=40000; y1=10000; x2=40000; y2=0; stroke=titlebox-frame; } + ha:text.20 { x1=1000; y1=16500; dyntext=0; stroke=titlebox-big; text=TITLE; } + ha:text.21 { x1=1000; y1=10500; x2=79000; y2=16000; dyntext=1; stroke=titlebox-big; text=%../../A.title%; } + ha:text.22 { x1=1000; y1=5500; dyntext=0; stroke=titlebox-small; text={PROJECT:}; } + ha:text.23 { x1=13000; y1=5500; x2=39000; y2=9500; dyntext=1; stroke=titlebox-big; text=%project.name%; } + ha:text.24 { x1=1000; y1=500; dyntext=0; stroke=titlebox-small; text={PAGE:}; } + ha:text.25 { x1=10000; y1=500; x2=39000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.page%; } + ha:text.26 { x1=41000; y1=5500; dyntext=0; stroke=titlebox-small; text={FILE:}; } + ha:text.27 { x1=48000; y1=5500; x2=79000; y2=9500; dyntext=1; stroke=titlebox-big; text=%filename%; } + ha:text.28 { x1=41000; y1=500; dyntext=0; stroke=titlebox-small; text={MAINTAINER:}; } + ha:text.29 { x1=55000; y1=500; x2=79000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.maintainer%; } + } + ha:attrib { + purpose=titlebox + } + } + ha:group.2 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAV; src_uuid=iNOQfJpO6hT/HFDFGjoAAABx; + x=16000; y=76000; rot=270.000000; mirx=1; + li:objects { + ha:arc.1 { cx=10000; cy=0; r=6000; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:arc.2 { cx=8000; cy=0; r=2000; sang=0.000000; dang=180.000000; stroke=sym-decor; } + ha:arc.3 { cx=12000; cy=0; r=2000; sang=180.000000; dang=180.000000; stroke=sym-decor; } + ha:group.4 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAW; src_uuid=iNOQfJpO6hT/HFDFGjoAAABy; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=N + role=terminal + } + } + ha:group.5 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAX; src_uuid=iNOQfJpO6hT/HFDFGjoAAABz; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=P + role=terminal + } + } + ha:text.6 { x1=8000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:text.8 { x1=-2000; y1=6000; dyntext=1; stroke=sym-secondary; text=%../A.spice/params%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=V1 + li:portmap { + {P->spice/pinnum=1} + {N->spice/pinnum=2} + } + role=symbol + spice/params=PULSE (0 5 1u 1u 1u 1 1) + spice/prefix=V + } + } + ha:group.3 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAY; + x=-28000; y=-32000; + li:objects { + ha:line.1 { x1=36000; y1=116000; x2=52000; y2=116000; stroke=wire; } + ha:line.2 { x1=44000; y1=108000; x2=44000; y2=116000; stroke=wire; } + ha:line.3 { x1=44000; y1=116000; x2=44000; y2=116000; stroke=junction; } + ha:text.4 { x1=36000; y1=116000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=in + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.6 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAZ; + x=-24000; y=-32000; + li:objects { + ha:line.1 { x1=40000; y1=88000; x2=40000; y2=80000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.8 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAg; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=24000; y=84000; + li:objects { + ha:group.1 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAh; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAi; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=R1 + role=symbol + spice/prefix=R + value=10k + } + } + ha:group.10 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAp; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAh; + x=52000; y=76000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAq; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAi; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAr; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAj; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.5 { x1=9000; y1=5000; x2=9000; y2=-5000; stroke=sym-decor; } + ha:line.6 { x1=11000; y1=5000; x2=11000; y2=-5000; stroke=sym-decor; } + ha:line.7 { x1=4000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.8 { x1=11000; y1=0; x2=16000; y2=0; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=C1 + role=symbol + spice/prefix=C + value=1u + } + } + ha:group.11 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAs; + x=-28000; y=-32000; + li:objects { + ha:line.2 { x1=80000; y1=116000; x2=80000; y2=108000; stroke=wire; } + ha:line.3 { x1=72000; y1=116000; x2=88000; y2=116000; stroke=wire; } + ha:line.4 { x1=80000; y1=116000; x2=80000; y2=116000; stroke=junction; } + ha:text.5 { x1=84000; y1=116000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=mid + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.14 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAz; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=60000; y=84000; + li:objects { + ha:group.1 { + uuid=LnNTcUkV1CIzG7F2EXUAAAA0; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=LnNTcUkV1CIzG7F2EXUAAAA1; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=R2 + role=symbol + spice/prefix=R + value=15k + } + } + ha:group.16 { + uuid=LnNTcUkV1CIzG7F2EXUAAAA2; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAh; + x=88000; y=76000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=LnNTcUkV1CIzG7F2EXUAAAA3; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAi; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=LnNTcUkV1CIzG7F2EXUAAAA4; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAj; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.5 { x1=9000; y1=5000; x2=9000; y2=-5000; stroke=sym-decor; } + ha:line.6 { x1=11000; y1=5000; x2=11000; y2=-5000; stroke=sym-decor; } + ha:line.7 { x1=4000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.8 { x1=11000; y1=0; x2=16000; y2=0; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=C2 + role=symbol + spice/prefix=C + value=1.2u + } + } + ha:group.17 { + uuid=LnNTcUkV1CIzG7F2EXUAAAA5; + x=-28000; y=-32000; + li:objects { + ha:line.2 { x1=116000; y1=116000; x2=116000; y2=108000; stroke=wire; } + ha:line.3 { x1=108000; y1=116000; x2=132000; y2=116000; stroke=wire; } + ha:line.4 { x1=116000; y1=116000; x2=116000; y2=116000; stroke=junction; } + ha:text.5 { x1=128000; y1=116000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=out + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.20 { + uuid=LnNTcUkV1CIzG7F2EXUAAAA6; + x=-28000; y=-32000; + li:objects { + ha:line.1 { x1=80000; y1=88000; x2=80000; y2=80000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.22 { + uuid=LnNTcUkV1CIzG7F2EXUAAAA7; + x=-28000; y=-32000; + li:objects { + ha:line.1 { x1=116000; y1=88000; x2=116000; y2=80000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.24 { + uuid=LnNTcUkV1CIzG7F2EXUAAABA; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=16000; y=48000; + li:objects { + ha:group.1 { + uuid=LnNTcUkV1CIzG7F2EXUAAABB; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.26 { + uuid=LnNTcUkV1CIzG7F2EXUAAABC; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=52000; y=48000; + li:objects { + ha:group.1 { + uuid=LnNTcUkV1CIzG7F2EXUAAABD; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.28 { + uuid=LnNTcUkV1CIzG7F2EXUAAABE; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=88000; y=48000; + li:objects { + ha:group.1 { + uuid=LnNTcUkV1CIzG7F2EXUAAABF; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.33 { + uuid=F3n6uHwVbWw4HTjelNgAAAAf; src_uuid=TeGEOMuew6iCb2kzckAAAAAD; + x=16000; y=136000; + li:objects { + ha:text.1 { x1=2000; y1=-4000; dyntext=0; stroke=sym-decor; text=raw spice; } + ha:text.2 { x1=2000; y1=-8000; dyntext=0; stroke=sym-decor; text=command; } + ha:polygon.3 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=-10000; } + ha:line { x1=0; y1=-10000; x2=12000; y2=-10000; } + ha:line { x1=12000; y1=-10000; x2=12000; y2=0; } + ha:line { x1=12000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + } + ha:attrib { + -sym-comment={ Fill in spice/command and use export_spice (e.g. the spice_raw view) to get that string exported at the end of the spice netlist file. } + -sym-copyright=(C) 2023 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + role=symbol + spice/command={print tran v(in) v(mid) v(out) +tran 0.1ms 200ms > LOG} + } + } + ha:connection.34 { + li:conn { + /2/3/2 + /2/2/5/1 + } + } + ha:connection.35 { + li:conn { + /2/6/1 + /2/2/4/1 + } + } + ha:connection.36 { + li:conn { + /2/8/2/1 + /2/3/1 + } + } + ha:connection.37 { + li:conn { + /2/11/2 + /2/10/2/1 + } + } + ha:connection.38 { + li:conn { + /2/11/3 + /2/8/1/1 + } + } + ha:connection.40 { + li:conn { + /2/14/2/1 + /2/11/3 + } + } + ha:connection.41 { + li:conn { + /2/17/2 + /2/16/2/1 + } + } + ha:connection.42 { + li:conn { + /2/17/3 + /2/14/1/1 + } + } + ha:connection.43 { + li:conn { + /2/20/1 + /2/10/1/1 + } + } + ha:connection.44 { + li:conn { + /2/22/1 + /2/16/1/1 + } + } + ha:connection.45 { + li:conn { + /2/24/1/1 + /2/6/1 + } + } + ha:connection.46 { + li:conn { + /2/26/1/1 + /2/20/1 + } + } + ha:connection.47 { + li:conn { + /2/28/1/1 + /2/22/1 + } + } + } + ha:attrib { + maintainer=Tibor 'Igor2' Palinkas + page=1 of 1 + print_page=A/4 + title={SIM raw spice: passives, tran (for gnucap)} + } + } +} Index: tags/1.0.5/doc/tutorial/simulation/raw/gnucap/06_passive_ac.rs =================================================================== --- tags/1.0.5/doc/tutorial/simulation/raw/gnucap/06_passive_ac.rs (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/raw/gnucap/06_passive_ac.rs (revision 10414) @@ -0,0 +1,577 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.1 { + uuid=8/SYZ/pfBzxyqFA12WQAAAAC; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAg; + li:objects { + ha:polygon.11 { + li:outline { + ha:line { x1=0; y1=0; x2=80000; y2=0; } + ha:line { x1=80000; y1=0; x2=80000; y2=20000; } + ha:line { x1=80000; y1=20000; x2=0; y2=20000; } + ha:line { x1=0; y1=20000; x2=0; y2=0; } + } + stroke=titlebox-frame; + fill=titlebox-fill; + } + ha:line.12 { x1=0; y1=10000; x2=80000; y2=10000; stroke=titlebox-frame; } + ha:line.13 { x1=40000; y1=10000; x2=40000; y2=0; stroke=titlebox-frame; } + ha:text.20 { x1=1000; y1=16500; dyntext=0; stroke=titlebox-big; text=TITLE; } + ha:text.21 { x1=1000; y1=10500; x2=79000; y2=16000; dyntext=1; stroke=titlebox-big; text=%../../A.title%; } + ha:text.22 { x1=1000; y1=5500; dyntext=0; stroke=titlebox-small; text={PROJECT:}; } + ha:text.23 { x1=13000; y1=5500; x2=39000; y2=9500; dyntext=1; stroke=titlebox-big; text=%project.name%; } + ha:text.24 { x1=1000; y1=500; dyntext=0; stroke=titlebox-small; text={PAGE:}; } + ha:text.25 { x1=10000; y1=500; x2=39000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.page%; } + ha:text.26 { x1=41000; y1=5500; dyntext=0; stroke=titlebox-small; text={FILE:}; } + ha:text.27 { x1=48000; y1=5500; x2=79000; y2=9500; dyntext=1; stroke=titlebox-big; text=%filename%; } + ha:text.28 { x1=41000; y1=500; dyntext=0; stroke=titlebox-small; text={MAINTAINER:}; } + ha:text.29 { x1=55000; y1=500; x2=79000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.maintainer%; } + } + ha:attrib { + purpose=titlebox + } + } + ha:group.2 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAV; src_uuid=iNOQfJpO6hT/HFDFGjoAAABx; + x=12000; y=72000; rot=270.000000; mirx=1; + li:objects { + ha:arc.1 { cx=10000; cy=0; r=6000; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:arc.2 { cx=8000; cy=0; r=2000; sang=0.000000; dang=180.000000; stroke=sym-decor; } + ha:arc.3 { cx=12000; cy=0; r=2000; sang=180.000000; dang=180.000000; stroke=sym-decor; } + ha:group.4 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAW; src_uuid=iNOQfJpO6hT/HFDFGjoAAABy; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=N + role=terminal + } + } + ha:group.5 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAX; src_uuid=iNOQfJpO6hT/HFDFGjoAAABz; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=P + role=terminal + } + } + ha:text.6 { x1=8000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=V1 + li:portmap { + {P->spice/pinnum=1} + {N->spice/pinnum=2} + } + role=symbol + spice/params=dc 0 ac 1 + spice/prefix=V + } + } + ha:group.3 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAY; + x=-32000; y=-36000; + li:objects { + ha:line.1 { x1=36000; y1=116000; x2=52000; y2=116000; stroke=wire; } + ha:line.2 { x1=44000; y1=108000; x2=44000; y2=116000; stroke=wire; } + ha:line.3 { x1=44000; y1=116000; x2=44000; y2=116000; stroke=junction; } + ha:text.4 { x1=36000; y1=116000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=in + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.6 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAZ; + x=-28000; y=-36000; + li:objects { + ha:line.1 { x1=40000; y1=88000; x2=40000; y2=80000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.8 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAg; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=20000; y=80000; + li:objects { + ha:group.1 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAh; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAi; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=R1 + role=symbol + spice/prefix=R + value=10k + } + } + ha:group.10 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAp; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAh; + x=48000; y=72000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAq; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAi; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAr; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAj; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.5 { x1=9000; y1=5000; x2=9000; y2=-5000; stroke=sym-decor; } + ha:line.6 { x1=11000; y1=5000; x2=11000; y2=-5000; stroke=sym-decor; } + ha:line.7 { x1=4000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.8 { x1=11000; y1=0; x2=16000; y2=0; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=C1 + role=symbol + spice/prefix=C + value=1u + } + } + ha:group.11 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAs; + x=-32000; y=-36000; + li:objects { + ha:line.2 { x1=80000; y1=116000; x2=80000; y2=108000; stroke=wire; } + ha:line.3 { x1=72000; y1=116000; x2=88000; y2=116000; stroke=wire; } + ha:line.4 { x1=80000; y1=116000; x2=80000; y2=116000; stroke=junction; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.14 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAz; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=56000; y=80000; + li:objects { + ha:group.1 { + uuid=LnNTcUkV1CIzG7F2EXUAAAA0; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=LnNTcUkV1CIzG7F2EXUAAAA1; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=R2 + role=symbol + spice/prefix=R + value=1k + } + } + ha:group.16 { + uuid=LnNTcUkV1CIzG7F2EXUAAAA2; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAh; + x=84000; y=72000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=LnNTcUkV1CIzG7F2EXUAAAA3; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAi; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=LnNTcUkV1CIzG7F2EXUAAAA4; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAj; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.5 { x1=9000; y1=5000; x2=9000; y2=-5000; stroke=sym-decor; } + ha:line.6 { x1=11000; y1=5000; x2=11000; y2=-5000; stroke=sym-decor; } + ha:line.7 { x1=4000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.8 { x1=11000; y1=0; x2=16000; y2=0; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=C2 + role=symbol + spice/prefix=C + value=100n + } + } + ha:group.17 { + uuid=LnNTcUkV1CIzG7F2EXUAAAA5; + x=-32000; y=-36000; + li:objects { + ha:line.2 { x1=116000; y1=116000; x2=116000; y2=108000; stroke=wire; } + ha:line.3 { x1=108000; y1=116000; x2=132000; y2=116000; stroke=wire; } + ha:line.4 { x1=116000; y1=116000; x2=116000; y2=116000; stroke=junction; } + ha:text.5 { x1=128000; y1=116000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=out + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.20 { + uuid=LnNTcUkV1CIzG7F2EXUAAAA6; + x=-32000; y=-36000; + li:objects { + ha:line.1 { x1=80000; y1=88000; x2=80000; y2=80000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.22 { + uuid=LnNTcUkV1CIzG7F2EXUAAAA7; + x=-32000; y=-36000; + li:objects { + ha:line.1 { x1=116000; y1=88000; x2=116000; y2=80000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.24 { + uuid=LnNTcUkV1CIzG7F2EXUAAABA; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=12000; y=44000; + li:objects { + ha:group.1 { + uuid=LnNTcUkV1CIzG7F2EXUAAABB; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.26 { + uuid=LnNTcUkV1CIzG7F2EXUAAABC; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=48000; y=44000; + li:objects { + ha:group.1 { + uuid=LnNTcUkV1CIzG7F2EXUAAABD; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.28 { + uuid=LnNTcUkV1CIzG7F2EXUAAABE; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=84000; y=44000; + li:objects { + ha:group.1 { + uuid=LnNTcUkV1CIzG7F2EXUAAABF; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.33 { + uuid=F3n6uHwVbWw4HTjelNgAAAAf; src_uuid=TeGEOMuew6iCb2kzckAAAAAD; + x=4000; y=100000; + li:objects { + ha:text.1 { x1=2000; y1=-4000; dyntext=0; stroke=sym-decor; text=raw spice; } + ha:text.2 { x1=2000; y1=-8000; dyntext=0; stroke=sym-decor; text=command; } + ha:polygon.3 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=-10000; } + ha:line { x1=0; y1=-10000; x2=12000; y2=-10000; } + ha:line { x1=12000; y1=-10000; x2=12000; y2=0; } + ha:line { x1=12000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + } + ha:attrib { + -sym-comment={ Fill in spice/command and use export_spice (e.g. the spice_raw view) to get that string exported at the end of the spice netlist file. } + -sym-copyright=(C) 2023 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + role=symbol + spice/command={print ac vdb(out) zp(out) +op +ac dec 10 1 1000k > plot.txt +} + } + } + ha:connection.34 { + li:conn { + /2/3/2 + /2/2/5/1 + } + } + ha:connection.35 { + li:conn { + /2/6/1 + /2/2/4/1 + } + } + ha:connection.36 { + li:conn { + /2/8/2/1 + /2/3/1 + } + } + ha:connection.37 { + li:conn { + /2/11/2 + /2/10/2/1 + } + } + ha:connection.39 { + li:conn { + /2/11/3 + /2/8/1/1 + } + } + ha:connection.40 { + li:conn { + /2/14/2/1 + /2/11/3 + } + } + ha:connection.41 { + li:conn { + /2/17/2 + /2/16/2/1 + } + } + ha:connection.43 { + li:conn { + /2/17/3 + /2/14/1/1 + } + } + ha:connection.44 { + li:conn { + /2/20/1 + /2/10/1/1 + } + } + ha:connection.45 { + li:conn { + /2/22/1 + /2/16/1/1 + } + } + ha:connection.46 { + li:conn { + /2/24/1/1 + /2/6/1 + } + } + ha:connection.47 { + li:conn { + /2/26/1/1 + /2/20/1 + } + } + ha:connection.48 { + li:conn { + /2/28/1/1 + /2/22/1 + } + } + } + ha:attrib { + maintainer=Tibor 'Igor2' Palinkas + page=1 of 1 + print_page=A/4 + title={SIM raw spice: passives, ac (for gnucap)} + } + } +} Index: tags/1.0.5/doc/tutorial/simulation/raw/gnucap/10_bjt_amp_tr.rs =================================================================== --- tags/1.0.5/doc/tutorial/simulation/raw/gnucap/10_bjt_amp_tr.rs (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/raw/gnucap/10_bjt_amp_tr.rs (revision 10414) @@ -0,0 +1,1143 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAp; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAq; loclib_name=bc817_sot23; + li:objects { + } + ha:attrib { + footprint=SOT23 + li:portmap { + {B->pcb/pinnum=1} + {E->pcb/pinnum=2} + {C->pcb/pinnum=3} + } + } + } + } + ha:attrib { + ha:purpose = { value=devmap; prio=0; } + } + } + ha:group.2 { + uuid=DWHOYByNBsqCfIkWh9EAAAA9; + li:objects { + ha:group.1 { + uuid=DWHOYByNBsqCfIkWh9EAAAA+; loclib_name=bc817; + li:objects { + } + ha:attrib { + spice/model_card={* (C) 2023 Tibor 'Igor2' Palinkas +* License: CC0 (no rights reserved): https://creativecommons.org/publicdomain/zero/1.0/ +* Source: based on Vishay's datasheet: https://archive.org/details/bc817_spice_vishay +* +.model BC817 npn ( ++ IS=2.43485e-13 VAF=10 BF=270 IKF=1.12487 NE=1.84302 ISE=7.17747e-12 ++ IKR=0.149889 ISC=2.42047e-12 NC=3.94859 NR=1.04566 BR=2.51332 RC=0.407107 ++ CJC=5.516e-11 FC=0.8 MJC=0.529364 VJC=0.4 CJE=5.10473e-11 MJE=0.412728 ++ VJE=0.561234 TF=7.1424e-10 ITF=0.175457 VTF=1.86025 XTF=1.09929 RB=6.50128 ++ IRB=0.1 RBM=0.1 RE=0.0814215 TR=1e-07 ++ ) + +} + } + } + } + ha:attrib { + ha:purpose = { value=spicelib; prio=0; } + } + } + } + } + ha:obj_direct.2 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.1 { + uuid=8/SYZ/pfBzxyqFA12WQAAAAC; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAg; + li:objects { + ha:polygon.11 { + li:outline { + ha:line { x1=0; y1=0; x2=80000; y2=0; } + ha:line { x1=80000; y1=0; x2=80000; y2=20000; } + ha:line { x1=80000; y1=20000; x2=0; y2=20000; } + ha:line { x1=0; y1=20000; x2=0; y2=0; } + } + stroke=titlebox-frame; + fill=titlebox-fill; + } + ha:line.12 { x1=0; y1=10000; x2=80000; y2=10000; stroke=titlebox-frame; } + ha:line.13 { x1=40000; y1=10000; x2=40000; y2=0; stroke=titlebox-frame; } + ha:text.20 { x1=1000; y1=16500; dyntext=0; stroke=titlebox-big; text=TITLE; } + ha:text.21 { x1=1000; y1=10500; x2=79000; y2=16000; dyntext=1; stroke=titlebox-big; text=%../../A.title%; } + ha:text.22 { x1=1000; y1=5500; dyntext=0; stroke=titlebox-small; text={PROJECT:}; } + ha:text.23 { x1=13000; y1=5500; x2=39000; y2=9500; dyntext=1; stroke=titlebox-big; text=%project.name%; } + ha:text.24 { x1=1000; y1=500; dyntext=0; stroke=titlebox-small; text={PAGE:}; } + ha:text.25 { x1=10000; y1=500; x2=39000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.page%; } + ha:text.26 { x1=41000; y1=5500; dyntext=0; stroke=titlebox-small; text={FILE:}; } + ha:text.27 { x1=48000; y1=5500; x2=79000; y2=9500; dyntext=1; stroke=titlebox-big; text=%filename%; } + ha:text.28 { x1=41000; y1=500; dyntext=0; stroke=titlebox-small; text={MAINTAINER:}; } + ha:text.29 { x1=55000; y1=500; x2=79000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.maintainer%; } + } + ha:attrib { + purpose=titlebox + } + } + ha:group.2 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAJ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAh; + x=20000; y=100000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAK; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAi; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAL; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAj; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.5 { x1=9000; y1=5000; x2=9000; y2=-5000; stroke=sym-decor; } + ha:line.6 { x1=11000; y1=5000; x2=11000; y2=-5000; stroke=sym-decor; } + ha:line.7 { x1=4000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.8 { x1=11000; y1=0; x2=16000; y2=0; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=C1 + role=symbol + value=10u + } + } + ha:group.3 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAM; + x=-20000; y=-20000; + li:objects { + ha:line.1 { x1=40000; y1=120000; x2=32000; y2=120000; stroke=wire; } + ha:text.2 { x1=33000; y1=120000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + ha:line.3 { x1=32000; y1=84000; x2=32000; y2=120000; stroke=wire; } + } + ha:attrib { + name=in + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.5 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAN; + x=-20000; y=-20000; + li:objects { + ha:line.1 { x1=60000; y1=120000; x2=76000; y2=120000; stroke=wire; } + ha:line.3 { x1=64000; y1=120000; x2=64000; y2=120000; stroke=junction; } + ha:line.4 { x1=64000; y1=100000; x2=64000; y2=140000; stroke=wire; } + ha:text.5 { x1=66000; y1=120000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=int_b + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.7 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAU; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=44000; y=140000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAV; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAW; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=R1 + role=symbol + value=87k + } + } + ha:group.9 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAa; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=44000; y=80000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAb; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAc; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=R2 + role=symbol + value=10k + } + } + ha:group.14 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAr; + x=-52000; y=-20000; + li:objects { + ha:line.1 { x1=120000; y1=112000; x2=120000; y2=56000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.16 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAs; + x=-40000; y=-20000; + li:objects { + ha:line.1 { x1=84000; y1=80000; x2=84000; y2=56000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.18 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAw; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=68000; y=140000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAx; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAy; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=R3 + role=symbol + value=33k + } + } + ha:group.19 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAz; + x=-52000; y=-20000; + li:objects { + ha:line.1 { x1=120000; y1=128000; x2=120000; y2=140000; stroke=wire; } + ha:line.2 { x1=120000; y1=132000; x2=132000; y2=132000; stroke=wire; } + ha:line.3 { x1=120000; y1=132000; x2=120000; y2=132000; stroke=junction; } + ha:text.4 { x1=122000; y1=132000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=int_c + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.22 { + uuid=60PZRPnx0Y9mYJZvZgYAAAA0; + x=-40000; y=-20000; + li:objects { + ha:line.1 { x1=84000; y1=160000; x2=84000; y2=172000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.24 { + uuid=60PZRPnx0Y9mYJZvZgYAAAA1; + x=-52000; y=-20000; + li:objects { + ha:line.1 { x1=120000; y1=160000; x2=120000; y2=172000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.26 { + uuid=60PZRPnx0Y9mYJZvZgYAAAA5; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAh; + x=80000; y=112000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAA6; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAi; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=60PZRPnx0Y9mYJZvZgYAAAA7; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAj; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.5 { x1=9000; y1=5000; x2=9000; y2=-5000; stroke=sym-decor; } + ha:line.6 { x1=11000; y1=5000; x2=11000; y2=-5000; stroke=sym-decor; } + ha:line.7 { x1=4000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.8 { x1=11000; y1=0; x2=16000; y2=0; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=C2 + role=symbol + value=10u + } + } + ha:group.28 { + uuid=60PZRPnx0Y9mYJZvZgYAAAA/; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=108000; y=100000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAABA; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=60PZRPnx0Y9mYJZvZgYAAABB; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=R4 + role=symbol + value=100k + } + } + ha:group.29 { + uuid=60PZRPnx0Y9mYJZvZgYAAABC; + x=-60000; y=-20000; + li:objects { + ha:line.1 { x1=160000; y1=132000; x2=176000; y2=132000; stroke=wire; } + ha:line.2 { x1=168000; y1=120000; x2=168000; y2=132000; stroke=wire; } + ha:line.3 { x1=168000; y1=132000; x2=168000; y2=132000; stroke=junction; } + ha:text.4 { x1=173000; y1=132000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=out + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.32 { + uuid=60PZRPnx0Y9mYJZvZgYAAABD; + x=-60000; y=-20000; + li:objects { + ha:line.2 { x1=168000; y1=100000; x2=168000; y2=56000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.34 { + uuid=60PZRPnx0Y9mYJZvZgYAAABi; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB0; + x=128000; y=64000; rot=270.000000; mirx=1; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAABj; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB1; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=N + role=terminal + } + } + ha:group.2 { + uuid=60PZRPnx0Y9mYJZvZgYAAABk; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB2; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=P + role=terminal + } + } + ha:arc.3 { cx=10000; cy=0; r=6000; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:line.4 { x1=7000; y1=2000; x2=7000; y2=-2000; stroke=sym-decor; } + ha:line.5 { x1=5000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=11000; y1=0; x2=15000; y2=0; stroke=sym-decor; } + ha:text.7 { x1=0; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:text.8 { x1=8000; y1=-10000; dyntext=1; stroke=sym-secondary; text=%../A.spice/params%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=V2 + role=symbol + spice/params=dc 5 + li:spice/portmap { + {P->spice/pinnum=1} + {N->spice/pinnum=2} + } + } + } + ha:group.35 { + uuid=60PZRPnx0Y9mYJZvZgYAAABo; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB0; + x=12000; y=64000; rot=270.000000; mirx=1; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAABp; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB1; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=N + role=terminal + } + } + ha:group.2 { + uuid=60PZRPnx0Y9mYJZvZgYAAABq; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB2; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=P + role=terminal + } + } + ha:arc.3 { cx=10000; cy=0; r=6000; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:line.4 { x1=7000; y1=2000; x2=7000; y2=-2000; stroke=sym-decor; } + ha:line.5 { x1=5000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=11000; y1=0; x2=15000; y2=0; stroke=sym-decor; } + ha:text.7 { x1=0; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:text.8 { x1=6000; y1=-9000; dyntext=1; stroke=sym-secondary; text=%../A.spice/params%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=V1 + role=symbol + spice/params=SINE(0 0.01 1k) + li:spice/portmap { + {P->spice/pinnum=1} + {N->spice/pinnum=2} + } + } + } + ha:group.36 { + uuid=60PZRPnx0Y9mYJZvZgYAAABr; + x=-80000; y=-20000; + li:objects { + ha:line.1 { x1=208000; y1=64000; x2=208000; y2=56000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.38 { + uuid=60PZRPnx0Y9mYJZvZgYAAABs; + x=-232000; y=-20000; + li:objects { + ha:line.1 { x1=244000; y1=64000; x2=244000; y2=56000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.40 { + uuid=60PZRPnx0Y9mYJZvZgYAAABt; + x=-80000; y=-20000; + li:objects { + ha:line.1 { x1=208000; y1=84000; x2=208000; y2=92000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.46 { + uuid=60PZRPnx0Y9mYJZvZgYAAABz; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=12000; y=36000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAB0; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.48 { + uuid=60PZRPnx0Y9mYJZvZgYAAAB1; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=44000; y=36000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAB2; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.50 { + uuid=60PZRPnx0Y9mYJZvZgYAAAB3; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=68000; y=36000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAB4; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.52 { + uuid=60PZRPnx0Y9mYJZvZgYAAAB5; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=108000; y=36000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAB6; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.54 { + uuid=60PZRPnx0Y9mYJZvZgYAAAB7; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=128000; y=36000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAB8; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.56 { + uuid=60PZRPnx0Y9mYJZvZgYAAACB; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB6; + x=128000; y=72000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAACC; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB7; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-4000; y1=4000; x2=4000; y2=7000; halign=center; dyntext=0; stroke=sym-primary; text=Vcc; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:Vcc} + } + role=symbol + } + } + ha:group.58 { + uuid=60PZRPnx0Y9mYJZvZgYAAACD; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB6; + x=68000; y=152000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAACE; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB7; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-4000; y1=4000; x2=4000; y2=7000; halign=center; dyntext=0; stroke=sym-primary; text=Vcc; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:Vcc} + } + role=symbol + } + } + ha:group.60 { + uuid=60PZRPnx0Y9mYJZvZgYAAACF; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB6; + x=44000; y=152000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAACG; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB7; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-4000; y1=4000; x2=4000; y2=7000; halign=center; dyntext=0; stroke=sym-primary; text=Vcc; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:Vcc} + } + role=symbol + } + } + ha:group.62 { + uuid=uo/hkCCyjHkmVGRW0F0AAAA+; src_uuid=TeGEOMuew6iCb2kzckAAAAAD; + x=9000; y=124000; + li:objects { + ha:text.1 { x1=2000; y1=-4000; dyntext=0; stroke=sym-decor; text=raw spice; } + ha:text.2 { x1=2000; y1=-8000; dyntext=0; stroke=sym-decor; text=command; } + ha:polygon.3 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=-10000; } + ha:line { x1=0; y1=-10000; x2=12000; y2=-10000; } + ha:line { x1=12000; y1=-10000; x2=12000; y2=0; } + ha:line { x1=12000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + } + ha:attrib { + -sym-comment={ Fill in spice/command and use export_spice (e.g. the spice_raw view) to get that string exported at the end of the spice netlist file. } + -sym-copyright=(C) 2023 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + role=symbol + spice/command={print tran v(out) v(in) +tran 1u 10m > plot.txt} + } + } + ha:group.70 { + uuid=emEhKEkrgdRFzXxchToAAABZ; src_uuid=iNOQfJpO6hT/HFDFGjoAAACK; + x=56000; y=100000; + li:objects { + ha:polygon.1 { + li:outline { + ha:line { x1=10266; y1=-1780; x2=9224; y2=-3517; } + ha:line { x1=9224; y1=-3517; x2=10935; y2=-3368; } + ha:line { x1=10935; y1=-3368; x2=10266; y2=-1780; } + } + stroke=sym-decor; + fill=sym-decor; + } + ha:group.2 { + uuid=emEhKEkrgdRFzXxchToAAABa; src_uuid=iNOQfJpO6hT/HFDFGjoAAACL; + x=12000; y=8000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=-4000; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=C + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:group.3 { + uuid=emEhKEkrgdRFzXxchToAAABb; src_uuid=iNOQfJpO6hT/HFDFGjoAAACM; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=B + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.4 { + uuid=emEhKEkrgdRFzXxchToAAABc; src_uuid=iNOQfJpO6hT/HFDFGjoAAACN; + x=12000; y=-4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=-4000; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=E + role=terminal + ha:spice/pinnum = { value=3; prio=31050; } + } + } + ha:text.5 { x1=8000; y1=8000; rot=90.000000; dyntext=1; stroke=sym-secondary; text=%../a.devmap%; floater=1; } + ha:text.6 { x1=4000; y1=8000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:arc.7 { cx=9000; cy=0; r=5500; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:line.8 { x1=7000; y1=4000; x2=7000; y2=-4000; stroke=sym-decor; } + ha:line.9 { x1=4000; y1=0; x2=7000; y2=0; stroke=sym-decor; } + ha:line.10 { x1=7000; y1=-1000; x2=12000; y2=-4000; stroke=sym-decor; } + ha:line.11 { x1=7000; y1=1000; x2=12000; y2=4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + devmap=bc817_sot23 + name=Q1 + role=symbol + spice/model=bc817 + } + } + ha:connection.74 { + li:conn { + /2/3/1 + /2/2/2/1 + } + } + ha:connection.75 { + li:conn { + /2/5/1 + /2/2/1/1 + } + } + ha:connection.87 { + li:conn { + /2/35/2/1 + /2/3/3 + } + } + ha:connection.89 { + li:conn { + /2/38/1 + /2/35/1/1 + } + } + ha:connection.91 { + li:conn { + /2/46/1/1 + /2/38/1 + } + } + ha:connection.102 { + li:conn { + /2/7/1/1 + /2/5/4 + } + } + ha:connection.103 { + li:conn { + /2/9/2/1 + /2/5/4 + } + } + ha:connection.104 { + li:conn { + /2/16/1 + /2/9/1/1 + } + } + ha:connection.105 { + li:conn { + /2/22/1 + /2/7/2/1 + } + } + ha:connection.106 { + li:conn { + /2/48/1/1 + /2/16/1 + } + } + ha:connection.107 { + li:conn { + /2/60/1/1 + /2/22/1 + } + } + ha:connection.108 { + li:conn { + /2/19/1 + /2/18/1/1 + } + } + ha:connection.109 { + li:conn { + /2/24/1 + /2/18/2/1 + } + } + ha:connection.116 { + li:conn { + /2/50/1/1 + /2/14/1 + } + } + ha:connection.120 { + li:conn { + /2/58/1/1 + /2/24/1 + } + } + ha:connection.121 { + li:conn { + /2/70/2/1 + /2/19/1 + } + } + ha:connection.122 { + li:conn { + /2/70/3/1 + /2/5/1 + } + } + ha:connection.123 { + li:conn { + /2/70/4/1 + /2/14/1 + } + } + ha:connection.124 { + li:conn { + /2/26/2/1 + /2/19/2 + } + } + ha:connection.125 { + li:conn { + /2/29/1 + /2/26/1/1 + } + } + ha:connection.126 { + li:conn { + /2/29/2 + /2/28/2/1 + } + } + ha:connection.127 { + li:conn { + /2/32/2 + /2/28/1/1 + } + } + ha:connection.130 { + li:conn { + /2/52/1/1 + /2/32/2 + } + } + ha:connection.133 { + li:conn { + /2/36/1 + /2/34/1/1 + } + } + ha:connection.134 { + li:conn { + /2/40/1 + /2/34/2/1 + } + } + ha:connection.135 { + li:conn { + /2/54/1/1 + /2/36/1 + } + } + ha:connection.136 { + li:conn { + /2/56/1/1 + /2/40/1 + } + } + } + ha:attrib { + maintainer=Tibor 'Igor2' Palinkas + page=1 of 1 + print_page=A/4 + title={SIM raw spice: BJT amplifier, tran (for gnucap)} + } + } +} Index: tags/1.0.5/doc/tutorial/simulation/raw/gnucap/12_bjt_amp_ac.rs =================================================================== --- tags/1.0.5/doc/tutorial/simulation/raw/gnucap/12_bjt_amp_ac.rs (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/raw/gnucap/12_bjt_amp_ac.rs (revision 10414) @@ -0,0 +1,1147 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAp; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAq; loclib_name=bc817_sot23; + li:objects { + } + ha:attrib { + footprint=SOT23 + li:portmap { + {B->pcb/pinnum=1} + {E->pcb/pinnum=2} + {C->pcb/pinnum=3} + } + } + } + } + ha:attrib { + ha:purpose = { value=devmap; prio=0; } + } + } + ha:group.2 { + uuid=z0b4zSqeNVj4ZxfDauMAAAA9; + li:objects { + ha:group.1 { + uuid=z0b4zSqeNVj4ZxfDauMAAAA+; loclib_name=bc817; + li:objects { + } + ha:attrib { + spice/model_card={* (C) 2023 Tibor 'Igor2' Palinkas +* License: CC0 (no rights reserved): https://creativecommons.org/publicdomain/zero/1.0/ +* Source: based on Vishay's datasheet: https://archive.org/details/bc817_spice_vishay +* +.model BC817 npn ( ++ IS=2.43485e-13 VAF=10 BF=270 IKF=1.12487 NE=1.84302 ISE=7.17747e-12 ++ IKR=0.149889 ISC=2.42047e-12 NC=3.94859 NR=1.04566 BR=2.51332 RC=0.407107 ++ CJC=5.516e-11 FC=0.8 MJC=0.529364 VJC=0.4 CJE=5.10473e-11 MJE=0.412728 ++ VJE=0.561234 TF=7.1424e-10 ITF=0.175457 VTF=1.86025 XTF=1.09929 RB=6.50128 ++ IRB=0.1 RBM=0.1 RE=0.0814215 TR=1e-07 ++ ) + +} + } + } + } + ha:attrib { + ha:purpose = { value=spicelib; prio=0; } + } + } + } + } + ha:obj_direct.2 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.1 { + uuid=8/SYZ/pfBzxyqFA12WQAAAAC; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAg; + li:objects { + ha:polygon.11 { + li:outline { + ha:line { x1=0; y1=0; x2=80000; y2=0; } + ha:line { x1=80000; y1=0; x2=80000; y2=20000; } + ha:line { x1=80000; y1=20000; x2=0; y2=20000; } + ha:line { x1=0; y1=20000; x2=0; y2=0; } + } + stroke=titlebox-frame; + fill=titlebox-fill; + } + ha:line.12 { x1=0; y1=10000; x2=80000; y2=10000; stroke=titlebox-frame; } + ha:line.13 { x1=40000; y1=10000; x2=40000; y2=0; stroke=titlebox-frame; } + ha:text.20 { x1=1000; y1=16500; dyntext=0; stroke=titlebox-big; text=TITLE; } + ha:text.21 { x1=1000; y1=10500; x2=79000; y2=16000; dyntext=1; stroke=titlebox-big; text=%../../A.title%; } + ha:text.22 { x1=1000; y1=5500; dyntext=0; stroke=titlebox-small; text={PROJECT:}; } + ha:text.23 { x1=13000; y1=5500; x2=39000; y2=9500; dyntext=1; stroke=titlebox-big; text=%project.name%; } + ha:text.24 { x1=1000; y1=500; dyntext=0; stroke=titlebox-small; text={PAGE:}; } + ha:text.25 { x1=10000; y1=500; x2=39000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.page%; } + ha:text.26 { x1=41000; y1=5500; dyntext=0; stroke=titlebox-small; text={FILE:}; } + ha:text.27 { x1=48000; y1=5500; x2=79000; y2=9500; dyntext=1; stroke=titlebox-big; text=%filename%; } + ha:text.28 { x1=41000; y1=500; dyntext=0; stroke=titlebox-small; text={MAINTAINER:}; } + ha:text.29 { x1=55000; y1=500; x2=79000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.maintainer%; } + } + ha:attrib { + purpose=titlebox + } + } + ha:group.2 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAJ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAh; + x=20000; y=100000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAK; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAi; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAL; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAj; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.5 { x1=9000; y1=5000; x2=9000; y2=-5000; stroke=sym-decor; } + ha:line.6 { x1=11000; y1=5000; x2=11000; y2=-5000; stroke=sym-decor; } + ha:line.7 { x1=4000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.8 { x1=11000; y1=0; x2=16000; y2=0; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=C1 + role=symbol + value=10u + } + } + ha:group.3 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAM; + x=-20000; y=-20000; + li:objects { + ha:line.1 { x1=40000; y1=120000; x2=32000; y2=120000; stroke=wire; } + ha:text.2 { x1=33000; y1=120000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + ha:line.3 { x1=32000; y1=84000; x2=32000; y2=120000; stroke=wire; } + } + ha:attrib { + name=in + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.5 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAN; + x=-20000; y=-20000; + li:objects { + ha:line.1 { x1=60000; y1=120000; x2=76000; y2=120000; stroke=wire; } + ha:line.3 { x1=64000; y1=120000; x2=64000; y2=120000; stroke=junction; } + ha:line.4 { x1=64000; y1=100000; x2=64000; y2=140000; stroke=wire; } + ha:text.5 { x1=66000; y1=120000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=int_b + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.7 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAU; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=44000; y=140000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAV; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAW; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=R1 + role=symbol + value=87k + } + } + ha:group.9 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAa; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=44000; y=80000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAb; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAc; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=R2 + role=symbol + value=10k + } + } + ha:group.14 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAr; + x=-52000; y=-20000; + li:objects { + ha:line.1 { x1=120000; y1=112000; x2=120000; y2=56000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.16 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAs; + x=-40000; y=-20000; + li:objects { + ha:line.1 { x1=84000; y1=80000; x2=84000; y2=56000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.18 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAw; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=68000; y=140000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAx; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAy; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=R3 + role=symbol + value=33k + } + } + ha:group.19 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAz; + x=-52000; y=-20000; + li:objects { + ha:line.1 { x1=120000; y1=128000; x2=120000; y2=140000; stroke=wire; } + ha:line.2 { x1=120000; y1=132000; x2=132000; y2=132000; stroke=wire; } + ha:line.3 { x1=120000; y1=132000; x2=120000; y2=132000; stroke=junction; } + ha:text.4 { x1=122000; y1=132000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=int_c + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.22 { + uuid=60PZRPnx0Y9mYJZvZgYAAAA0; + x=-40000; y=-20000; + li:objects { + ha:line.1 { x1=84000; y1=160000; x2=84000; y2=172000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.24 { + uuid=60PZRPnx0Y9mYJZvZgYAAAA1; + x=-52000; y=-20000; + li:objects { + ha:line.1 { x1=120000; y1=160000; x2=120000; y2=172000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.26 { + uuid=60PZRPnx0Y9mYJZvZgYAAAA5; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAh; + x=80000; y=112000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAA6; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAi; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=60PZRPnx0Y9mYJZvZgYAAAA7; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAj; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.5 { x1=9000; y1=5000; x2=9000; y2=-5000; stroke=sym-decor; } + ha:line.6 { x1=11000; y1=5000; x2=11000; y2=-5000; stroke=sym-decor; } + ha:line.7 { x1=4000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.8 { x1=11000; y1=0; x2=16000; y2=0; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=C2 + role=symbol + value=10u + } + } + ha:group.28 { + uuid=60PZRPnx0Y9mYJZvZgYAAAA/; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=108000; y=100000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAABA; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=60PZRPnx0Y9mYJZvZgYAAABB; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=R4 + role=symbol + value=100k + } + } + ha:group.29 { + uuid=60PZRPnx0Y9mYJZvZgYAAABC; + x=-60000; y=-20000; + li:objects { + ha:line.1 { x1=160000; y1=132000; x2=176000; y2=132000; stroke=wire; } + ha:line.2 { x1=168000; y1=120000; x2=168000; y2=132000; stroke=wire; } + ha:line.3 { x1=168000; y1=132000; x2=168000; y2=132000; stroke=junction; } + ha:text.4 { x1=173000; y1=132000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=out + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.32 { + uuid=60PZRPnx0Y9mYJZvZgYAAABD; + x=-60000; y=-20000; + li:objects { + ha:line.2 { x1=168000; y1=100000; x2=168000; y2=56000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.34 { + uuid=60PZRPnx0Y9mYJZvZgYAAABi; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB0; + x=128000; y=64000; rot=270.000000; mirx=1; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAABj; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB1; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=N + role=terminal + } + } + ha:group.2 { + uuid=60PZRPnx0Y9mYJZvZgYAAABk; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB2; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=P + role=terminal + } + } + ha:arc.3 { cx=10000; cy=0; r=6000; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:line.4 { x1=7000; y1=2000; x2=7000; y2=-2000; stroke=sym-decor; } + ha:line.5 { x1=5000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=11000; y1=0; x2=15000; y2=0; stroke=sym-decor; } + ha:text.7 { x1=0; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:text.8 { x1=8000; y1=-10000; dyntext=1; stroke=sym-secondary; text=%../A.spice/params%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=V2 + role=symbol + spice/params=dc 5 + li:spice/portmap { + {P->spice/pinnum=1} + {N->spice/pinnum=2} + } + } + } + ha:group.35 { + uuid=60PZRPnx0Y9mYJZvZgYAAABo; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB0; + x=12000; y=64000; rot=270.000000; mirx=1; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAABp; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB1; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=N + role=terminal + } + } + ha:group.2 { + uuid=60PZRPnx0Y9mYJZvZgYAAABq; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB2; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=P + role=terminal + } + } + ha:arc.3 { cx=10000; cy=0; r=6000; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:line.4 { x1=7000; y1=2000; x2=7000; y2=-2000; stroke=sym-decor; } + ha:line.5 { x1=5000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=11000; y1=0; x2=15000; y2=0; stroke=sym-decor; } + ha:text.7 { x1=0; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:text.8 { x1=6000; y1=-9000; dyntext=1; stroke=sym-secondary; text=%../A.spice/params%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=V1 + role=symbol + spice/params=dc 0 ac 0.1 + li:spice/portmap { + {P->spice/pinnum=1} + {N->spice/pinnum=2} + } + } + } + ha:group.36 { + uuid=60PZRPnx0Y9mYJZvZgYAAABr; + x=-80000; y=-20000; + li:objects { + ha:line.1 { x1=208000; y1=64000; x2=208000; y2=56000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.38 { + uuid=60PZRPnx0Y9mYJZvZgYAAABs; + x=-232000; y=-20000; + li:objects { + ha:line.1 { x1=244000; y1=64000; x2=244000; y2=56000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.40 { + uuid=60PZRPnx0Y9mYJZvZgYAAABt; + x=-80000; y=-20000; + li:objects { + ha:line.1 { x1=208000; y1=84000; x2=208000; y2=92000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.46 { + uuid=60PZRPnx0Y9mYJZvZgYAAABz; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=12000; y=36000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAB0; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.48 { + uuid=60PZRPnx0Y9mYJZvZgYAAAB1; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=44000; y=36000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAB2; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.50 { + uuid=60PZRPnx0Y9mYJZvZgYAAAB3; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=68000; y=36000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAB4; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.52 { + uuid=60PZRPnx0Y9mYJZvZgYAAAB5; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=108000; y=36000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAB6; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.54 { + uuid=60PZRPnx0Y9mYJZvZgYAAAB7; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=128000; y=36000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAB8; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.56 { + uuid=60PZRPnx0Y9mYJZvZgYAAACB; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB6; + x=128000; y=72000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAACC; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB7; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-4000; y1=4000; x2=4000; y2=7000; halign=center; dyntext=0; stroke=sym-primary; text=Vcc; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:Vcc} + } + role=symbol + } + } + ha:group.58 { + uuid=60PZRPnx0Y9mYJZvZgYAAACD; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB6; + x=68000; y=152000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAACE; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB7; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-4000; y1=4000; x2=4000; y2=7000; halign=center; dyntext=0; stroke=sym-primary; text=Vcc; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:Vcc} + } + role=symbol + } + } + ha:group.60 { + uuid=60PZRPnx0Y9mYJZvZgYAAACF; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB6; + x=44000; y=152000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAACG; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB7; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-4000; y1=4000; x2=4000; y2=7000; halign=center; dyntext=0; stroke=sym-primary; text=Vcc; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:Vcc} + } + role=symbol + } + } + ha:group.62 { + uuid=uo/hkCCyjHkmVGRW0F0AAAA+; src_uuid=TeGEOMuew6iCb2kzckAAAAAD; + x=9000; y=124000; + li:objects { + ha:text.1 { x1=2000; y1=-4000; dyntext=0; stroke=sym-decor; text=raw spice; } + ha:text.2 { x1=2000; y1=-8000; dyntext=0; stroke=sym-decor; text=command; } + ha:polygon.3 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=-10000; } + ha:line { x1=0; y1=-10000; x2=12000; y2=-10000; } + ha:line { x1=12000; y1=-10000; x2=12000; y2=0; } + ha:line { x1=12000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + } + ha:attrib { + -sym-comment={ Fill in spice/command and use export_spice (e.g. the spice_raw view) to get that string exported at the end of the spice netlist file. } + -sym-copyright=(C) 2023 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + role=symbol + spice/command={print ac vdb(out) zp(out) +op +ac dec 10 1 1000k > plot.txt +} + } + } + ha:group.70 { + uuid=emEhKEkrgdRFzXxchToAAABZ; src_uuid=iNOQfJpO6hT/HFDFGjoAAACK; + x=56000; y=100000; + li:objects { + ha:polygon.1 { + li:outline { + ha:line { x1=10266; y1=-1780; x2=9224; y2=-3517; } + ha:line { x1=9224; y1=-3517; x2=10935; y2=-3368; } + ha:line { x1=10935; y1=-3368; x2=10266; y2=-1780; } + } + stroke=sym-decor; + fill=sym-decor; + } + ha:group.2 { + uuid=emEhKEkrgdRFzXxchToAAABa; src_uuid=iNOQfJpO6hT/HFDFGjoAAACL; + x=12000; y=8000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=-4000; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=C + role=terminal + } + } + ha:group.3 { + uuid=emEhKEkrgdRFzXxchToAAABb; src_uuid=iNOQfJpO6hT/HFDFGjoAAACM; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=B + role=terminal + } + } + ha:group.4 { + uuid=emEhKEkrgdRFzXxchToAAABc; src_uuid=iNOQfJpO6hT/HFDFGjoAAACN; + x=12000; y=-4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=-4000; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=E + role=terminal + } + } + ha:text.5 { x1=8000; y1=8000; rot=90.000000; dyntext=1; stroke=sym-secondary; text=%../a.devmap%; floater=1; } + ha:text.6 { x1=4000; y1=8000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:arc.7 { cx=9000; cy=0; r=5500; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:line.8 { x1=7000; y1=4000; x2=7000; y2=-4000; stroke=sym-decor; } + ha:line.9 { x1=4000; y1=0; x2=7000; y2=0; stroke=sym-decor; } + ha:line.10 { x1=7000; y1=-1000; x2=12000; y2=-4000; stroke=sym-decor; } + ha:line.11 { x1=7000; y1=1000; x2=12000; y2=4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + devmap=bc817_sot23 + name=Q1 + li:portmap { + {C->spice/pinnum=1} + {B->spice/pinnum=2} + {E->spice/pinnum=3} + } + role=symbol + spice/model=bc817 + } + } + ha:connection.74 { + li:conn { + /2/3/1 + /2/2/2/1 + } + } + ha:connection.75 { + li:conn { + /2/5/1 + /2/2/1/1 + } + } + ha:connection.87 { + li:conn { + /2/35/2/1 + /2/3/3 + } + } + ha:connection.89 { + li:conn { + /2/38/1 + /2/35/1/1 + } + } + ha:connection.91 { + li:conn { + /2/46/1/1 + /2/38/1 + } + } + ha:connection.102 { + li:conn { + /2/7/1/1 + /2/5/4 + } + } + ha:connection.103 { + li:conn { + /2/9/2/1 + /2/5/4 + } + } + ha:connection.104 { + li:conn { + /2/16/1 + /2/9/1/1 + } + } + ha:connection.105 { + li:conn { + /2/22/1 + /2/7/2/1 + } + } + ha:connection.106 { + li:conn { + /2/48/1/1 + /2/16/1 + } + } + ha:connection.107 { + li:conn { + /2/60/1/1 + /2/22/1 + } + } + ha:connection.108 { + li:conn { + /2/19/1 + /2/18/1/1 + } + } + ha:connection.109 { + li:conn { + /2/24/1 + /2/18/2/1 + } + } + ha:connection.116 { + li:conn { + /2/50/1/1 + /2/14/1 + } + } + ha:connection.120 { + li:conn { + /2/58/1/1 + /2/24/1 + } + } + ha:connection.121 { + li:conn { + /2/70/2/1 + /2/19/1 + } + } + ha:connection.122 { + li:conn { + /2/70/3/1 + /2/5/1 + } + } + ha:connection.123 { + li:conn { + /2/70/4/1 + /2/14/1 + } + } + ha:connection.124 { + li:conn { + /2/26/2/1 + /2/19/2 + } + } + ha:connection.125 { + li:conn { + /2/29/1 + /2/26/1/1 + } + } + ha:connection.126 { + li:conn { + /2/29/2 + /2/28/2/1 + } + } + ha:connection.127 { + li:conn { + /2/32/2 + /2/28/1/1 + } + } + ha:connection.130 { + li:conn { + /2/52/1/1 + /2/32/2 + } + } + ha:connection.133 { + li:conn { + /2/36/1 + /2/34/1/1 + } + } + ha:connection.134 { + li:conn { + /2/40/1 + /2/34/2/1 + } + } + ha:connection.135 { + li:conn { + /2/54/1/1 + /2/36/1 + } + } + ha:connection.136 { + li:conn { + /2/56/1/1 + /2/40/1 + } + } + } + ha:attrib { + maintainer=Tibor 'Igor2' Palinkas + page=1 of 1 + print_page=A/4 + title={SIM raw spice: BJT amplifier, ac (for gnucap)} + } + } +} Index: tags/1.0.5/doc/tutorial/simulation/raw/gnucap/16_opamp_dc.rs =================================================================== --- tags/1.0.5/doc/tutorial/simulation/raw/gnucap/16_opamp_dc.rs (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/raw/gnucap/16_opamp_dc.rs (revision 10414) @@ -0,0 +1,1043 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + ha:group.1 { + uuid=Hif/m8o2mo/CrYnTszoAAAAV; + li:objects { + ha:group.1 { + uuid=Hif/m8o2mo/CrYnTszoAAAAW; loclib_name=lm358_so8; + li:objects { + } + ha:attrib { + footprint=so(8) + li:portmap { + {1/in- -> pcb/pinnum=2} + {1/in+ -> pcb/pinnum=3} + {1/out -> pcb/pinnum=1} + {1/V+ -> pcb/pinnum=8} + {1/V- -> pcb/pinnum=4} + {2/in- -> pcb/pinnum=6} + {2/in+ -> pcb/pinnum=5} + {2/out -> pcb/pinnum=7} + {2/V+ -> pcb/pinnum=8} + {2/V- -> pcb/pinnum=4} + } + } + } + } + ha:attrib { + ha:purpose = { value=devmap; prio=0; } + } + } + ha:group.2 { + uuid=q2/sAR5PfxztjLc/eYgAAAA1; + li:objects { + ha:group.1 { + uuid=q2/sAR5PfxztjLc/eYgAAAA2; loclib_name=lm358; + li:objects { + } + ha:attrib { + spice/model_card={* lm358 - low power opamp model (single slot) +* +* (C) 2023 Tibor 'Igor2' Palinkas +* License: CC0 (no rights reserved): https://creativecommons.org/publicdomain/zero/1.0/ +* Source: from ST's datasheet: https://archive.org/details/st-ts321 +* (st321 is reasonably close to lm358 for simple simulation cases; see +* warnings on page 7) +* +* +** CONNECTIONS: +* 1 inverting input +* 2 non-inverting INPUT +* 3 output +* 4 positive power supply +* 5 negative power supply +.SUBCKT LM358 1 2 3 4 5 + +.MODEL MDTH D IS=1E-8 KF=3.104131E-15 CJO=10F + +* INPUT STAGE +CIP 2 5 1.000000E-12 +CIN 1 5 1.000000E-12 +EIP 10 5 2 5 1 +EIN 16 5 1 5 1 +RIP 10 11 2.600000E+01 +RIN 15 16 2.600000E+01 +RIS 11 15 2.003862E+02 +DIP 11 12 MDTH 400E-12 +DIN 15 14 MDTH 400E-12 +VOFP 12 13 DC 0 +VOFN 13 14 DC 0 +IPOL 13 5 1.000000E-05 +CPS 11 15 3.783376E-09 +DINN 17 13 MDTH 400E-12 +VIN 17 5 0.000000e+00 +DINR 15 18 MDTH 400E-12 +VIP 4 18 2.000000E+00 +FCP 4 5 VOFP 3.400000E+01 +FCN 5 4 VOFN 3.400000E+01 +FIBP 2 5 VOFN 2.000000E-03 +FIBN 5 1 VOFP 2.000000E-03 + +* AMPLIFYING STAGE +FIP 5 19 VOFP 3.600000E+02 +FIN 5 19 VOFN 3.600000E+02 +RG1 19 5 3.652997E+06 +RG2 19 4 3.652997E+06 +CC 19 5 6.000000E-09 +DOPM 19 22 MDTH 400E-12 +DONM 21 19 MDTH 400E-12 +HOPM 22 28 VOUT 7.500000E+03 +VIPM 28 4 1.500000E+02 +HONM 21 27 VOUT 7.500000E+03 +VINM 5 27 1.500000E+02 +EOUT 26 23 19 5 1 +VOUT 23 5 0 +ROUT 26 3 20 +COUT 3 5 1.000000E-12 +DOP 19 25 MDTH 400E-12 +VOP 4 25 2.242230E+00 +DON 24 19 MDTH 400E-12 +VON 24 5 7.922301E-01 +.ENDS +} + } + } + } + ha:attrib { + ha:purpose = { value=spicelib; prio=0; } + } + } + } + } + ha:obj_direct.2 { + uuid=Hif/m8o2mo/CrYnTszoAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.1 { + uuid=8/SYZ/pfBzxyqFA12WQAAAAC; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAg; + li:objects { + ha:polygon.11 { + li:outline { + ha:line { x1=0; y1=0; x2=80000; y2=0; } + ha:line { x1=80000; y1=0; x2=80000; y2=20000; } + ha:line { x1=80000; y1=20000; x2=0; y2=20000; } + ha:line { x1=0; y1=20000; x2=0; y2=0; } + } + stroke=titlebox-frame; + fill=titlebox-fill; + } + ha:line.12 { x1=0; y1=10000; x2=80000; y2=10000; stroke=titlebox-frame; } + ha:line.13 { x1=40000; y1=10000; x2=40000; y2=0; stroke=titlebox-frame; } + ha:text.20 { x1=1000; y1=16500; dyntext=0; stroke=titlebox-big; text=TITLE; } + ha:text.21 { x1=1000; y1=10500; x2=79000; y2=16000; dyntext=1; stroke=titlebox-big; text=%../../A.title%; } + ha:text.22 { x1=1000; y1=5500; dyntext=0; stroke=titlebox-small; text={PROJECT:}; } + ha:text.23 { x1=13000; y1=5500; x2=39000; y2=9500; dyntext=1; stroke=titlebox-big; text=%project.name%; } + ha:text.24 { x1=1000; y1=500; dyntext=0; stroke=titlebox-small; text={PAGE:}; } + ha:text.25 { x1=10000; y1=500; x2=39000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.page%; } + ha:text.26 { x1=41000; y1=5500; dyntext=0; stroke=titlebox-small; text={FILE:}; } + ha:text.27 { x1=48000; y1=5500; x2=79000; y2=9500; dyntext=1; stroke=titlebox-big; text=%filename%; } + ha:text.28 { x1=41000; y1=500; dyntext=0; stroke=titlebox-small; text={MAINTAINER:}; } + ha:text.29 { x1=55000; y1=500; x2=79000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.maintainer%; } + } + ha:attrib { + purpose=titlebox + } + } + ha:group.2 { + uuid=Hif/m8o2mo/CrYnTszoAAAAP; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAH; + x=80000; y=116000; + li:objects { + ha:group.1 { + uuid=Hif/m8o2mo/CrYnTszoAAAAQ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAI; + x=-20000; y=4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=in+ + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.2 { + uuid=Hif/m8o2mo/CrYnTszoAAAAR; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAJ; + x=-20000; y=-4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=in- + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:group.3 { + uuid=Hif/m8o2mo/CrYnTszoAAAAS; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAK; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=out + role=terminal + ha:spice/pinnum = { value=3; prio=31050; } + } + } + ha:line.4 { x1=-20000; y1=-8000; x2=-20000; y2=8000; stroke=sym-decor; } + ha:line.5 { x1=-20000; y1=8000; x2=-4000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=-4000; y1=0; x2=-20000; y2=-8000; stroke=sym-decor; } + ha:line.7 { x1=-18000; y1=5000; x2=-18000; y2=3000; stroke=sym-decor; } + ha:line.8 { x1=-19000; y1=4000; x2=-17000; y2=4000; stroke=sym-decor; } + ha:line.9 { x1=-19000; y1=-4000; x2=-17000; y2=-4000; stroke=sym-decor; } + ha:group.10 { + uuid=Hif/m8o2mo/CrYnTszoAAAAT; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAL; + x=-12000; y=-4000; rot=270.000000; mirx=1; miry=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=0; y1=-1000; rot=180.000000; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=V- + role=terminal + ha:spice/pinnum = { value=5; prio=31050; } + } + } + ha:group.11 { + uuid=Hif/m8o2mo/CrYnTszoAAAAU; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAM; + x=-12000; y=8000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=-4000; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=V+ + role=terminal + ha:spice/pinnum = { value=4; prio=31050; } + } + } + ha:text.12 { x1=-21000; y1=9000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -slot=1 + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + devmap=lm358_so8 + name=U1 + role=symbol + spice/model=lm358 + } + } + ha:group.3 { + uuid=Hif/m8o2mo/CrYnTszoAAAAd; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=24000; y=112000; + li:objects { + ha:group.1 { + uuid=Hif/m8o2mo/CrYnTszoAAAAe; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=Hif/m8o2mo/CrYnTszoAAAAf; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=R1 + role=symbol + value=1k + } + } + ha:group.4 { + uuid=Hif/m8o2mo/CrYnTszoAAAAg; + x=-20000; y=0; + li:objects { + ha:line.1 { x1=64000; y1=112000; x2=76000; y2=112000; stroke=wire; } + ha:line.2 { x1=72000; y1=112000; x2=72000; y2=84000; stroke=wire; } + ha:line.3 { x1=72000; y1=112000; x2=72000; y2=112000; stroke=junction; } + ha:line.4 { x1=72000; y1=84000; x2=84000; y2=84000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.5 { + li:conn { + /2/4/1 + /2/2/2/1 + } + } + ha:group.7 { + uuid=Hif/m8o2mo/CrYnTszoAAAAk; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=64000; y=84000; + li:objects { + ha:group.1 { + uuid=Hif/m8o2mo/CrYnTszoAAAAl; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=Hif/m8o2mo/CrYnTszoAAAAm; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=R2 + role=symbol + value=100k + } + } + ha:group.9 { + uuid=Hif/m8o2mo/CrYnTszoAAAAn; + x=-20000; y=0; + li:objects { + ha:line.1 { x1=104000; y1=84000; x2=112000; y2=84000; stroke=wire; } + ha:line.2 { x1=112000; y1=84000; x2=112000; y2=116000; stroke=wire; } + ha:line.3 { x1=100000; y1=116000; x2=116000; y2=116000; stroke=wire; } + ha:line.4 { x1=112000; y1=116000; x2=112000; y2=116000; stroke=junction; } + ha:text.5 { x1=112000; y1=116000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=out + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.12 { + uuid=Hif/m8o2mo/CrYnTszoAAAAo; + x=-12000; y=0; + li:objects { + ha:line.1 { x1=36000; y1=112000; x2=24000; y2=112000; stroke=wire; } + ha:text.2 { x1=28000; y1=112000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + ha:line.3 { x1=24000; y1=104000; x2=24000; y2=112000; stroke=wire; } + } + ha:attrib { + name=in + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.14 { + uuid=Hif/m8o2mo/CrYnTszoAAAAt; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=48000; y=120000; + li:objects { + ha:group.1 { + uuid=Hif/m8o2mo/CrYnTszoAAAAu; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.15 { + uuid=Hif/m8o2mo/CrYnTszoAAAAv; + x=-20000; y=0; + li:objects { + ha:line.1 { x1=68000; y1=120000; x2=76000; y2=120000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.16 { + li:conn { + /2/15/1 + /2/2/1/1 + } + } + ha:group.18 { + uuid=Hif/m8o2mo/CrYnTszoAAAA8; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB6; + x=68000; y=128000; + li:objects { + ha:group.1 { + uuid=Hif/m8o2mo/CrYnTszoAAAA9; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB7; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-4000; y1=4000; x2=4000; y2=7000; halign=center; dyntext=0; stroke=sym-primary; text=Vcc; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:Vcc} + } + role=symbol + } + } + ha:group.19 { + uuid=Hif/m8o2mo/CrYnTszoAAAA+; + x=-20000; y=0; + li:objects { + ha:line.1 { x1=88000; y1=124000; x2=88000; y2=128000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.22 { + uuid=Hif/m8o2mo/CrYnTszoAAABH; src_uuid=iNOQfJpO6hT/HFDFGjoAAABv; + x=68000; y=104000; rot=180.000000; + li:objects { + ha:group.1 { + uuid=Hif/m8o2mo/CrYnTszoAAABI; src_uuid=iNOQfJpO6hT/HFDFGjoAAABw; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=6000; y1=7000; x2=18000; y2=10000; rot=180.000000; halign=center; dyntext=1; stroke=sym-primary; text=%../A.rail%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:forge { + delete,forge/tmp + scalar,forge/tmp + {sub,^,1:,forge/tmp} + suba,$,rail,forge/tmp + array,connect + append,connect,forge/tmp + } + rail=Vneg + role=symbol + } + } + ha:group.23 { + uuid=Hif/m8o2mo/CrYnTszoAAABJ; + x=-20000; y=0; + li:objects { + ha:line.1 { x1=88000; y1=104000; x2=88000; y2=108000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.28 { + uuid=Hif/m8o2mo/CrYnTszoAAABh; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=12000; y=80000; + li:objects { + ha:group.1 { + uuid=Hif/m8o2mo/CrYnTszoAAABi; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.29 { + uuid=Hif/m8o2mo/CrYnTszoAAABj; + x=-12000; y=0; + li:objects { + ha:line.1 { x1=24000; y1=80000; x2=24000; y2=84000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.33 { + uuid=Hif/m8o2mo/CrYnTszoAAABs; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB6; + x=56000; y=68000; + li:objects { + ha:group.1 { + uuid=Hif/m8o2mo/CrYnTszoAAABt; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB7; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-4000; y1=4000; x2=4000; y2=7000; halign=center; dyntext=0; stroke=sym-primary; text=Vcc; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:Vcc} + } + role=symbol + } + } + ha:group.34 { + uuid=Hif/m8o2mo/CrYnTszoAAABw; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=56000; y=40000; + li:objects { + ha:group.1 { + uuid=Hif/m8o2mo/CrYnTszoAAABx; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.35 { + uuid=Hif/m8o2mo/CrYnTszoAAABy; + x=-104000; y=-28000; + li:objects { + ha:line.1 { x1=160000; y1=92000; x2=160000; y2=96000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.38 { + uuid=Hif/m8o2mo/CrYnTszoAAABz; + x=-104000; y=-28000; + li:objects { + ha:line.1 { x1=160000; y1=68000; x2=160000; y2=72000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.42 { + uuid=Hif/m8o2mo/CrYnTszoAAAB8; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=92000; y=68000; + li:objects { + ha:group.1 { + uuid=Hif/m8o2mo/CrYnTszoAAAB9; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.43 { + uuid=Hif/m8o2mo/CrYnTszoAAAB+; + x=-104000; y=-28000; + li:objects { + ha:line.1 { x1=184000; y1=92000; x2=184000; y2=104000; stroke=wire; } + ha:line.2 { x1=184000; y1=104000; x2=196000; y2=104000; stroke=wire; } + ha:line.3 { x1=196000; y1=104000; x2=196000; y2=96000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.46 { + uuid=Hif/m8o2mo/CrYnTszoAAACB; src_uuid=iNOQfJpO6hT/HFDFGjoAAABv; + x=80000; y=40000; rot=180.000000; + li:objects { + ha:group.1 { + uuid=Hif/m8o2mo/CrYnTszoAAACC; src_uuid=iNOQfJpO6hT/HFDFGjoAAABw; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=6000; y1=7000; x2=18000; y2=10000; rot=180.000000; halign=center; dyntext=1; stroke=sym-primary; text=%../A.rail%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:forge { + delete,forge/tmp + scalar,forge/tmp + {sub,^,1:,forge/tmp} + suba,$,rail,forge/tmp + array,connect + append,connect,forge/tmp + } + rail=Vneg + role=symbol + } + } + ha:group.47 { + uuid=Hif/m8o2mo/CrYnTszoAAACD; + x=-104000; y=-28000; + li:objects { + ha:line.1 { x1=184000; y1=72000; x2=184000; y2=68000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.50 { + uuid=guptF1eHUCXR7MoVgJUAAAA2; src_uuid=TeGEOMuew6iCb2kzckAAAAAD; + x=8000; y=56000; + li:objects { + ha:text.1 { x1=2000; y1=-4000; dyntext=0; stroke=sym-decor; text=raw spice; } + ha:text.2 { x1=2000; y1=-8000; dyntext=0; stroke=sym-decor; text=command; } + ha:polygon.3 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=-10000; } + ha:line { x1=0; y1=-10000; x2=12000; y2=-10000; } + ha:line { x1=12000; y1=-10000; x2=12000; y2=0; } + ha:line { x1=12000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + } + ha:attrib { + -sym-comment={ Fill in spice/command and use export_spice (e.g. the spice_raw view) to get that string exported at the end of the spice netlist file. } + -sym-copyright=(C) 2023 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + role=symbol + spice/command={print dc v(in) v(out) +dc V1 -50m 60m 2m > plot.txt +} + } + } + ha:group.51 { + uuid=XFxbV/afs+qvJqWppTgAAABB; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB0; + x=12000; y=104000; rot=270.000000; mirx=1; + li:objects { + ha:group.1 { + uuid=XFxbV/afs+qvJqWppTgAAABC; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB1; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=N + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.2 { + uuid=XFxbV/afs+qvJqWppTgAAABD; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB2; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=P + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:arc.3 { cx=10000; cy=0; r=6000; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:line.4 { x1=7000; y1=2000; x2=7000; y2=-2000; stroke=sym-decor; } + ha:line.5 { x1=5000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=11000; y1=0; x2=15000; y2=0; stroke=sym-decor; } + ha:text.7 { x1=0; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:text.8 { x1=0; y1=4000; dyntext=1; stroke=sym-secondary; text=%../A.spice/params%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=V1 + role=symbol + spice/params=dc 0 + } + } + ha:group.54 { + uuid=XFxbV/afs+qvJqWppTgAAABE; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB0; + x=56000; y=64000; rot=270.000000; mirx=1; + li:objects { + ha:group.1 { + uuid=XFxbV/afs+qvJqWppTgAAABF; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB1; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=N + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.2 { + uuid=XFxbV/afs+qvJqWppTgAAABG; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB2; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=P + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:arc.3 { cx=10000; cy=0; r=6000; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:line.4 { x1=7000; y1=2000; x2=7000; y2=-2000; stroke=sym-decor; } + ha:line.5 { x1=5000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=11000; y1=0; x2=15000; y2=0; stroke=sym-decor; } + ha:text.7 { x1=0; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:text.8 { x1=0; y1=4000; dyntext=1; stroke=sym-secondary; text=%../A.spice/params%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=V2 + role=symbol + spice/params=dc 5 + } + } + ha:group.57 { + uuid=XFxbV/afs+qvJqWppTgAAABH; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB0; + x=80000; y=64000; rot=270.000000; mirx=1; + li:objects { + ha:group.1 { + uuid=XFxbV/afs+qvJqWppTgAAABI; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB1; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=N + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.2 { + uuid=XFxbV/afs+qvJqWppTgAAABJ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB2; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=P + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:arc.3 { cx=10000; cy=0; r=6000; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:line.4 { x1=7000; y1=2000; x2=7000; y2=-2000; stroke=sym-decor; } + ha:line.5 { x1=5000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=11000; y1=0; x2=15000; y2=0; stroke=sym-decor; } + ha:text.7 { x1=0; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:text.8 { x1=0; y1=4000; dyntext=1; stroke=sym-secondary; text=%../A.spice/params%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=V3 + role=symbol + spice/params=dc 5 + } + } + ha:connection.89 { + li:conn { + /2/29/1 + /2/28/1/1 + } + } + ha:connection.90 { + li:conn { + /2/35/1 + /2/33/1/1 + } + } + ha:connection.91 { + li:conn { + /2/38/1 + /2/34/1/1 + } + } + ha:connection.93 { + li:conn { + /2/43/3 + /2/42/1/1 + } + } + ha:connection.94 { + li:conn { + /2/47/1 + /2/46/1/1 + } + } + ha:connection.95 { + li:conn { + /2/51/1/1 + /2/29/1 + } + } + ha:connection.96 { + li:conn { + /2/51/2/1 + /2/12/3 + } + } + ha:connection.97 { + li:conn { + /2/54/1/1 + /2/38/1 + } + } + ha:connection.98 { + li:conn { + /2/54/2/1 + /2/35/1 + } + } + ha:connection.99 { + li:conn { + /2/57/1/1 + /2/47/1 + } + } + ha:connection.100 { + li:conn { + /2/57/2/1 + /2/43/1 + } + } + ha:connection.102 { + li:conn { + /2/3/2/1 + /2/12/1 + } + } + ha:connection.103 { + li:conn { + /2/4/1 + /2/3/1/1 + } + } + ha:connection.104 { + li:conn { + /2/7/2/1 + /2/4/4 + } + } + ha:connection.105 { + li:conn { + /2/9/1 + /2/7/1/1 + } + } + ha:connection.106 { + li:conn { + /2/9/3 + /2/2/3/1 + } + } + ha:connection.107 { + li:conn { + /2/15/1 + /2/14/1/1 + } + } + ha:connection.108 { + li:conn { + /2/19/1 + /2/18/1/1 + } + } + ha:connection.109 { + li:conn { + /2/19/1 + /2/2/11/1 + } + } + ha:connection.110 { + li:conn { + /2/23/1 + /2/2/10/1 + } + } + ha:connection.111 { + li:conn { + /2/23/1 + /2/22/1/1 + } + } + } + ha:attrib { + maintainer=Tibor 'Igor2' Palinkas + page=1 of 1 + print_page=A/4 + title={SIM raw spice: ompamp circuit, dc gain} + } + } +} Index: tags/1.0.5/doc/tutorial/simulation/raw/gnucap/18_opamp_ac.rs =================================================================== --- tags/1.0.5/doc/tutorial/simulation/raw/gnucap/18_opamp_ac.rs (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/raw/gnucap/18_opamp_ac.rs (revision 10414) @@ -0,0 +1,1558 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + ha:group.1 { + uuid=Hif/m8o2mo/CrYnTszoAAAAV; + li:objects { + ha:group.1 { + uuid=Hif/m8o2mo/CrYnTszoAAAAW; loclib_name=lm358_so8; + li:objects { + } + ha:attrib { + footprint=so(8) + li:portmap { + {1/in- -> pcb/pinnum=2} + {1/in+ -> pcb/pinnum=3} + {1/out -> pcb/pinnum=1} + {1/V+ -> pcb/pinnum=8} + {1/V- -> pcb/pinnum=4} + {2/in- -> pcb/pinnum=6} + {2/in+ -> pcb/pinnum=5} + {2/out -> pcb/pinnum=7} + {2/V+ -> pcb/pinnum=8} + {2/V- -> pcb/pinnum=4} + } + } + } + } + ha:attrib { + ha:purpose = { value=devmap; prio=0; } + } + } + ha:group.2 { + uuid=1ufQxkEY+kLwRSZVvqoAAABQ; + li:objects { + ha:group.1 { + uuid=1ufQxkEY+kLwRSZVvqoAAABR; loclib_name=lm358; + li:objects { + } + ha:attrib { + spice/model_card={* lm358 - low power opamp model (single slot) +* +* (C) 2023 Tibor 'Igor2' Palinkas +* License: CC0 (no rights reserved): https://creativecommons.org/publicdomain/zero/1.0/ +* Source: from ST's datasheet: https://archive.org/details/st-ts321 +* (st321 is reasonably close to lm358 for simple simulation cases; see +* warnings on page 7) +* +* +** CONNECTIONS: +* 1 inverting input +* 2 non-inverting INPUT +* 3 output +* 4 positive power supply +* 5 negative power supply +.SUBCKT LM358 1 2 3 4 5 + +.MODEL MDTH D IS=1E-8 KF=3.104131E-15 CJO=10F + +* INPUT STAGE +CIP 2 5 1.000000E-12 +CIN 1 5 1.000000E-12 +EIP 10 5 2 5 1 +EIN 16 5 1 5 1 +RIP 10 11 2.600000E+01 +RIN 15 16 2.600000E+01 +RIS 11 15 2.003862E+02 +DIP 11 12 MDTH 400E-12 +DIN 15 14 MDTH 400E-12 +VOFP 12 13 DC 0 +VOFN 13 14 DC 0 +IPOL 13 5 1.000000E-05 +CPS 11 15 3.783376E-09 +DINN 17 13 MDTH 400E-12 +VIN 17 5 0.000000e+00 +DINR 15 18 MDTH 400E-12 +VIP 4 18 2.000000E+00 +FCP 4 5 VOFP 3.400000E+01 +FCN 5 4 VOFN 3.400000E+01 +FIBP 2 5 VOFN 2.000000E-03 +FIBN 5 1 VOFP 2.000000E-03 + +* AMPLIFYING STAGE +FIP 5 19 VOFP 3.600000E+02 +FIN 5 19 VOFN 3.600000E+02 +RG1 19 5 3.652997E+06 +RG2 19 4 3.652997E+06 +CC 19 5 6.000000E-09 +DOPM 19 22 MDTH 400E-12 +DONM 21 19 MDTH 400E-12 +HOPM 22 28 VOUT 7.500000E+03 +VIPM 28 4 1.500000E+02 +HONM 21 27 VOUT 7.500000E+03 +VINM 5 27 1.500000E+02 +EOUT 26 23 19 5 1 +VOUT 23 5 0 +ROUT 26 3 20 +COUT 3 5 1.000000E-12 +DOP 19 25 MDTH 400E-12 +VOP 4 25 2.242230E+00 +DON 24 19 MDTH 400E-12 +VON 24 5 7.922301E-01 +.ENDS +} + } + } + } + ha:attrib { + ha:purpose = { value=spicelib; prio=0; } + } + } + } + } + ha:obj_direct.2 { + uuid=Hif/m8o2mo/CrYnTszoAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.1 { + uuid=8/SYZ/pfBzxyqFA12WQAAAAC; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAg; + li:objects { + ha:polygon.11 { + li:outline { + ha:line { x1=0; y1=0; x2=80000; y2=0; } + ha:line { x1=80000; y1=0; x2=80000; y2=20000; } + ha:line { x1=80000; y1=20000; x2=0; y2=20000; } + ha:line { x1=0; y1=20000; x2=0; y2=0; } + } + stroke=titlebox-frame; + fill=titlebox-fill; + } + ha:line.12 { x1=0; y1=10000; x2=80000; y2=10000; stroke=titlebox-frame; } + ha:line.13 { x1=40000; y1=10000; x2=40000; y2=0; stroke=titlebox-frame; } + ha:text.20 { x1=1000; y1=16500; dyntext=0; stroke=titlebox-big; text=TITLE; } + ha:text.21 { x1=1000; y1=10500; x2=79000; y2=16000; dyntext=1; stroke=titlebox-big; text=%../../A.title%; } + ha:text.22 { x1=1000; y1=5500; dyntext=0; stroke=titlebox-small; text={PROJECT:}; } + ha:text.23 { x1=13000; y1=5500; x2=39000; y2=9500; dyntext=1; stroke=titlebox-big; text=%project.name%; } + ha:text.24 { x1=1000; y1=500; dyntext=0; stroke=titlebox-small; text={PAGE:}; } + ha:text.25 { x1=10000; y1=500; x2=39000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.page%; } + ha:text.26 { x1=41000; y1=5500; dyntext=0; stroke=titlebox-small; text={FILE:}; } + ha:text.27 { x1=48000; y1=5500; x2=79000; y2=9500; dyntext=1; stroke=titlebox-big; text=%filename%; } + ha:text.28 { x1=41000; y1=500; dyntext=0; stroke=titlebox-small; text={MAINTAINER:}; } + ha:text.29 { x1=55000; y1=500; x2=79000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.maintainer%; } + } + ha:attrib { + purpose=titlebox + } + } + ha:group.2 { + uuid=Hif/m8o2mo/CrYnTszoAAAAP; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAH; + x=116000; y=116000; + li:objects { + ha:group.1 { + uuid=Hif/m8o2mo/CrYnTszoAAAAQ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAI; + x=-20000; y=4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=in+ + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.2 { + uuid=Hif/m8o2mo/CrYnTszoAAAAR; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAJ; + x=-20000; y=-4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=in- + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:group.3 { + uuid=Hif/m8o2mo/CrYnTszoAAAAS; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAK; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=out + role=terminal + ha:spice/pinnum = { value=3; prio=31050; } + } + } + ha:line.4 { x1=-20000; y1=-8000; x2=-20000; y2=8000; stroke=sym-decor; } + ha:line.5 { x1=-20000; y1=8000; x2=-4000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=-4000; y1=0; x2=-20000; y2=-8000; stroke=sym-decor; } + ha:line.7 { x1=-18000; y1=5000; x2=-18000; y2=3000; stroke=sym-decor; } + ha:line.8 { x1=-19000; y1=4000; x2=-17000; y2=4000; stroke=sym-decor; } + ha:line.9 { x1=-19000; y1=-4000; x2=-17000; y2=-4000; stroke=sym-decor; } + ha:group.10 { + uuid=Hif/m8o2mo/CrYnTszoAAAAT; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAL; + x=-12000; y=-4000; rot=270.000000; mirx=1; miry=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=0; y1=-1000; rot=180.000000; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=V- + role=terminal + ha:spice/pinnum = { value=5; prio=31050; } + spice/shared=yes + } + } + ha:group.11 { + uuid=Hif/m8o2mo/CrYnTszoAAAAU; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAM; + x=-12000; y=8000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=-4000; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=V+ + role=terminal + ha:spice/pinnum = { value=4; prio=31050; } + spice/shared=yes + } + } + ha:text.12 { x1=-21000; y1=9000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:text.13 { x1=-17000; y1=9000; dyntext=1; stroke=sym-secondary; text=%../A.-slot%; floater=1; } + ha:text.14 { x1=-8000; y1=4000; dyntext=1; stroke=sym-secondary; text=%../A.devmap%; floater=1; } + } + ha:attrib { + -slot=1 + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + devmap=lm358_so8 + name=U1 + role=symbol + spice/model=lm358 + } + } + ha:group.3 { + uuid=Hif/m8o2mo/CrYnTszoAAAAd; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=60000; y=120000; + li:objects { + ha:group.1 { + uuid=Hif/m8o2mo/CrYnTszoAAAAe; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=Hif/m8o2mo/CrYnTszoAAAAf; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=R2 + role=symbol + value=1600 + } + } + ha:group.7 { + uuid=Hif/m8o2mo/CrYnTszoAAAAk; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=48000; y=104000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=Hif/m8o2mo/CrYnTszoAAAAl; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=Hif/m8o2mo/CrYnTszoAAAAm; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=-6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=-6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=R3 + role=symbol + value=800 + } + } + ha:group.12 { + uuid=Hif/m8o2mo/CrYnTszoAAAAo; + x=-12000; y=0; + li:objects { + ha:line.1 { x1=36000; y1=120000; x2=24000; y2=120000; stroke=wire; } + ha:text.2 { x1=28000; y1=120000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + ha:line.5 { x1=24000; y1=108000; x2=36000; y2=108000; stroke=wire; } + ha:line.6 { x1=24000; y1=108000; x2=24000; y2=108000; stroke=junction; } + ha:line.7 { x1=24000; y1=68000; x2=24000; y2=120000; stroke=wire; } + } + ha:attrib { + name=in + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.18 { + uuid=Hif/m8o2mo/CrYnTszoAAAA8; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB6; + x=104000; y=128000; + li:objects { + ha:group.1 { + uuid=Hif/m8o2mo/CrYnTszoAAAA9; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB7; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-4000; y1=4000; x2=4000; y2=7000; halign=center; dyntext=0; stroke=sym-primary; text=Vcc; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:Vcc} + } + role=symbol + } + } + ha:group.19 { + uuid=Hif/m8o2mo/CrYnTszoAAAA+; + x=16000; y=0; + li:objects { + ha:line.1 { x1=88000; y1=124000; x2=88000; y2=128000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.22 { + uuid=Hif/m8o2mo/CrYnTszoAAABH; src_uuid=iNOQfJpO6hT/HFDFGjoAAABv; + x=104000; y=104000; rot=180.000000; + li:objects { + ha:group.1 { + uuid=Hif/m8o2mo/CrYnTszoAAABI; src_uuid=iNOQfJpO6hT/HFDFGjoAAABw; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=6000; y1=7000; x2=18000; y2=10000; rot=180.000000; halign=center; dyntext=1; stroke=sym-primary; text=%../A.rail%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:forge { + delete,forge/tmp + scalar,forge/tmp + {sub,^,1:,forge/tmp} + suba,$,rail,forge/tmp + array,connect + append,connect,forge/tmp + } + rail=Vneg + role=symbol + } + } + ha:group.23 { + uuid=Hif/m8o2mo/CrYnTszoAAABJ; + x=16000; y=0; + li:objects { + ha:line.1 { x1=88000; y1=104000; x2=88000; y2=108000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.28 { + uuid=Hif/m8o2mo/CrYnTszoAAABh; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=12000; y=44000; + li:objects { + ha:group.1 { + uuid=Hif/m8o2mo/CrYnTszoAAABi; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.29 { + uuid=Hif/m8o2mo/CrYnTszoAAABj; + x=-12000; y=-36000; + li:objects { + ha:line.1 { x1=24000; y1=80000; x2=24000; y2=84000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.33 { + uuid=Hif/m8o2mo/CrYnTszoAAABs; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB6; + x=92000; y=36000; + li:objects { + ha:group.1 { + uuid=Hif/m8o2mo/CrYnTszoAAABt; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB7; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-4000; y1=4000; x2=4000; y2=7000; halign=center; dyntext=0; stroke=sym-primary; text=Vcc; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:Vcc} + } + role=symbol + } + } + ha:group.34 { + uuid=Hif/m8o2mo/CrYnTszoAAABw; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=92000; y=8000; + li:objects { + ha:group.1 { + uuid=Hif/m8o2mo/CrYnTszoAAABx; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.35 { + uuid=Hif/m8o2mo/CrYnTszoAAABy; + x=-68000; y=-60000; + li:objects { + ha:line.1 { x1=160000; y1=92000; x2=160000; y2=96000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.38 { + uuid=Hif/m8o2mo/CrYnTszoAAABz; + x=-68000; y=-60000; + li:objects { + ha:line.1 { x1=160000; y1=68000; x2=160000; y2=72000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.42 { + uuid=Hif/m8o2mo/CrYnTszoAAAB8; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=128000; y=36000; + li:objects { + ha:group.1 { + uuid=Hif/m8o2mo/CrYnTszoAAAB9; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.43 { + uuid=Hif/m8o2mo/CrYnTszoAAAB+; + x=-68000; y=-60000; + li:objects { + ha:line.1 { x1=184000; y1=92000; x2=184000; y2=100000; stroke=wire; } + ha:line.2 { x1=184000; y1=100000; x2=196000; y2=100000; stroke=wire; } + ha:line.3 { x1=196000; y1=100000; x2=196000; y2=96000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.46 { + uuid=Hif/m8o2mo/CrYnTszoAAACB; src_uuid=iNOQfJpO6hT/HFDFGjoAAABv; + x=116000; y=8000; rot=180.000000; + li:objects { + ha:group.1 { + uuid=Hif/m8o2mo/CrYnTszoAAACC; src_uuid=iNOQfJpO6hT/HFDFGjoAAABw; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=6000; y1=7000; x2=18000; y2=10000; rot=180.000000; halign=center; dyntext=1; stroke=sym-primary; text=%../A.rail%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:forge { + delete,forge/tmp + scalar,forge/tmp + {sub,^,1:,forge/tmp} + suba,$,rail,forge/tmp + array,connect + append,connect,forge/tmp + } + rail=Vneg + role=symbol + } + } + ha:group.47 { + uuid=Hif/m8o2mo/CrYnTszoAAACD; + x=-68000; y=-60000; + li:objects { + ha:line.1 { x1=184000; y1=72000; x2=184000; y2=68000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.50 { + uuid=guptF1eHUCXR7MoVgJUAAAA2; src_uuid=TeGEOMuew6iCb2kzckAAAAAD; + x=36000; y=40000; + li:objects { + ha:text.1 { x1=2000; y1=-4000; dyntext=0; stroke=sym-decor; text=raw spice; } + ha:text.2 { x1=2000; y1=-8000; dyntext=0; stroke=sym-decor; text=command; } + ha:polygon.3 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=-10000; } + ha:line { x1=0; y1=-10000; x2=12000; y2=-10000; } + ha:line { x1=12000; y1=-10000; x2=12000; y2=0; } + ha:line { x1=12000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + } + ha:attrib { + -sym-comment={ Fill in spice/command and use export_spice (e.g. the spice_raw view) to get that string exported at the end of the spice netlist file. } + -sym-copyright=(C) 2023 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + role=symbol + spice/command={print ac vdb(out) zp(out) +op +ac dec 10 1 1000k > plot.txt} + } + } + ha:group.51 { + uuid=XFxbV/afs+qvJqWppTgAAABB; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB0; + x=12000; y=68000; rot=270.000000; mirx=1; + li:objects { + ha:group.1 { + uuid=XFxbV/afs+qvJqWppTgAAABC; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB1; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=N + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.2 { + uuid=XFxbV/afs+qvJqWppTgAAABD; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB2; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=P + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:arc.3 { cx=10000; cy=0; r=6000; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:line.4 { x1=7000; y1=2000; x2=7000; y2=-2000; stroke=sym-decor; } + ha:line.5 { x1=5000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=11000; y1=0; x2=15000; y2=0; stroke=sym-decor; } + ha:text.7 { x1=0; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:text.8 { x1=0; y1=4000; dyntext=1; stroke=sym-secondary; text=%../A.spice/params%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=V1 + role=symbol + spice/params=dc 0 ac 0.1 + } + } + ha:group.54 { + uuid=XFxbV/afs+qvJqWppTgAAABE; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB0; + x=92000; y=32000; rot=270.000000; mirx=1; + li:objects { + ha:group.1 { + uuid=XFxbV/afs+qvJqWppTgAAABF; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB1; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=N + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.2 { + uuid=XFxbV/afs+qvJqWppTgAAABG; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB2; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=P + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:arc.3 { cx=10000; cy=0; r=6000; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:line.4 { x1=7000; y1=2000; x2=7000; y2=-2000; stroke=sym-decor; } + ha:line.5 { x1=5000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=11000; y1=0; x2=15000; y2=0; stroke=sym-decor; } + ha:text.7 { x1=0; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:text.8 { x1=0; y1=4000; dyntext=1; stroke=sym-secondary; text=%../A.spice/params%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=V2 + role=symbol + spice/params=dc 5 + } + } + ha:group.57 { + uuid=XFxbV/afs+qvJqWppTgAAABH; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB0; + x=116000; y=32000; rot=270.000000; mirx=1; + li:objects { + ha:group.1 { + uuid=XFxbV/afs+qvJqWppTgAAABI; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB1; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=N + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.2 { + uuid=XFxbV/afs+qvJqWppTgAAABJ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB2; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=P + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:arc.3 { cx=10000; cy=0; r=6000; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:line.4 { x1=7000; y1=2000; x2=7000; y2=-2000; stroke=sym-decor; } + ha:line.5 { x1=5000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=11000; y1=0; x2=15000; y2=0; stroke=sym-decor; } + ha:text.7 { x1=0; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:text.8 { x1=0; y1=4000; dyntext=1; stroke=sym-secondary; text=%../A.spice/params%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=V3 + role=symbol + spice/params=dc 5 + } + } + ha:connection.125 { + li:conn { + /2/3/1/1 + /2/197/2 + } + } + ha:group.132 { + uuid=GePylIY1T4cR3zcyR1kAAAA7; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=24000; y=120000; + li:objects { + ha:group.1 { + uuid=GePylIY1T4cR3zcyR1kAAAA8; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=GePylIY1T4cR3zcyR1kAAAA9; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=R1 + role=symbol + value=1600 + } + } + ha:group.142 { + uuid=GePylIY1T4cR3zcyR1kAAABQ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAH; + x=92000; y=72000; mirx=1; + li:objects { + ha:group.1 { + uuid=GePylIY1T4cR3zcyR1kAAABR; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAI; + x=-20000; y=4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=in+ + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.2 { + uuid=GePylIY1T4cR3zcyR1kAAABS; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAJ; + x=-20000; y=-4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=in- + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:group.3 { + uuid=GePylIY1T4cR3zcyR1kAAABT; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAK; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=out + role=terminal + ha:spice/pinnum = { value=3; prio=31050; } + } + } + ha:line.4 { x1=-20000; y1=-8000; x2=-20000; y2=8000; stroke=sym-decor; } + ha:line.5 { x1=-20000; y1=8000; x2=-4000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=-4000; y1=0; x2=-20000; y2=-8000; stroke=sym-decor; } + ha:line.7 { x1=-18000; y1=5000; x2=-18000; y2=3000; stroke=sym-decor; } + ha:line.8 { x1=-19000; y1=4000; x2=-17000; y2=4000; stroke=sym-decor; } + ha:line.9 { x1=-19000; y1=-4000; x2=-17000; y2=-4000; stroke=sym-decor; } + ha:group.10 { + uuid=GePylIY1T4cR3zcyR1kAAABU; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAL; + x=-12000; y=-4000; rot=270.000000; mirx=1; miry=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=0; y1=-1000; rot=180.000000; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=V- + role=terminal + ha:spice/pinnum = { value=5; prio=31050; } + spice/shared=yes + } + } + ha:group.11 { + uuid=GePylIY1T4cR3zcyR1kAAABV; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAM; + x=-12000; y=8000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=-4000; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=V+ + role=terminal + ha:spice/pinnum = { value=4; prio=31050; } + spice/shared=yes + } + } + ha:text.12 { x1=-21000; y1=9000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:text.13 { x1=-17000; y1=9000; dyntext=1; stroke=sym-secondary; text=%../A.-slot%; floater=1; } + ha:text.14 { x1=-10000; y1=6000; dyntext=1; stroke=sym-secondary; text=%../A.devmap%; floater=1; } + } + ha:attrib { + -slot=2 + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + devmap=lm358_so8 + name=U1 + role=symbol + spice/model=lm358 + } + } + ha:group.146 { + uuid=GePylIY1T4cR3zcyR1kAAABX; + x=4000; y=0; + li:objects { + ha:line.1 { x1=112000; y1=76000; x2=124000; y2=76000; stroke=wire; } + ha:line.2 { x1=124000; y1=84000; x2=124000; y2=72000; stroke=wire; } + ha:line.3 { x1=124000; y1=76000; x2=124000; y2=76000; stroke=junction; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.147 { + li:conn { + /2/146/1 + /2/142/1/1 + } + } + ha:group.148 { + uuid=GePylIY1T4cR3zcyR1kAAABb; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=128000; y=104000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=GePylIY1T4cR3zcyR1kAAABc; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=GePylIY1T4cR3zcyR1kAAABd; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=R4 + role=symbol + value=250 + } + } + ha:group.149 { + uuid=GePylIY1T4cR3zcyR1kAAABh; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=128000; y=72000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=GePylIY1T4cR3zcyR1kAAABi; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=GePylIY1T4cR3zcyR1kAAABj; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=R5 + role=symbol + value=10k + } + } + ha:group.157 { + uuid=GePylIY1T4cR3zcyR1kAAABm; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=128000; y=52000; + li:objects { + ha:group.1 { + uuid=GePylIY1T4cR3zcyR1kAAABn; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.161 { + uuid=GePylIY1T4cR3zcyR1kAAABu; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAh; + x=24000; y=108000; + li:objects { + ha:group.1 { + uuid=GePylIY1T4cR3zcyR1kAAABv; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAi; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=GePylIY1T4cR3zcyR1kAAABw; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAj; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=16000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.5 { x1=9000; y1=5000; x2=9000; y2=-5000; stroke=sym-decor; } + ha:line.6 { x1=11000; y1=5000; x2=11000; y2=-5000; stroke=sym-decor; } + ha:line.7 { x1=4000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.8 { x1=11000; y1=0; x2=16000; y2=0; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=C1 + role=symbol + value=100n + } + } + ha:connection.162 { + li:conn { + /2/12/5 + /2/161/2/1 + } + } + ha:connection.163 { + li:conn { + /2/12/1 + /2/132/2/1 + } + } + ha:group.164 { + uuid=GePylIY1T4cR3zcyR1kAAABx; + li:objects { + ha:line.1 { x1=44000; y1=108000; x2=60000; y2=108000; stroke=wire; } + ha:line.2 { x1=48000; y1=108000; x2=48000; y2=104000; stroke=wire; } + ha:line.3 { x1=48000; y1=108000; x2=48000; y2=108000; stroke=junction; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.165 { + li:conn { + /2/164/1 + /2/161/1/1 + } + } + ha:group.166 { + uuid=GePylIY1T4cR3zcyR1kAAAB1; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAh; + x=60000; y=108000; + li:objects { + ha:group.1 { + uuid=GePylIY1T4cR3zcyR1kAAAB2; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAi; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=GePylIY1T4cR3zcyR1kAAAB3; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAj; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=16000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.5 { x1=9000; y1=5000; x2=9000; y2=-5000; stroke=sym-decor; } + ha:line.6 { x1=11000; y1=5000; x2=11000; y2=-5000; stroke=sym-decor; } + ha:line.7 { x1=4000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.8 { x1=11000; y1=0; x2=16000; y2=0; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=C2 + role=symbol + value=100n + } + } + ha:group.168 { + uuid=GePylIY1T4cR3zcyR1kAAAB7; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAh; + x=56000; y=104000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=GePylIY1T4cR3zcyR1kAAAB8; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAi; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=GePylIY1T4cR3zcyR1kAAAB9; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAj; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=16000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.5 { x1=9000; y1=5000; x2=9000; y2=-5000; stroke=sym-decor; } + ha:line.6 { x1=11000; y1=5000; x2=11000; y2=-5000; stroke=sym-decor; } + ha:line.7 { x1=4000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.8 { x1=11000; y1=0; x2=16000; y2=0; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=C3 + role=symbol + value=200n + } + } + ha:connection.170 { + li:conn { + /2/2/1/1 + /2/197/2 + } + } + ha:connection.171 { + li:conn { + /2/19/1 + /2/2/11/1 + } + } + ha:connection.172 { + li:conn { + /2/19/1 + /2/18/1/1 + } + } + ha:connection.173 { + li:conn { + /2/23/1 + /2/2/10/1 + } + } + ha:connection.174 { + li:conn { + /2/23/1 + /2/22/1/1 + } + } + ha:connection.176 { + li:conn { + /2/142/3/1 + /2/189/6 + } + } + ha:connection.177 { + li:conn { + /2/148/1/1 + /2/146/2 + } + } + ha:connection.178 { + li:conn { + /2/149/2/1 + /2/146/2 + } + } + ha:connection.179 { + li:conn { + /2/157/1/1 + /2/149/1/1 + } + } + ha:connection.180 { + li:conn { + /2/164/1 + /2/166/2/1 + } + } + ha:group.181 { + uuid=GePylIY1T4cR3zcyR1kAAAB+; + li:objects { + ha:line.1 { x1=44000; y1=120000; x2=60000; y2=120000; stroke=wire; } + ha:line.2 { x1=56000; y1=104000; x2=56000; y2=120000; stroke=wire; } + ha:line.3 { x1=56000; y1=120000; x2=56000; y2=120000; stroke=junction; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.182 { + li:conn { + /2/181/1 + /2/132/1/1 + } + } + ha:connection.183 { + li:conn { + /2/181/1 + /2/3/2/1 + } + } + ha:connection.184 { + li:conn { + /2/181/2 + /2/168/2/1 + } + } + ha:connection.185 { + li:conn { + /2/164/2 + /2/7/2/1 + } + } + ha:connection.187 { + li:conn { + /2/7/1/1 + /2/189/5 + } + } + ha:connection.188 { + li:conn { + /2/168/1/1 + /2/189/7 + } + } + ha:group.189 { + uuid=GePylIY1T4cR3zcyR1kAAACA; + li:objects { + ha:line.1 { x1=120000; y1=68000; x2=116000; y2=68000; stroke=wire; } + ha:line.2 { x1=120000; y1=56000; x2=120000; y2=68000; stroke=wire; } + ha:line.4 { x1=88000; y1=56000; x2=120000; y2=56000; stroke=wire; } + ha:line.5 { x1=48000; y1=84000; x2=48000; y2=72000; stroke=wire; } + ha:line.6 { x1=48000; y1=72000; x2=92000; y2=72000; stroke=wire; } + ha:line.7 { x1=56000; y1=84000; x2=56000; y2=72000; stroke=wire; } + ha:line.8 { x1=56000; y1=72000; x2=56000; y2=72000; stroke=junction; } + ha:line.9 { x1=88000; y1=56000; x2=88000; y2=72000; stroke=wire; } + ha:line.10 { x1=88000; y1=72000; x2=88000; y2=72000; stroke=junction; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.190 { + li:conn { + /2/189/1 + /2/142/2/1 + } + } + ha:group.197 { + uuid=GePylIY1T4cR3zcyR1kAAACD; + li:objects { + ha:line.1 { x1=80000; y1=108000; x2=84000; y2=108000; stroke=wire; } + ha:line.2 { x1=80000; y1=120000; x2=92000; y2=120000; stroke=wire; } + ha:line.3 { x1=84000; y1=108000; x2=84000; y2=120000; stroke=wire; } + ha:line.4 { x1=84000; y1=120000; x2=84000; y2=120000; stroke=junction; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.198 { + li:conn { + /2/197/1 + /2/166/1/1 + } + } + ha:group.199 { + uuid=GePylIY1T4cR3zcyR1kAAACE; + li:objects { + ha:line.1 { x1=128000; y1=116000; x2=128000; y2=116000; stroke=junction; } + ha:line.2 { x1=92000; y1=92000; x2=120000; y2=92000; stroke=wire; } + ha:line.3 { x1=128000; y1=104000; x2=128000; y2=116000; stroke=wire; } + ha:line.4 { x1=116000; y1=116000; x2=136000; y2=116000; stroke=wire; } + ha:line.5 { x1=120000; y1=92000; x2=120000; y2=116000; stroke=wire; } + ha:line.6 { x1=120000; y1=116000; x2=120000; y2=116000; stroke=junction; } + ha:line.7 { x1=92000; y1=112000; x2=92000; y2=92000; stroke=wire; } + ha:text.8 { x1=131000; y1=116000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=out + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.200 { + li:conn { + /2/199/3 + /2/148/2/1 + } + } + ha:connection.201 { + li:conn { + /2/199/4 + /2/2/3/1 + } + } + ha:connection.202 { + li:conn { + /2/199/7 + /2/2/2/1 + } + } + ha:connection.203 { + li:conn { + /2/35/1 + /2/33/1/1 + } + } + ha:connection.204 { + li:conn { + /2/38/1 + /2/34/1/1 + } + } + ha:connection.205 { + li:conn { + /2/43/3 + /2/42/1/1 + } + } + ha:connection.206 { + li:conn { + /2/47/1 + /2/46/1/1 + } + } + ha:connection.207 { + li:conn { + /2/54/1/1 + /2/38/1 + } + } + ha:connection.208 { + li:conn { + /2/54/2/1 + /2/35/1 + } + } + ha:connection.209 { + li:conn { + /2/57/1/1 + /2/47/1 + } + } + ha:connection.210 { + li:conn { + /2/57/2/1 + /2/43/1 + } + } + ha:connection.219 { + li:conn { + /2/29/1 + /2/28/1/1 + } + } + ha:connection.220 { + li:conn { + /2/51/1/1 + /2/29/1 + } + } + ha:connection.221 { + li:conn { + /2/12/7 + /2/51/2/1 + } + } + } + ha:attrib { + maintainer=Tibor 'Igor2' Palinkas + page=1 of 1 + print_page=A/4 + title={SIM raw spice: notch filter with opamps, ac (for gnucap)} + } + } +} Index: tags/1.0.5/doc/tutorial/simulation/raw/gnucap/22_custom_sym.rs =================================================================== --- tags/1.0.5/doc/tutorial/simulation/raw/gnucap/22_custom_sym.rs (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/raw/gnucap/22_custom_sym.rs (revision 10414) @@ -0,0 +1,399 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=k5U87rmc6yaL/+FNsFAAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.1 { + uuid=8/SYZ/pfBzxyqFA12WQAAAAC; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAg; + li:objects { + ha:polygon.11 { + li:outline { + ha:line { x1=0; y1=0; x2=80000; y2=0; } + ha:line { x1=80000; y1=0; x2=80000; y2=20000; } + ha:line { x1=80000; y1=20000; x2=0; y2=20000; } + ha:line { x1=0; y1=20000; x2=0; y2=0; } + } + stroke=titlebox-frame; + fill=titlebox-fill; + } + ha:line.12 { x1=0; y1=10000; x2=80000; y2=10000; stroke=titlebox-frame; } + ha:line.13 { x1=40000; y1=10000; x2=40000; y2=0; stroke=titlebox-frame; } + ha:text.20 { x1=1000; y1=16500; dyntext=0; stroke=titlebox-big; text=TITLE; } + ha:text.21 { x1=1000; y1=10500; x2=79000; y2=16000; dyntext=1; stroke=titlebox-big; text=%../../A.title%; } + ha:text.22 { x1=1000; y1=5500; dyntext=0; stroke=titlebox-small; text={PROJECT:}; } + ha:text.23 { x1=13000; y1=5500; x2=39000; y2=9500; dyntext=1; stroke=titlebox-big; text=%project.name%; } + ha:text.24 { x1=1000; y1=500; dyntext=0; stroke=titlebox-small; text={PAGE:}; } + ha:text.25 { x1=10000; y1=500; x2=39000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.page%; } + ha:text.26 { x1=41000; y1=5500; dyntext=0; stroke=titlebox-small; text={FILE:}; } + ha:text.27 { x1=48000; y1=5500; x2=79000; y2=9500; dyntext=1; stroke=titlebox-big; text=%filename%; } + ha:text.28 { x1=41000; y1=500; dyntext=0; stroke=titlebox-small; text={MAINTAINER:}; } + ha:text.29 { x1=55000; y1=500; x2=79000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.maintainer%; } + } + ha:attrib { + purpose=titlebox + } + } + ha:group.10 { + uuid=k5U87rmc6yaL/+FNsFAAAAAR; + x=56000; y=60000; + li:objects { + ha:line.1 { x1=0; y1=-4000; x2=-4000; y2=-16000; stroke=sym-decor; } + ha:line.2 { x1=-4000; y1=-16000; x2=4000; y2=-16000; stroke=sym-decor; } + ha:line.3 { x1=4000; y1=-16000; x2=0; y2=-4000; stroke=sym-decor; } + ha:line.4 { x1=-4000; y1=-4000; x2=4000; y2=-4000; stroke=sym-decor; } + ha:group.5 { + uuid=k5U87rmc6yaL/+FNsFAAAAAS; src_uuid=k5U87rmc6yaL/+FNsFAAAAAD; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=C + role=terminal + spice/pinnum=2 + } + } + ha:group.6 { + uuid=k5U87rmc6yaL/+FNsFAAAAAT; src_uuid=k5U87rmc6yaL/+FNsFAAAAAD; + x=0; y=-20000; rot=270.000000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=A + role=terminal + spice/pinnum=1 + } + } + ha:polygon.7 { + li:outline { + ha:line { x1=-6000; y1=-2000; x2=-6000; y2=-18000; } + ha:line { x1=-6000; y1=-18000; x2=6000; y2=-18000; } + ha:line { x1=6000; y1=-18000; x2=6000; y2=-2000; } + ha:line { x1=6000; y1=-2000; x2=-6000; y2=-2000; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + ha:text.8 { x1=-6000; y1=-2000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + name=U1 + role=symbol + spice/model_card={.MODEL my_diode D (IS=2f RS=3.4 N=2.2)} + spice/prefix=D + } + } + ha:group.11 { + uuid=k5U87rmc6yaL/+FNsFAAAAAa; src_uuid=iNOQfJpO6hT/HFDFGjoAAABx; + x=20000; y=60000; rot=270.000000; mirx=1; + li:objects { + ha:arc.1 { cx=10000; cy=0; r=6000; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:arc.2 { cx=8000; cy=0; r=2000; sang=0.000000; dang=180.000000; stroke=sym-decor; } + ha:arc.3 { cx=12000; cy=0; r=2000; sang=180.000000; dang=180.000000; stroke=sym-decor; } + ha:group.4 { + uuid=k5U87rmc6yaL/+FNsFAAAAAb; src_uuid=iNOQfJpO6hT/HFDFGjoAAABy; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=N + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.5 { + uuid=k5U87rmc6yaL/+FNsFAAAAAc; src_uuid=iNOQfJpO6hT/HFDFGjoAAABz; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=P + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:text.6 { x1=0; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=V1 + role=symbol + spice/params=SINE(0 20 1k) + } + } + ha:group.12 { + uuid=k5U87rmc6yaL/+FNsFAAAAAd; + x=-8000; y=-32000; + li:objects { + ha:line.1 { x1=28000; y1=92000; x2=28000; y2=104000; stroke=wire; } + ha:line.3 { x1=28000; y1=104000; x2=32000; y2=104000; stroke=wire; } + ha:text.4 { x1=28000; y1=104000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=in + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.14 { + uuid=k5U87rmc6yaL/+FNsFAAAAAk; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=24000; y=72000; + li:objects { + ha:group.1 { + uuid=k5U87rmc6yaL/+FNsFAAAAAl; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=k5U87rmc6yaL/+FNsFAAAAAm; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=R1 + role=symbol + ha:spice/prefix = { value=R; prio=31050; } + value=100 + } + } + ha:group.16 { + uuid=k5U87rmc6yaL/+FNsFAAAAAn; + x=-8000; y=-32000; + li:objects { + ha:line.2 { x1=64000; y1=104000; x2=64000; y2=92000; stroke=wire; } + ha:line.3 { x1=52000; y1=104000; x2=76000; y2=104000; stroke=wire; } + ha:line.4 { x1=64000; y1=104000; x2=64000; y2=104000; stroke=junction; } + ha:text.5 { x1=72000; y1=104000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=out + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.19 { + uuid=k5U87rmc6yaL/+FNsFAAAAAs; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=20000; y=36000; + li:objects { + ha:group.1 { + uuid=k5U87rmc6yaL/+FNsFAAAAAt; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.20 { + uuid=k5U87rmc6yaL/+FNsFAAAAAu; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=56000; y=36000; + li:objects { + ha:group.1 { + uuid=k5U87rmc6yaL/+FNsFAAAAAv; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.21 { + uuid=k5U87rmc6yaL/+FNsFAAAAAw; + x=-8000; y=-32000; + li:objects { + ha:line.1 { x1=28000; y1=72000; x2=28000; y2=68000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.24 { + uuid=k5U87rmc6yaL/+FNsFAAAAAx; + x=-8000; y=-32000; + li:objects { + ha:line.1 { x1=64000; y1=72000; x2=64000; y2=68000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.27 { + li:conn { + /2/12/1 + /2/11/5/1 + } + } + ha:connection.29 { + li:conn { + /2/14/2/1 + /2/12/3 + } + } + ha:connection.30 { + li:conn { + /2/16/2 + /2/10/5/1 + } + } + ha:connection.31 { + li:conn { + /2/16/3 + /2/14/1/1 + } + } + ha:connection.32 { + li:conn { + /2/21/1 + /2/11/4/1 + } + } + ha:connection.33 { + li:conn { + /2/21/1 + /2/19/1/1 + } + } + ha:connection.34 { + li:conn { + /2/24/1 + /2/10/6/1 + } + } + ha:connection.35 { + li:conn { + /2/24/1 + /2/20/1/1 + } + } + ha:group.36 { + uuid=k5U87rmc6yaL/+FNsFAAAAA0; src_uuid=TeGEOMuew6iCb2kzckAAAAAD; + x=12000; y=96000; + li:objects { + ha:text.1 { x1=2000; y1=-4000; dyntext=0; stroke=sym-decor; text=raw spice; } + ha:text.2 { x1=2000; y1=-8000; dyntext=0; stroke=sym-decor; text=command; } + ha:polygon.3 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=-10000; } + ha:line { x1=0; y1=-10000; x2=12000; y2=-10000; } + ha:line { x1=12000; y1=-10000; x2=12000; y2=0; } + ha:line { x1=12000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + } + ha:attrib { + -sym-comment={ Fill in spice/command and use export_spice (e.g. the spice_raw view) to get that string exported at the end of the spice netlist file. } + -sym-copyright=(C) 2023 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + role=symbol + spice/command={print tran v(out) v(in) +tran 1u 4m > plot.txt} + } + } + } + ha:attrib { + maintainer=Tibor 'Igor2' Palinkas + page=1/1 + print_page=A/4 + title={raw spice: custom symbol (for gnucap)} + } + } +} Index: tags/1.0.5/doc/tutorial/simulation/sim/01_dc/01_dc.rs =================================================================== --- tags/1.0.5/doc/tutorial/simulation/sim/01_dc/01_dc.rs (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/sim/01_dc/01_dc.rs (revision 10414) @@ -0,0 +1,581 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.1 { + uuid=8/SYZ/pfBzxyqFA12WQAAAAC; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAg; + li:objects { + ha:polygon.11 { + li:outline { + ha:line { x1=0; y1=0; x2=80000; y2=0; } + ha:line { x1=80000; y1=0; x2=80000; y2=20000; } + ha:line { x1=80000; y1=20000; x2=0; y2=20000; } + ha:line { x1=0; y1=20000; x2=0; y2=0; } + } + stroke=titlebox-frame; + fill=titlebox-fill; + } + ha:line.12 { x1=0; y1=10000; x2=80000; y2=10000; stroke=titlebox-frame; } + ha:line.13 { x1=40000; y1=10000; x2=40000; y2=0; stroke=titlebox-frame; } + ha:text.20 { x1=1000; y1=16500; dyntext=0; stroke=titlebox-big; text=TITLE; } + ha:text.21 { x1=1000; y1=10500; x2=79000; y2=16000; dyntext=1; stroke=titlebox-big; text=%../../A.title%; } + ha:text.22 { x1=1000; y1=5500; dyntext=0; stroke=titlebox-small; text={PROJECT:}; } + ha:text.23 { x1=13000; y1=5500; x2=39000; y2=9500; dyntext=1; stroke=titlebox-big; text=%project.name%; } + ha:text.24 { x1=1000; y1=500; dyntext=0; stroke=titlebox-small; text={PAGE:}; } + ha:text.25 { x1=10000; y1=500; x2=39000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.page%; } + ha:text.26 { x1=41000; y1=5500; dyntext=0; stroke=titlebox-small; text={FILE:}; } + ha:text.27 { x1=48000; y1=5500; x2=79000; y2=9500; dyntext=1; stroke=titlebox-big; text=%filename%; } + ha:text.28 { x1=41000; y1=500; dyntext=0; stroke=titlebox-small; text={MAINTAINER:}; } + ha:text.29 { x1=55000; y1=500; x2=79000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.maintainer%; } + } + ha:attrib { + purpose=titlebox + } + } + ha:group.3 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAY; + x=-24000; y=-12000; + li:objects { + ha:line.1 { x1=44000; y1=116000; x2=52000; y2=116000; stroke=wire; } + ha:text.4 { x1=48000; y1=116000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=in + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.8 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAg; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=28000; y=104000; + li:objects { + ha:group.1 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAh; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAi; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=R1 + role=symbol + spice/prefix=R + value=2.2k + } + } + ha:group.14 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAz; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=52000; y=100000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=LnNTcUkV1CIzG7F2EXUAAAA0; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=LnNTcUkV1CIzG7F2EXUAAAA1; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=R2 + role=symbol + spice/prefix=R + value=1k + } + } + ha:group.24 { + uuid=LnNTcUkV1CIzG7F2EXUAAABA; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=24000; y=48000; + li:objects { + ha:group.1 { + uuid=LnNTcUkV1CIzG7F2EXUAAABB; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.37 { + uuid=XkMAnbHX1rIO2D9kjFAAAAAn; + x=-24000; y=-12000; + li:objects { + ha:line.2 { x1=76000; y1=112000; x2=76000; y2=116000; stroke=wire; } + ha:line.3 { x1=76000; y1=116000; x2=76000; y2=116000; stroke=junction; } + ha:text.4 { x1=84000; y1=116000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + ha:line.5 { x1=72000; y1=116000; x2=88000; y2=116000; stroke=wire; } + ha:line.6 { x1=88000; y1=116000; x2=88000; y2=92000; stroke=wire; } + ha:line.7 { x1=88000; y1=92000; x2=92000; y2=92000; stroke=wire; } + } + ha:attrib { + name=out1 + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.40 { + uuid=XkMAnbHX1rIO2D9kjFAAAAAr; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=52000; y=72000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=XkMAnbHX1rIO2D9kjFAAAAAs; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=XkMAnbHX1rIO2D9kjFAAAAAt; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=R3 + role=symbol + spice/prefix=R + value=1k + } + } + ha:group.42 { + uuid=XkMAnbHX1rIO2D9kjFAAAAAw; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=52000; y=48000; + li:objects { + ha:group.1 { + uuid=XkMAnbHX1rIO2D9kjFAAAAAx; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.43 { + uuid=XkMAnbHX1rIO2D9kjFAAAAAy; + x=-24000; y=-16000; + li:objects { + ha:line.1 { x1=76000; y1=64000; x2=76000; y2=68000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.49 { + uuid=XkMAnbHX1rIO2D9kjFAAAAAz; + x=-24000; y=-12000; + li:objects { + ha:line.1 { x1=76000; y1=84000; x2=76000; y2=92000; stroke=wire; } + ha:line.2 { x1=76000; y1=88000; x2=92000; y2=88000; stroke=wire; } + ha:line.3 { x1=76000; y1=88000; x2=76000; y2=88000; stroke=junction; } + ha:text.4 { x1=84000; y1=88000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=out2 + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.53 { + li:conn { + /2/8/2/1 + /2/3/1 + } + } + ha:connection.57 { + li:conn { + /2/8/1/1 + /2/37/5 + } + } + ha:connection.58 { + li:conn { + /2/37/2 + /2/14/2/1 + } + } + ha:connection.59 { + li:conn { + /2/43/1 + /2/40/1/1 + } + } + ha:connection.60 { + li:conn { + /2/43/1 + /2/42/1/1 + } + } + ha:connection.61 { + li:conn { + /2/49/1 + /2/14/1/1 + } + } + ha:connection.62 { + li:conn { + /2/49/1 + /2/40/2/1 + } + } + ha:group.63 { + uuid=YwPM9NEZm6Skk0Cu7xAAAAAe; src_uuid=YwPM9NEZm6Skk0Cu7xAAAAAb; + x=16000; y=100000; mirx=1; + li:objects { + ha:text.1 { x1=0; y1=-6000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:group.2 { + uuid=YwPM9NEZm6Skk0Cu7xAAAAAf; src_uuid=YwPM9NEZm6Skk0Cu7xAAAAAc; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:group.3 { + uuid=YwPM9NEZm6Skk0Cu7xAAAAAg; src_uuid=YwPM9NEZm6Skk0Cu7xAAAAAd; + x=0; y=4000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:polygon.4 { + li:outline { + ha:line { x1=0; y1=-2000; x2=0; y2=6000; } + ha:line { x1=0; y1=6000; x2=4000; y2=6000; } + ha:line { x1=4000; y1=6000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=0; y2=-2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + footprint=connector(1,2) + name=CN1 + role=symbol + spice/omit=yes + } + } + ha:group.64 { + uuid=YwPM9NEZm6Skk0Cu7xAAAAAp; src_uuid=YwPM9NEZm6Skk0Cu7xAAAAAl; + x=72000; y=72000; + li:objects { + ha:text.1 { x1=0; y1=-6000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:group.2 { + uuid=YwPM9NEZm6Skk0Cu7xAAAAAq; src_uuid=YwPM9NEZm6Skk0Cu7xAAAAAm; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:group.3 { + uuid=YwPM9NEZm6Skk0Cu7xAAAAAr; src_uuid=YwPM9NEZm6Skk0Cu7xAAAAAn; + x=0; y=4000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.4 { + uuid=YwPM9NEZm6Skk0Cu7xAAAAAs; src_uuid=YwPM9NEZm6Skk0Cu7xAAAAAo; + x=0; y=8000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=3 + role=terminal + } + } + ha:polygon.5 { + li:outline { + ha:line { x1=0; y1=-2000; x2=0; y2=10000; } + ha:line { x1=0; y1=10000; x2=4000; y2=10000; } + ha:line { x1=4000; y1=10000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=0; y2=-2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + footprint=connector(3,1) + name=CN2 + role=symbol + spice/omit=yes + } + } + ha:connection.65 { + li:conn { + /2/63/3/1 + /2/3/1 + } + } + ha:group.66 { + uuid=YwPM9NEZm6Skk0Cu7xAAAAAt; + li:objects { + ha:line.1 { x1=20000; y1=100000; x2=24000; y2=100000; stroke=wire; } + ha:line.2 { x1=24000; y1=100000; x2=24000; y2=48000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.67 { + li:conn { + /2/66/1 + /2/63/2/1 + } + } + ha:connection.69 { + li:conn { + /2/37/7 + /2/64/4/1 + } + } + ha:connection.70 { + li:conn { + /2/49/2 + /2/64/3/1 + } + } + ha:group.71 { + uuid=YwPM9NEZm6Skk0Cu7xAAAAAw; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=64000; y=48000; + li:objects { + ha:group.1 { + uuid=YwPM9NEZm6Skk0Cu7xAAAAAx; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.72 { + uuid=YwPM9NEZm6Skk0Cu7xAAAAAy; + li:objects { + ha:line.1 { x1=64000; y1=48000; x2=64000; y2=72000; stroke=wire; } + ha:line.2 { x1=64000; y1=72000; x2=68000; y2=72000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.73 { + li:conn { + /2/72/1 + /2/71/1/1 + } + } + ha:connection.74 { + li:conn { + /2/72/2 + /2/64/2/1 + } + } + ha:connection.75 { + li:conn { + /2/66/2 + /2/24/1/1 + } + } + } + ha:attrib { + maintainer=Tibor 'Igor2' Palinkas + page=1 of 1 + print_page=A/4 + title={high level SIM: DC operating point} + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 2 + grid = 4.0960 mm + } + } + } +} Index: tags/1.0.5/doc/tutorial/simulation/sim/01_dc/01_dc.svg =================================================================== --- tags/1.0.5/doc/tutorial/simulation/sim/01_dc/01_dc.svg (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/sim/01_dc/01_dc.svg (revision 10414) @@ -0,0 +1,592 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/1.0.5/doc/tutorial/simulation/sim/01_dc/index.html =================================================================== --- tags/1.0.5/doc/tutorial/simulation/sim/01_dc/index.html (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/sim/01_dc/index.html (revision 10414) @@ -0,0 +1,227 @@ + + +

01_dc: sheet preparation and DC op point

+ +

Scope

+

+In this simulation we are going to calculate the DC operating point of a +simple voltage divider. This is also an introduction to setting up a +sheet for circuit simulation and setting up the high level simulation +infrastructure. + +

The schematics

+

+The single-sheet schematic contains the voltage divider with all networks +named. There are no extra symbols for the simulation, the circuit is in its +original form, as designed for the PCB workflow. +

+

+ +
Click the image to get the sch-rnd sheet; also requires this project.lht in the same directory
+

+ +

SPICE: what is a DC op point

+

+In SPICE simulation there are different analysis options available: these +are different simulation actions or operations or modes. Basically each +analysis is a different algorithm to run on the circuit. The simplest +analysis is called the "DC operating point analysis". +

+In the op point analysis, the simulator will apply all sources, assume +all inductors are shorted and assume all capacitors are open and then calculate +the voltage for all nodes. (Node is the spice terminology for an equipotential +electrical network.) This simulation is not time or frequency dependent, and +represents a single DC operating point once the circuit has already stabilized. +

+In our example, this means 5V would be applied at CN1 then out1 and +out2 are calculated. Since our voltage sources are ideal and capable of supplying +any amount of current, the voltage on the in network will be 5V; but the +voltages on out1 and out2 will depend on the resistor values of R1, R2 and R3. + + +

Preparing for simulation

+ +

Symbols and nets

+

+Draw the schematics as usual; make sure there is a gnd network, spice won't +work without that. Ideally, use the stock gnd symbol for that. Make sure +all resistors have a unique name and a value. Spice understands the normal +SI suffixes such as k for kilo, but as it is generally not case sensitive, +m and M are both milli, so you will need to write meg to get mega. +

+Your symbols also need to have the proper spice pin numbers. First switch +your view from the default pcb to sim_ngspice: there's a button for this on +the top right part of the main window, on the left of the help/support button. +This pops up a view selector; click sim_ngspice twice and the selector will close +and the view will change. The new view will show pin numbers as seen by the +spice target. For plain resistors, pin ordering does not matter, but it is +important for polarized parts like diodes, transistors, and sources. The +stock library has spice pin numbers set up and should work without +modification. Later chapters of this tutorial will explain how to deal with +spice pin numbers in symbols. +

+Using the sim_ngspice view CN1 and CN2 are crossed out with red. This means +these symbols are not exported: spice can not simulate connectors. This happens +because the attribute spice/omit is set to yes on these symbols. The stock +library has spice/omit set on mechanical symbols. +

+The message log also has an error message saying that modifications could +not be applied to the sim setup because there is no active simulation setup. +This is normal when sim_ngspice is manually selected, which is the rare case. +Normally a simulation setup is activated from the simulation setup dialog and +that configures everything properly. + +

Opening the simulation setup dialog

+

+High level simulation needs to store a lot of simualtion-specific configuration: +different simulation setups, different output (e.g. plot) options. Since +many real life designs use multiple sheets, these can not be stored on the sheet +level but has to be stored on the project level. Thus the high level sim +feature always operates on the project level and always stores configuration +in the project file, project.lht. This is true even on the single sheet case. +

+The dialog box for the high levle sim feature is accessible through the +File menu, Project... submenu, Circuit simulation submenu. This opens the +Simulation selector dialog, presenting a set of different simulation +setups (or sim setups for short). Different sim setups will simulate +

    +
  • different subsets of the circuit +
  • with different stimulus +
  • using different networks for the output +
  • doing different presentation of those results +
+

+A typical use case is to have a sim setup for evaluating the board in the +simplest DC case and a few other sim setups exploring how the circuit works +with different AC stimulus. Another typical use case is to take a complex +circuit apart and simulate different stages separately - this can be done +without adding any extra symbols or other clutter in the drawing, only by +high level sim configuration. +

+In this example, and in most of the examples, there would be only one +simulation, to keep things simple. Click on that one item on the list to +select it and click the Open... button. (This sim setup was once created +by clicking the New... button, which asked for a name for the new sim +setup, created it blank, and then opened the same sim setup dialog described +below.). Sim setup names are arbitrary user assigned strings, only to help +the user remember which sim setup is for what (sch-rnd is not basing any +decision on the name). +

+This opens the simulation setup dialog for the selected sim setup. +

+

+ +
Simulation setup dialog, with 3 tabs
+

+The sim setup dialog has 3 tabs and a control block on the bottom. Each +tab is configuring an important aspect of the given simulation setup +and is going to be described in detail below. + +

Sim setup: test bench & modifications

+

+The first tab defines the circuit that is going to be simulated: +

    +
  • "test bench to use" can limit the scope, picking parts of the circuit + to include int he simulation, omitting other parts; for this example + and for most of these simple examples in the tutorial we are going with + "whole circuit" (instead of partial circuit simulation) +
  • "modifications" is a table that lists modifications to be performed on + the circuit's abstract model before the simulation. All the tutorial + examples heavily depend on this feature. +
+

+This is equvalent to the process of physical testing of a circuit: +once the basic circuit is built as documented by the schematics, optionally +a part of it is isolated for testing (this is called test benching in sch-rnd) +and external stimulus, probes and sometimes artifical connections or loading +resistors and alike are added for the measurement (this is the modifications +part). +

+Select the only item in the modifications tableand click the Edit button. This +opens the modification editor that shows: +

    +
  • this modification is going to add... +
  • ... a voltage source (V) +
  • connected between CN1-2 and GND (it doesn't matter that CN1 is omitted + from the export, the connection is really made to networks and CN1 is only + used to look up the nets to connect the new voltage source to); since the + negative pole is not named, sch-rnd assumes it's GND +
  • with a dc value of 5 (volts)... +
  • ... and no AC value or time dependent (function) value +
+

+

+ +
Simulation modification, adding a DC voltage source
+

+Or in short: this is the 5V power supply connected to CN1. +

+The advantage of having this as a modification instead of drawing it as a +voltage source symbol on the sheet is the less visual clutter on the drawing, +especially when not dealing with simulation. It is also more natural to say +"connect 5V to CN1 for this test" than to draw symbols of non-existing parts. +

+This advantage pays off even more when there are multiple different simulation +setups each having different sources installed at random parts of the circuit. +Without modifications, all sources of all simulation setups would need to be +added to the drawing (or on separate "test bench sheets"). +

+Note: CN1-2 uses component name - port name; +port name means the name the port is listed by in the abstract +model, which is typically the original terminal name, and not the +"pin number", or the calculated display/name attribute. In case oc CN1-2, port +name and "pin number" or display/name happens to match, but for example using +a polarized symbol, e.g. a diode it is typically A and C (not 1 and 2); +or using a transistor symbol, the port names are B, E, C (and not 1, 2 and 3). +Tip: switch to the raw view to reveal the original port names or use the +abstract model dialog to find them. + +

Sim setup: output config

+

+The second tab, output config, defines the spice analysis to execute and +how the results are presented. A single simulation setup can define multiple +output, in which case each simulation is ran on the given setup, in the order +they are specified, and are presented in the same order. This is useful to +get multiple printouts or plots of the same or different analyses. +

+

+ +
Simulation setup dialog, second tab
+

+Select the first entry, which runs the 'op' analysis and presents the result +simply printing values. Click on the edit button. This opens the sim output +config dialog. The top half of the dialog box configures the analysis; the +op analysis does not have parameters so it's sparse in this example. The bottom +half configures the presentation, which is set to 'print' in this case, which +will simply print the textual value of any property listed. The list can be +edited using New/Edit/Remove buttons. Each item of the list is a network name +or a component-port pair (or a function based on one of these). In this example +we are measuring voltages at two pins of connector CN2. +

+

+ +
Simulation output configuration for op+print
+

+ +

Sim setup: run & output

+

+The third tab presents simulation results. Before the simulation is first +ran, this tab is empty. Click on the 'run' button in the bottom control block +of the dialog box; the 'run' button will activate the sim setup (selects +the sim_ngspice view and sets all sim related configuration) and run +the simulation (ngspice) in the background and fill in the third tab once +the simulation finishes. +

+In this simple example the output will contain: +

+CN2-3 = 2.38095238e+00
+CN2-2 = 1.19047619e+00
+
+the voltages measured on pin 3 and 2 of the connector CN2, as requested in +the output config. +

+

+ +
Simulation setup dialog, third tab, after execution
+

+ Index: tags/1.0.5/doc/tutorial/simulation/sim/01_dc/project.lht =================================================================== --- tags/1.0.5/doc/tutorial/simulation/sim/01_dc/project.lht (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/sim/01_dc/project.lht (revision 10414) @@ -0,0 +1,39 @@ +ha:coraleda-project-v1 { + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:plugins { + ha:sim { + li:setups { + {ha:dc op point} { + li:mods { + ha:add { + value = 5 + pos = CN1-2 + neg = CN1-1 + device = V + tdf = none + ha:tdf_params { + } + } + } + li:output { + {ha:DC output voltages} { + ha:presentation { + li:props { + CN2-3 + CN2-2 + } + type = print + } + ha:analysis { + type = op + } + } + } + } + } + } + } + } + } +} Index: tags/1.0.5/doc/tutorial/simulation/sim/01_dc/sim_mod.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/1.0.5/doc/tutorial/simulation/sim/01_dc/sim_mod.png =================================================================== --- tags/1.0.5/doc/tutorial/simulation/sim/01_dc/sim_mod.png (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/sim/01_dc/sim_mod.png (revision 10414) Property changes on: tags/1.0.5/doc/tutorial/simulation/sim/01_dc/sim_mod.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/1.0.5/doc/tutorial/simulation/sim/01_dc/sim_out.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/1.0.5/doc/tutorial/simulation/sim/01_dc/sim_out.png =================================================================== --- tags/1.0.5/doc/tutorial/simulation/sim/01_dc/sim_out.png (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/sim/01_dc/sim_out.png (revision 10414) Property changes on: tags/1.0.5/doc/tutorial/simulation/sim/01_dc/sim_out.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/1.0.5/doc/tutorial/simulation/sim/01_dc/sim_setup.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/1.0.5/doc/tutorial/simulation/sim/01_dc/sim_setup.png =================================================================== --- tags/1.0.5/doc/tutorial/simulation/sim/01_dc/sim_setup.png (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/sim/01_dc/sim_setup.png (revision 10414) Property changes on: tags/1.0.5/doc/tutorial/simulation/sim/01_dc/sim_setup.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/1.0.5/doc/tutorial/simulation/sim/01_dc/sim_setup2.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/1.0.5/doc/tutorial/simulation/sim/01_dc/sim_setup2.png =================================================================== --- tags/1.0.5/doc/tutorial/simulation/sim/01_dc/sim_setup2.png (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/sim/01_dc/sim_setup2.png (revision 10414) Property changes on: tags/1.0.5/doc/tutorial/simulation/sim/01_dc/sim_setup2.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/1.0.5/doc/tutorial/simulation/sim/01_dc/sim_setup3.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/1.0.5/doc/tutorial/simulation/sim/01_dc/sim_setup3.png =================================================================== --- tags/1.0.5/doc/tutorial/simulation/sim/01_dc/sim_setup3.png (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/sim/01_dc/sim_setup3.png (revision 10414) Property changes on: tags/1.0.5/doc/tutorial/simulation/sim/01_dc/sim_setup3.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/1.0.5/doc/tutorial/simulation/sim/01_dc/simdlg.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/1.0.5/doc/tutorial/simulation/sim/01_dc/simdlg.png =================================================================== --- tags/1.0.5/doc/tutorial/simulation/sim/01_dc/simdlg.png (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/sim/01_dc/simdlg.png (revision 10414) Property changes on: tags/1.0.5/doc/tutorial/simulation/sim/01_dc/simdlg.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/1.0.5/doc/tutorial/simulation/sim/04_passive_tr/04_passive_tr.rs =================================================================== --- tags/1.0.5/doc/tutorial/simulation/sim/04_passive_tr/04_passive_tr.rs (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/sim/04_passive_tr/04_passive_tr.rs (revision 10414) @@ -0,0 +1,657 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.1 { + uuid=8/SYZ/pfBzxyqFA12WQAAAAC; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAg; + li:objects { + ha:polygon.11 { + li:outline { + ha:line { x1=0; y1=0; x2=80000; y2=0; } + ha:line { x1=80000; y1=0; x2=80000; y2=20000; } + ha:line { x1=80000; y1=20000; x2=0; y2=20000; } + ha:line { x1=0; y1=20000; x2=0; y2=0; } + } + stroke=titlebox-frame; + fill=titlebox-fill; + } + ha:line.12 { x1=0; y1=10000; x2=80000; y2=10000; stroke=titlebox-frame; } + ha:line.13 { x1=40000; y1=10000; x2=40000; y2=0; stroke=titlebox-frame; } + ha:text.20 { x1=1000; y1=16500; dyntext=0; stroke=titlebox-big; text=TITLE; } + ha:text.21 { x1=1000; y1=10500; x2=79000; y2=16000; dyntext=1; stroke=titlebox-big; text=%../../A.title%; } + ha:text.22 { x1=1000; y1=5500; dyntext=0; stroke=titlebox-small; text={PROJECT:}; } + ha:text.23 { x1=13000; y1=5500; x2=39000; y2=9500; dyntext=1; stroke=titlebox-big; text=%project.name%; } + ha:text.24 { x1=1000; y1=500; dyntext=0; stroke=titlebox-small; text={PAGE:}; } + ha:text.25 { x1=10000; y1=500; x2=39000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.page%; } + ha:text.26 { x1=41000; y1=5500; dyntext=0; stroke=titlebox-small; text={FILE:}; } + ha:text.27 { x1=48000; y1=5500; x2=79000; y2=9500; dyntext=1; stroke=titlebox-big; text=%filename%; } + ha:text.28 { x1=41000; y1=500; dyntext=0; stroke=titlebox-small; text={MAINTAINER:}; } + ha:text.29 { x1=55000; y1=500; x2=79000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.maintainer%; } + } + ha:attrib { + purpose=titlebox + } + } + ha:group.3 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAY; + x=-28000; y=-32000; + li:objects { + ha:line.1 { x1=36000; y1=116000; x2=52000; y2=116000; stroke=wire; } + ha:text.4 { x1=49000; y1=116000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=in + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.8 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAg; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=24000; y=84000; + li:objects { + ha:group.1 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAh; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAi; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=R1 + role=symbol + spice/prefix=R + value=10k + } + } + ha:group.10 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAp; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAh; + x=52000; y=76000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAq; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAi; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAr; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAj; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.5 { x1=9000; y1=5000; x2=9000; y2=-5000; stroke=sym-decor; } + ha:line.6 { x1=11000; y1=5000; x2=11000; y2=-5000; stroke=sym-decor; } + ha:line.7 { x1=4000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.8 { x1=11000; y1=0; x2=16000; y2=0; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=C1 + role=symbol + spice/prefix=C + value=1u + } + } + ha:group.11 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAs; + x=-28000; y=-32000; + li:objects { + ha:line.2 { x1=80000; y1=116000; x2=80000; y2=108000; stroke=wire; } + ha:line.3 { x1=72000; y1=116000; x2=88000; y2=116000; stroke=wire; } + ha:line.4 { x1=80000; y1=116000; x2=80000; y2=116000; stroke=junction; } + ha:text.5 { x1=84000; y1=116000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=mid + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.14 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAz; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=60000; y=84000; + li:objects { + ha:group.1 { + uuid=LnNTcUkV1CIzG7F2EXUAAAA0; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=LnNTcUkV1CIzG7F2EXUAAAA1; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=R2 + role=symbol + spice/prefix=R + value=15k + } + } + ha:group.16 { + uuid=LnNTcUkV1CIzG7F2EXUAAAA2; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAh; + x=88000; y=76000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=LnNTcUkV1CIzG7F2EXUAAAA3; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAi; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=LnNTcUkV1CIzG7F2EXUAAAA4; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAj; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.5 { x1=9000; y1=5000; x2=9000; y2=-5000; stroke=sym-decor; } + ha:line.6 { x1=11000; y1=5000; x2=11000; y2=-5000; stroke=sym-decor; } + ha:line.7 { x1=4000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.8 { x1=11000; y1=0; x2=16000; y2=0; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=C2 + role=symbol + spice/prefix=C + value=1.2u + } + } + ha:group.17 { + uuid=LnNTcUkV1CIzG7F2EXUAAAA5; + x=-28000; y=-32000; + li:objects { + ha:line.2 { x1=116000; y1=116000; x2=116000; y2=108000; stroke=wire; } + ha:line.3 { x1=108000; y1=116000; x2=132000; y2=116000; stroke=wire; } + ha:line.4 { x1=116000; y1=116000; x2=116000; y2=116000; stroke=junction; } + ha:text.5 { x1=128000; y1=116000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=out + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.20 { + uuid=LnNTcUkV1CIzG7F2EXUAAAA6; + x=-28000; y=-32000; + li:objects { + ha:line.1 { x1=80000; y1=88000; x2=80000; y2=80000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.22 { + uuid=LnNTcUkV1CIzG7F2EXUAAAA7; + x=-28000; y=-32000; + li:objects { + ha:line.1 { x1=116000; y1=88000; x2=116000; y2=80000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.24 { + uuid=LnNTcUkV1CIzG7F2EXUAAABA; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=12000; y=48000; + li:objects { + ha:group.1 { + uuid=LnNTcUkV1CIzG7F2EXUAAABB; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.26 { + uuid=LnNTcUkV1CIzG7F2EXUAAABC; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=52000; y=48000; + li:objects { + ha:group.1 { + uuid=LnNTcUkV1CIzG7F2EXUAAABD; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.28 { + uuid=LnNTcUkV1CIzG7F2EXUAAABE; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=88000; y=48000; + li:objects { + ha:group.1 { + uuid=LnNTcUkV1CIzG7F2EXUAAABF; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:connection.36 { + li:conn { + /2/8/2/1 + /2/3/1 + } + } + ha:connection.37 { + li:conn { + /2/11/2 + /2/10/2/1 + } + } + ha:connection.38 { + li:conn { + /2/11/3 + /2/8/1/1 + } + } + ha:connection.40 { + li:conn { + /2/14/2/1 + /2/11/3 + } + } + ha:connection.41 { + li:conn { + /2/17/2 + /2/16/2/1 + } + } + ha:connection.42 { + li:conn { + /2/17/3 + /2/14/1/1 + } + } + ha:connection.43 { + li:conn { + /2/20/1 + /2/10/1/1 + } + } + ha:connection.44 { + li:conn { + /2/22/1 + /2/16/1/1 + } + } + ha:connection.46 { + li:conn { + /2/26/1/1 + /2/20/1 + } + } + ha:connection.47 { + li:conn { + /2/28/1/1 + /2/22/1 + } + } + ha:group.48 { + uuid=65ViUwZSa7RX5OF8xWcAAAAk; src_uuid=65ViUwZSa7RX5OF8xWcAAAAh; + x=4000; y=80000; mirx=1; + li:objects { + ha:text.1 { x1=0; y1=-2000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:group.2 { + uuid=65ViUwZSa7RX5OF8xWcAAAAl; src_uuid=65ViUwZSa7RX5OF8xWcAAAAi; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:group.3 { + uuid=65ViUwZSa7RX5OF8xWcAAAAm; src_uuid=65ViUwZSa7RX5OF8xWcAAAAj; + x=0; y=4000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:polygon.4 { + li:outline { + ha:line { x1=0; y1=-2000; x2=0; y2=6000; } + ha:line { x1=0; y1=6000; x2=4000; y2=6000; } + ha:line { x1=4000; y1=6000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=0; y2=-2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + footprint=connector(2,1) + name=CN1 + role=symbol + spice/omit=yes + } + } + ha:connection.49 { + li:conn { + /2/48/3/1 + /2/3/1 + } + } + ha:group.50 { + uuid=65ViUwZSa7RX5OF8xWcAAAAn; + li:objects { + ha:line.1 { x1=8000; y1=80000; x2=12000; y2=80000; stroke=wire; } + ha:line.2 { x1=12000; y1=80000; x2=12000; y2=48000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.51 { + li:conn { + /2/50/1 + /2/48/2/1 + } + } + ha:group.53 { + uuid=65ViUwZSa7RX5OF8xWcAAAAr; src_uuid=65ViUwZSa7RX5OF8xWcAAAAh; + x=108000; y=80000; + li:objects { + ha:text.1 { x1=0; y1=-2000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:group.2 { + uuid=65ViUwZSa7RX5OF8xWcAAAAs; src_uuid=65ViUwZSa7RX5OF8xWcAAAAi; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:group.3 { + uuid=65ViUwZSa7RX5OF8xWcAAAAt; src_uuid=65ViUwZSa7RX5OF8xWcAAAAj; + x=0; y=4000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:polygon.4 { + li:outline { + ha:line { x1=0; y1=-2000; x2=0; y2=6000; } + ha:line { x1=0; y1=6000; x2=4000; y2=6000; } + ha:line { x1=4000; y1=6000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=0; y2=-2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + footprint=connector(2,1) + name=CN2 + role=symbol + spice/omit=yes + } + } + ha:connection.54 { + li:conn { + /2/53/3/1 + /2/17/3 + } + } + ha:group.55 { + uuid=65ViUwZSa7RX5OF8xWcAAAAw; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=100000; y=48000; + li:objects { + ha:group.1 { + uuid=65ViUwZSa7RX5OF8xWcAAAAx; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.56 { + uuid=65ViUwZSa7RX5OF8xWcAAAAy; + li:objects { + ha:line.1 { x1=100000; y1=48000; x2=100000; y2=80000; stroke=wire; } + ha:line.2 { x1=100000; y1=80000; x2=104000; y2=80000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.58 { + li:conn { + /2/56/2 + /2/53/2/1 + } + } + ha:connection.59 { + li:conn { + /2/56/1 + /2/55/1/1 + } + } + ha:connection.60 { + li:conn { + /2/50/2 + /2/24/1/1 + } + } + } + ha:attrib { + maintainer=Tibor 'Igor2' Palinkas + page=1 of 1 + print_page=A/4 + title={high level SIM: passives, tran} + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 2 + grid = 4.0960 mm + } + } + } +} Index: tags/1.0.5/doc/tutorial/simulation/sim/04_passive_tr/04_passive_tr.svg =================================================================== --- tags/1.0.5/doc/tutorial/simulation/sim/04_passive_tr/04_passive_tr.svg (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/sim/04_passive_tr/04_passive_tr.svg (revision 10414) @@ -0,0 +1,659 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/1.0.5/doc/tutorial/simulation/sim/04_passive_tr/index.html =================================================================== --- tags/1.0.5/doc/tutorial/simulation/sim/04_passive_tr/index.html (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/sim/04_passive_tr/index.html (revision 10414) @@ -0,0 +1,79 @@ + + +

04_passive_tr: time domain simulation: tran

+ + +

Scope

+

+In this simulation we are going to look at how a multi-stage RC filter behaves +when the input voltage is switched from 0 to 5V. + +

The schematics

+

+The single-sheet schematic contains the filter, directly usable in the PCB +workflow. +

+

+ +
Click the image to get the sch-rnd sheet; also requires this project.lht in the same directory
+

+ +

SPICE: what a tran simulation is

+

+In the tran(sient) analysis a DC solution is calculated first +then a simulation is run with a fixed time stepping, updating the internal +states of components (e.g. capacitor charges) and networks (voltages). The +result is typically a graph with time along the X axis and voltages/currents on +the Y axis. + +

Preparing for simulation

+

+The process is largely the same as in the +base example of dc op point . The simulation +setup in this example is called "dc transition". Below are +the summary of differences for the current example. + +

Modifications

+

+Our input source is not a stable DC voltage source anymore, but a pulse. It's +still a 'V' for voltage source, connected to CN1-2, but the dc and ac +components are left empty and the time dependent value is set to pulse. +This exposes a set of pulse-specific fields. The setup in this example +uses a square wave that starts at 0V, goes up to 5V after 1 usec (TD). It's +not a perfect square, rather a trapezoid, with raise and fall time of 1 usec +each (TR and TF). +

+

+ +
Simulation modification, adding a pulse source
+

+Note: details of the available functions and their fields can be found in +the relevant section of the ngspice manual. + +

Sim setup: output config

+

+Analysis is set to transient (linear). Linear means the X axis will +be presented as a linear axis (common for time domain simulations). Start +time is not specified so it is assumed to be 0. Simulation stop time is set +to 200 miliseconds, sampling done at 1ms rate (resulting about 200 rows of data). +

+

+ +
Simulation output configuration for transient + plot
+

+Presentation is set to plot and the input and two output nets are listed by +net name. + +

Sim setup: run & output

+

+After running the simulation a plot is presented with three color +coded traces. The plot can be zoomed and panned with the mouse scroll +button. A left click at any point of the plot reads out the closest x +value and corresponding y values for the three traces; these are printed +above the plot. +

+

+ +
Simulation setup dialog, third tab, after execution
+

+ Index: tags/1.0.5/doc/tutorial/simulation/sim/04_passive_tr/project.lht =================================================================== --- tags/1.0.5/doc/tutorial/simulation/sim/04_passive_tr/project.lht (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/sim/04_passive_tr/project.lht (revision 10414) @@ -0,0 +1,47 @@ +ha:coraleda-project-v1 { + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:plugins { + ha:sim { + li:setups { + {ha:dc transition} { + li:mods { + ha:add { + pos = CN1-2 + tdf = pulse + device = V + ha:tdf_params { + TR = 1u + V1 = 0 + V2 = 5 + PER = 1 + PW = 1 + TD = 1u + TF = 1u + } + } + } + li:output { + {ha:time plot all} { + ha:presentation { + type = plot + li:props { + in + mid + out + } + } + ha:analysis { + type = tran_lin + incr = 1ms + stop = 200ms + } + } + } + } + } + } + } + } + } +} Index: tags/1.0.5/doc/tutorial/simulation/sim/04_passive_tr/sim_mod.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/1.0.5/doc/tutorial/simulation/sim/04_passive_tr/sim_mod.png =================================================================== --- tags/1.0.5/doc/tutorial/simulation/sim/04_passive_tr/sim_mod.png (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/sim/04_passive_tr/sim_mod.png (revision 10414) Property changes on: tags/1.0.5/doc/tutorial/simulation/sim/04_passive_tr/sim_mod.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/1.0.5/doc/tutorial/simulation/sim/04_passive_tr/sim_out.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/1.0.5/doc/tutorial/simulation/sim/04_passive_tr/sim_out.png =================================================================== --- tags/1.0.5/doc/tutorial/simulation/sim/04_passive_tr/sim_out.png (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/sim/04_passive_tr/sim_out.png (revision 10414) Property changes on: tags/1.0.5/doc/tutorial/simulation/sim/04_passive_tr/sim_out.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/1.0.5/doc/tutorial/simulation/sim/04_passive_tr/sim_run.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/1.0.5/doc/tutorial/simulation/sim/04_passive_tr/sim_run.png =================================================================== --- tags/1.0.5/doc/tutorial/simulation/sim/04_passive_tr/sim_run.png (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/sim/04_passive_tr/sim_run.png (revision 10414) Property changes on: tags/1.0.5/doc/tutorial/simulation/sim/04_passive_tr/sim_run.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/1.0.5/doc/tutorial/simulation/sim/06_passive_ac/06_passive_ac.rs =================================================================== --- tags/1.0.5/doc/tutorial/simulation/sim/06_passive_ac/06_passive_ac.rs (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/sim/06_passive_ac/06_passive_ac.rs (revision 10414) @@ -0,0 +1,657 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.1 { + uuid=8/SYZ/pfBzxyqFA12WQAAAAC; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAg; + li:objects { + ha:polygon.11 { + li:outline { + ha:line { x1=0; y1=0; x2=80000; y2=0; } + ha:line { x1=80000; y1=0; x2=80000; y2=20000; } + ha:line { x1=80000; y1=20000; x2=0; y2=20000; } + ha:line { x1=0; y1=20000; x2=0; y2=0; } + } + stroke=titlebox-frame; + fill=titlebox-fill; + } + ha:line.12 { x1=0; y1=10000; x2=80000; y2=10000; stroke=titlebox-frame; } + ha:line.13 { x1=40000; y1=10000; x2=40000; y2=0; stroke=titlebox-frame; } + ha:text.20 { x1=1000; y1=16500; dyntext=0; stroke=titlebox-big; text=TITLE; } + ha:text.21 { x1=1000; y1=10500; x2=79000; y2=16000; dyntext=1; stroke=titlebox-big; text=%../../A.title%; } + ha:text.22 { x1=1000; y1=5500; dyntext=0; stroke=titlebox-small; text={PROJECT:}; } + ha:text.23 { x1=13000; y1=5500; x2=39000; y2=9500; dyntext=1; stroke=titlebox-big; text=%project.name%; } + ha:text.24 { x1=1000; y1=500; dyntext=0; stroke=titlebox-small; text={PAGE:}; } + ha:text.25 { x1=10000; y1=500; x2=39000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.page%; } + ha:text.26 { x1=41000; y1=5500; dyntext=0; stroke=titlebox-small; text={FILE:}; } + ha:text.27 { x1=48000; y1=5500; x2=79000; y2=9500; dyntext=1; stroke=titlebox-big; text=%filename%; } + ha:text.28 { x1=41000; y1=500; dyntext=0; stroke=titlebox-small; text={MAINTAINER:}; } + ha:text.29 { x1=55000; y1=500; x2=79000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.maintainer%; } + } + ha:attrib { + purpose=titlebox + } + } + ha:group.3 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAY; + x=-28000; y=-32000; + li:objects { + ha:line.1 { x1=36000; y1=116000; x2=52000; y2=116000; stroke=wire; } + ha:text.4 { x1=49000; y1=116000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=in + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.8 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAg; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=24000; y=84000; + li:objects { + ha:group.1 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAh; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAi; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=R1 + role=symbol + spice/prefix=R + value=10k + } + } + ha:group.10 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAp; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAh; + x=52000; y=76000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAq; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAi; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAr; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAj; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.5 { x1=9000; y1=5000; x2=9000; y2=-5000; stroke=sym-decor; } + ha:line.6 { x1=11000; y1=5000; x2=11000; y2=-5000; stroke=sym-decor; } + ha:line.7 { x1=4000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.8 { x1=11000; y1=0; x2=16000; y2=0; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=C1 + role=symbol + spice/prefix=C + value=1u + } + } + ha:group.11 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAs; + x=-28000; y=-32000; + li:objects { + ha:line.2 { x1=80000; y1=116000; x2=80000; y2=108000; stroke=wire; } + ha:line.3 { x1=72000; y1=116000; x2=88000; y2=116000; stroke=wire; } + ha:line.4 { x1=80000; y1=116000; x2=80000; y2=116000; stroke=junction; } + ha:text.5 { x1=84000; y1=116000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=mid + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.14 { + uuid=LnNTcUkV1CIzG7F2EXUAAAAz; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=60000; y=84000; + li:objects { + ha:group.1 { + uuid=LnNTcUkV1CIzG7F2EXUAAAA0; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=LnNTcUkV1CIzG7F2EXUAAAA1; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=R2 + role=symbol + spice/prefix=R + value=1k + } + } + ha:group.16 { + uuid=LnNTcUkV1CIzG7F2EXUAAAA2; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAh; + x=88000; y=76000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=LnNTcUkV1CIzG7F2EXUAAAA3; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAi; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=LnNTcUkV1CIzG7F2EXUAAAA4; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAj; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.5 { x1=9000; y1=5000; x2=9000; y2=-5000; stroke=sym-decor; } + ha:line.6 { x1=11000; y1=5000; x2=11000; y2=-5000; stroke=sym-decor; } + ha:line.7 { x1=4000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.8 { x1=11000; y1=0; x2=16000; y2=0; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=C2 + role=symbol + spice/prefix=C + value=100n + } + } + ha:group.17 { + uuid=LnNTcUkV1CIzG7F2EXUAAAA5; + x=-28000; y=-32000; + li:objects { + ha:line.2 { x1=116000; y1=116000; x2=116000; y2=108000; stroke=wire; } + ha:line.3 { x1=108000; y1=116000; x2=132000; y2=116000; stroke=wire; } + ha:line.4 { x1=116000; y1=116000; x2=116000; y2=116000; stroke=junction; } + ha:text.5 { x1=128000; y1=116000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=out + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.20 { + uuid=LnNTcUkV1CIzG7F2EXUAAAA6; + x=-28000; y=-32000; + li:objects { + ha:line.1 { x1=80000; y1=88000; x2=80000; y2=80000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.22 { + uuid=LnNTcUkV1CIzG7F2EXUAAAA7; + x=-28000; y=-32000; + li:objects { + ha:line.1 { x1=116000; y1=88000; x2=116000; y2=80000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.24 { + uuid=LnNTcUkV1CIzG7F2EXUAAABA; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=12000; y=48000; + li:objects { + ha:group.1 { + uuid=LnNTcUkV1CIzG7F2EXUAAABB; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.26 { + uuid=LnNTcUkV1CIzG7F2EXUAAABC; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=52000; y=48000; + li:objects { + ha:group.1 { + uuid=LnNTcUkV1CIzG7F2EXUAAABD; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.28 { + uuid=LnNTcUkV1CIzG7F2EXUAAABE; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=88000; y=48000; + li:objects { + ha:group.1 { + uuid=LnNTcUkV1CIzG7F2EXUAAABF; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:connection.36 { + li:conn { + /2/8/2/1 + /2/3/1 + } + } + ha:connection.37 { + li:conn { + /2/11/2 + /2/10/2/1 + } + } + ha:connection.38 { + li:conn { + /2/11/3 + /2/8/1/1 + } + } + ha:connection.40 { + li:conn { + /2/14/2/1 + /2/11/3 + } + } + ha:connection.41 { + li:conn { + /2/17/2 + /2/16/2/1 + } + } + ha:connection.42 { + li:conn { + /2/17/3 + /2/14/1/1 + } + } + ha:connection.43 { + li:conn { + /2/20/1 + /2/10/1/1 + } + } + ha:connection.44 { + li:conn { + /2/22/1 + /2/16/1/1 + } + } + ha:connection.46 { + li:conn { + /2/26/1/1 + /2/20/1 + } + } + ha:connection.47 { + li:conn { + /2/28/1/1 + /2/22/1 + } + } + ha:group.48 { + uuid=65ViUwZSa7RX5OF8xWcAAAAk; src_uuid=65ViUwZSa7RX5OF8xWcAAAAh; + x=4000; y=80000; mirx=1; + li:objects { + ha:text.1 { x1=0; y1=-2000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:group.2 { + uuid=65ViUwZSa7RX5OF8xWcAAAAl; src_uuid=65ViUwZSa7RX5OF8xWcAAAAi; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:group.3 { + uuid=65ViUwZSa7RX5OF8xWcAAAAm; src_uuid=65ViUwZSa7RX5OF8xWcAAAAj; + x=0; y=4000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:polygon.4 { + li:outline { + ha:line { x1=0; y1=-2000; x2=0; y2=6000; } + ha:line { x1=0; y1=6000; x2=4000; y2=6000; } + ha:line { x1=4000; y1=6000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=0; y2=-2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + footprint=connector(2,1) + name=CN1 + role=symbol + spice/omit=yes + } + } + ha:connection.49 { + li:conn { + /2/48/3/1 + /2/3/1 + } + } + ha:group.50 { + uuid=65ViUwZSa7RX5OF8xWcAAAAn; + li:objects { + ha:line.1 { x1=8000; y1=80000; x2=12000; y2=80000; stroke=wire; } + ha:line.2 { x1=12000; y1=80000; x2=12000; y2=48000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.51 { + li:conn { + /2/50/1 + /2/48/2/1 + } + } + ha:group.53 { + uuid=65ViUwZSa7RX5OF8xWcAAAAr; src_uuid=65ViUwZSa7RX5OF8xWcAAAAh; + x=108000; y=80000; + li:objects { + ha:text.1 { x1=0; y1=-2000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:group.2 { + uuid=65ViUwZSa7RX5OF8xWcAAAAs; src_uuid=65ViUwZSa7RX5OF8xWcAAAAi; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:group.3 { + uuid=65ViUwZSa7RX5OF8xWcAAAAt; src_uuid=65ViUwZSa7RX5OF8xWcAAAAj; + x=0; y=4000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:polygon.4 { + li:outline { + ha:line { x1=0; y1=-2000; x2=0; y2=6000; } + ha:line { x1=0; y1=6000; x2=4000; y2=6000; } + ha:line { x1=4000; y1=6000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=0; y2=-2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + footprint=connector(2,1) + name=CN2 + role=symbol + spice/omit=yes + } + } + ha:connection.54 { + li:conn { + /2/53/3/1 + /2/17/3 + } + } + ha:group.55 { + uuid=65ViUwZSa7RX5OF8xWcAAAAw; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=100000; y=48000; + li:objects { + ha:group.1 { + uuid=65ViUwZSa7RX5OF8xWcAAAAx; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.56 { + uuid=65ViUwZSa7RX5OF8xWcAAAAy; + li:objects { + ha:line.1 { x1=100000; y1=48000; x2=100000; y2=80000; stroke=wire; } + ha:line.2 { x1=100000; y1=80000; x2=104000; y2=80000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.58 { + li:conn { + /2/56/2 + /2/53/2/1 + } + } + ha:connection.59 { + li:conn { + /2/56/1 + /2/55/1/1 + } + } + ha:connection.60 { + li:conn { + /2/50/2 + /2/24/1/1 + } + } + } + ha:attrib { + maintainer=Tibor 'Igor2' Palinkas + page=1 of 1 + print_page=A/4 + title={high level SIM: passives, ac} + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 2 + grid = 4.0960 mm + } + } + } +} Index: tags/1.0.5/doc/tutorial/simulation/sim/06_passive_ac/06_passive_ac.svg =================================================================== --- tags/1.0.5/doc/tutorial/simulation/sim/06_passive_ac/06_passive_ac.svg (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/sim/06_passive_ac/06_passive_ac.svg (revision 10414) @@ -0,0 +1,690 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/1.0.5/doc/tutorial/simulation/sim/06_passive_ac/index.html =================================================================== --- tags/1.0.5/doc/tutorial/simulation/sim/06_passive_ac/index.html (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/sim/06_passive_ac/index.html (revision 10414) @@ -0,0 +1,67 @@ + + +

06_passive_ac: freqency domain simulation: ac

+ +

Scope

+

+In this simulation we are going to look at how a multi-stage RC filter behaves +when stimulated with sine waves of various frequencies. + +

The schematics

+

+The single-sheet schematic contains the filter, directy usable in the PCB +workflow. +

+

+ +
Click the image to get the sch-rnd sheet; also requires this project.lht in the same directory
+

+ +

SPICE: what an ac simulation is

+

+In the ac analysis simulation a DC solution is calculated first +and then a small signal sinusoidal stimulus is applied over a range of +frequencies. The result is typically a graph with frequency on the X axis +and gain or phase on the Y axis. The AC analysis is often used to get +a transfer function. + +

Preparing for simulation

+ +The process is largely the same as in the +base example of dc op point. The simulation +setup in this example is called "freq domain characteristics". Below are +the summary of differences compared to +the trans analysis of a very similar circuit + + +

Modifications

+

+Our input source is not a stable DC voltage source anymore, but an AC source. +It's still a 'V' for voltage source, connected to CN1-2, but the AC field +is set to 1 (volt). Because of the AC field set, a spice AC analysis will +automatically use this voltage source to feed in various frequencies. + +

Sim setup: output config

+

+This simulation has two output configs, one for displaying the transfer +(in decibel) and one for the phase (in radian). The reason for specify them +in two separate output is the largely different y scale and unit. +

+The first output uses ac (dec) for analysis. This will feed in 10 +different frequencies per decade and caputre the output. This also means +the X axis, frequency, is logarithmic (common for frequency domain analysis). +

+The property to plot is vdb(out), which is the "voltage decibel" of +the network called out. Instead of the net name a component-port could be +specified within vdb(). +

+The second output uses anlaysis previous, which means no new simulation +is ran, but the data of the previous simulation is used. The presentation is +also a plot of "out", but using the cph() function, which is the phase in +radian. +

+

+ +
Simulation setup dialog, third tab, after execution
+

+ Index: tags/1.0.5/doc/tutorial/simulation/sim/06_passive_ac/sim_run.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/1.0.5/doc/tutorial/simulation/sim/06_passive_ac/sim_run.png =================================================================== --- tags/1.0.5/doc/tutorial/simulation/sim/06_passive_ac/sim_run.png (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/sim/06_passive_ac/sim_run.png (revision 10414) Property changes on: tags/1.0.5/doc/tutorial/simulation/sim/06_passive_ac/sim_run.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/1.0.5/doc/tutorial/simulation/sim/10_bjt_amp_tr/10_bjt_amp_tr.rs =================================================================== --- tags/1.0.5/doc/tutorial/simulation/sim/10_bjt_amp_tr/10_bjt_amp_tr.rs (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/sim/10_bjt_amp_tr/10_bjt_amp_tr.rs (revision 10414) @@ -0,0 +1,1067 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAp; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAq; loclib_name=bc817_sot23; + li:objects { + } + ha:attrib { + footprint=SOT23 + li:portmap { + {B->pcb/pinnum=1} + {E->pcb/pinnum=2} + {C->pcb/pinnum=3} + } + } + } + } + ha:attrib { + ha:purpose = { value=devmap; prio=0; } + } + } + ha:group.2 { + uuid=mpbUxZA3TcX63n9yc2EAAAA9; + li:objects { + ha:group.1 { + uuid=mpbUxZA3TcX63n9yc2EAAAA+; loclib_name=bc817; + li:objects { + } + ha:attrib { + spice/model_card={* (C) 2023 Tibor 'Igor2' Palinkas +* License: CC0 (no rights reserved): https://creativecommons.org/publicdomain/zero/1.0/ +* Source: based on Vishay's datasheet: https://archive.org/details/bc817_spice_vishay +* +.model BC817 npn ( ++ IS=2.43485e-13 VAF=10 BF=270 IKF=1.12487 NE=1.84302 ISE=7.17747e-12 ++ IKR=0.149889 ISC=2.42047e-12 NC=3.94859 NR=1.04566 BR=2.51332 RC=0.407107 ++ CJC=5.516e-11 FC=0.8 MJC=0.529364 VJC=0.4 CJE=5.10473e-11 MJE=0.412728 ++ VJE=0.561234 TF=7.1424e-10 ITF=0.175457 VTF=1.86025 XTF=1.09929 RB=6.50128 ++ IRB=0.1 RBM=0.1 RE=0.0814215 TR=1e-07 ++ ) + +} + } + } + } + ha:attrib { + ha:purpose = { value=spicelib; prio=0; } + } + } + } + } + ha:obj_direct.2 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.1 { + uuid=8/SYZ/pfBzxyqFA12WQAAAAC; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAg; + li:objects { + ha:polygon.11 { + li:outline { + ha:line { x1=0; y1=0; x2=80000; y2=0; } + ha:line { x1=80000; y1=0; x2=80000; y2=20000; } + ha:line { x1=80000; y1=20000; x2=0; y2=20000; } + ha:line { x1=0; y1=20000; x2=0; y2=0; } + } + stroke=titlebox-frame; + fill=titlebox-fill; + } + ha:line.12 { x1=0; y1=10000; x2=80000; y2=10000; stroke=titlebox-frame; } + ha:line.13 { x1=40000; y1=10000; x2=40000; y2=0; stroke=titlebox-frame; } + ha:text.20 { x1=1000; y1=16500; dyntext=0; stroke=titlebox-big; text=TITLE; } + ha:text.21 { x1=1000; y1=10500; x2=79000; y2=16000; dyntext=1; stroke=titlebox-big; text=%../../A.title%; } + ha:text.22 { x1=1000; y1=5500; dyntext=0; stroke=titlebox-small; text={PROJECT:}; } + ha:text.23 { x1=13000; y1=5500; x2=39000; y2=9500; dyntext=1; stroke=titlebox-big; text=%project.name%; } + ha:text.24 { x1=1000; y1=500; dyntext=0; stroke=titlebox-small; text={PAGE:}; } + ha:text.25 { x1=10000; y1=500; x2=39000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.page%; } + ha:text.26 { x1=41000; y1=5500; dyntext=0; stroke=titlebox-small; text={FILE:}; } + ha:text.27 { x1=48000; y1=5500; x2=79000; y2=9500; dyntext=1; stroke=titlebox-big; text=%filename%; } + ha:text.28 { x1=41000; y1=500; dyntext=0; stroke=titlebox-small; text={MAINTAINER:}; } + ha:text.29 { x1=55000; y1=500; x2=79000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.maintainer%; } + } + ha:attrib { + purpose=titlebox + } + } + ha:group.2 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAJ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAh; + x=20000; y=100000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAK; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAi; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAL; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAj; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.5 { x1=9000; y1=5000; x2=9000; y2=-5000; stroke=sym-decor; } + ha:line.6 { x1=11000; y1=5000; x2=11000; y2=-5000; stroke=sym-decor; } + ha:line.7 { x1=4000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.8 { x1=11000; y1=0; x2=16000; y2=0; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=C1 + role=symbol + value=10u + } + } + ha:group.3 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAM; + x=-20000; y=-20000; + li:objects { + ha:line.1 { x1=40000; y1=120000; x2=32000; y2=120000; stroke=wire; } + ha:text.2 { x1=33000; y1=120000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=in + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.5 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAN; + x=-20000; y=-20000; + li:objects { + ha:line.1 { x1=60000; y1=120000; x2=76000; y2=120000; stroke=wire; } + ha:line.3 { x1=64000; y1=120000; x2=64000; y2=120000; stroke=junction; } + ha:line.4 { x1=64000; y1=100000; x2=64000; y2=140000; stroke=wire; } + ha:text.5 { x1=66000; y1=120000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=int_b + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.7 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAU; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=44000; y=140000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAV; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAW; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=R1 + role=symbol + value=87k + } + } + ha:group.9 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAa; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=44000; y=80000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAb; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAc; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=R2 + role=symbol + value=10k + } + } + ha:group.14 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAr; + x=-52000; y=-20000; + li:objects { + ha:line.1 { x1=120000; y1=112000; x2=120000; y2=56000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.16 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAs; + x=-40000; y=-20000; + li:objects { + ha:line.1 { x1=84000; y1=80000; x2=84000; y2=56000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.18 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAw; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=68000; y=140000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAx; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAy; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=R3 + role=symbol + value=33k + } + } + ha:group.19 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAz; + x=-52000; y=-20000; + li:objects { + ha:line.1 { x1=120000; y1=128000; x2=120000; y2=140000; stroke=wire; } + ha:line.2 { x1=120000; y1=132000; x2=132000; y2=132000; stroke=wire; } + ha:line.3 { x1=120000; y1=132000; x2=120000; y2=132000; stroke=junction; } + ha:text.4 { x1=122000; y1=132000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=int_c + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.22 { + uuid=60PZRPnx0Y9mYJZvZgYAAAA0; + x=-40000; y=-20000; + li:objects { + ha:line.1 { x1=84000; y1=160000; x2=84000; y2=172000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.24 { + uuid=60PZRPnx0Y9mYJZvZgYAAAA1; + x=-52000; y=-20000; + li:objects { + ha:line.1 { x1=120000; y1=160000; x2=120000; y2=172000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.26 { + uuid=60PZRPnx0Y9mYJZvZgYAAAA5; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAh; + x=80000; y=112000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAA6; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAi; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=60PZRPnx0Y9mYJZvZgYAAAA7; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAj; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.5 { x1=9000; y1=5000; x2=9000; y2=-5000; stroke=sym-decor; } + ha:line.6 { x1=11000; y1=5000; x2=11000; y2=-5000; stroke=sym-decor; } + ha:line.7 { x1=4000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.8 { x1=11000; y1=0; x2=16000; y2=0; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=C2 + role=symbol + value=10u + } + } + ha:group.28 { + uuid=60PZRPnx0Y9mYJZvZgYAAAA/; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=108000; y=100000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAABA; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=60PZRPnx0Y9mYJZvZgYAAABB; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=R4 + role=symbol + value=100k + } + } + ha:group.29 { + uuid=60PZRPnx0Y9mYJZvZgYAAABC; + x=-60000; y=-20000; + li:objects { + ha:line.1 { x1=160000; y1=132000; x2=176000; y2=132000; stroke=wire; } + ha:line.2 { x1=168000; y1=120000; x2=168000; y2=132000; stroke=wire; } + ha:line.3 { x1=168000; y1=132000; x2=168000; y2=132000; stroke=junction; } + ha:text.4 { x1=173000; y1=132000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=out + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.32 { + uuid=60PZRPnx0Y9mYJZvZgYAAABD; + x=-60000; y=-20000; + li:objects { + ha:line.2 { x1=168000; y1=100000; x2=168000; y2=56000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.46 { + uuid=60PZRPnx0Y9mYJZvZgYAAABz; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=16000; y=92000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAB0; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.48 { + uuid=60PZRPnx0Y9mYJZvZgYAAAB1; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=44000; y=36000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAB2; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.50 { + uuid=60PZRPnx0Y9mYJZvZgYAAAB3; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=68000; y=36000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAB4; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.52 { + uuid=60PZRPnx0Y9mYJZvZgYAAAB5; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=108000; y=36000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAB6; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.58 { + uuid=60PZRPnx0Y9mYJZvZgYAAACD; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB6; + x=68000; y=152000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAACE; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB7; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-4000; y1=4000; x2=4000; y2=7000; halign=center; dyntext=0; stroke=sym-primary; text=Vcc; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:Vcc} + } + role=symbol + } + } + ha:group.60 { + uuid=60PZRPnx0Y9mYJZvZgYAAACF; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB6; + x=44000; y=152000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAACG; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB7; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-4000; y1=4000; x2=4000; y2=7000; halign=center; dyntext=0; stroke=sym-primary; text=Vcc; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:Vcc} + } + role=symbol + } + } + ha:group.70 { + uuid=emEhKEkrgdRFzXxchToAAABZ; src_uuid=iNOQfJpO6hT/HFDFGjoAAACK; + x=56000; y=100000; + li:objects { + ha:polygon.1 { + li:outline { + ha:line { x1=10266; y1=-1780; x2=9224; y2=-3517; } + ha:line { x1=9224; y1=-3517; x2=10935; y2=-3368; } + ha:line { x1=10935; y1=-3368; x2=10266; y2=-1780; } + } + stroke=sym-decor; + fill=sym-decor; + } + ha:group.2 { + uuid=emEhKEkrgdRFzXxchToAAABa; src_uuid=iNOQfJpO6hT/HFDFGjoAAACL; + x=12000; y=8000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=-4000; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=C + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:group.3 { + uuid=emEhKEkrgdRFzXxchToAAABb; src_uuid=iNOQfJpO6hT/HFDFGjoAAACM; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=B + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.4 { + uuid=emEhKEkrgdRFzXxchToAAABc; src_uuid=iNOQfJpO6hT/HFDFGjoAAACN; + x=12000; y=-4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=-4000; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=E + role=terminal + ha:spice/pinnum = { value=3; prio=31050; } + } + } + ha:text.5 { x1=8000; y1=8000; rot=90.000000; dyntext=1; stroke=sym-secondary; text=%../a.devmap%; floater=1; } + ha:text.6 { x1=4000; y1=8000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:arc.7 { cx=9000; cy=0; r=5500; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:line.8 { x1=7000; y1=4000; x2=7000; y2=-4000; stroke=sym-decor; } + ha:line.9 { x1=4000; y1=0; x2=7000; y2=0; stroke=sym-decor; } + ha:line.10 { x1=7000; y1=-1000; x2=12000; y2=-4000; stroke=sym-decor; } + ha:line.11 { x1=7000; y1=1000; x2=12000; y2=4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + devmap=bc817_sot23 + name=Q1 + role=symbol + spice/model=bc817 + } + } + ha:connection.74 { + li:conn { + /2/3/1 + /2/2/2/1 + } + } + ha:connection.75 { + li:conn { + /2/5/1 + /2/2/1/1 + } + } + ha:connection.102 { + li:conn { + /2/7/1/1 + /2/5/4 + } + } + ha:connection.103 { + li:conn { + /2/9/2/1 + /2/5/4 + } + } + ha:connection.104 { + li:conn { + /2/16/1 + /2/9/1/1 + } + } + ha:connection.105 { + li:conn { + /2/22/1 + /2/7/2/1 + } + } + ha:connection.106 { + li:conn { + /2/48/1/1 + /2/16/1 + } + } + ha:connection.107 { + li:conn { + /2/60/1/1 + /2/22/1 + } + } + ha:connection.108 { + li:conn { + /2/19/1 + /2/18/1/1 + } + } + ha:connection.109 { + li:conn { + /2/24/1 + /2/18/2/1 + } + } + ha:connection.116 { + li:conn { + /2/50/1/1 + /2/14/1 + } + } + ha:connection.120 { + li:conn { + /2/58/1/1 + /2/24/1 + } + } + ha:connection.121 { + li:conn { + /2/70/2/1 + /2/19/1 + } + } + ha:connection.122 { + li:conn { + /2/70/3/1 + /2/5/1 + } + } + ha:connection.123 { + li:conn { + /2/70/4/1 + /2/14/1 + } + } + ha:connection.124 { + li:conn { + /2/26/2/1 + /2/19/2 + } + } + ha:connection.125 { + li:conn { + /2/29/1 + /2/26/1/1 + } + } + ha:connection.126 { + li:conn { + /2/29/2 + /2/28/2/1 + } + } + ha:connection.127 { + li:conn { + /2/32/2 + /2/28/1/1 + } + } + ha:connection.130 { + li:conn { + /2/52/1/1 + /2/32/2 + } + } + ha:group.137 { + uuid=qO6PuXTr1q4KsRucJCoAAABF; src_uuid=qO6PuXTr1q4KsRucJCoAAABC; + x=120000; y=108000; + li:objects { + ha:text.1 { x1=0; y1=-2000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:group.2 { + uuid=qO6PuXTr1q4KsRucJCoAAABG; src_uuid=qO6PuXTr1q4KsRucJCoAAABD; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:group.3 { + uuid=qO6PuXTr1q4KsRucJCoAAABH; src_uuid=qO6PuXTr1q4KsRucJCoAAABE; + x=0; y=4000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:polygon.4 { + li:outline { + ha:line { x1=0; y1=-2000; x2=0; y2=6000; } + ha:line { x1=0; y1=6000; x2=4000; y2=6000; } + ha:line { x1=4000; y1=6000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=0; y2=-2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + name=CN2 + role=symbol + spice/omit=yes + } + } + ha:connection.138 { + li:conn { + /2/137/3/1 + /2/29/1 + } + } + ha:group.139 { + uuid=qO6PuXTr1q4KsRucJCoAAABI; + li:objects { + ha:line.1 { x1=116000; y1=108000; x2=112000; y2=108000; stroke=wire; } + ha:line.2 { x1=112000; y1=108000; x2=112000; y2=104000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.140 { + li:conn { + /2/139/1 + /2/137/2/1 + } + } + ha:group.141 { + uuid=qO6PuXTr1q4KsRucJCoAAABL; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=112000; y=104000; + li:objects { + ha:group.1 { + uuid=qO6PuXTr1q4KsRucJCoAAABM; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:connection.142 { + li:conn { + /2/141/1/1 + /2/139/2 + } + } + ha:group.143 { + uuid=qO6PuXTr1q4KsRucJCoAAABQ; src_uuid=qO6PuXTr1q4KsRucJCoAAABC; + x=8000; y=96000; mirx=1; + li:objects { + ha:text.1 { x1=0; y1=-2000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:group.2 { + uuid=qO6PuXTr1q4KsRucJCoAAABR; src_uuid=qO6PuXTr1q4KsRucJCoAAABD; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:group.3 { + uuid=qO6PuXTr1q4KsRucJCoAAABS; src_uuid=qO6PuXTr1q4KsRucJCoAAABE; + x=0; y=4000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:polygon.4 { + li:outline { + ha:line { x1=0; y1=-2000; x2=0; y2=6000; } + ha:line { x1=0; y1=6000; x2=4000; y2=6000; } + ha:line { x1=4000; y1=6000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=0; y2=-2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + name=CN1 + role=symbol + spice/omit=yes + } + } + ha:connection.144 { + li:conn { + /2/143/3/1 + /2/3/1 + } + } + ha:group.145 { + uuid=qO6PuXTr1q4KsRucJCoAAABT; + li:objects { + ha:line.1 { x1=12000; y1=96000; x2=16000; y2=96000; stroke=wire; } + ha:line.2 { x1=16000; y1=96000; x2=16000; y2=92000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.146 { + li:conn { + /2/145/1 + /2/143/2/1 + } + } + ha:connection.147 { + li:conn { + /2/46/1/1 + /2/145/2 + } + } + } + ha:attrib { + maintainer=Tibor 'Igor2' Palinkas + page=1 of 1 + print_page=A/4 + title={high level SIM: BJT amplifier, tran} + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + } + } + } +} Index: tags/1.0.5/doc/tutorial/simulation/sim/10_bjt_amp_tr/10_bjt_amp_tr.svg =================================================================== --- tags/1.0.5/doc/tutorial/simulation/sim/10_bjt_amp_tr/10_bjt_amp_tr.svg (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/sim/10_bjt_amp_tr/10_bjt_amp_tr.svg (revision 10414) @@ -0,0 +1,933 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/1.0.5/doc/tutorial/simulation/sim/10_bjt_amp_tr/index.html =================================================================== --- tags/1.0.5/doc/tutorial/simulation/sim/10_bjt_amp_tr/index.html (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/sim/10_bjt_amp_tr/index.html (revision 10414) @@ -0,0 +1,106 @@ + + +

10_bjt_amp_tr: model from the library

+ +

Scope

+

+In this simulation we are going to look at a single-transistor amplifier +in the time domain to verify how it amplifies a sine wave. + +

The schematics

+

+The single-sheet schematic contains the amplifier without simulation-specific +extra symbols. +

+

+ +
Click the image to get the sch-rnd sheet; also requires this project.lht in the same directory
+

+ +

How to specify the model

+

+In the previous examples all components used were ideal: simple +resistors and capacitors, without any special characteristics +or side effects. More complex components such as transistors typically +have a large set of parameters that differ by device type. Spice addresses +this by using models. +

+A model in spice is really two things: +

    +
  • the code that implements how to simulate the given thing (e.g. an npn transistor) +
  • a set of parameters for this model which make the behavior match a specific real world device +
+

+The first of these, the code, is typically provided as part of the simulator software, +at least for the most common, basic component types. The second of these, the set of +model parameters, is specified by the user (normally acquired from the device +vendor or derived from the datasheet or actual measurements). +

+In sch-rnd these models are kept in the spice library, which is very much like +the symbol or devmap library: a directory tree that holds spice models, +one model per file, with models identified by file name. Spice export files +are self-contained and do not rely on external model files. This is achieved +by sch-rnd copying the content of these spice model files from the library +into the output file. +

+Furthermore there's a sheet-local library, just like with devmap (and +optionally with symbols), so that any spice model used by the sheet is +also saved within the sheet, keeping the sheet self-contained and portable. + +

Preparing for simulation

+ +

Q1

+

+This is the usual npn symbol from the stock symbol library shipped with +sch-rnd. The devmap has been set to bc817_sot23 so that the sheet can also +be used in a PCB workflow with a sot23 footprint as well. +

+The spice-specific aspects are the model and the spice pinout. The model +is specified using the spice/model attribute, with value bc817. +There is a file in the spice model library shipped with sch-rnd called +bc817.prm. The pinout is set by the spice/pinnum terminal attributes. +For the BJT spice model the pinout is always the same, so the stock +library symbol has this attribute hardwired in terminals with a low priority +(so that it can be overridden by other mechanisms). +

+The devmap file could contain the symbol's spice/model and portmap to set +spice/pinnum for each terminal, but this is not a good idea because there may be +different spice models for different complexities of simulation. Simple models, +like bc817.prm, concentrate only on the core of the functionality, while +more complex models implemented as "subcircuits" (subckt in spice slang) may +add parasitic effects, such as pin inductances and pin/package +related stray capacitances. Such complex models run slower, but may be +more accurate in some cases, while the simpler model would cover most of the +normal use cases. The user needs to decide which model to use for the given +circuit or even the given simulation; accordingly, this should not be defined +in the devmap. +

+Specifying the spice pinout from the devmap is unnecessary if both the model +and the symbol use the standard spice BJT pinout that matches the model code +in spice. However, for subcircuit models the pinout may differ, and sch-rnd +offers multiple mechanisms +to deal with different spice pinouts. +

+The simulation setup process is largely the same as in the +base example of dc op point. The simulation +setup in this example is called "ac trans". + +

Modifications

+

+This circuit needs two voltage sources, which are both added as modifications. +The first one is a DC 5V source connected to net Vcc (and GND). The second +source is connected to the input (and GND) and specifies an 1 kHz small signal +(0.01V) sine wave. + +

Sim setup: output config

+

+Output config is very similar to +the trans analysis of simpler circuit of an earlier example. Once ran, +it produces a long plot. Because of the large amplification factor, the +input (green) trace is visible only when zoomed in. +

+

+ +
Simulation setup dialog, third tab, after execution
+

+ Index: tags/1.0.5/doc/tutorial/simulation/sim/10_bjt_amp_tr/project.lht =================================================================== --- tags/1.0.5/doc/tutorial/simulation/sim/10_bjt_amp_tr/project.lht (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/sim/10_bjt_amp_tr/project.lht (revision 10414) @@ -0,0 +1,50 @@ +ha:coraleda-project-v1 { + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:plugins { + ha:sim { + li:setups { + {ha:ac trans} { + li:mods { + ha:add { + value = 5 + pos = Vcc + tdf = none + device = V + ha:tdf_params { + } + } + ha:add { + pos = in + tdf = sin + device = V + ha:tdf_params { + VA = 0.01 + FREQ = 1k + VO = 0 + } + } + } + li:output { + ha:transition { + ha:presentation { + type = plot + li:props { + out + in + } + } + ha:analysis { + type = tran_lin + incr = 1u + stop = 10m + } + } + } + } + } + } + } + } + } +} Index: tags/1.0.5/doc/tutorial/simulation/sim/10_bjt_amp_tr/sim_run.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/1.0.5/doc/tutorial/simulation/sim/10_bjt_amp_tr/sim_run.png =================================================================== --- tags/1.0.5/doc/tutorial/simulation/sim/10_bjt_amp_tr/sim_run.png (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/sim/10_bjt_amp_tr/sim_run.png (revision 10414) Property changes on: tags/1.0.5/doc/tutorial/simulation/sim/10_bjt_amp_tr/sim_run.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/1.0.5/doc/tutorial/simulation/sim/12_bjt_amp_ac/12_bjt_amp_ac.rs =================================================================== --- tags/1.0.5/doc/tutorial/simulation/sim/12_bjt_amp_ac/12_bjt_amp_ac.rs (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/sim/12_bjt_amp_ac/12_bjt_amp_ac.rs (revision 10414) @@ -0,0 +1,1070 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAp; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAq; loclib_name=bc817_sot23; + li:objects { + } + ha:attrib { + footprint=SOT23 + li:portmap { + {B->pcb/pinnum=1} + {E->pcb/pinnum=2} + {C->pcb/pinnum=3} + } + } + } + } + ha:attrib { + ha:purpose = { value=devmap; prio=0; } + } + } + ha:group.2 { + uuid=ocyrXFXWgSsRrvvVMDcAAAA9; + li:objects { + ha:group.1 { + uuid=ocyrXFXWgSsRrvvVMDcAAAA+; loclib_name=bc817; + li:objects { + } + ha:attrib { + spice/model_card={* (C) 2023 Tibor 'Igor2' Palinkas +* License: CC0 (no rights reserved): https://creativecommons.org/publicdomain/zero/1.0/ +* Source: based on Vishay's datasheet: https://archive.org/details/bc817_spice_vishay +* +.model BC817 npn ( ++ IS=2.43485e-13 VAF=10 BF=270 IKF=1.12487 NE=1.84302 ISE=7.17747e-12 ++ IKR=0.149889 ISC=2.42047e-12 NC=3.94859 NR=1.04566 BR=2.51332 RC=0.407107 ++ CJC=5.516e-11 FC=0.8 MJC=0.529364 VJC=0.4 CJE=5.10473e-11 MJE=0.412728 ++ VJE=0.561234 TF=7.1424e-10 ITF=0.175457 VTF=1.86025 XTF=1.09929 RB=6.50128 ++ IRB=0.1 RBM=0.1 RE=0.0814215 TR=1e-07 ++ ) + +} + } + } + } + ha:attrib { + ha:purpose = { value=spicelib; prio=0; } + } + } + } + } + ha:obj_direct.2 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.1 { + uuid=8/SYZ/pfBzxyqFA12WQAAAAC; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAg; + li:objects { + ha:polygon.11 { + li:outline { + ha:line { x1=0; y1=0; x2=80000; y2=0; } + ha:line { x1=80000; y1=0; x2=80000; y2=20000; } + ha:line { x1=80000; y1=20000; x2=0; y2=20000; } + ha:line { x1=0; y1=20000; x2=0; y2=0; } + } + stroke=titlebox-frame; + fill=titlebox-fill; + } + ha:line.12 { x1=0; y1=10000; x2=80000; y2=10000; stroke=titlebox-frame; } + ha:line.13 { x1=40000; y1=10000; x2=40000; y2=0; stroke=titlebox-frame; } + ha:text.20 { x1=1000; y1=16500; dyntext=0; stroke=titlebox-big; text=TITLE; } + ha:text.21 { x1=1000; y1=10500; x2=79000; y2=16000; dyntext=1; stroke=titlebox-big; text=%../../A.title%; } + ha:text.22 { x1=1000; y1=5500; dyntext=0; stroke=titlebox-small; text={PROJECT:}; } + ha:text.23 { x1=13000; y1=5500; x2=39000; y2=9500; dyntext=1; stroke=titlebox-big; text=%project.name%; } + ha:text.24 { x1=1000; y1=500; dyntext=0; stroke=titlebox-small; text={PAGE:}; } + ha:text.25 { x1=10000; y1=500; x2=39000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.page%; } + ha:text.26 { x1=41000; y1=5500; dyntext=0; stroke=titlebox-small; text={FILE:}; } + ha:text.27 { x1=48000; y1=5500; x2=79000; y2=9500; dyntext=1; stroke=titlebox-big; text=%filename%; } + ha:text.28 { x1=41000; y1=500; dyntext=0; stroke=titlebox-small; text={MAINTAINER:}; } + ha:text.29 { x1=55000; y1=500; x2=79000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.maintainer%; } + } + ha:attrib { + purpose=titlebox + } + } + ha:group.2 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAJ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAh; + x=20000; y=100000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAK; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAi; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAL; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAj; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.5 { x1=9000; y1=5000; x2=9000; y2=-5000; stroke=sym-decor; } + ha:line.6 { x1=11000; y1=5000; x2=11000; y2=-5000; stroke=sym-decor; } + ha:line.7 { x1=4000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.8 { x1=11000; y1=0; x2=16000; y2=0; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=C1 + role=symbol + value=10u + } + } + ha:group.3 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAM; + x=-20000; y=-20000; + li:objects { + ha:line.1 { x1=40000; y1=120000; x2=32000; y2=120000; stroke=wire; } + ha:text.2 { x1=33000; y1=120000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=in + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.5 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAN; + x=-20000; y=-20000; + li:objects { + ha:line.1 { x1=60000; y1=120000; x2=76000; y2=120000; stroke=wire; } + ha:line.3 { x1=64000; y1=120000; x2=64000; y2=120000; stroke=junction; } + ha:line.4 { x1=64000; y1=100000; x2=64000; y2=140000; stroke=wire; } + ha:text.5 { x1=66000; y1=120000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=int_b + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.7 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAU; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=44000; y=140000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAV; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAW; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=R1 + role=symbol + value=87k + } + } + ha:group.9 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAa; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=44000; y=80000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAb; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAc; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=R2 + role=symbol + value=10k + } + } + ha:group.14 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAr; + x=-52000; y=-20000; + li:objects { + ha:line.1 { x1=120000; y1=112000; x2=120000; y2=56000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.16 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAs; + x=-40000; y=-20000; + li:objects { + ha:line.1 { x1=84000; y1=80000; x2=84000; y2=56000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.18 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAw; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=68000; y=140000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAx; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAy; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=R3 + role=symbol + value=33k + } + } + ha:group.19 { + uuid=60PZRPnx0Y9mYJZvZgYAAAAz; + x=-52000; y=-20000; + li:objects { + ha:line.1 { x1=120000; y1=128000; x2=120000; y2=140000; stroke=wire; } + ha:line.2 { x1=120000; y1=132000; x2=132000; y2=132000; stroke=wire; } + ha:line.3 { x1=120000; y1=132000; x2=120000; y2=132000; stroke=junction; } + ha:text.4 { x1=122000; y1=132000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=int_c + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.22 { + uuid=60PZRPnx0Y9mYJZvZgYAAAA0; + x=-40000; y=-20000; + li:objects { + ha:line.1 { x1=84000; y1=160000; x2=84000; y2=172000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.24 { + uuid=60PZRPnx0Y9mYJZvZgYAAAA1; + x=-52000; y=-20000; + li:objects { + ha:line.1 { x1=120000; y1=160000; x2=120000; y2=172000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.26 { + uuid=60PZRPnx0Y9mYJZvZgYAAAA5; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAh; + x=80000; y=112000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAA6; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAi; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=60PZRPnx0Y9mYJZvZgYAAAA7; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAj; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.5 { x1=9000; y1=5000; x2=9000; y2=-5000; stroke=sym-decor; } + ha:line.6 { x1=11000; y1=5000; x2=11000; y2=-5000; stroke=sym-decor; } + ha:line.7 { x1=4000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.8 { x1=11000; y1=0; x2=16000; y2=0; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=C2 + role=symbol + value=10u + } + } + ha:group.28 { + uuid=60PZRPnx0Y9mYJZvZgYAAAA/; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=108000; y=100000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAABA; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=60PZRPnx0Y9mYJZvZgYAAABB; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=R4 + role=symbol + value=100k + } + } + ha:group.29 { + uuid=60PZRPnx0Y9mYJZvZgYAAABC; + x=-60000; y=-20000; + li:objects { + ha:line.1 { x1=160000; y1=132000; x2=180000; y2=132000; stroke=wire; } + ha:line.2 { x1=168000; y1=120000; x2=168000; y2=132000; stroke=wire; } + ha:line.3 { x1=168000; y1=132000; x2=168000; y2=132000; stroke=junction; } + ha:text.4 { x1=173000; y1=132000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=out + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.32 { + uuid=60PZRPnx0Y9mYJZvZgYAAABD; + x=-60000; y=-20000; + li:objects { + ha:line.2 { x1=168000; y1=100000; x2=168000; y2=56000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.46 { + uuid=60PZRPnx0Y9mYJZvZgYAAABz; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=16000; y=92000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAB0; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.48 { + uuid=60PZRPnx0Y9mYJZvZgYAAAB1; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=44000; y=36000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAB2; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.50 { + uuid=60PZRPnx0Y9mYJZvZgYAAAB3; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=68000; y=36000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAB4; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.52 { + uuid=60PZRPnx0Y9mYJZvZgYAAAB5; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=108000; y=36000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAB6; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.54 { + uuid=60PZRPnx0Y9mYJZvZgYAAAB7; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=116000; y=104000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAAB8; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.58 { + uuid=60PZRPnx0Y9mYJZvZgYAAACD; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB6; + x=68000; y=152000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAACE; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB7; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-4000; y1=4000; x2=4000; y2=7000; halign=center; dyntext=0; stroke=sym-primary; text=Vcc; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:Vcc} + } + role=symbol + } + } + ha:group.60 { + uuid=60PZRPnx0Y9mYJZvZgYAAACF; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB6; + x=44000; y=152000; + li:objects { + ha:group.1 { + uuid=60PZRPnx0Y9mYJZvZgYAAACG; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB7; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-4000; y1=4000; x2=4000; y2=7000; halign=center; dyntext=0; stroke=sym-primary; text=Vcc; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:Vcc} + } + role=symbol + } + } + ha:group.70 { + uuid=emEhKEkrgdRFzXxchToAAABZ; src_uuid=iNOQfJpO6hT/HFDFGjoAAACK; + x=56000; y=100000; + li:objects { + ha:polygon.1 { + li:outline { + ha:line { x1=10266; y1=-1780; x2=9224; y2=-3517; } + ha:line { x1=9224; y1=-3517; x2=10935; y2=-3368; } + ha:line { x1=10935; y1=-3368; x2=10266; y2=-1780; } + } + stroke=sym-decor; + fill=sym-decor; + } + ha:group.2 { + uuid=emEhKEkrgdRFzXxchToAAABa; src_uuid=iNOQfJpO6hT/HFDFGjoAAACL; + x=12000; y=8000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=-4000; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=C + role=terminal + } + } + ha:group.3 { + uuid=emEhKEkrgdRFzXxchToAAABb; src_uuid=iNOQfJpO6hT/HFDFGjoAAACM; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=B + role=terminal + } + } + ha:group.4 { + uuid=emEhKEkrgdRFzXxchToAAABc; src_uuid=iNOQfJpO6hT/HFDFGjoAAACN; + x=12000; y=-4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=-4000; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=E + role=terminal + } + } + ha:text.5 { x1=8000; y1=8000; rot=90.000000; dyntext=1; stroke=sym-secondary; text=%../a.devmap%; floater=1; } + ha:text.6 { x1=4000; y1=8000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:arc.7 { cx=9000; cy=0; r=5500; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:line.8 { x1=7000; y1=4000; x2=7000; y2=-4000; stroke=sym-decor; } + ha:line.9 { x1=4000; y1=0; x2=7000; y2=0; stroke=sym-decor; } + ha:line.10 { x1=7000; y1=-1000; x2=12000; y2=-4000; stroke=sym-decor; } + ha:line.11 { x1=7000; y1=1000; x2=12000; y2=4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + devmap=bc817_sot23 + name=Q1 + li:portmap { + {C->spice/pinnum=1} + {B->spice/pinnum=2} + {E->spice/pinnum=3} + } + role=symbol + spice/model=bc817 + } + } + ha:connection.74 { + li:conn { + /2/3/1 + /2/2/2/1 + } + } + ha:connection.75 { + li:conn { + /2/5/1 + /2/2/1/1 + } + } + ha:connection.102 { + li:conn { + /2/7/1/1 + /2/5/4 + } + } + ha:connection.103 { + li:conn { + /2/9/2/1 + /2/5/4 + } + } + ha:connection.104 { + li:conn { + /2/16/1 + /2/9/1/1 + } + } + ha:connection.105 { + li:conn { + /2/22/1 + /2/7/2/1 + } + } + ha:connection.106 { + li:conn { + /2/48/1/1 + /2/16/1 + } + } + ha:connection.107 { + li:conn { + /2/60/1/1 + /2/22/1 + } + } + ha:connection.108 { + li:conn { + /2/19/1 + /2/18/1/1 + } + } + ha:connection.109 { + li:conn { + /2/24/1 + /2/18/2/1 + } + } + ha:connection.116 { + li:conn { + /2/50/1/1 + /2/14/1 + } + } + ha:connection.120 { + li:conn { + /2/58/1/1 + /2/24/1 + } + } + ha:connection.121 { + li:conn { + /2/70/2/1 + /2/19/1 + } + } + ha:connection.122 { + li:conn { + /2/70/3/1 + /2/5/1 + } + } + ha:connection.123 { + li:conn { + /2/70/4/1 + /2/14/1 + } + } + ha:connection.124 { + li:conn { + /2/26/2/1 + /2/19/2 + } + } + ha:connection.125 { + li:conn { + /2/29/1 + /2/26/1/1 + } + } + ha:connection.126 { + li:conn { + /2/29/2 + /2/28/2/1 + } + } + ha:connection.127 { + li:conn { + /2/32/2 + /2/28/1/1 + } + } + ha:connection.130 { + li:conn { + /2/52/1/1 + /2/32/2 + } + } + ha:group.137 { + uuid=q7jNL8tNDwr0npd8eeMAAABL; src_uuid=q7jNL8tNDwr0npd8eeMAAABI; + x=8000; y=96000; mirx=1; + li:objects { + ha:text.1 { x1=0; y1=-2000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:group.2 { + uuid=q7jNL8tNDwr0npd8eeMAAABM; src_uuid=q7jNL8tNDwr0npd8eeMAAABJ; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:group.3 { + uuid=q7jNL8tNDwr0npd8eeMAAABN; src_uuid=q7jNL8tNDwr0npd8eeMAAABK; + x=0; y=4000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:polygon.4 { + li:outline { + ha:line { x1=0; y1=-2000; x2=0; y2=6000; } + ha:line { x1=0; y1=6000; x2=4000; y2=6000; } + ha:line { x1=4000; y1=6000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=0; y2=-2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + name=CN1 + role=symbol + spice/omit=yes + } + } + ha:connection.138 { + li:conn { + /2/137/3/1 + /2/3/1 + } + } + ha:group.139 { + uuid=q7jNL8tNDwr0npd8eeMAAABO; + li:objects { + ha:line.1 { x1=12000; y1=96000; x2=16000; y2=96000; stroke=wire; } + ha:line.2 { x1=16000; y1=96000; x2=16000; y2=92000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.140 { + li:conn { + /2/139/1 + /2/137/2/1 + } + } + ha:connection.141 { + li:conn { + /2/139/2 + /2/46/1/1 + } + } + ha:group.142 { + uuid=q7jNL8tNDwr0npd8eeMAAABS; src_uuid=q7jNL8tNDwr0npd8eeMAAABI; + x=124000; y=108000; + li:objects { + ha:text.1 { x1=0; y1=-2000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:group.2 { + uuid=q7jNL8tNDwr0npd8eeMAAABT; src_uuid=q7jNL8tNDwr0npd8eeMAAABJ; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:group.3 { + uuid=q7jNL8tNDwr0npd8eeMAAABU; src_uuid=q7jNL8tNDwr0npd8eeMAAABK; + x=0; y=4000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:polygon.4 { + li:outline { + ha:line { x1=0; y1=-2000; x2=0; y2=6000; } + ha:line { x1=0; y1=6000; x2=4000; y2=6000; } + ha:line { x1=4000; y1=6000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=0; y2=-2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + name=CN2 + role=symbol + spice/omit=yes + } + } + ha:connection.143 { + li:conn { + /2/29/1 + /2/142/3/1 + } + } + ha:group.144 { + uuid=q7jNL8tNDwr0npd8eeMAAABV; + li:objects { + ha:line.1 { x1=120000; y1=108000; x2=116000; y2=108000; stroke=wire; } + ha:line.2 { x1=116000; y1=108000; x2=116000; y2=104000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.145 { + li:conn { + /2/144/1 + /2/142/2/1 + } + } + ha:connection.146 { + li:conn { + /2/144/2 + /2/54/1/1 + } + } + } + ha:attrib { + maintainer=Tibor 'Igor2' Palinkas + page=1 of 1 + print_page=A/4 + title={high level SIM: BJT amplifier, ac} + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + fullscreen = 0 + } + } + } +} Index: tags/1.0.5/doc/tutorial/simulation/sim/12_bjt_amp_ac/index.html =================================================================== --- tags/1.0.5/doc/tutorial/simulation/sim/12_bjt_amp_ac/index.html (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/sim/12_bjt_amp_ac/index.html (revision 10414) @@ -0,0 +1,75 @@ + + +

12_bjt_amp_ac: pinout with spice/portmap

+ +

Scope

+

+In this simulation we are going to look at a single-transistor amplifier +in frequency domain to verify how it amplifies a sine waves. Compared to +the trans variant the only difference is +how we specify the transistor pinout and how the simulation setup is configured. + +

The schematics

+

+Largely the same as trans variant. +

+

+ +
Click the image to get the sch-rnd sheet; also requires this project.lht in the same directory
+

+ +

Preparing for simulation

+ +

Q1

+

+This example demonstrates using spice/portmap to set the pinout: the +stock spice/pinnum attributes has been manually removed from Q1 terminals and +a portmap attribute, array type, added to the Q1 symbol. The portmap is: +

+{C->spice/pinnum=1}
+{B->spice/pinnum=2}
+{E->spice/pinnum=3}
+
+

+Since the attribute is called spice/portmap, it does not interfere with +the normal portmap attribute (installed by devmap in our example) and it +affects the spice workflow only. +

+The simulation setup process is largely the same as in the +base example of dc op point. The simulation +setup in this example is called "ac characteristics". + +

Modifications

+

+This circuit needs two voltage sources, which are both added as modifications. +The first one is a DC 5V source connected to net Vcc (and GND). The second +acts as the small signal AC source for the AC analysis, this it has a an AC +value (of 0.1 V); it is connected to net in (and GND). + + +

Sim setup: output config

+

+(Same as in example 06_passive_ac ) +

+This simulation has two output configs, one for displaying the transfer +(in decibel) and one for the phase (in radian). The reason for specify them +in two separate output is the largely different y scale and unit. +

+The first output uses ac (dec) for analysis. This will feed in 10 +different frequencies per decade and caputre the output. This also means +the X axis, frequency, is logarithmic (common for frequency domain analysis). +

+The property to plot is vdb(out), which is the "voltage decibel" of +the network called out. Instead of the net name a component-port could be +specified within vdb(). +

+The second output uses anlaysis previous, which means no new simulation +is ran, but the data of the previous simulation is used. The presentation is +also a plot of "out", but using the cph() function, which is the phase in +radian. +

+

+ +
Simulation setup dialog, third tab, after execution
+

+ Index: tags/1.0.5/doc/tutorial/simulation/sim/12_bjt_amp_ac/project.lht =================================================================== --- tags/1.0.5/doc/tutorial/simulation/sim/12_bjt_amp_ac/project.lht (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/sim/12_bjt_amp_ac/project.lht (revision 10414) @@ -0,0 +1,60 @@ +ha:coraleda-project-v1 { + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:plugins { + ha:sim { + li:setups { + {ha:ac characteristics} { + li:mods { + ha:add { + value = 5 + pos = Vcc + tdf = none + device = V + ha:tdf_params { + } + } + ha:add { + ac_value = 0.1 + value = 0 + pos = in + tdf = none + device = V + ha:tdf_params { + } + } + } + li:output { + ha:decibel { + ha:presentation { + type = plot + li:props { + vdb(out) + } + } + ha:analysis { + type = ac_dec + start = 1 + numpt = 10 + stop = 1000k + } + } + ha:phase { + ha:presentation { + type = plot + li:props { + cph(out) + } + } + ha:analysis { + type = previous + } + } + } + } + } + } + } + } + } +} Index: tags/1.0.5/doc/tutorial/simulation/sim/12_bjt_amp_ac/sim_run.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/1.0.5/doc/tutorial/simulation/sim/12_bjt_amp_ac/sim_run.png =================================================================== --- tags/1.0.5/doc/tutorial/simulation/sim/12_bjt_amp_ac/sim_run.png (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/sim/12_bjt_amp_ac/sim_run.png (revision 10414) Property changes on: tags/1.0.5/doc/tutorial/simulation/sim/12_bjt_amp_ac/sim_run.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/1.0.5/doc/tutorial/simulation/sim/16_opamp_dc/16_opamp_dc.rs =================================================================== --- tags/1.0.5/doc/tutorial/simulation/sim/16_opamp_dc/16_opamp_dc.rs (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/sim/16_opamp_dc/16_opamp_dc.rs (revision 10414) @@ -0,0 +1,886 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + ha:group.1 { + uuid=Hif/m8o2mo/CrYnTszoAAAAV; + li:objects { + ha:group.1 { + uuid=Hif/m8o2mo/CrYnTszoAAAAW; loclib_name=lm358_so8; + li:objects { + } + ha:attrib { + footprint=so(8) + li:portmap { + {1/in- -> pcb/pinnum=2} + {1/in+ -> pcb/pinnum=3} + {1/out -> pcb/pinnum=1} + {1/V+ -> pcb/pinnum=8} + {1/V- -> pcb/pinnum=4} + {2/in- -> pcb/pinnum=6} + {2/in+ -> pcb/pinnum=5} + {2/out -> pcb/pinnum=7} + {2/V+ -> pcb/pinnum=8} + {2/V- -> pcb/pinnum=4} + } + } + } + } + ha:attrib { + ha:purpose = { value=devmap; prio=0; } + } + } + ha:group.2 { + uuid=y4qxH+ae2qngQHst1jcAAAA1; + li:objects { + ha:group.1 { + uuid=y4qxH+ae2qngQHst1jcAAAA2; loclib_name=lm358; + li:objects { + } + ha:attrib { + spice/model_card={* lm358 - low power opamp model (single slot) +* +* (C) 2023 Tibor 'Igor2' Palinkas +* License: CC0 (no rights reserved): https://creativecommons.org/publicdomain/zero/1.0/ +* Source: from ST's datasheet: https://archive.org/details/st-ts321 +* (st321 is reasonably close to lm358 for simple simulation cases; see +* warnings on page 7) +* +* +** CONNECTIONS: +* 1 inverting input +* 2 non-inverting INPUT +* 3 output +* 4 positive power supply +* 5 negative power supply +.SUBCKT LM358 1 2 3 4 5 + +.MODEL MDTH D IS=1E-8 KF=3.104131E-15 CJO=10F + +* INPUT STAGE +CIP 2 5 1.000000E-12 +CIN 1 5 1.000000E-12 +EIP 10 5 2 5 1 +EIN 16 5 1 5 1 +RIP 10 11 2.600000E+01 +RIN 15 16 2.600000E+01 +RIS 11 15 2.003862E+02 +DIP 11 12 MDTH 400E-12 +DIN 15 14 MDTH 400E-12 +VOFP 12 13 DC 0 +VOFN 13 14 DC 0 +IPOL 13 5 1.000000E-05 +CPS 11 15 3.783376E-09 +DINN 17 13 MDTH 400E-12 +VIN 17 5 0.000000e+00 +DINR 15 18 MDTH 400E-12 +VIP 4 18 2.000000E+00 +FCP 4 5 VOFP 3.400000E+01 +FCN 5 4 VOFN 3.400000E+01 +FIBP 2 5 VOFN 2.000000E-03 +FIBN 5 1 VOFP 2.000000E-03 + +* AMPLIFYING STAGE +FIP 5 19 VOFP 3.600000E+02 +FIN 5 19 VOFN 3.600000E+02 +RG1 19 5 3.652997E+06 +RG2 19 4 3.652997E+06 +CC 19 5 6.000000E-09 +DOPM 19 22 MDTH 400E-12 +DONM 21 19 MDTH 400E-12 +HOPM 22 28 VOUT 7.500000E+03 +VIPM 28 4 1.500000E+02 +HONM 21 27 VOUT 7.500000E+03 +VINM 5 27 1.500000E+02 +EOUT 26 23 19 5 1 +VOUT 23 5 0 +ROUT 26 3 20 +COUT 3 5 1.000000E-12 +DOP 19 25 MDTH 400E-12 +VOP 4 25 2.242230E+00 +DON 24 19 MDTH 400E-12 +VON 24 5 7.922301E-01 +.ENDS +} + } + } + } + ha:attrib { + ha:purpose = { value=spicelib; prio=0; } + } + } + } + } + ha:obj_direct.2 { + uuid=Hif/m8o2mo/CrYnTszoAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.1 { + uuid=8/SYZ/pfBzxyqFA12WQAAAAC; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAg; + li:objects { + ha:polygon.11 { + li:outline { + ha:line { x1=0; y1=0; x2=80000; y2=0; } + ha:line { x1=80000; y1=0; x2=80000; y2=20000; } + ha:line { x1=80000; y1=20000; x2=0; y2=20000; } + ha:line { x1=0; y1=20000; x2=0; y2=0; } + } + stroke=titlebox-frame; + fill=titlebox-fill; + } + ha:line.12 { x1=0; y1=10000; x2=80000; y2=10000; stroke=titlebox-frame; } + ha:line.13 { x1=40000; y1=10000; x2=40000; y2=0; stroke=titlebox-frame; } + ha:text.20 { x1=1000; y1=16500; dyntext=0; stroke=titlebox-big; text=TITLE; } + ha:text.21 { x1=1000; y1=10500; x2=79000; y2=16000; dyntext=1; stroke=titlebox-big; text=%../../A.title%; } + ha:text.22 { x1=1000; y1=5500; dyntext=0; stroke=titlebox-small; text={PROJECT:}; } + ha:text.23 { x1=13000; y1=5500; x2=39000; y2=9500; dyntext=1; stroke=titlebox-big; text=%project.name%; } + ha:text.24 { x1=1000; y1=500; dyntext=0; stroke=titlebox-small; text={PAGE:}; } + ha:text.25 { x1=10000; y1=500; x2=39000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.page%; } + ha:text.26 { x1=41000; y1=5500; dyntext=0; stroke=titlebox-small; text={FILE:}; } + ha:text.27 { x1=48000; y1=5500; x2=79000; y2=9500; dyntext=1; stroke=titlebox-big; text=%filename%; } + ha:text.28 { x1=41000; y1=500; dyntext=0; stroke=titlebox-small; text={MAINTAINER:}; } + ha:text.29 { x1=55000; y1=500; x2=79000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.maintainer%; } + } + ha:attrib { + purpose=titlebox + } + } + ha:group.2 { + uuid=Hif/m8o2mo/CrYnTszoAAAAP; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAH; + x=80000; y=116000; + li:objects { + ha:group.1 { + uuid=Hif/m8o2mo/CrYnTszoAAAAQ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAI; + x=-20000; y=4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=in+ + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.2 { + uuid=Hif/m8o2mo/CrYnTszoAAAAR; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAJ; + x=-20000; y=-4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=in- + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:group.3 { + uuid=Hif/m8o2mo/CrYnTszoAAAAS; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAK; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=out + role=terminal + ha:spice/pinnum = { value=3; prio=31050; } + } + } + ha:line.4 { x1=-20000; y1=-8000; x2=-20000; y2=8000; stroke=sym-decor; } + ha:line.5 { x1=-20000; y1=8000; x2=-4000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=-4000; y1=0; x2=-20000; y2=-8000; stroke=sym-decor; } + ha:line.7 { x1=-18000; y1=5000; x2=-18000; y2=3000; stroke=sym-decor; } + ha:line.8 { x1=-19000; y1=4000; x2=-17000; y2=4000; stroke=sym-decor; } + ha:line.9 { x1=-19000; y1=-4000; x2=-17000; y2=-4000; stroke=sym-decor; } + ha:group.10 { + uuid=Hif/m8o2mo/CrYnTszoAAAAT; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAL; + x=-12000; y=-4000; rot=270.000000; mirx=1; miry=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=0; y1=-1000; rot=180.000000; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=V- + role=terminal + ha:spice/pinnum = { value=5; prio=31050; } + } + } + ha:group.11 { + uuid=Hif/m8o2mo/CrYnTszoAAAAU; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAM; + x=-12000; y=8000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=-4000; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=V+ + role=terminal + ha:spice/pinnum = { value=4; prio=31050; } + } + } + ha:text.12 { x1=-21000; y1=9000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -slot=1 + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + devmap=lm358_so8 + name=U1 + role=symbol + spice/model=lm358 + } + } + ha:group.3 { + uuid=Hif/m8o2mo/CrYnTszoAAAAd; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=24000; y=112000; + li:objects { + ha:group.1 { + uuid=Hif/m8o2mo/CrYnTszoAAAAe; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=Hif/m8o2mo/CrYnTszoAAAAf; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=R1 + role=symbol + value=1k + } + } + ha:group.4 { + uuid=Hif/m8o2mo/CrYnTszoAAAAg; + x=-20000; y=0; + li:objects { + ha:line.1 { x1=64000; y1=112000; x2=76000; y2=112000; stroke=wire; } + ha:line.2 { x1=72000; y1=112000; x2=72000; y2=84000; stroke=wire; } + ha:line.3 { x1=72000; y1=112000; x2=72000; y2=112000; stroke=junction; } + ha:line.4 { x1=72000; y1=84000; x2=84000; y2=84000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.5 { + li:conn { + /2/4/1 + /2/2/2/1 + } + } + ha:group.7 { + uuid=Hif/m8o2mo/CrYnTszoAAAAk; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=64000; y=84000; + li:objects { + ha:group.1 { + uuid=Hif/m8o2mo/CrYnTszoAAAAl; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=Hif/m8o2mo/CrYnTszoAAAAm; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=R2 + role=symbol + value=100k + } + } + ha:group.9 { + uuid=Hif/m8o2mo/CrYnTszoAAAAn; + x=-20000; y=0; + li:objects { + ha:line.1 { x1=104000; y1=84000; x2=112000; y2=84000; stroke=wire; } + ha:line.2 { x1=112000; y1=84000; x2=112000; y2=116000; stroke=wire; } + ha:line.3 { x1=100000; y1=116000; x2=116000; y2=116000; stroke=wire; } + ha:line.4 { x1=112000; y1=116000; x2=112000; y2=116000; stroke=junction; } + ha:text.5 { x1=112000; y1=116000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=out + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.12 { + uuid=Hif/m8o2mo/CrYnTszoAAAAo; + x=-12000; y=0; + li:objects { + ha:line.1 { x1=36000; y1=112000; x2=24000; y2=112000; stroke=wire; } + ha:text.2 { x1=28000; y1=112000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=in + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.14 { + uuid=Hif/m8o2mo/CrYnTszoAAAAt; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=48000; y=120000; + li:objects { + ha:group.1 { + uuid=Hif/m8o2mo/CrYnTszoAAAAu; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.15 { + uuid=Hif/m8o2mo/CrYnTszoAAAAv; + x=-20000; y=0; + li:objects { + ha:line.1 { x1=68000; y1=120000; x2=76000; y2=120000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.16 { + li:conn { + /2/15/1 + /2/2/1/1 + } + } + ha:group.18 { + uuid=Hif/m8o2mo/CrYnTszoAAAA8; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB6; + x=68000; y=128000; + li:objects { + ha:group.1 { + uuid=Hif/m8o2mo/CrYnTszoAAAA9; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB7; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-4000; y1=4000; x2=4000; y2=7000; halign=center; dyntext=0; stroke=sym-primary; text=Vcc; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:Vcc} + } + role=symbol + } + } + ha:group.19 { + uuid=Hif/m8o2mo/CrYnTszoAAAA+; + x=-20000; y=0; + li:objects { + ha:line.1 { x1=88000; y1=124000; x2=88000; y2=128000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.22 { + uuid=Hif/m8o2mo/CrYnTszoAAABH; src_uuid=iNOQfJpO6hT/HFDFGjoAAABv; + x=68000; y=104000; rot=180.000000; + li:objects { + ha:group.1 { + uuid=Hif/m8o2mo/CrYnTszoAAABI; src_uuid=iNOQfJpO6hT/HFDFGjoAAABw; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=6000; y1=7000; x2=18000; y2=10000; rot=180.000000; halign=center; dyntext=1; stroke=sym-primary; text=%../A.rail%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:forge { + delete,forge/tmp + scalar,forge/tmp + {sub,^,1:,forge/tmp} + suba,$,rail,forge/tmp + array,connect + append,connect,forge/tmp + } + rail=Vneg + role=symbol + } + } + ha:group.23 { + uuid=Hif/m8o2mo/CrYnTszoAAABJ; + x=-20000; y=0; + li:objects { + ha:line.1 { x1=88000; y1=104000; x2=88000; y2=108000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.102 { + li:conn { + /2/3/2/1 + /2/12/1 + } + } + ha:connection.103 { + li:conn { + /2/4/1 + /2/3/1/1 + } + } + ha:connection.104 { + li:conn { + /2/7/2/1 + /2/4/4 + } + } + ha:connection.105 { + li:conn { + /2/9/1 + /2/7/1/1 + } + } + ha:connection.106 { + li:conn { + /2/9/3 + /2/2/3/1 + } + } + ha:connection.107 { + li:conn { + /2/15/1 + /2/14/1/1 + } + } + ha:connection.108 { + li:conn { + /2/19/1 + /2/18/1/1 + } + } + ha:connection.109 { + li:conn { + /2/19/1 + /2/2/11/1 + } + } + ha:connection.110 { + li:conn { + /2/23/1 + /2/2/10/1 + } + } + ha:connection.111 { + li:conn { + /2/23/1 + /2/22/1/1 + } + } + ha:group.112 { + uuid=u6bADXQQa0V4HJRNz+sAAABD; src_uuid=u6bADXQQa0V4HJRNz+sAAAA9; + x=24000; y=44000; mirx=1; + li:objects { + ha:text.1 { x1=0; y1=-2000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:group.2 { + uuid=u6bADXQQa0V4HJRNz+sAAABE; src_uuid=u6bADXQQa0V4HJRNz+sAAAA+; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:group.3 { + uuid=u6bADXQQa0V4HJRNz+sAAABF; src_uuid=u6bADXQQa0V4HJRNz+sAAAA/; + x=0; y=4000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.4 { + uuid=u6bADXQQa0V4HJRNz+sAAABG; src_uuid=u6bADXQQa0V4HJRNz+sAAABA; + x=0; y=8000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=3 + role=terminal + } + } + ha:group.5 { + uuid=u6bADXQQa0V4HJRNz+sAAABH; src_uuid=u6bADXQQa0V4HJRNz+sAAABB; + x=0; y=12000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=4 + role=terminal + } + } + ha:group.6 { + uuid=u6bADXQQa0V4HJRNz+sAAABI; src_uuid=u6bADXQQa0V4HJRNz+sAAABC; + x=0; y=16000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=5 + role=terminal + } + } + ha:polygon.7 { + li:outline { + ha:line { x1=0; y1=-2000; x2=0; y2=18000; } + ha:line { x1=0; y1=18000; x2=4000; y2=18000; } + ha:line { x1=4000; y1=18000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=0; y2=-2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + name=CN1 + role=symbol + spice/omit=yes + } + } + ha:group.113 { + uuid=u6bADXQQa0V4HJRNz+sAAABL; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=32000; y=40000; + li:objects { + ha:group.1 { + uuid=u6bADXQQa0V4HJRNz+sAAABM; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.114 { + uuid=u6bADXQQa0V4HJRNz+sAAABN; + x=-20000; y=-16000; + li:objects { + ha:line.1 { x1=48000; y1=60000; x2=52000; y2=60000; stroke=wire; } + ha:line.2 { x1=52000; y1=60000; x2=52000; y2=56000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.117 { + li:conn { + /2/114/1 + /2/112/2/1 + } + } + ha:connection.118 { + li:conn { + /2/114/2 + /2/113/1/1 + } + } + ha:group.120 { + uuid=u6bADXQQa0V4HJRNz+sAAABS; src_uuid=iNOQfJpO6hT/HFDFGjoAAABv; + x=40000; y=40000; rot=180.000000; + li:objects { + ha:group.1 { + uuid=u6bADXQQa0V4HJRNz+sAAABT; src_uuid=iNOQfJpO6hT/HFDFGjoAAABw; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=6000; y1=7000; x2=18000; y2=10000; rot=180.000000; halign=center; dyntext=1; stroke=sym-primary; text=%../A.rail%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:forge { + delete,forge/tmp + scalar,forge/tmp + {sub,^,1:,forge/tmp} + suba,$,rail,forge/tmp + array,connect + append,connect,forge/tmp + } + rail=Vneg + role=symbol + } + } + ha:group.121 { + uuid=u6bADXQQa0V4HJRNz+sAAABU; + li:objects { + ha:line.1 { x1=28000; y1=48000; x2=40000; y2=48000; stroke=wire; } + ha:line.2 { x1=40000; y1=48000; x2=40000; y2=40000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.122 { + li:conn { + /2/121/1 + /2/112/3/1 + } + } + ha:connection.123 { + li:conn { + /2/121/2 + /2/120/1/1 + } + } + ha:group.126 { + uuid=u6bADXQQa0V4HJRNz+sAAABY; src_uuid=Hif/m8o2mo/CrYnTszoAAAAo; + x=4000; y=-60000; + li:objects { + ha:line.1 { x1=28000; y1=112000; x2=24000; y2=112000; stroke=wire; } + ha:text.2 { x1=29000; y1=111000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=in + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.127 { + li:conn { + /2/126/1 + /2/112/4/1 + } + } + ha:group.128 { + uuid=u6bADXQQa0V4HJRNz+sAAABa; src_uuid=Hif/m8o2mo/CrYnTszoAAAAo; + x=4000; y=-56000; + li:objects { + ha:line.1 { x1=28000; y1=112000; x2=24000; y2=112000; stroke=wire; } + ha:text.2 { x1=29000; y1=111000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=out + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.129 { + li:conn { + /2/128/1 + /2/112/5/1 + } + } + ha:group.130 { + uuid=u6bADXQQa0V4HJRNz+sAAABd; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB6; + x=32000; y=64000; + li:objects { + ha:group.1 { + uuid=u6bADXQQa0V4HJRNz+sAAABe; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB7; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-4000; y1=4000; x2=4000; y2=7000; halign=center; dyntext=0; stroke=sym-primary; text=Vcc; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:Vcc} + } + role=symbol + } + } + ha:group.131 { + uuid=u6bADXQQa0V4HJRNz+sAAABf; + li:objects { + ha:line.1 { x1=28000; y1=60000; x2=32000; y2=60000; stroke=wire; } + ha:line.2 { x1=32000; y1=60000; x2=32000; y2=64000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.132 { + li:conn { + /2/131/1 + /2/112/6/1 + } + } + ha:connection.133 { + li:conn { + /2/131/2 + /2/130/1/1 + } + } + } + ha:attrib { + maintainer=Tibor 'Igor2' Palinkas + page=1 of 1 + print_page=A/4 + title={high level SIM: ompamp circuit, dc gain} + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 2 + grid = 4.0960 mm + } + } + } +} Index: tags/1.0.5/doc/tutorial/simulation/sim/16_opamp_dc/16_opamp_dc.svg =================================================================== --- tags/1.0.5/doc/tutorial/simulation/sim/16_opamp_dc/16_opamp_dc.svg (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/sim/16_opamp_dc/16_opamp_dc.svg (revision 10414) @@ -0,0 +1,759 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/1.0.5/doc/tutorial/simulation/sim/16_opamp_dc/index.html =================================================================== --- tags/1.0.5/doc/tutorial/simulation/sim/16_opamp_dc/index.html (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/sim/16_opamp_dc/index.html (revision 10414) @@ -0,0 +1,64 @@ + + +

16_opamp_dc: dc sweep

+ +

Scope

+

+In this simulation we are going to map a simple opamp circuit's gain +at different voltages (dc sweep). + +

The schematics

+

+The single-sheet schematic contains the opamp circuit with connectors, +suitable for the PCB workflow. +

+

+ +
Click the image to get the sch-rnd sheet; also requires this project.lht in the same directory
+

+ +

Opamp model

+

+This example uses the lm358 macromodel from sch-rnd's stock spice +library. This model is a subcircuit of the amplifier and simulates a +lot of limiters and parasitics. + +

Preparing for simulation

+ +

Q1

+

+The model uses the standard opamp pinout so the hardwired spice/pinnum +attributes on the terminals will simply work. +

+The simulation setup process is largely the same as in the +base example of dc op point. The simulation +setup in this example is called "dc gain". + +

Modifications

+

+This circuit needs three voltage sources, which are both added as modifications. +The first one is a DC 5V source connected to net Vcc (and GND). The second is +a DC -5V source connected to net Vneg (and GND). These are the power supply +rails of the opamp. +

+The third source is connected to the net in (and GND). Unlike other +sources in the examples so far, this one has a name: V1. This is important +because the analysis will need a named source for the sweep. + +

Sim setup: output config

+

+The analysis to use is dc (lin) which is a linear DC sweep: spice +will vary the voltage on V1 (selected in the source name field, refers to +V1 set up as a modification above). It is configured to run +from -50mV to +60mV on the input, increasing voltage by 2 mV steps. +

+At the end the input and output voltages are plotted. The plot will use +linear X axis because of the analysis is "(lin)". + +

+

+ +
Simulation setup dialog, third tab, after execution
+

+Because of the large amplification factor, the +input (red) trace is visible only when zoomed in. Index: tags/1.0.5/doc/tutorial/simulation/sim/16_opamp_dc/project.lht =================================================================== --- tags/1.0.5/doc/tutorial/simulation/sim/16_opamp_dc/project.lht (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/sim/16_opamp_dc/project.lht (revision 10414) @@ -0,0 +1,59 @@ +ha:coraleda-project-v1 { + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:plugins { + ha:sim { + li:setups { + {ha:dc gain} { + li:mods { + ha:add { + value = 5 + pos = Vcc + tdf = none + device = V + ha:tdf_params { + } + } + ha:add { + value = -5 + pos = Vneg + tdf = none + device = V + ha:tdf_params { + } + } + ha:add { + value = 0 + pos = in + tdf = none + device = V + ha:tdf_params { + } + name = V1 + } + } + li:output { + {ha:dc sweep} { + ha:presentation { + type = plot + li:props { + in + out + } + } + ha:analysis { + type = dc_lin + start = -50m + incr = 2m + src = V1 + stop = 60m + } + } + } + } + } + } + } + } + } +} Index: tags/1.0.5/doc/tutorial/simulation/sim/16_opamp_dc/sim_run.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/1.0.5/doc/tutorial/simulation/sim/16_opamp_dc/sim_run.png =================================================================== --- tags/1.0.5/doc/tutorial/simulation/sim/16_opamp_dc/sim_run.png (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/sim/16_opamp_dc/sim_run.png (revision 10414) Property changes on: tags/1.0.5/doc/tutorial/simulation/sim/16_opamp_dc/sim_run.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/1.0.5/doc/tutorial/simulation/sim/18_opamp_ac/18_opamp_ac.rs =================================================================== --- tags/1.0.5/doc/tutorial/simulation/sim/18_opamp_ac/18_opamp_ac.rs (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/sim/18_opamp_ac/18_opamp_ac.rs (revision 10414) @@ -0,0 +1,1404 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + ha:group.1 { + uuid=Hif/m8o2mo/CrYnTszoAAAAV; + li:objects { + ha:group.1 { + uuid=Hif/m8o2mo/CrYnTszoAAAAW; loclib_name=lm358_so8; + li:objects { + } + ha:attrib { + footprint=so(8) + li:portmap { + {1/in- -> pcb/pinnum=2} + {1/in+ -> pcb/pinnum=3} + {1/out -> pcb/pinnum=1} + {1/V+ -> pcb/pinnum=8} + {1/V- -> pcb/pinnum=4} + {2/in- -> pcb/pinnum=6} + {2/in+ -> pcb/pinnum=5} + {2/out -> pcb/pinnum=7} + {2/V+ -> pcb/pinnum=8} + {2/V- -> pcb/pinnum=4} + } + } + } + } + ha:attrib { + ha:purpose = { value=devmap; prio=0; } + } + } + ha:group.2 { + uuid=mWD+aTBiBXTjVEOQC6IAAABQ; + li:objects { + ha:group.1 { + uuid=mWD+aTBiBXTjVEOQC6IAAABR; loclib_name=lm358; + li:objects { + } + ha:attrib { + spice/model_card={* lm358 - low power opamp model (single slot) +* +* (C) 2023 Tibor 'Igor2' Palinkas +* License: CC0 (no rights reserved): https://creativecommons.org/publicdomain/zero/1.0/ +* Source: from ST's datasheet: https://archive.org/details/st-ts321 +* (st321 is reasonably close to lm358 for simple simulation cases; see +* warnings on page 7) +* +* +** CONNECTIONS: +* 1 inverting input +* 2 non-inverting INPUT +* 3 output +* 4 positive power supply +* 5 negative power supply +.SUBCKT LM358 1 2 3 4 5 + +.MODEL MDTH D IS=1E-8 KF=3.104131E-15 CJO=10F + +* INPUT STAGE +CIP 2 5 1.000000E-12 +CIN 1 5 1.000000E-12 +EIP 10 5 2 5 1 +EIN 16 5 1 5 1 +RIP 10 11 2.600000E+01 +RIN 15 16 2.600000E+01 +RIS 11 15 2.003862E+02 +DIP 11 12 MDTH 400E-12 +DIN 15 14 MDTH 400E-12 +VOFP 12 13 DC 0 +VOFN 13 14 DC 0 +IPOL 13 5 1.000000E-05 +CPS 11 15 3.783376E-09 +DINN 17 13 MDTH 400E-12 +VIN 17 5 0.000000e+00 +DINR 15 18 MDTH 400E-12 +VIP 4 18 2.000000E+00 +FCP 4 5 VOFP 3.400000E+01 +FCN 5 4 VOFN 3.400000E+01 +FIBP 2 5 VOFN 2.000000E-03 +FIBN 5 1 VOFP 2.000000E-03 + +* AMPLIFYING STAGE +FIP 5 19 VOFP 3.600000E+02 +FIN 5 19 VOFN 3.600000E+02 +RG1 19 5 3.652997E+06 +RG2 19 4 3.652997E+06 +CC 19 5 6.000000E-09 +DOPM 19 22 MDTH 400E-12 +DONM 21 19 MDTH 400E-12 +HOPM 22 28 VOUT 7.500000E+03 +VIPM 28 4 1.500000E+02 +HONM 21 27 VOUT 7.500000E+03 +VINM 5 27 1.500000E+02 +EOUT 26 23 19 5 1 +VOUT 23 5 0 +ROUT 26 3 20 +COUT 3 5 1.000000E-12 +DOP 19 25 MDTH 400E-12 +VOP 4 25 2.242230E+00 +DON 24 19 MDTH 400E-12 +VON 24 5 7.922301E-01 +.ENDS +} + } + } + } + ha:attrib { + ha:purpose = { value=spicelib; prio=0; } + } + } + } + } + ha:obj_direct.2 { + uuid=Hif/m8o2mo/CrYnTszoAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.1 { + uuid=8/SYZ/pfBzxyqFA12WQAAAAC; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAg; + li:objects { + ha:polygon.11 { + li:outline { + ha:line { x1=0; y1=0; x2=80000; y2=0; } + ha:line { x1=80000; y1=0; x2=80000; y2=20000; } + ha:line { x1=80000; y1=20000; x2=0; y2=20000; } + ha:line { x1=0; y1=20000; x2=0; y2=0; } + } + stroke=titlebox-frame; + fill=titlebox-fill; + } + ha:line.12 { x1=0; y1=10000; x2=80000; y2=10000; stroke=titlebox-frame; } + ha:line.13 { x1=40000; y1=10000; x2=40000; y2=0; stroke=titlebox-frame; } + ha:text.20 { x1=1000; y1=16500; dyntext=0; stroke=titlebox-big; text=TITLE; } + ha:text.21 { x1=1000; y1=10500; x2=79000; y2=16000; dyntext=1; stroke=titlebox-big; text=%../../A.title%; } + ha:text.22 { x1=1000; y1=5500; dyntext=0; stroke=titlebox-small; text={PROJECT:}; } + ha:text.23 { x1=13000; y1=5500; x2=39000; y2=9500; dyntext=1; stroke=titlebox-big; text=%project.name%; } + ha:text.24 { x1=1000; y1=500; dyntext=0; stroke=titlebox-small; text={PAGE:}; } + ha:text.25 { x1=10000; y1=500; x2=39000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.page%; } + ha:text.26 { x1=41000; y1=5500; dyntext=0; stroke=titlebox-small; text={FILE:}; } + ha:text.27 { x1=48000; y1=5500; x2=79000; y2=9500; dyntext=1; stroke=titlebox-big; text=%filename%; } + ha:text.28 { x1=41000; y1=500; dyntext=0; stroke=titlebox-small; text={MAINTAINER:}; } + ha:text.29 { x1=55000; y1=500; x2=79000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.maintainer%; } + } + ha:attrib { + purpose=titlebox + } + } + ha:group.2 { + uuid=Hif/m8o2mo/CrYnTszoAAAAP; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAH; + x=116000; y=116000; + li:objects { + ha:group.1 { + uuid=Hif/m8o2mo/CrYnTszoAAAAQ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAI; + x=-20000; y=4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=in+ + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.2 { + uuid=Hif/m8o2mo/CrYnTszoAAAAR; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAJ; + x=-20000; y=-4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=in- + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:group.3 { + uuid=Hif/m8o2mo/CrYnTszoAAAAS; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAK; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=out + role=terminal + ha:spice/pinnum = { value=3; prio=31050; } + } + } + ha:line.4 { x1=-20000; y1=-8000; x2=-20000; y2=8000; stroke=sym-decor; } + ha:line.5 { x1=-20000; y1=8000; x2=-4000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=-4000; y1=0; x2=-20000; y2=-8000; stroke=sym-decor; } + ha:line.7 { x1=-18000; y1=5000; x2=-18000; y2=3000; stroke=sym-decor; } + ha:line.8 { x1=-19000; y1=4000; x2=-17000; y2=4000; stroke=sym-decor; } + ha:line.9 { x1=-19000; y1=-4000; x2=-17000; y2=-4000; stroke=sym-decor; } + ha:group.10 { + uuid=Hif/m8o2mo/CrYnTszoAAAAT; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAL; + x=-12000; y=-4000; rot=270.000000; mirx=1; miry=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=0; y1=-1000; rot=180.000000; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=V- + role=terminal + ha:spice/pinnum = { value=5; prio=31050; } + spice/shared=yes + } + } + ha:group.11 { + uuid=Hif/m8o2mo/CrYnTszoAAAAU; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAM; + x=-12000; y=8000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=-4000; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=V+ + role=terminal + ha:spice/pinnum = { value=4; prio=31050; } + spice/shared=yes + } + } + ha:text.12 { x1=-21000; y1=9000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:text.13 { x1=-17000; y1=9000; dyntext=1; stroke=sym-secondary; text=%../A.-slot%; floater=1; } + ha:text.14 { x1=-8000; y1=4000; dyntext=1; stroke=sym-secondary; text=%../A.devmap%; floater=1; } + } + ha:attrib { + -slot=1 + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + devmap=lm358_so8 + name=U1 + role=symbol + spice/model=lm358 + } + } + ha:group.3 { + uuid=Hif/m8o2mo/CrYnTszoAAAAd; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=60000; y=120000; + li:objects { + ha:group.1 { + uuid=Hif/m8o2mo/CrYnTszoAAAAe; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=Hif/m8o2mo/CrYnTszoAAAAf; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=R2 + role=symbol + value=1600 + } + } + ha:group.7 { + uuid=Hif/m8o2mo/CrYnTszoAAAAk; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=48000; y=104000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=Hif/m8o2mo/CrYnTszoAAAAl; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=Hif/m8o2mo/CrYnTszoAAAAm; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=-6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=-6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=R3 + role=symbol + value=800 + } + } + ha:group.12 { + uuid=Hif/m8o2mo/CrYnTszoAAAAo; + x=-12000; y=0; + li:objects { + ha:text.2 { x1=20000; y1=120000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + ha:line.5 { x1=24000; y1=108000; x2=36000; y2=108000; stroke=wire; } + ha:line.7 { x1=24000; y1=108000; x2=24000; y2=120000; stroke=wire; } + ha:line.8 { x1=20000; y1=120000; x2=36000; y2=120000; stroke=wire; } + ha:line.9 { x1=24000; y1=120000; x2=24000; y2=120000; stroke=junction; } + } + ha:attrib { + name=in + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.18 { + uuid=Hif/m8o2mo/CrYnTszoAAAA8; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB6; + x=104000; y=128000; + li:objects { + ha:group.1 { + uuid=Hif/m8o2mo/CrYnTszoAAAA9; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB7; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-4000; y1=4000; x2=4000; y2=7000; halign=center; dyntext=0; stroke=sym-primary; text=Vcc; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:Vcc} + } + role=symbol + } + } + ha:group.19 { + uuid=Hif/m8o2mo/CrYnTszoAAAA+; + x=16000; y=0; + li:objects { + ha:line.1 { x1=88000; y1=124000; x2=88000; y2=128000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.22 { + uuid=Hif/m8o2mo/CrYnTszoAAABH; src_uuid=iNOQfJpO6hT/HFDFGjoAAABv; + x=104000; y=104000; rot=180.000000; + li:objects { + ha:group.1 { + uuid=Hif/m8o2mo/CrYnTszoAAABI; src_uuid=iNOQfJpO6hT/HFDFGjoAAABw; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=6000; y1=7000; x2=18000; y2=10000; rot=180.000000; halign=center; dyntext=1; stroke=sym-primary; text=%../A.rail%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:forge { + delete,forge/tmp + scalar,forge/tmp + {sub,^,1:,forge/tmp} + suba,$,rail,forge/tmp + array,connect + append,connect,forge/tmp + } + rail=Vneg + role=symbol + } + } + ha:group.23 { + uuid=Hif/m8o2mo/CrYnTszoAAABJ; + x=16000; y=0; + li:objects { + ha:line.1 { x1=88000; y1=104000; x2=88000; y2=108000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.125 { + li:conn { + /2/3/1/1 + /2/197/2 + } + } + ha:group.132 { + uuid=GePylIY1T4cR3zcyR1kAAAA7; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=24000; y=120000; + li:objects { + ha:group.1 { + uuid=GePylIY1T4cR3zcyR1kAAAA8; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=GePylIY1T4cR3zcyR1kAAAA9; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=R1 + role=symbol + value=1600 + } + } + ha:group.142 { + uuid=GePylIY1T4cR3zcyR1kAAABQ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAH; + x=92000; y=72000; mirx=1; + li:objects { + ha:group.1 { + uuid=GePylIY1T4cR3zcyR1kAAABR; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAI; + x=-20000; y=4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=in+ + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.2 { + uuid=GePylIY1T4cR3zcyR1kAAABS; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAJ; + x=-20000; y=-4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=in- + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:group.3 { + uuid=GePylIY1T4cR3zcyR1kAAABT; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAK; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=out + role=terminal + ha:spice/pinnum = { value=3; prio=31050; } + } + } + ha:line.4 { x1=-20000; y1=-8000; x2=-20000; y2=8000; stroke=sym-decor; } + ha:line.5 { x1=-20000; y1=8000; x2=-4000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=-4000; y1=0; x2=-20000; y2=-8000; stroke=sym-decor; } + ha:line.7 { x1=-18000; y1=5000; x2=-18000; y2=3000; stroke=sym-decor; } + ha:line.8 { x1=-19000; y1=4000; x2=-17000; y2=4000; stroke=sym-decor; } + ha:line.9 { x1=-19000; y1=-4000; x2=-17000; y2=-4000; stroke=sym-decor; } + ha:group.10 { + uuid=GePylIY1T4cR3zcyR1kAAABU; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAL; + x=-12000; y=-4000; rot=270.000000; mirx=1; miry=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=0; y1=-1000; rot=180.000000; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=V- + role=terminal + ha:spice/pinnum = { value=5; prio=31050; } + spice/shared=yes + } + } + ha:group.11 { + uuid=GePylIY1T4cR3zcyR1kAAABV; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAM; + x=-12000; y=8000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=-4000; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=V+ + role=terminal + ha:spice/pinnum = { value=4; prio=31050; } + spice/shared=yes + } + } + ha:text.12 { x1=-21000; y1=9000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:text.13 { x1=-17000; y1=9000; dyntext=1; stroke=sym-secondary; text=%../A.-slot%; floater=1; } + ha:text.14 { x1=-10000; y1=6000; dyntext=1; stroke=sym-secondary; text=%../A.devmap%; floater=1; } + } + ha:attrib { + -slot=2 + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + devmap=lm358_so8 + name=U1 + role=symbol + spice/model=lm358 + } + } + ha:group.146 { + uuid=GePylIY1T4cR3zcyR1kAAABX; + x=4000; y=0; + li:objects { + ha:line.1 { x1=112000; y1=76000; x2=124000; y2=76000; stroke=wire; } + ha:line.2 { x1=124000; y1=84000; x2=124000; y2=72000; stroke=wire; } + ha:line.3 { x1=124000; y1=76000; x2=124000; y2=76000; stroke=junction; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.147 { + li:conn { + /2/146/1 + /2/142/1/1 + } + } + ha:group.148 { + uuid=GePylIY1T4cR3zcyR1kAAABb; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=128000; y=104000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=GePylIY1T4cR3zcyR1kAAABc; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=GePylIY1T4cR3zcyR1kAAABd; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=R4 + role=symbol + value=250 + } + } + ha:group.149 { + uuid=GePylIY1T4cR3zcyR1kAAABh; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=128000; y=72000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=GePylIY1T4cR3zcyR1kAAABi; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=GePylIY1T4cR3zcyR1kAAABj; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=R5 + role=symbol + value=10k + } + } + ha:group.157 { + uuid=GePylIY1T4cR3zcyR1kAAABm; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=128000; y=52000; + li:objects { + ha:group.1 { + uuid=GePylIY1T4cR3zcyR1kAAABn; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.161 { + uuid=GePylIY1T4cR3zcyR1kAAABu; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAh; + x=24000; y=108000; + li:objects { + ha:group.1 { + uuid=GePylIY1T4cR3zcyR1kAAABv; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAi; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=GePylIY1T4cR3zcyR1kAAABw; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAj; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=16000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.5 { x1=9000; y1=5000; x2=9000; y2=-5000; stroke=sym-decor; } + ha:line.6 { x1=11000; y1=5000; x2=11000; y2=-5000; stroke=sym-decor; } + ha:line.7 { x1=4000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.8 { x1=11000; y1=0; x2=16000; y2=0; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=C1 + role=symbol + value=100n + } + } + ha:connection.162 { + li:conn { + /2/12/5 + /2/161/2/1 + } + } + ha:connection.163 { + li:conn { + /2/132/2/1 + /2/12/8 + } + } + ha:group.164 { + uuid=GePylIY1T4cR3zcyR1kAAABx; + li:objects { + ha:line.1 { x1=44000; y1=108000; x2=60000; y2=108000; stroke=wire; } + ha:line.2 { x1=48000; y1=108000; x2=48000; y2=104000; stroke=wire; } + ha:line.3 { x1=48000; y1=108000; x2=48000; y2=108000; stroke=junction; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.165 { + li:conn { + /2/164/1 + /2/161/1/1 + } + } + ha:group.166 { + uuid=GePylIY1T4cR3zcyR1kAAAB1; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAh; + x=60000; y=108000; + li:objects { + ha:group.1 { + uuid=GePylIY1T4cR3zcyR1kAAAB2; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAi; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=GePylIY1T4cR3zcyR1kAAAB3; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAj; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=16000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.5 { x1=9000; y1=5000; x2=9000; y2=-5000; stroke=sym-decor; } + ha:line.6 { x1=11000; y1=5000; x2=11000; y2=-5000; stroke=sym-decor; } + ha:line.7 { x1=4000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.8 { x1=11000; y1=0; x2=16000; y2=0; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=C2 + role=symbol + value=100n + } + } + ha:group.168 { + uuid=GePylIY1T4cR3zcyR1kAAAB7; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAh; + x=56000; y=104000; rot=270.000000; + li:objects { + ha:group.1 { + uuid=GePylIY1T4cR3zcyR1kAAAB8; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAi; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=GePylIY1T4cR3zcyR1kAAAB9; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAj; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=16000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.5 { x1=9000; y1=5000; x2=9000; y2=-5000; stroke=sym-decor; } + ha:line.6 { x1=11000; y1=5000; x2=11000; y2=-5000; stroke=sym-decor; } + ha:line.7 { x1=4000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.8 { x1=11000; y1=0; x2=16000; y2=0; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + footprint=1206 + name=C3 + role=symbol + value=200n + } + } + ha:connection.170 { + li:conn { + /2/2/1/1 + /2/197/2 + } + } + ha:connection.171 { + li:conn { + /2/19/1 + /2/2/11/1 + } + } + ha:connection.172 { + li:conn { + /2/19/1 + /2/18/1/1 + } + } + ha:connection.173 { + li:conn { + /2/23/1 + /2/2/10/1 + } + } + ha:connection.174 { + li:conn { + /2/23/1 + /2/22/1/1 + } + } + ha:connection.176 { + li:conn { + /2/142/3/1 + /2/189/6 + } + } + ha:connection.177 { + li:conn { + /2/148/1/1 + /2/146/2 + } + } + ha:connection.178 { + li:conn { + /2/149/2/1 + /2/146/2 + } + } + ha:connection.179 { + li:conn { + /2/157/1/1 + /2/149/1/1 + } + } + ha:connection.180 { + li:conn { + /2/164/1 + /2/166/2/1 + } + } + ha:group.181 { + uuid=GePylIY1T4cR3zcyR1kAAAB+; + li:objects { + ha:line.1 { x1=44000; y1=120000; x2=60000; y2=120000; stroke=wire; } + ha:line.2 { x1=56000; y1=104000; x2=56000; y2=120000; stroke=wire; } + ha:line.3 { x1=56000; y1=120000; x2=56000; y2=120000; stroke=junction; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.182 { + li:conn { + /2/181/1 + /2/132/1/1 + } + } + ha:connection.183 { + li:conn { + /2/181/1 + /2/3/2/1 + } + } + ha:connection.184 { + li:conn { + /2/181/2 + /2/168/2/1 + } + } + ha:connection.185 { + li:conn { + /2/164/2 + /2/7/2/1 + } + } + ha:connection.187 { + li:conn { + /2/7/1/1 + /2/189/5 + } + } + ha:connection.188 { + li:conn { + /2/168/1/1 + /2/189/7 + } + } + ha:group.189 { + uuid=GePylIY1T4cR3zcyR1kAAACA; + li:objects { + ha:line.1 { x1=120000; y1=68000; x2=116000; y2=68000; stroke=wire; } + ha:line.2 { x1=120000; y1=56000; x2=120000; y2=68000; stroke=wire; } + ha:line.4 { x1=88000; y1=56000; x2=120000; y2=56000; stroke=wire; } + ha:line.5 { x1=48000; y1=84000; x2=48000; y2=72000; stroke=wire; } + ha:line.6 { x1=48000; y1=72000; x2=92000; y2=72000; stroke=wire; } + ha:line.7 { x1=56000; y1=84000; x2=56000; y2=72000; stroke=wire; } + ha:line.8 { x1=56000; y1=72000; x2=56000; y2=72000; stroke=junction; } + ha:line.9 { x1=88000; y1=56000; x2=88000; y2=72000; stroke=wire; } + ha:line.10 { x1=88000; y1=72000; x2=88000; y2=72000; stroke=junction; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.190 { + li:conn { + /2/189/1 + /2/142/2/1 + } + } + ha:group.197 { + uuid=GePylIY1T4cR3zcyR1kAAACD; + li:objects { + ha:line.1 { x1=80000; y1=108000; x2=84000; y2=108000; stroke=wire; } + ha:line.2 { x1=80000; y1=120000; x2=92000; y2=120000; stroke=wire; } + ha:line.3 { x1=84000; y1=108000; x2=84000; y2=120000; stroke=wire; } + ha:line.4 { x1=84000; y1=120000; x2=84000; y2=120000; stroke=junction; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.198 { + li:conn { + /2/197/1 + /2/166/1/1 + } + } + ha:group.199 { + uuid=GePylIY1T4cR3zcyR1kAAACE; + li:objects { + ha:line.1 { x1=128000; y1=116000; x2=128000; y2=116000; stroke=junction; } + ha:line.2 { x1=92000; y1=92000; x2=120000; y2=92000; stroke=wire; } + ha:line.3 { x1=128000; y1=104000; x2=128000; y2=116000; stroke=wire; } + ha:line.4 { x1=116000; y1=116000; x2=136000; y2=116000; stroke=wire; } + ha:line.5 { x1=120000; y1=92000; x2=120000; y2=116000; stroke=wire; } + ha:line.6 { x1=120000; y1=116000; x2=120000; y2=116000; stroke=junction; } + ha:line.7 { x1=92000; y1=112000; x2=92000; y2=92000; stroke=wire; } + ha:text.8 { x1=131000; y1=116000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=out + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.200 { + li:conn { + /2/199/3 + /2/148/2/1 + } + } + ha:connection.201 { + li:conn { + /2/199/4 + /2/2/3/1 + } + } + ha:connection.202 { + li:conn { + /2/199/7 + /2/2/2/1 + } + } + ha:group.203 { + uuid=NZH2CJ+qOBOuN1271HYAAAB4; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=28000; y=40000; + li:objects { + ha:group.1 { + uuid=NZH2CJ+qOBOuN1271HYAAAB5; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.204 { + uuid=NZH2CJ+qOBOuN1271HYAAAB6; src_uuid=Hif/m8o2mo/CrYnTszoAAAAo; + x=0; y=-56000; + li:objects { + ha:line.1 { x1=28000; y1=112000; x2=24000; y2=112000; stroke=wire; } + ha:text.2 { x1=29000; y1=111000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=out + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.205 { + uuid=NZH2CJ+qOBOuN1271HYAAAB7; src_uuid=iNOQfJpO6hT/HFDFGjoAAABv; + x=36000; y=40000; rot=180.000000; + li:objects { + ha:group.1 { + uuid=NZH2CJ+qOBOuN1271HYAAAB8; src_uuid=iNOQfJpO6hT/HFDFGjoAAABw; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=6000; y1=7000; x2=18000; y2=10000; rot=180.000000; halign=center; dyntext=1; stroke=sym-primary; text=%../A.rail%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:forge { + delete,forge/tmp + scalar,forge/tmp + {sub,^,1:,forge/tmp} + suba,$,rail,forge/tmp + array,connect + append,connect,forge/tmp + } + rail=Vneg + role=symbol + } + } + ha:group.206 { + uuid=NZH2CJ+qOBOuN1271HYAAAB9; src_uuid=u6bADXQQa0V4HJRNz+sAAAA9; + x=20000; y=44000; mirx=1; + li:objects { + ha:text.1 { x1=0; y1=-2000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:group.2 { + uuid=NZH2CJ+qOBOuN1271HYAAAB+; src_uuid=u6bADXQQa0V4HJRNz+sAAAA+; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:group.3 { + uuid=NZH2CJ+qOBOuN1271HYAAAB/; src_uuid=u6bADXQQa0V4HJRNz+sAAAA/; + x=0; y=4000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.4 { + uuid=NZH2CJ+qOBOuN1271HYAAACA; src_uuid=u6bADXQQa0V4HJRNz+sAAABA; + x=0; y=8000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=3 + role=terminal + } + } + ha:group.5 { + uuid=NZH2CJ+qOBOuN1271HYAAACB; src_uuid=u6bADXQQa0V4HJRNz+sAAABB; + x=0; y=12000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=4 + role=terminal + } + } + ha:group.6 { + uuid=NZH2CJ+qOBOuN1271HYAAACC; src_uuid=u6bADXQQa0V4HJRNz+sAAABC; + x=0; y=16000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; } + } + ha:attrib { + name=5 + role=terminal + } + } + ha:polygon.7 { + li:outline { + ha:line { x1=0; y1=-2000; x2=0; y2=18000; } + ha:line { x1=0; y1=18000; x2=4000; y2=18000; } + ha:line { x1=4000; y1=18000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=0; y2=-2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + name=CN1 + role=symbol + spice/omit=yes + } + } + ha:connection.207 { + li:conn { + /2/206/5/1 + /2/204/1 + } + } + ha:group.208 { + uuid=NZH2CJ+qOBOuN1271HYAAACD; src_uuid=u6bADXQQa0V4HJRNz+sAAABU; + x=-4000; y=0; + li:objects { + ha:line.1 { x1=28000; y1=48000; x2=40000; y2=48000; stroke=wire; } + ha:line.2 { x1=40000; y1=48000; x2=40000; y2=40000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.209 { + li:conn { + /2/208/1 + /2/206/3/1 + } + } + ha:connection.210 { + li:conn { + /2/208/2 + /2/205/1/1 + } + } + ha:group.211 { + uuid=NZH2CJ+qOBOuN1271HYAAACE; src_uuid=u6bADXQQa0V4HJRNz+sAAABf; + x=-4000; y=0; + li:objects { + ha:line.1 { x1=28000; y1=60000; x2=32000; y2=60000; stroke=wire; } + ha:line.2 { x1=32000; y1=60000; x2=32000; y2=64000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.212 { + li:conn { + /2/211/1 + /2/206/6/1 + } + } + ha:group.213 { + uuid=NZH2CJ+qOBOuN1271HYAAACF; src_uuid=u6bADXQQa0V4HJRNz+sAAABN; + x=-24000; y=-16000; + li:objects { + ha:line.1 { x1=48000; y1=60000; x2=52000; y2=60000; stroke=wire; } + ha:line.2 { x1=52000; y1=60000; x2=52000; y2=56000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.214 { + li:conn { + /2/213/1 + /2/206/2/1 + } + } + ha:connection.215 { + li:conn { + /2/213/2 + /2/203/1/1 + } + } + ha:group.216 { + uuid=NZH2CJ+qOBOuN1271HYAAACG; src_uuid=Hif/m8o2mo/CrYnTszoAAAAo; + x=0; y=-60000; + li:objects { + ha:line.1 { x1=28000; y1=112000; x2=24000; y2=112000; stroke=wire; } + ha:text.2 { x1=29000; y1=111000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=in + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.217 { + li:conn { + /2/216/1 + /2/206/4/1 + } + } + ha:group.218 { + uuid=NZH2CJ+qOBOuN1271HYAAACH; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB6; + x=28000; y=64000; + li:objects { + ha:group.1 { + uuid=NZH2CJ+qOBOuN1271HYAAACI; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB7; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-4000; y1=4000; x2=4000; y2=7000; halign=center; dyntext=0; stroke=sym-primary; text=Vcc; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:Vcc} + } + role=symbol + } + } + ha:connection.219 { + li:conn { + /2/218/1/1 + /2/211/2 + } + } + } + ha:attrib { + maintainer=Tibor 'Igor2' Palinkas + page=1 of 1 + print_page=A/4 + title={high level SIM: notch filter with opamps, ac} + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 2 + grid = 4.0960 mm + } + } + } +} Index: tags/1.0.5/doc/tutorial/simulation/sim/18_opamp_ac/18_opamp_ac.svg =================================================================== --- tags/1.0.5/doc/tutorial/simulation/sim/18_opamp_ac/18_opamp_ac.svg (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/sim/18_opamp_ac/18_opamp_ac.svg (revision 10414) @@ -0,0 +1,1322 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/1.0.5/doc/tutorial/simulation/sim/18_opamp_ac/index.html =================================================================== --- tags/1.0.5/doc/tutorial/simulation/sim/18_opamp_ac/index.html (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/sim/18_opamp_ac/index.html (revision 10414) @@ -0,0 +1,68 @@ + + +

18_opamp_ac: 2 slot opamp

+ +

Scope

+

+A notch filter built with two opamps: this filter passes signals between DC +and 100 kHz but filters out 1 kHz signals. Demonstrated using a slotted +opamp with simulation. + +

The schematics

+

+

+ +
Click the image to get the sch-rnd sheet; also requires this project.lht in the same directory
+

+More info on the circuit: www.electronics-tutorials.ws + +

Preparing for simulation

+

+The lm358 contains two opamps in a single physical package. For the PCB +workflow this is going to be a single footprint with 8 pins. For spice +simulation, two separate components are exported, one per slot. The problem is: +only slot 1's power terminals are connected! This is no problem for the +PCB workflow, where a physical connection between slots exists within the package. +For simulation, the trick is to set spice/shared on the power terminals on both +slots (4 terminals total). This tells sch-rnd to share the connection between +the same numbered terminals of different slots of the same symbol. +

+Other than this, everything else about the drawing is pretty much the same as in +12_bjt_amp_ac. + +

Modifications

+

+This circuit needs three voltage sources, which are both added as modifications. +The first one is a DC 5V source connected to net Vcc (and GND). The second is +a DC -5V source connected to net Vneg (and GND). These are the power supply +rails of the opamp. +

+The third source is connected to the net in (and GND) and acts as the +small signal AC source for the AC analysis, this it has a an AC value (of 0.1 V) + +

Sim setup: output config

+

+(Same as in example 06_passive_ac ) +

+This simulation has two output configs, one for displaying the transfer +(in decibel) and one for the phase (in radian). The reason for specify them +in two separate output is the largely different y scale and unit. +

+The first output uses ac (dec) for analysis. This will feed in 10 +different frequencies per decade and caputre the output. This also means +the X axis, frequency, is logarithmic (common for frequency domain analysis). +

+The property to plot is vdb(out), which is the "voltage decibel" of +the network called out. Instead of the net name a component-port could be +specified within vdb(). +

+The second output uses anlaysis previous, which means no new simulation +is ran, but the data of the previous simulation is used. The presentation is +also a plot of "out", but using the cph() function, which is the phase in +radian. +

+

+ +
Simulation setup dialog, third tab, after execution
+

+ Index: tags/1.0.5/doc/tutorial/simulation/sim/18_opamp_ac/project.lht =================================================================== --- tags/1.0.5/doc/tutorial/simulation/sim/18_opamp_ac/project.lht (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/sim/18_opamp_ac/project.lht (revision 10414) @@ -0,0 +1,68 @@ +ha:coraleda-project-v1 { + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:plugins { + ha:sim { + li:setups { + {ha:ac analysis} { + li:mods { + ha:add { + value = 5 + pos = Vcc + tdf = none + device = V + ha:tdf_params { + } + } + ha:add { + value = -5 + pos = Vneg + tdf = none + device = V + ha:tdf_params { + } + } + ha:add { + ac_value = 0.1 + value = 0 + pos = in + tdf = none + device = V + ha:tdf_params { + } + } + } + li:output { + {ha:outout decibel} { + ha:presentation { + type = plot + li:props { + vdb(out) + } + } + ha:analysis { + type = ac_dec + start = 1 + numpt = 10 + stop = 1000k + } + } + ha:phase { + ha:presentation { + type = plot + li:props { + cph(out) + } + } + ha:analysis { + type = previous + } + } + } + } + } + } + } + } + } +} Index: tags/1.0.5/doc/tutorial/simulation/sim/18_opamp_ac/sim_run.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/1.0.5/doc/tutorial/simulation/sim/18_opamp_ac/sim_run.png =================================================================== --- tags/1.0.5/doc/tutorial/simulation/sim/18_opamp_ac/sim_run.png (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/sim/18_opamp_ac/sim_run.png (revision 10414) Property changes on: tags/1.0.5/doc/tutorial/simulation/sim/18_opamp_ac/sim_run.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/1.0.5/doc/tutorial/simulation/sim/22_custom_sym/22_custom_sym.rs =================================================================== --- tags/1.0.5/doc/tutorial/simulation/sim/22_custom_sym/22_custom_sym.rs (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/sim/22_custom_sym/22_custom_sym.rs (revision 10414) @@ -0,0 +1,377 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=k5U87rmc6yaL/+FNsFAAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.1 { + uuid=8/SYZ/pfBzxyqFA12WQAAAAC; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAg; + li:objects { + ha:polygon.11 { + li:outline { + ha:line { x1=0; y1=0; x2=80000; y2=0; } + ha:line { x1=80000; y1=0; x2=80000; y2=20000; } + ha:line { x1=80000; y1=20000; x2=0; y2=20000; } + ha:line { x1=0; y1=20000; x2=0; y2=0; } + } + stroke=titlebox-frame; + fill=titlebox-fill; + } + ha:line.12 { x1=0; y1=10000; x2=80000; y2=10000; stroke=titlebox-frame; } + ha:line.13 { x1=40000; y1=10000; x2=40000; y2=0; stroke=titlebox-frame; } + ha:text.20 { x1=1000; y1=16500; dyntext=0; stroke=titlebox-big; text=TITLE; } + ha:text.21 { x1=1000; y1=10500; x2=79000; y2=16000; dyntext=1; stroke=titlebox-big; text=%../../A.title%; } + ha:text.22 { x1=1000; y1=5500; dyntext=0; stroke=titlebox-small; text={PROJECT:}; } + ha:text.23 { x1=13000; y1=5500; x2=39000; y2=9500; dyntext=1; stroke=titlebox-big; text=%project.name%; } + ha:text.24 { x1=1000; y1=500; dyntext=0; stroke=titlebox-small; text={PAGE:}; } + ha:text.25 { x1=10000; y1=500; x2=39000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.page%; } + ha:text.26 { x1=41000; y1=5500; dyntext=0; stroke=titlebox-small; text={FILE:}; } + ha:text.27 { x1=48000; y1=5500; x2=79000; y2=9500; dyntext=1; stroke=titlebox-big; text=%filename%; } + ha:text.28 { x1=41000; y1=500; dyntext=0; stroke=titlebox-small; text={MAINTAINER:}; } + ha:text.29 { x1=55000; y1=500; x2=79000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.maintainer%; } + } + ha:attrib { + purpose=titlebox + } + } + ha:group.10 { + uuid=k5U87rmc6yaL/+FNsFAAAAAR; + x=56000; y=60000; + li:objects { + ha:line.1 { x1=0; y1=-4000; x2=-4000; y2=-16000; stroke=sym-decor; } + ha:line.2 { x1=-4000; y1=-16000; x2=4000; y2=-16000; stroke=sym-decor; } + ha:line.3 { x1=4000; y1=-16000; x2=0; y2=-4000; stroke=sym-decor; } + ha:line.4 { x1=-4000; y1=-4000; x2=4000; y2=-4000; stroke=sym-decor; } + ha:group.5 { + uuid=k5U87rmc6yaL/+FNsFAAAAAS; src_uuid=k5U87rmc6yaL/+FNsFAAAAAD; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=C + role=terminal + spice/pinnum=2 + } + } + ha:group.6 { + uuid=k5U87rmc6yaL/+FNsFAAAAAT; src_uuid=k5U87rmc6yaL/+FNsFAAAAAD; + x=0; y=-20000; rot=270.000000; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=A + role=terminal + spice/pinnum=1 + } + } + ha:polygon.7 { + li:outline { + ha:line { x1=-6000; y1=-2000; x2=-6000; y2=-18000; } + ha:line { x1=-6000; y1=-18000; x2=6000; y2=-18000; } + ha:line { x1=6000; y1=-18000; x2=6000; y2=-2000; } + ha:line { x1=6000; y1=-2000; x2=-6000; y2=-2000; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + ha:text.8 { x1=-6000; y1=-2000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + name=U1 + role=symbol + spice/model_card={.MODEL my_diode D (IS=2f RS=3.4 N=2.2)} + spice/prefix=D + } + } + ha:group.11 { + uuid=k5U87rmc6yaL/+FNsFAAAAAa; src_uuid=iNOQfJpO6hT/HFDFGjoAAABx; + x=20000; y=60000; rot=270.000000; mirx=1; + li:objects { + ha:arc.1 { cx=10000; cy=0; r=6000; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:arc.2 { cx=8000; cy=0; r=2000; sang=0.000000; dang=180.000000; stroke=sym-decor; } + ha:arc.3 { cx=12000; cy=0; r=2000; sang=180.000000; dang=180.000000; stroke=sym-decor; } + ha:group.4 { + uuid=k5U87rmc6yaL/+FNsFAAAAAb; src_uuid=iNOQfJpO6hT/HFDFGjoAAABy; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=N + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.5 { + uuid=k5U87rmc6yaL/+FNsFAAAAAc; src_uuid=iNOQfJpO6hT/HFDFGjoAAABz; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=P + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:text.6 { x1=0; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=V1 + role=symbol + spice/params=SINE(0 20 1k) + } + } + ha:group.12 { + uuid=k5U87rmc6yaL/+FNsFAAAAAd; + x=-8000; y=-32000; + li:objects { + ha:line.1 { x1=28000; y1=92000; x2=28000; y2=104000; stroke=wire; } + ha:line.3 { x1=28000; y1=104000; x2=32000; y2=104000; stroke=wire; } + ha:text.4 { x1=28000; y1=104000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=in + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.14 { + uuid=k5U87rmc6yaL/+FNsFAAAAAk; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=24000; y=72000; + li:objects { + ha:group.1 { + uuid=k5U87rmc6yaL/+FNsFAAAAAl; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=k5U87rmc6yaL/+FNsFAAAAAm; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=R1 + role=symbol + ha:spice/prefix = { value=R; prio=31050; } + value=100 + } + } + ha:group.16 { + uuid=k5U87rmc6yaL/+FNsFAAAAAn; + x=-8000; y=-32000; + li:objects { + ha:line.2 { x1=64000; y1=104000; x2=64000; y2=92000; stroke=wire; } + ha:line.3 { x1=52000; y1=104000; x2=76000; y2=104000; stroke=wire; } + ha:line.4 { x1=64000; y1=104000; x2=64000; y2=104000; stroke=junction; } + ha:text.5 { x1=72000; y1=104000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=out + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.19 { + uuid=k5U87rmc6yaL/+FNsFAAAAAs; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=20000; y=36000; + li:objects { + ha:group.1 { + uuid=k5U87rmc6yaL/+FNsFAAAAAt; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.20 { + uuid=k5U87rmc6yaL/+FNsFAAAAAu; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=56000; y=36000; + li:objects { + ha:group.1 { + uuid=k5U87rmc6yaL/+FNsFAAAAAv; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.21 { + uuid=k5U87rmc6yaL/+FNsFAAAAAw; + x=-8000; y=-32000; + li:objects { + ha:line.1 { x1=28000; y1=72000; x2=28000; y2=68000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.24 { + uuid=k5U87rmc6yaL/+FNsFAAAAAx; + x=-8000; y=-32000; + li:objects { + ha:line.1 { x1=64000; y1=72000; x2=64000; y2=68000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.27 { + li:conn { + /2/12/1 + /2/11/5/1 + } + } + ha:connection.29 { + li:conn { + /2/14/2/1 + /2/12/3 + } + } + ha:connection.30 { + li:conn { + /2/16/2 + /2/10/5/1 + } + } + ha:connection.31 { + li:conn { + /2/16/3 + /2/14/1/1 + } + } + ha:connection.32 { + li:conn { + /2/21/1 + /2/11/4/1 + } + } + ha:connection.33 { + li:conn { + /2/21/1 + /2/19/1/1 + } + } + ha:connection.34 { + li:conn { + /2/24/1 + /2/10/6/1 + } + } + ha:connection.35 { + li:conn { + /2/24/1 + /2/20/1/1 + } + } + } + ha:attrib { + maintainer=Tibor 'Igor2' Palinkas + page=1/1 + print_page=A/4 + title={high level SIM: custom symbol} + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + } + } + } +} Index: tags/1.0.5/doc/tutorial/simulation/sim/22_custom_sym/index.html =================================================================== --- tags/1.0.5/doc/tutorial/simulation/sim/22_custom_sym/index.html (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/sim/22_custom_sym/index.html (revision 10414) @@ -0,0 +1,42 @@ + + +

22_custom_sym: creating a custom symbol

+ +

Scope

+

+Create a custom diode symbol with an embedded (inline) model card. + +

The schematics

+

+

+ +
Click the image to get the sch-rnd sheet; also requires this project.lht in the same directory
+ +

Preparing for simulation

+

+Draw the symbol the usual way, using lines, rectangles and {p t} +for placing terminals; select the objects, convert selection to symbol; +set the usual attributes (e.g. name on the symbol and on the terminals). +

+For spice simulation, set the following attributes: +

    +
  • symbol attribute spice/prefix to D: for the simulation + this is a diode; this attribute lets the sheet name the symbol U1 + still show spice a D component by prefixing the name with D_. +
  • symbol attribute spice/model_card to + .MODEL my_diode D (IS=2f RS=3.4 N=2.2): + this is how the model is specified inline, within the symbol, not + relying on external libs +
  • terminal attribute spice/pinnum; the positive (anode) terminal + should be 1, the negative (cathode) should be 2. +
+

+The inline model card option is useful for one-off symbols or for an easy +and quick way of tuning model parameters in test-bench schematics. + +

+Simulation settings are similar to those used in +10_bjt_amp_tr, except for +modifications: instead of using modifications, this circuit has a voltage +source symbol. + Index: tags/1.0.5/doc/tutorial/simulation/sim/22_custom_sym/project.lht =================================================================== --- tags/1.0.5/doc/tutorial/simulation/sim/22_custom_sym/project.lht (nonexistent) +++ tags/1.0.5/doc/tutorial/simulation/sim/22_custom_sym/project.lht (revision 10414) @@ -0,0 +1,30 @@ +ha:coraleda-project-v1 { + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:plugins { + ha:sim { + li:setups { + {ha:ac trans} { + li:output { + ha:transition { + ha:presentation { + type = plot + li:props { + out + in + } + } + ha:analysis { + type = tran_lin + incr = 1u + stop = 4m + } + } + } + } + } + } + } + } + } +} Index: tags/1.0.5/doc/user/02_model/devmap.svg =================================================================== --- tags/1.0.5/doc/user/02_model/devmap.svg (nonexistent) +++ tags/1.0.5/doc/user/02_model/devmap.svg (revision 10414) @@ -0,0 +1,130 @@ + + + + + + +target + + +cluster_0 + +symbol in the +concrete model + + + +attr +symbol attributes + + + +std_devmap1 + +engine plugin: +std_devmap +(applying devmap) + + + +attr->std_devmap1 + + +devmap + + + +term + +terminal in the +concrete model + + + +abstract1 + +port in the +abstract model +(model version 1) + + + +term->abstract1 + + + + + +std_devmap1->abstract1 + + +component's +portmap[] + + + +std_devmap2 + +engine plugin: +std_devmap +(applying portmap) + + + +abstract2 + +port in the +abstract model +(model version 2) + + + +std_devmap2->abstract2 + + +port's +pcb/pinnum + + + +target_pcb + +engine plugin: +target_pcb + + + +abstract3 + +port in the +abstract model +(model version 3) + + + +target_pcb->abstract3 + + +display/name + + + +abstract1->std_devmap2 + + +component's +portmap[] + + + +abstract2->target_pcb + + +port's +pcb/pinnum + + + Index: tags/1.0.5/doc/user/02_model/display_name.html =================================================================== --- tags/1.0.5/doc/user/02_model/display_name.html (nonexistent) +++ tags/1.0.5/doc/user/02_model/display_name.html (revision 10414) @@ -0,0 +1,259 @@ + + +

sch-rnd - terminal display name

+ +

In a nutshell

+

+Sch-rnd doesn't alaways display drawing object (concrete model) attributes +directly on screen and export. For many things, like label of terminals, +(really: final terminal name) we use display names, which are calculated. +

+This allows final names and displayed labels to change depending on which view (workflow) +is active, e.g. show specific "pin numbers" for a pcb view, but when the user +changes the view to spice, show the positional numbers (in the spice file) +of the same pins instead. +

+In the most common case this is all done automatically after setting the +devmap attribute of a symbol. But there are two more, lower layers, +and the user may intervene there: portmap and direct pin name/number +attributes. + +

The problem

+

+In the cschem data model (that sch-rnd uses), sheet graphics and attributes +entered by the user are all part of the concrete model. Before a netlist +export or other complex output can be generated, the concrete model +needs to be compiled into an abstract model. +

+The abstract model is the true meaning of the schematics, reflects +the intentions of the user. For example a complex microcontroller may be +split up into multiple symbols on the concrete model and these +symbols may be placed across multiple sheets. At the end, the user knows +it's all the same one physical MCU because all symbol had the name "U17". +The abstract model simply represents this knowledge because the compiler +understands those symbols are all part of the same big component and +creates that one U17 component in the abstract model. +

+Compiling matching symbols into a single component is simple. Having the +right terminal names ("pin numbers", in PCB terms) is a bit trickier, because +there are factors like: +

    +
  • the same generic transistor symbol may be used for different devices with varying pinouts +
  • a dual opamp is often represented as two copies of the same single channel opamp symbol but will need to get different "pin numbers" at the end +
  • even a plain old diode may need to be displayed with different "pin numbers" depending on whether the output would be a PCB or a spice simulation workflow +
+

+This chapter explains how sch-rnd solves these problems for terminals. + +

What is a display name?

+

+A display name is an attribute called display/name in the abstract +model. In the abstract model ports of components (which are compiled +from terminals of symbols) will typically have this attribute set by the +compilation process. There is usually a floater+dyntext object placed next +to the terminal in the concrete model, which has ../a.display/name +in its template. This prints the display name of the abstract port that +was compiled from the concrete terminal. + +

The anatomy of the display name

+

+The reference ../a.display/name is split in the middle, at the dot. +

+The left side, "../a" means "fetch an attribute of the abstract parent", +because ".." means parent (like in a UNIX file system) and "a" means +"attribute of the abstract object". The parent of the text object in this case +is the concrete group that represents the terminal; the abstract parent +is the abstract port that got compile from this terminal. (The port is +an abstract group with type=PORT in the abstract model). +

+The right side is an attribute name (key), "display/name". On the right +side slash does not have any special meaning, it's just a convention to group +attributes visually. + +

What writes display/name?

+

+Compilation takes all concrete objects and generate varying number of abstract +objects, using engine plugins. Engines whose name start with "target" are +typically responsible for rendering display/name attributes. +

+How concrete port name or pinnum is compiled to display name in the abstract model by target_pcb +

+Let's take the problem of a simple diode that will need to have a different +pinout for: +

    +
  • a PCB workflow (physical pin numbers) +
  • a spice simulation (spice requires a specific numbering) +
+

+To use the same sheet (concrete model) for both PCB and spice, there are +two different views set up. One has the "target_pcb" plugin in it, the +other has the "target_spice" plugin in it. One of the things these two plugins +differ is how they calculate the value of display/name for ports. +

+Target_spice is the simpler case: it looks at some device type (TODO) +attribute of the symbol, which would be diode (TODO), and it would know +that for spice it's always "Dname N+ N- modelname", so anode is pin 1 and +cathode is pin 2. +

+Target_pcb looks at the attribute pcb/pinnum, if it exists, display name +is set to that. If it doesn't, it looks for a plain pinnum attribute and +uses that. If that doesn't exist either it falls back using the name of +the terminal. +

+So at the end, the display pin number will potentially differ depending on +which target_* plugin participated in compiling. (Without compiling there is +no display name so a dummy is displayed.) + +

PCB workflow: how to set terminal display name

+

+There are different methods depending on complexity of the symbol. + +

Heavy symbol

+

+The simplest setup is hardwiring a footprint attribute in the symbol and +pin numbers in the terminals. Such symbol will work with only a matching +footprint and is called a heavy symbol. +

+The easiest way to do this is to simply set the name attribute of terminals +to the final pin number. Alternatively, if symbolic names (like A and C in +case of a diode) are preferreed, set the pcb/pinnum attribute for each terminal. +Because of how target_pcb picks the display name for terminals, either +will result in the right display name. +

+The drawback of this method is that symbols are not generic in the +physical device/vendor/pinout sense. If there are +three different n channel FETs are used in the design, they need three different +symbols so they each can hardwire the footprint and the pinout in the symbol. +In a symbol library this means many many copies of the same graphics only +for the difference of a few text fields. It's also hard to extract the +actual pinout from such symbol files both programatically and by looking +at the file. +

+Heavy symbols are not generic in workflow sense either: a heavy symbol +designed to work for the pcb workflow, hardwiring smd lead numbers will +likely unusable in a breadboard or spice simulation context. + +

Target plugins

+

+To avoid the per workflow problem, we prefer using terminal names and +different "pin number" attributes per workflow. For example the base +terminal of a workflow-generic BJT would be called "B" or "base" (this +is the name attribute), then pcb pin number would be specified as +"1" in the pcb/pinnum attribute and spice/pinnum would be 2 +(it's "Qname C B E model" in spice). +

+Each view normally contains a target_* plugin, which has +a workflow-specific heuristics to determine the final pin number. For example +target_pcb will first look if there's a pcb/pinnum attribute +available and use that; if that fails, it goes for pinnum; if that +fails too, it assumes heavy symbol and just copies the original terminal +name attribute. Other target_ plugins, e.g. target_spice, will prefer +different input attributes so if the terminal has all different workflow +specific attributes filled in, every target_ plugin can pick the right one. +Or if not, fall back to a more generic attribute. +

+How concrete port name or pinnum is compiled to display name in the abstract model using different target plugins +

+The result is always written to the display/name attribute of the +component's port in the abstract model. It's displayed on screen because +the text object displaying the port label will normally reference the +display/name attribute, not the input name attribute. +

+Since different workflows will simply use different views, and different +views will use different target_ plugins, this mechanism guarantees that +it is possible to craft generic light symbols that work with any workflow, +and it is only a question of adding the right attributes. +

+For the rest of this document drawings will show only one view and only +until the abstract model is finished, to keep drawings simple. + +

Portmap

+

+However, the above does not solve the problem where the same symbol needs to +deliver different pinouts within the same workflow, e.g. depending on +the footprint. +

+The middle level solution cschem model offers is port mapping. It is implemented +as the portmap attribute of the symbol. The portmap attribute is +an array, each element describes a "terminal_name -> attribute=value" pair. +The std_devmap plugin goes and applies each element: it finds the terminal +referenced by the left side of the arrow and sets the attribute on it as +requested by the right side. Attributes are typically pin numbers, e.g. +"B -> pcb/pinnum=1" and "B -> spice/pinnum=2" for the above example. +

+How portmap is applied to generate final display name of a port +

+This way there's a central array or table in the symbol that describes the +pinout, potentially for all workflows. The same BJT symbol can be placed +in two copies and the pcb/pinnum attributes of the portmap attribute +modified in one of the copies to get it work with a different physical device. +

+In other words, it's possible to reuse the graphics and structure of the +symbol and deal with the port mapping per case only. + +

Devmap

+

+The portmap mechanism is real convenient in the small scale, when a given +symbol has the right mapping for majority of the cases and occassionally +local deviation is needed. However, it does not scale well for the common +case of using dozens of different transistors all having the same symbol +but potentially different pinout and footprint. Even if there would be only +5..6 different footprint+pinout combinations for the board, it would not +be practical to maintain the portmap attribute manually for each +instance. +

+Fortunately it can be automated. The standard way is using devmap, +part of the std_devmap plugin. Devmap keeps a library, a "database". +Each entry in the devmap library has a name and a list of attributes to +set on a symbol. +

+Using the devmap is simple: +

    +
  • use generic/light symbols that have terminal names, no per workflow + pin information, no portmap and no footprint attribute +
  • have a devmap file named after the physical device, e.g. 2n7002_sot23 +
  • this devmap file should set the footprint attribute to sot23 and + the portmap attribute to the correct pinout for all relevant workflows. +
+

+When std_devmap processes the absract model, it will pick up the devmap +attribute, look it up in the devmap library and fill in the footprint and +portap from there. +

+How devmap is applied to generate final display name of a port +

+In a sense on the user interface this method is an alternative to setting +the footprint. The cost of setting the devmap attribute instead is not +significantly higher, but using a rich devmap entry setting that single +attribute can auto-fill-in all device-specific attributes. + +

Conclusion

+

+For the PCB workflow example, standard options for setting display name +(final/output name) of a port: +

+ + + + +
 symbol attributesterminal attributepros cons +
heavy symbol + footprint + pcb/pinnum
or pinnum or name +
simple; all pinout data is in symbol and term attributes + every part requires a different symbol + +
pinmap + footprint and pinmap[] + name + a generic symbol with local attribute modification can be used for any part; all pinout data is in symbol attributes + have to look up pinout and set pinmap attribute manually + +
devmap + devmap + name + a generic symbol with a devmap lib can be used for any part; maintaining the pinout data in a separate devmap lib ("parts lib") may be easier than maintaining them in symbols + have to maintain a devmap lib + +
+ Index: tags/1.0.5/doc/user/02_model/portmap.svg =================================================================== --- tags/1.0.5/doc/user/02_model/portmap.svg (nonexistent) +++ tags/1.0.5/doc/user/02_model/portmap.svg (revision 10414) @@ -0,0 +1,95 @@ + + + + + + +target + + +cluster_0 + +symbol in the +concrete model + + + +attr +symbol attributes + + + +std_devmap + +engine plugin: +std_devmap + + + +attr->std_devmap + + +portmap[] + + + +term + +terminal in the +concrete model + + + +abstract1 + +port in the +abstract model +(model version 1) + + + +term->abstract1 + + + + + +std_devmap->abstract1 + + +pcb/pinnum + + + +target_pcb + +engine plugin: +target_pcb + + + +abstract2 + +port in the +abstract model +(model version 2) + + + +target_pcb->abstract2 + + +display/name + + + +abstract1->target_pcb + + +pcb/pinnum + + + Index: tags/1.0.5/doc/user/02_model/src/Makefile =================================================================== --- tags/1.0.5/doc/user/02_model/src/Makefile (nonexistent) +++ tags/1.0.5/doc/user/02_model/src/Makefile (revision 10414) @@ -0,0 +1,13 @@ +all: ../target.svg ../target2.svg ../portmap.svg ../devmap.svg + +../target.svg: target.dot + dot -T svg $^ > $@ + +../target2.svg: target2.dot + dot -T svg $^ > $@ + +../portmap.svg: portmap.dot + dot -T svg $^ > $@ + +../devmap.svg: devmap.dot + dot -T svg $^ > $@ Index: tags/1.0.5/doc/user/02_model/src/devmap.dot =================================================================== --- tags/1.0.5/doc/user/02_model/src/devmap.dot (nonexistent) +++ tags/1.0.5/doc/user/02_model/src/devmap.dot (revision 10414) @@ -0,0 +1,23 @@ +digraph target{ + rankdir=LR + subgraph cluster_0 { + label="symbol in the\nconcrete model" + shape=box + attr [label="symbol attributes" shape=plain] + term [label="terminal in the\nconcrete model" shape=box] + } + std_devmap1 [label="engine plugin:\nstd_devmap\n(applying devmap)"] + std_devmap2 [label="engine plugin:\nstd_devmap\n(applying portmap)"] + target_pcb [label="engine plugin:\ntarget_pcb"] + abstract1 [label="port in the\nabstract model\n(model version 1)" shape="box"] + abstract2 [label="port in the\nabstract model\n(model version 2)" shape="box"] + abstract3 [label="port in the\nabstract model\n(model version 3)" shape="box"] + + term -> abstract1 [style=dashed] + attr -> std_devmap1 [label="devmap"] + std_devmap1 -> abstract1 [label="component's\nportmap[]"] + abstract1 -> std_devmap2 [label="component's\nportmap[]"] + std_devmap2 -> abstract2 [label="port's\npcb/pinnum"] + abstract2 -> target_pcb [label="port's\npcb/pinnum"] + target_pcb -> abstract3 [label="display/name"] +} Index: tags/1.0.5/doc/user/02_model/src/portmap.dot =================================================================== --- tags/1.0.5/doc/user/02_model/src/portmap.dot (nonexistent) +++ tags/1.0.5/doc/user/02_model/src/portmap.dot (revision 10414) @@ -0,0 +1,19 @@ +digraph target{ + rankdir=LR + subgraph cluster_0 { + label="symbol in the\nconcrete model" + shape=box + attr [label="symbol attributes" shape=plain] + term [label="terminal in the\nconcrete model" shape=box] + } + std_devmap [label="engine plugin:\nstd_devmap"] + target_pcb [label="engine plugin:\ntarget_pcb"] + abstract1 [label="port in the\nabstract model\n(model version 1)" shape="box"] + abstract2 [label="port in the\nabstract model\n(model version 2)" shape="box"] + + term -> abstract1 [style=dashed] + attr -> std_devmap [label="portmap[]"] + std_devmap -> abstract1 [label="pcb/pinnum"] + abstract1 -> target_pcb [label="pcb/pinnum"] + target_pcb -> abstract2 [label="display/name"] +} \ No newline at end of file Index: tags/1.0.5/doc/user/02_model/src/target.dot =================================================================== --- tags/1.0.5/doc/user/02_model/src/target.dot (nonexistent) +++ tags/1.0.5/doc/user/02_model/src/target.dot (revision 10414) @@ -0,0 +1,13 @@ +digraph target{ + rankdir=LR + concrete [label="terminal in the\nconcrete model\nattr: pcb_pinnum\nnattr: pinnum\nattr: name" shape=box] + target_pcb [label="engine plugin:\ntarget_pcb"] + abstract [label="port in the\nabstract model\nattr: display/name" shape="box"] + export_tedax [label="export plugin:\nexport_tedax"] + netlist [label="netlist output:\nfoo.tdx" shape="box"] + + concrete -> target_pcb + target_pcb -> abstract + abstract -> export_tedax + export_tedax -> netlist +} \ No newline at end of file Index: tags/1.0.5/doc/user/02_model/src/target2.dot =================================================================== --- tags/1.0.5/doc/user/02_model/src/target2.dot (nonexistent) +++ tags/1.0.5/doc/user/02_model/src/target2.dot (revision 10414) @@ -0,0 +1,22 @@ +digraph target{ + rankdir=LR + concrete [label="terminal in the\nconcrete model" shape=box] + target_pcb [label="target_pcb"] + target_spice [label="target_spice"] + abstract1 [label="port in the\nabstract model for\nthe pcb view"] + abstract2 [label="port in the\nabstract model for\nthe spice view"] + export_tedax [label="export plugin:\nexport_tedax"] + netlist1 [label="netlist output:\nfoo.tdx" shape="box"] + export_spice [label="export plugin:\nexport_spice"] + netlist2 [label="netlist output:\nfoo.spice" shape="box"] + + concrete -> target_pcb [label="pcb/pinnum\npinnum\nname"] + concrete -> target_spice [label="spice/pinnum"] + target_pcb->abstract1 [label="display/name"] + target_spice->abstract2 [label="display/name"] + abstract1->export_tedax [label="display/name"] + export_tedax->netlist1 + abstract2->export_spice [label="display/name"] + export_spice->netlist2 + +} \ No newline at end of file Index: tags/1.0.5/doc/user/02_model/target.svg =================================================================== --- tags/1.0.5/doc/user/02_model/target.svg (nonexistent) +++ tags/1.0.5/doc/user/02_model/target.svg (revision 10414) @@ -0,0 +1,76 @@ + + + + + + +target + + + +concrete + +terminal in the +concrete model +attr: pcb_pinnum +nattr: pinnum +attr: name + + + +target_pcb + +engine plugin: +target_pcb + + + +concrete->target_pcb + + + + + +abstract + +port in the +abstract model +attr: display/name + + + +target_pcb->abstract + + + + + +export_tedax + +export plugin: +export_tedax + + + +abstract->export_tedax + + + + + +netlist + +netlist output: +foo.tdx + + + +export_tedax->netlist + + + + + Index: tags/1.0.5/doc/user/02_model/target2.svg =================================================================== --- tags/1.0.5/doc/user/02_model/target2.svg (nonexistent) +++ tags/1.0.5/doc/user/02_model/target2.svg (revision 10414) @@ -0,0 +1,132 @@ + + + + + + +target + + + +concrete + +terminal in the +concrete model + + + +target_pcb + +target_pcb + + + +concrete->target_pcb + + +pcb/pinnum +pinnum +name + + + +target_spice + +target_spice + + + +concrete->target_spice + + +spice/pinnum + + + +abstract1 + +port in the +abstract model for +the pcb view + + + +target_pcb->abstract1 + + +display/name + + + +abstract2 + +port in the +abstract model for +the spice view + + + +target_spice->abstract2 + + +display/name + + + +export_tedax + +export plugin: +export_tedax + + + +abstract1->export_tedax + + +display/name + + + +export_spice + +export plugin: +export_spice + + + +abstract2->export_spice + + +display/name + + + +netlist1 + +netlist output: +foo.tdx + + + +export_tedax->netlist1 + + + + + +netlist2 + +netlist output: +foo.spice + + + +export_spice->netlist2 + + + + + Index: tags/1.0.5/doc/user/03_data/attrib_export_name.html =================================================================== --- tags/1.0.5/doc/user/03_data/attrib_export_name.html (nonexistent) +++ tags/1.0.5/doc/user/03_data/attrib_export_name.html (revision 10414) @@ -0,0 +1,44 @@ + + +

sch-rnd - attribute export naming

+

+

Attribute export names

+

+Each attribute in the abstract model has an optional "export name" field. +If the export file format supports arbitrary key/value pairs exported +(e.g. with nets, components or even ports), those attributes that have an +export name set are exported, using the export name instead of the original +attribute name. This allows plugins to control which attributes to export +for a given workflow, under what output attribute name. +

+Usually the target plugin sets export name on some of the attributes, +typically using the standard attribute export naming mechanism. + +

Standard attribute export naming mechanism

+

+The target plugin has the following configuration nodes: + + +
end of node path description +
flow_prefix workflow prefix (domain prefix) +
sw_prefix consumer software prefix +
whitelist list of attribute names to export with an option to use a different name in export +
blacklist list of attribute names that shall not be exported +
+ +

+The mechanism is specified in +CoralEDA crl001, with the followint sch-rnd specific implementation details: +

    +
  • flow_prefix is the same as "domain scope prefix" in crl001; it's typically the same as the target plugin's basename, e.g. "pcb" for plugin target_pcb, so symbol attribute "pcb:foo" is exported as component attribute "foo" when using target_pcb +
  • whitelist items are either plain attibute names, or "attr_name->export_name" pairs for a rename; e.g. "display/dnp->dnp" means the display/dnp attribute is exported under the name dnp +
  • blacklist is a list of attribute names; a blacklisted attribute's export name is removed even if it was also whitelisted or matched any of the prefixes or another plugin has set it earlier during the compilation process +
+

+The order of precedence (later items override earlier items on the list): +

    +
  1. whitelist +
  2. sw_prefix +
  3. flow_prefix +
  4. blacklist +
Index: tags/1.0.5/doc/user/03_data/devmap_ff.html =================================================================== --- tags/1.0.5/doc/user/03_data/devmap_ff.html (nonexistent) +++ tags/1.0.5/doc/user/03_data/devmap_ff.html (revision 10414) @@ -0,0 +1,34 @@ + + +

sch-rnd - the devmap file format

+

+A devmap file is a +lihata document. The root node is ha:std_devmap.v1, which has +a ha:comp_attribs subtree. This subtree contains all attributes +that are set on the component that refers to the devmap. +

+Scalar attributes are plain text nodes in key=value form. Array attributes +are lists of text items. +

+For example this is the devmap file for 2n7002 in sot23: +

+ha:std_devmap.v1 {
+ ha:comp_attribs {
+  footprint=sot23
+  li:portmap={
+   {G->pcb/pinnum=1}
+   {S->pcb/pinnum=2}
+   {D->pcb/pinnum=3}
+  }
+ }
+}
+
+

+It sets the footprint to sot23 then specifies a portmap array. Since portmap +items contain slash, they each need to be quoted using {}. +

+Note: devmap does not know about the portmap syntax. For devmap li:portmap +is just an arbitrary array-type attribute with 3 string/text items in it. +Portmap has its own documentation, +and can be used independently of devmap. + Index: tags/1.0.5/doc/user/05_ui/keytree.svg =================================================================== --- tags/1.0.5/doc/user/05_ui/keytree.svg (nonexistent) +++ tags/1.0.5/doc/user/05_ui/keytree.svg (revision 10414) @@ -0,0 +1,1914 @@ + + + + + + +keytree + + + +a_a + +{a a} +Change name (refdes) + + + +a + +a + + + +a->a_a + + + + + +a_c + +{a c} +Change connections + + + +a->a_c + + + + + +a_d + +{a d} +Change devmap + + + +a->a_d + + + + + +a_f + +{a f} +Change footprint + + + +a->a_f + + + + + +a_n + +{a n} +Change name + + + +a->a_n + + + + + +a_o + +{a o} +Change role + + + +a->a_o + + + + + +a_p + +{a p} +Change portmap + + + +a->a_p + + + + + +a_r + +{a r} +Change name (refdes) + + + +a->a_r + + + + + +a_s + +{a s} +Change slot num + + + +a->a_s + + + + + +a_u + +{a u} +Change funcmap + + + +a->a_u + + + + + +a_v + +{a v} +Change value + + + +a->a_v + + + + + +b_c_c + +{b c c} +Clear buffer + + + +b + +b + + + +b_c + +b_c + + + +b->b_c + + + + + +b_f + +b_f + + + +b->b_f + + + + + +b_l + +b_l + + + +b->b_l + + + + + +b_m + +b_m + + + +b->b_m + + + + + +b_r + +b_r + + + +b->b_r + + + + + +b_s + +b_s + + + +b->b_s + + + + + +b_c->b_c_c + + + + + +b_f_l + +{b f l} +Load buffer content from file + + + +b_f->b_f_l + + + + + +b_f_s + +{b f s} +Save buffer content to file + + + +b_f->b_f_s + + + + + +b_l_s + +{b l s} +Load buffer symbol/group from file + + + +b_l->b_l_s + + + + + +b_m_l + +{b m l} +Mirror buffer (left/right) + + + +b_m->b_m_l + + + + + +b_m_u + +{b m u} +Mirror buffer (up/down) + + + +b_m->b_m_u + + + + + +b_r_a + +{b r a} +Arbitrarily Rotate Buffer + + + +b_r->b_r_a + + + + + +b_r_l + +{b r l} +Rotate buffer 90 deg CCW (left) + + + +b_r->b_r_l + + + + + +b_r_r + +{b r r} +Rotate buffer 90 deg CW (right) + + + +b_r->b_r_r + + + + + +b_s_g + +{b s g} +Save buffer group to file + + + +b_s->b_s_g + + + + + +b_s_s + +{b s s} +Save buffer symbol to file + + + +b_s->b_s_s + + + + + +e_c + +{e c} +Copy selection to buffer + + + +e + +e + + + +e->e_c + + + + + +e_d + +{e d} +Remove object + + + +e->e_d + + + + + +e_h + +{e h} +Mirror object horizontally + + + +e->e_h + + + + + +e_m + +e_m + + + +e->e_m + + + + + +e_p + +{e p} +Object Properties... + + + +e->e_p + + + + + +e_s + +{e s} +Stroke + + + +e->e_s + + + + + +e_t + +{e t} +Text string + + + +e->e_t + + + + + +e_v + +{e v} +Mirror object vertically + + + +e->e_v + + + + + +e_w + +{e w} +Whirl object (rotate 90 deg) + + + +e->e_w + + + + + +e_x + +{e x} +Cut selection to buffer + + + +e->e_x + + + + + +e_m_r + +{e m r} +Renumber symbols + + + +e_m->e_m_r + + + + + +f_a + +{f a} +Save sheet as... + + + +f + +f + + + +f->f_a + + + + + +f_e + +{f e} +Export Sheet... + + + +f->f_e + + + + + +f_j + +{f j} +Export Project... + + + +f->f_j + + + + + +f_n + +{f n} +New root sheet + + + +f->f_n + + + + + +f_o + +{f o} +Load... + + + +f->f_o + + + + + +f_p + +{f p} +Print sheet... + + + +f->f_p + + + + + +f_q + +{f q} +Quit + + + +f->f_q + + + + + +f_r + +{f r} +Revert sheet + + + +f->f_r + + + + + +f_s + +{f s} +Save sheet... + + + +f->f_s + + + + + +f_u + +{f u} +Unload sheet + + + +f->f_u + + + + + +g_b + +{g b} +Previous grid + + + +g + +g + + + +g->g_b + + + + + +g_c + +{g c} +Custom grid + + + +g->g_c + + + + + +g_d + +{g d} +Grid *2 + + + +g->g_d + + + + + +g_f + +{g f} +Next grid + + + +g->g_f + + + + + +g_h + +{g h} +Grid /2 + + + +g->g_h + + + + + +g_l + +{g l} +Enable local grid + + + +g->g_l + + + + + +g_v + +{g v} +Enable visible grid + + + +g->g_v + + + + + +i_c_d + +{i c d} +Re-scan the devmap library + + + +i + +i + + + +i_c + +i_c + + + +i->i_c + + + + + +i_c->i_c_d + + + + + +i_c_i + +{i c i} +Data integrity check + + + +i_c->i_c_i + + + + + +i_c_p + +{i c p} +Preferences... + + + +i_c->i_c_p + + + + + +i_c_r + +{i c r} +Re-scan the symbol library + + + +i_c->i_c_r + + + + + +i_c_u + +{i c u} +Re-scan the funcmap library + + + +i_c->i_c_u + + + + + +l_r + +{l r} +TODO + + + +l + +l + + + +l->l_r + + + + + +m_f_l + +{m f l} +Lock floaters + + + +m + +m + + + +m_f + +m_f + + + +m->m_f + + + + + +m_k + +m_k + + + +m->m_k + + + + + +m_l + +m_l + + + +m->m_l + + + + + +m_r + +m_r + + + +m->m_r + + + + + +m_s + +m_s + + + +m->m_s + + + + + +m_f->m_f_l + + + + + +m_f_o + +{m f o} +Only floaters + + + +m_f->m_f_o + + + + + +m_k_s + +{m k s} +Loose symbol (no sym lock) + + + +m_k->m_k_s + + + + + +m_l_c + +{m l c} +Continuous draw (toggle) + + + +m_l->m_l_c + + + + + +m_l_f + +{m l f} +Cycle line clip/refraction (toggle) + + + +m_l->m_l_f + + + + + +m_r_o + +{m r o} +Rubber band: orthogonal lines + + + +m_r->m_r_o + + + + + +m_r_r + +{m r r} +Rubber band mode + + + +m_r->m_r_r + + + + + +m_s_p + +{m s p} +Enable symbol auto-pasting to local lib + + + +m_s->m_s_p + + + + + +p_a + +{p a} +place attribute text + + + +p + +p + + + +p->p_a + + + + + +p_m + +p_m + + + +p->p_m + + + + + +p_t + +{p t} +place terminal + + + +p->p_t + + + + + +p_m_p + +{p m p} +Manage plugins... + + + +p_m->p_m_p + + + + + +p_m_s + +{p m s} +Manage scripts... + + + +p_m->p_m_s + + + + + +s_a_a + +{s a a} +Select all visible objects on sheet + + + +s + +s + + + +s_a + +s_a + + + +s->s_a + + + + + +s_b + +s_b + + + +s->s_b + + + + + +s_c + +s_c + + + +s->s_c + + + + + +s_i + +{s i} +Invert selection on sheet + + + +s->s_i + + + + + +s_l + +s_l + + + +s->s_l + + + + + +s_p + +{s p} +Edit properties + + + +s->s_p + + + + + +s_r + +{s r} +Remove selected objects + + + +s->s_r + + + + + +s_s + +{s s} +Advanced search and select + + + +s->s_s + + + + + +s_t + +{s t} +Testbench affiliation + + + +s->s_t + + + + + +s_u + +s_u + + + +s->s_u + + + + + +s_a->s_a_a + + + + + +s_b_b + +{s b b} +objects + + + +s_b->s_b_b + + + + + +s_b_g + +{s b g} +groups + + + +s_b->s_b_g + + + + + +s_b_p + +{s b p} +polygons + + + +s_b->s_b_p + + + + + +s_c_g + +{s c g} +Custom group + + + +s_c->s_c_g + + + + + +s_c_p + +{s c p} +Polygon + + + +s_c->s_c_p + + + + + +s_c_s + +{s c s} +Symbol + + + +s_c->s_c_s + + + + + +s_c_t + +{s c t} +Terminal + + + +s_c->s_c_t + + + + + +s_l_k + +{s l k} +List locked objects + + + +s_l->s_l_k + + + + + +s_l_u + +{s l u} +List unnamed symbols + + + +s_l->s_l_u + + + + + +s_u_a + +{s u a} +Unselect all objects on sheet + + + +s_u->s_u_a + + + + + +s_u_p + +{s u p} +Unselect all objects in projet + + + +s_u->s_u_p + + + + + +t_b + +{t b} +Buffer + + + +t + +t + + + +t->t_b + + + + + +t_c + +{t c} +Circle + + + +t->t_c + + + + + +t_d + +{t d} +Del/remove + + + +t->t_d + + + + + +t_k + +{t k} +Lock + + + +t->t_k + + + + + +t_l + +{t l} +Line + + + +t->t_l + + + + + +t_m + +{t m} +Move + + + +t->t_m + + + + + +t_n + +{t n} +Arrow + + + +t->t_n + + + + + +t_o + +{t o} +Whirl (rotate 90 deg) + + + +t->t_o + + + + + +t_p + +{t p} +Change pen + + + +t->t_p + + + + + +t_r + +{t r} +Rectangle + + + +t->t_r + + + + + +t_t + +{t t} +Text + + + +t->t_t + + + + + +t_w + +{t w} +Wirenet + + + +t->t_w + + + + + +t_x + +{t x} +xmirror + + + +t->t_x + + + + + +t_y + +{t y} +ymirror + + + +t->t_y + + + + + +u_c + +{u c} +Clear undo-buffer + + + +u + +u + + + +u->u_c + + + + + +u_d + +{u d} +Undo dialog (for debugging) + + + +u->u_d + + + + + +u_r + +{u r} +Redo last undone operation + + + +u->u_r + + + + + +u_u + +{u u} +Undo last operation + + + +u->u_u + + + + + +v_c + +{v c} +Center cursor + + + +v + +v + + + +v->v_c + + + + + +v_d + +v_d + + + +v->v_d + + + + + +v_f + +{v f} +Zoom Extents + + + +v->v_f + + + + + +v_r + +v_r + + + +v->v_r + + + + + +v_d_n + +{v d n} +Next + + + +v_d->v_d_n + + + + + +v_d_p + +{v d p} +Previous + + + +v_d->v_d_p + + + + + +v_r_g + +{v r g} +Reset GUI + + + +v_r->v_r_g + + + + + +v_r_v + +{v r v} +Reset View + + + +v_r->v_r_v + + + + + +w_a + +{w a} +Abstract model + + + +w + +w + + + +w->w_a + + + + + +w_l + +{w l} +Library + + + +w->w_l + + + + + +w_m + +{w m} +Message Log + + + +w->w_m + + + + + +w_t + +{w t} +Tree view + + + +w->w_t + + + + + +w_w + +w_w + + + +w->w_w + + + + + +w_w_d + +{w w d} +devmaps + + + +w_w->w_w_d + + + + + +w_w_s + +{w w s} +spice libs + + + +w_w->w_w_s + + + + + +w_w_u + +{w w u} +funcmaps + + + +w_w->w_w_u + + + + + +z_e + +{z e} +Zoom Extents + + + +z + +z + + + +z->z_e + + + + + +z_s + +{z s} +Zoom to selection + + + +z->z_s + + + + + +z_x + +{z x} +Zoom Out 20% + + + +z->z_x + + + + + +z_z + +{z z} +Zoom In 20% + + + +z->z_z + + + + + Index: tags/1.0.5/doc/user/05_ui/keytree.txt =================================================================== --- tags/1.0.5/doc/user/05_ui/keytree.txt (nonexistent) +++ tags/1.0.5/doc/user/05_ui/keytree.txt (revision 10414) @@ -0,0 +1,157 @@ ++ menu-default.lht Zoom(-1.2) Zoom In 20% +- menu-default.lht Zoom(+1.2) Zoom Out 20% +/ menu-default.lht conf(toggle, editor/line_refraction, design) Cycle line clip\057refraction (toggle) +: menu-default.lht Command() Command Entry +< menu-default.lht SwitchRelative(-1) Previous +> menu-default.lht SwitchRelative(+1) Next +[ menu-default.lht Grid(down) Previous grid +\ menu-default.lht fullscreen(toggle) Full screen +] menu-default.lht Grid(up) Next grid +a;a menu-default.lht AttributeDialog(object, name) Change name (refdes) +a;c; menu-default.lht QuickAttr(object, connect) Change connections +a;d; menu-default.lht QuickAttr(object, devmap) Change devmap +a;f menu-default.lht AttributeDialog(object, footprint) Change footprint +a;n; menu-default.lht AttributeDialog(object, name) Change name +a;o; menu-default.lht QuickAttr(object, role) Change role +a;p; menu-default.lht QuickAttr(object, portmap) Change portmap +a;r menu-default.lht AttributeDialog(object, name) Change name (refdes) +a;s menu-default.lht AttributeDialog(object, -slot) Change slot num +a;u; menu-default.lht QuickAttr(object, funcmap) Change funcmap +a;v menu-default.lht AttributeDialog(object, value) Change value +b;1; menu-default.lht BufferSwitch(1) Select Buffer #1 +b;2; menu-default.lht BufferSwitch(2) Select Buffer #2 +b;3; menu-default.lht BufferSwitch(3) Select Buffer #3 +b;4; menu-default.lht BufferSwitch(4) Select Buffer #4 +b;5; menu-default.lht BufferSwitch(5) Select scratchpad +b;c;c; menu-default.lht BufferClear() Clear buffer +b;f;l; menu-default.lht BufferClear();BufferLoad(All);Tool(buffer) Load buffer content from file +b;f;s; menu-default.lht BufferSave(All) Save buffer content to file +b;l;s menu-default.lht BufferLoad(Symbol);Tool(buffer) Load buffer symbol\057group from file +b;m;l menu-default.lht Mirror(Buffer, horizontal) Mirror buffer (left\057right) +b;m;u menu-default.lht Mirror(Buffer, vertical) Mirror buffer (up\057down) +b;r;a menu-default.lht Rotate(Buffer, ask) Arbitrarily Rotate Buffer +b;r;l menu-default.lht Rotate90(Buffer, 1) Rotate buffer 90 deg CCW (left) +b;r;r menu-default.lht Rotate90(Buffer, -1) Rotate buffer 90 deg CW (right) +b;s;g menu-default.lht BufferSave(Group) Save buffer group to file +b;s;s menu-default.lht BufferSave(Symbol) Save buffer symbol to file +c-ctrl; menu-default.lht GetXY(Click to set the snap point for this buffer);BufferClear(Clear);BufferCopy();Unselect(All);Tool(buffer) Copy selection to buffer +delete menu-default.lht Tool(Save);Tool(remove);GetXY(Click on object to remove);Tool(Press);Tool(Restore) Remove object +e;c menu-default.lht GetXY(Click to set the snap point for this buffer);BufferClear(Clear);BufferCopy();Unselect(All);Tool(buffer) Copy selection to buffer +e;d menu-default.lht Tool(Save);Tool(remove);GetXY(Click on object to remove);Tool(Press);Tool(Restore) Remove object +e;h menu-default.lht Mirror(auto, horizontal) Mirror object horizontally +e;m;r menu-default.lht RenumberDialog Renumber symbols +e;p menu-default.lht PropEdit(selection) Object Properties... +e;s menu-default.lht pendialog(object) Stroke +e;t menu-default.lht EditText(Object) Text string +e;v menu-default.lht Mirror(auto, vertical) Mirror object vertically +e;w menu-default.lht Rotate90(auto) Whirl object (rotate 90 deg) +e;x menu-default.lht GetXY(Click to set the snap point for this buffer);BufferClear(Clear);BufferCut(MoveSelected);Tool(buffer) Cut selection to buffer +escape menu-default.lht Tool(escape) Cancel +f1 menu-default.lht Tool(circle) Circle +f11 menu-default.lht Tool(arrow) Arrow +f12 menu-default.lht Tool(lock) Lock +f2 menu-default.lht Tool(wirenet) Wirenet +f3 menu-default.lht Tool(line) Line +f4 menu-default.lht Tool(text) Text +f5 menu-default.lht Tool(rect) Rectangle +f7 menu-default.lht Tool(buffer) Buffer +f8 menu-default.lht Tool(remove) Del\057remove +f9 menu-default.lht Tool(rotate) Whirl (rotate 90 deg) +f;a menu-default.lht SaveAs() Save sheet as... +f;e menu-default.lht ExportDialog() Export Sheet... +f;j menu-default.lht ExportProjectDialog() Export Project... +f;n menu-default.lht New(@, root) New root sheet +f;n-shift menu-default.lht New(@, aux) New aux sheet +f;o menu-default.lht Load() Load... +f;p menu-default.lht Print() Print sheet... +f;q menu-default.lht Quit() Quit +f;r menu-default.lht Revert(sheet) Revert sheet +f;s menu-default.lht Save() Save sheet... +f;u menu-default.lht Unload(sheet) Unload sheet +g;b menu-default.lht Grid(down) Previous grid +g;c menu-default.lht Grid(ask) Custom grid +g;d menu-default.lht SetGrid(*2) Grid *2 +g;f menu-default.lht Grid(up) Next grid +g;h menu-default.lht SetGrid(/2) Grid \0572 +g;l menu-default.lht conf(toggle, editor/local_grid/enable, design) Enable local grid +g;v menu-default.lht conf(toggle, editor/draw_grid, design) Enable visible grid +i;c;d menu-default.lht devmaplibRehash() Re-scan the devmap library +i;c;i menu-default.lht Integrity() Data integrity check +i;c;p menu-default.lht preferences Preferences... +i;c;r menu-default.lht SymlibRehash() Re-scan the symbol library +i;c;u menu-default.lht funcmaplibRehash() Re-scan the funcmap library +l;- menu-default.lht Layer(remove) TODO +l;r menu-default.lht Layer(remove) TODO +m;f;l menu-default.lht ToggleFloaters(lock) Lock floaters +m;f;o menu-default.lht ToggleFloaters(only) Only floaters +m;k;s menu-default.lht proptoggle(sheet, p/sheet/loose_sym) Loose symbol (no sym lock) +m;l;c menu-default.lht conf(toggle, editor/line_cont, design) Continuous draw (toggle) +m;l;f menu-default.lht conf(toggle, editor/line_refraction, design) Cycle line clip\057refraction (toggle) +m;r;o menu-default.lht conf(toggle, editor/rubber_band_ortho, design) Rubber band: orthogonal lines +m;r;r menu-default.lht conf(toggle, editor/rubber_band_mode, design) Rubber band mode +m;s;p menu-default.lht conf(toggle, editor/paste_to_local_lib, design) Enable symbol auto-pasting to local lib +n-ctrl menu-default.lht New(@, root) New root sheet +p;a menu-default.lht GetXy(Click where the new attribute should be placed);PlaceAttrib() place attribute text +p;m;p; menu-default.lht ManagePlugins() Manage plugins... +p;m;s; menu-default.lht BrowseScripts() Manage scripts... +p;t menu-default.lht GetXy(Click where the new terminal should be placed);PlaceTerminal() place terminal +s-ctrl menu-default.lht Save() Save sheet... +s;a;a; menu-default.lht Select(All) Select all visible objects on sheet +s;b;b menu-default.lht Breakup(selected, any, sheet) objects +s;b;g menu-default.lht Breakup(selected, group, sheet) groups +s;b;p menu-default.lht Breakup(selected, poly, sheet) polygons +s;c;g menu-default.lht GetXY(Click to set origin);Convert(selected, group) Custom group +s;c;p menu-default.lht GetXY(Click to set origin);Convert(selected, polygon) Polygon +s;c;s menu-default.lht GetXY(Click to set origin);Convert(selected, symbol) Symbol +s;c;t menu-default.lht GetXY(Click to set origin);Convert(selected, terminal) Terminal +s;i; menu-default.lht Select(Invert) Invert selection on sheet +s;l;k; menu-default.lht query(view, "@.locked == 1") List locked objects +s;l;u; menu-default.lht query(view, '@.a.role == "sym" || @.a.name ~ "[?]$"') List unnamed symbols +s;p menu-default.lht propedit(selection) Edit properties +s;r; menu-default.lht RemoveSelected() Remove selected objects +s;s; menu-default.lht SearchDialog() Advanced search and select +s;t menu-default.lht TestBenchDialog(selected) Testbench affiliation +s;u;a; menu-default.lht Unselect(All) Unselect all objects on sheet +s;u;p; menu-default.lht Unselect(AllProject) Unselect all objects in projet +t;b menu-default.lht Tool(buffer) Buffer +t;c menu-default.lht Tool(circle) Circle +t;d menu-default.lht Tool(remove) Del\057remove +t;k menu-default.lht Tool(lock) Lock +t;l menu-default.lht Tool(line) Line +t;m menu-default.lht Tool(move) Move +t;n menu-default.lht Tool(arrow) Arrow +t;o menu-default.lht Tool(rotate) Whirl (rotate 90 deg) +t;p menu-default.lht Preferences(colors) Change pen +t;p-shift menu-default.lht Tool(copy) Copy +t;r menu-default.lht Tool(rect) Rectangle +t;t menu-default.lht Tool(text) Text +t;w menu-default.lht Tool(wirenet) Wirenet +t;x menu-default.lht Tool(xmirror) xmirror +t;y menu-default.lht Tool(ymirror) ymirror +u;c menu-default.lht Undo(ClearList) Clear undo-buffer +u;d; menu-default.lht UndoDialog() Undo dialog (for debugging) +u;r menu-default.lht Redo() Redo last undone operation +u;u menu-default.lht Undo() Undo last operation +v-ctrl; menu-default.lht Tool(buffer) Paste buffer to layout +v;c menu-default.lht Center() Center cursor +v;d;n menu-default.lht SwitchRelative(+1) Next +v;d;p menu-default.lht SwitchRelative(-1) Previous +v;f menu-default.lht Zoom() Zoom Extents +v;r;g menu-default.lht Reset GUI +v;r;v menu-default.lht Reset View +w;a menu-default.lht AbstractDialog() Abstract model +w;l menu-default.lht LibraryDialog(symbol, sheet) Library +w;m menu-default.lht LogDialog() Message Log +w;t menu-default.lht TreeDialog() Tree view +w;w;d menu-default.lht LibraryDialog(devmap, sheet) devmaps +w;w;s menu-default.lht LibraryDialog(spicelib, sheet) spice libs +w;w;u menu-default.lht LibraryDialog(funcmap, sheet) funcmaps +y-ctrl menu-default.lht Redo() Redo last undone operation +z-ctrl menu-default.lht Undo() Undo last operation +z;1; menu-default.lht Zoom(=100) Zoom to 0.10k\057px +z;2; menu-default.lht Zoom(=250) Zoom to 0.25k\057px +z;5; menu-default.lht Zoom(=500) Zoom to 0.50k\057px +z;e; menu-default.lht Zoom() Zoom Extents +z;s; menu-default.lht ZoomTo(selected) Zoom to selection +z;x; menu-default.lht Zoom(+1.2) Zoom Out 20% +z;z; menu-default.lht Zoom(-1.2) Zoom In 20% Index: tags/1.0.5/doc/user/06_features/funcmap/index.html =================================================================== --- tags/1.0.5/doc/user/06_features/funcmap/index.html (nonexistent) +++ tags/1.0.5/doc/user/06_features/funcmap/index.html (revision 10414) @@ -0,0 +1,312 @@ + + + +

Funcmap

+ +

Introduction

+

+Some integrated circuits like microcontrollers and embedded processors +have more features than physical pins and use internal multiplexers to +configure which physical pin should serve which functionality (peripheral). +

+There are different ways to cope with this on the schematics without extra +features: +

    +
  • list all functions in the terminal label +
  • the above, and let the user draw some marking around the active function's name +
  • better yet, the user could edit the symbol, change the terminal label, to mark the active function or even remove the inactive ones +
+

+However these are time consuming procedures and prone to error as some +functionality are in group, e.g. an SPI typically requires a clock and at +least a MISO or a MOSI (but usually both). With the above manual processes +the software is not doing any verification whether function-terminal assignments +are valid (the given terminal indeed has the given function) or whether a +group of functions, like SPI, have all relevant terminals marked. +

+The funcmap plugin provides an automated solution to the majority of the common +cases. It works a bit similar to devmap: (alternate pin) function maps, +or funcmaps for short, are written by the user in a text file on +a per part basis, collected in a funcmap library. Then the file name of +the funcmap is set in an attribute in one of the symbols +(contributing to a component). +

+During compilation the component inherits +the attribute and the plugin loads and caches the funcmap file into sheet +local library (so the sheet file is self-contained without the external +funcmap lib shipped with it). Then the plugin looks at the attributes of +each port of the component to compute a funcmap name to display - this is +how the alternate function is applied. Instead of a hardwired string, the +symbol shall print the computed funcmap name attribute. This way, after +a successful compilation, the sheet shows the dynamically calculated, +verified alternate function of each port. +

+Furthermore CLI actions and GUI dialog boxes are provided to overview and +edit and verify the consistency of the per terminal function selection. + +

Details

+

+Further details are sorted into the following sub-sections: +

+ +

Funcmap data model and file format

+

+A funcmap operates on the abstract model. It lists alternate functions +of each port and optionally groups those functions in weak and strong +function groups. +

+A typical example is a microcontroller (MCU) that can have the same port +act as a GPIO, as an analog input, a PWM output or part of a sync serial +device. The function is selected runtime by software. +

+As an example for such a situation consider 3 ports of the attiny24 +(full example for all pins is also available). Below +is the stripped down funcmap file from the external library: +

+ha:funcmap.v1 {
+  ha:comp_attribs {
+    li:funcmap/ports {
+      { PB6/PB6      -> sigtype=digital; }
+      { PB6/PCINT6   -> sigtype=digital; dir=input  }
+      { PB6/MOSI     -> sigtype=digital; }
+      { PB6/DI       -> sigtype=digital; dir=input  }
+      { PB6/SDA      -> sigtype=digital; }
+      { PB6/OC1A     -> sigtype=digital; dir=output }
+      { PB6/ADC6     -> sigtype=analog;  dir=input  }
+
+      { PA4/PA4      -> sigtype=digital; }
+      { PA4/PCINT4   -> sigtype=digital; dir=input  }
+      { PA4/SCK      -> sigtype=digital; }
+      { PA4/SCL      -> sigtype=digital; }
+      { PA4/ADC4     -> sigtype=analog;  dir=input  }
+
+      { PA5/PA5      -> sigtype=digital; }
+      { PA5/PCINT5   -> sigtype=digital; dir=input  }
+      { PA5/MISO     -> sigtype=digital; }
+      { PA5/DO       -> sigtype=digital; dir=output }
+      { PA5/OC1B     -> sigtype=digital; dir=output }
+      { PA5/ADC5     -> sigtype=analog;  dir=input  }
+    }
+
+    li:funcmap/weak_groups {
+      { gpio         -> PB6, PA4, PA5 }
+      { pcint        -> PCINT4, PCINT5, PCINT6 }
+      { PWM          -> OC1A, OC1B }
+      { adc          -> ADC4, ADC5, ADC6 }
+    }
+
+    li:funcmap/strong_groups {
+      { SPI          -> SCK, MISO, MOSI }
+      { I2C          -> SDA, SCL }
+      { USI          -> SCK, DI, DO }
+    }
+  }
+}
+
+

+The file is a lihata document with the root node ha:funcmap.v1. It hosts +a single ha:comp_attribs subtree (similar to devmap), to indicate that +the subsequent attributes are component-level (even tho the funcmap plugin +will not actually create these attributes in the components). +

+The li:funcmap/ports attribute is a list of port functions. Each line +is a port/function -> port attributes pair. Function names +are arbitrary. Once the given function is activated for a port, the funcmap +plugin will set all port attributes listed on the right side of the arrow. +As a convention the first function shall match the port name; this is going +to be the primary function of the port which is also used as a fallback +when the user does not activate any function for a port. The typical +port attributes to set are sigtype and dir (see +coraleda +std 002), but any port attribute may be set. +

+The li:funcmap/weak_groups attribute is a list of groups for displaying +purposes. Each line is function group in the form of group_name -> +function_list. Group names are arbitrary but must be unique within +a funcmap file. A function_list is a comma separated list of function names. +(Function names must be defined in the li:funcmap/ports section.) +

+In a tabular display each group is a column (while ports are +rows): +

+<port> gpio    pcint  PWM      adc  SPI  I2C USI <no-group>
+PB6    [[PB6]] PCINT6 OC1A     ADC6 MOSI SDA DI  -
+PA4    [[PA4]] PCINT4 -        ADC4 SCK  SCL SCK -
+PA5    PA5     PCINT5 [[OC1B]] ADC5 MISO -   DO  -
+
+

+The function wrapped in [[]] is the one activated for the given port. +

+li:funcmap/strong_groups has the same format and display properties as +weak_groups. The difference is that a strong group is also +checked in the DRC for consistency. +

+In the above table the <port> column holds raw port names; functions +start from the second column. The last column is always called +<no-group> and holds any function that is not referenced by any of the +function groups. Note: the same function may be referenced from multiple +groups (like SCK in this case), but it's generally best practice to +avoid that. + +

Attribute usage summary

+

+Component attribute: funcmap. Specifies the name of the +funcmap to use. This is the file name in the external library, without +the .funcmap suffix. The attribute is typically specified in the symbol. +If the component is compiled from multiple symbols, the attribute should +be specified only in one of the symbols. If not specified, the component +is not affected by funcmap. +

+Port attribute: funcmap/name (typically specified in a terminal). +Specifies the function the given port should take. Shall be one of the +functions available for the given port. Shall be used only for ports in +components with the funcmap attribute set. If a port in a component with +the funcmap attribute does not specify its funcmap/name, it is computed +by the funcmap plugin (the port name is copied into the funcmap/name attribute). +Thus funcmap/name always contains the valid function name used by the port +(of a funcmap capable symbol) and the symbol should print the +dyntext %../a.funcmap/name% for pin label. + + +

Funcmap library

+

+Funcmap files are loaded from external libs. External lib paths +are configured in the conf node plugins/funcmap/search_paths, which +has the same syntax as the symbol library. +

+Once a funcmap is referenced (from the funcmap attribute of +a component, typically coming from the funcmap attribute of a +symbol), the plugin loads the file from the external lib and places it +in the sheet local library. This keeps sheets self-contained and portable, +not relying on external files. +

+Both the sheet local library and the external library can be browsed +using the funcmap library dialog. The sheet local library can be +flushed (removed) from the File/Maintenance menu; upon the next compilation +all funcmap references are imported into the sheet local library from the +external libraries again. This is how external library changes can be +applied to a sheet. + + +

CLI: actions

+

+The generic way to manipulate funcmaps is simply editing +symbol and terminal attributes, e.g. using the propedit() action. The +funcmap system depends only on funcmap files and attributes, there are +not GUI-only aspects. +

+The specialized CLI actions to manage funcmaps (manually or from scripts) +are: +

    +
  • + FuncmapPrintTable that prints the funcmap state table for a + component to stdout (same table that the component funcmap dialog + presents) +
  • + FuncmapChange that can change port function selection in + a verified way and can select function for multiple ports by + a function group. +
+

+These actions work only if the project is compiled. + +

GUI: dialog boxes and menus

+

+Quick attribute edit for selecting the funcmap for a symbol is available +in the attribute editor, once the funcmap attribute is selected. It opens +the funcmap library dialog (also accessible from the window menu) which +allows browsing the external and sheet local funcmap libs for picking a +funcmap. +

+The per component funcmap summary table dialog can be invoked from the right +click context menu of symbols. This dialog box presents the tabular view +of all ports (rows) and functions (columns). Once a port is selected, +the function of that port can be easily stepped through its available +functions. Alternatively the function can also be set by explicitly +selecting one of the alternate functions (using the change button). +There's a button for activating the whole function group that matches +the currently selected port's function. Note: this dialog box does not +refresh automatically for changes made elsewhere; if there are relevant +changes in the drawing or attributes and the dialog box is still open, +click the refresh button. +

+The per port function selector can be invoked using the right click context +menu of a terminal. The dialog popping up allows selecting one of the +possible functions the port may have. +

+These dialog boxes work only if the project is compiled. + +

DRC: design rule checks

+

+DRC checks are ran automatically as part of the normal sch-rnd DRC process, +unless it is disabled using the conf node plugins/funcmap/drc_disable. +

+The funcmap DRC check verifies that each component with an active funcmap +has all strong function groups properly utilized. For each function (of +a function group) there are three possible states: +

    +
  • unused: the function is not assigned by any port +
  • single: the function is used by only one strong function group and is assigned to a port +
  • multi: the function is used by multiple strong function groups and is assigned to a port +
+

+A function group is valid if and only if: +

    +
  • all of its functions are unused or multi +
  • all of its functions are single or multi +
+

+If a strong function group has some functions unused while other +functions single used, that means the function group is partly +utilized, which is an error that is reported as a DRC violation. +

+For example on the attiny24, there are two +very similar sync serial devices are available with shared +ports: SPI and USI. SPI has SCK, MISO and MOSI while USI has SCK, DI and DO. +Both SPI and USI are strong function groups. Considerations when running the +verification for the SPI function group: +

    +
  • SCK is present in both SPI and USI using the same name; if it is assigned to a port, it's multi state, otherwise it is in unusedstate +
  • If MISO is assigned but MOSI is not, that is a violation +
  • If MOSI is assigned but MISO is not, that is a violation +
  • If MISO and MISO are assigned but SCK is not, that is a violation +
  • If SCK is assigned but neither MISO nor MOSI, that is not reported as a violation (because SCK is multi so it is assumed it'd be used for another group, e.g. USI - but it is not verified while checking on SPI) +
+

+Thus either all three functions of SPI must be activated, or none of them; +except for SCK, which may be activated (for the function group USI). + +

Example: using the system in practice

+

+A full example is provided in +doc/examples/funcmap. It consists of a boxsym-rnd generated +monolithic symbol and the corresponding funcmap file. Ports Vcc and GND +are not mentioned in the funcmap file since those ports are single-function. + +

boxsym-rnd aspects

+

+The symbol for MCUs and CPUs are typically generated using a tool, such +as boxsym-rnd. To play nicely with funcmap, the only requirement is that +the tool generates the affected terminal labels to use dyntext +%../a.funcmap/name%. In boxsym this is done when the funcmap property +(without any argument) is added to a pin block. +

+Boxsym-rnd does not generate the funcmap file; the funcmap file shall be +written manually. It is common that an MCU or CPU symbol is a heavy symbol +that works with only one funcmap. In that case the funcmap attribute could +be specified on component level (in the global section of the boxsym +input file). + + + + + Index: tags/1.0.5/doc/user/06_features/hierarchic/index.html =================================================================== --- tags/1.0.5/doc/user/06_features/hierarchic/index.html (nonexistent) +++ tags/1.0.5/doc/user/06_features/hierarchic/index.html (revision 10414) @@ -0,0 +1,423 @@ + + + + sch-rnd hierarchic + + + + +

sch-rnd hierarchic design

+ +

+This is an user guide; the formal specification of the feature is +documented in the design doc as + feature design and + implementation notes . + +

+After a brief intro, this document splits use cases in three categories. The +basic category contains the most trivial use cases with an intro on +how to set up a hierarchic design. The intermediate category contains more +advanced approaches, still limiting addressing to two different types. Finally +the expert category discusses usage that exploits the full potential of +sch-rnd but requires deeper understanding. + +

+Note: all examples are multisheet with an explicit project file so project.lht +needs to be loaded in sch-rnd. + +

Non-hierarchic cases

+

+A non-hierarchic design has a single sheet or a set of sheets, with or +without a project file. The latter is also called flat multisheet +design. +

+In a non-hierarchic case every component and network are in a single +project global namespace. In practice this means: +

    +
  • if two or more concrete symbols have the same name, they are merged into a single abstract component +
  • if two or more concrete nets have the same name, they are merged into a single abstract net +
+ +

Hierarchic design intro

+

+In a hierarchic design a schematic sheet contains a symbol that represents +a subsheet. This symbol is called the sheet reference symbol or +sheet ref sym for short; the sheet it is referring to is called the +child sheet. The sheet ref sym may have zero or more terminals and the +child sheet must have the same number of terminals placed directly on the sheet. +(In practice these terminals are typically placed from the symbol library; they +are called misc/shterm_* and they are not really symbols but terminals.) +

+The abstract model is produced by the compiler by compiling each root sheet +of the current project. Root sheets are all sharing the common namespace at +the hierarchy root. When compiling a sheet, the sheet ref sym is +detected and the compiler recurses into compiling the child sheet into a +new level of hierarchy. The terminals of the sheet ref sym are +connected to the terminals of the child sheet. +

+Child sheets can contain sheet ref syms to further child sheets, making up +a multi-level hierarchy. The only restriction is that the hierarchy needs to +be free of loops (circular references). + +

Scopes, addressing

+ +

Basic: using only the project global scope

+

+In the simplest setup each child sheet is used only once. There are two +ways to make connections across sheets: +

    +
  • by naming nets and components in any sheet; they all end up in the project global namespace (also called global namespace) +
  • by connecting the sheet ref sym's terminal on the parent sheet +
+

+The same child sheet can not be referred twice because it would create the +same components and networks again. +

+This is a typical setup for the so called "CPU board" case, where a top +level (root) sheet acts as a block diagram connecting terminals of sheet ref +syms of a single level of sheets, each realizing a different section of +the design, as shown in this example: +

+10_cpu example circuit +

+A large CPU is not specified in a single symbol but is split up into a set +of different "slot" symbols by functional blocks (this is called heterogeneous +slotting). At the end all these slot symbols are merged into the same final +abstract component referencing the whole CPU, because they all +have the same name (U1). Global nets, such as gnd and Vcc are easy to +address simply by referencing them by name - this happens in the stock +gnd and Vcc rail symbols. +

+The sheet reference symbol is manually crafted, one symbol for each child +sheet. Such symbols can be constructed right on the root sheet using the +graphical editor, or from text files using the utility boxsym-rnd. The sheet +ref sym has an attribute called cschem/child/name which holds the +name of the child sheet (with or without the .rs ending). The top sheet +must be added to the project file as a root sheet and all child sheets must +be added to the project file as an aux sheet. The project file needs to be +loaded when running sch-rnd. This ensures all sheets are available and can be +found by name and the project is self-contained (if the directory is packed up +and shared, it will load on anyone else's system as well). +

+The extra functionality that this setup provides over the plain flat multisheet +setup is that the same child sheets can be used by a different project in a +slightly different way by doing the wiring between sheet ref syms on the +project-specific top (root) sheet differently. + +

Intermediate: sheet-local objects

+

+Hierarchy can also be used to produce repetitive parts. In this (oversimplified) +20_led example circuit +the root sheet contains a +microcontroller that is controlling two LEDs using PWM. The "power +electronics" of driving the LED is the same on both channels so it makes +sense to draw it only once and reference it twice from the root sheet by +simply placing the sheet ref symbol twice, using different name for each +instance. +

+To avoid the two instances of the child sheet creating the same +components and nets twice, there is a mechanism for creating objects in the +sheet local scope. This is done by prefixing the component or net name +by ./ (a dot and a slash). This prefix is removed by the compiler and the +name is transformed into something unique - by default this is done prepending +the hierarchic path, which is a slash separated list of sheet ref sym +names from root to the given object. This is how Q1 becomes two FETs: +S1/Q1 and S2/Q1. This system works side by side with the basic +mechanism from the previous chapter: +

    +
  • the gnd symbol still addresses the ground as GND, without the + ./ prefix, which means it's the same GND as the parent sheet's GND; +
  • the control signals pwm1a and pwm1b are connected (and named) on the + root sheet and are bound through the sheet ref sym's terminal to + the child sheet's terminal; same applies tot he V9V power supply net. +
+

+So all in all, the intermediate method uses two different addressing +methods: the ./ name prefix to keep something sheet-local; and +names with no prefix, which are called automatic, which simply end +up being global. (At least in the intermediate use case). + +

Intermediate: component addressing

+

+In case of the classic "CPU board" example, the intention is that all the U1 +symbols are merged together into a single big CPU component. In case of the +LED example, the same Q1 on different child sheet instances should be different +FETs. This problem is the very same problem as with the networks, and the +solution is the same: name prefixing. In fact, components have the same +name prefixes and the same behavior as nets. +

+In the actual examples, this was achieved: +

    +
  • in the 10_cpu example by simply using U1 for symbol name, with no prefix +
  • in the 20_led example by using ./Q1, ./D1 and ./R1 for symbol names (./ is the sheet-local prefix) +
+

+This rule of network and symbol name prefixes work the same is true for +the more advanced use cases, for the rest of this document as well, although +the document will use networks to demonstrate different tricks. + +

Intermediate: more on final names

+

+A slightly modified version of the same example is + 22_led. +This removes the net name pwm1a in the top sheet but the control +net is named on the child sheet. In this case the same number of networks +are generated and generally the same abstract model is produced, but the +network that was called pwm1a in the previous example becomes S2/gate, +because that's the second best name sch-rnd could find. +

+In case the child sheet did not name the control net, a globally unique +anon net name would have been generated for this net. + +

Intermediate: passing down global nets

+

+Another modification of the original LED example is + 24_led. +This introduces a common enable signal, controlled by the +microcontroller, that can cut off both LEDs at once. To avoid having to +have an extra terminal on the both sheet ref syms and having to draw the +enable signal to both syms, child sheets simply refer to the blink_enable +net without the ./ prefix, which means this is a global scope net and all three +sheet instances will join its references into a single net. +

+This is the same mechanism that the GND symbol uses. + +

Expert: subtree scope

+

+The intermediate setup covers the situation of reusable single-sheet +modules, locking internal networks and components into the sheet local scope +using the ./ name prefix. In some cases the reusable module is large enough +that it needs to be a multi-sheet hierarchy. In that case there should be +a single root sheet of the module that references all other sheet of +the same module using sheet ref syms. The module is then instantiated +by a bigger design by: +

    +
  • listing all the module files as aux sheets in the project file +
  • having a sheet ref sym referencing to the root sheet of the module +
+

+(The bigger design is generally not interested in the internals of the +multi-sheet module, the interface ("API") between the module and the +bigger design should be the terminals of the module's root sheet and a few +well documented global nets, such as GND.) +

+When a common signal needs to be distributed among all subsheets within the +module the most trivial solution is to create a new terminal on all the +sheet ref syms and do the wiring on the module's root sheet. However this +leads back to the same problem of having too many terminals and too many wires +on the module's root sheet. It would be easier to use a global net that is +accessible from all the module's sheets. However, using a true global net +for this purpose is a bad idea, as it may unintentionally merge with the same +named global net in the bigger design or with the same named global net of +a second instance of the same module that should have been independent. +

+The solution is using subtree local objects (nets and components). This works +by declaring the object (net or component) on the module's root sheet using +a v/ prefix to the name. The v/ prefix means this object is mergable only +downward in the hierarchy so only subsheets of this module, all somewhere +under the module's root sheet will see the object, but it will not +merge with anything above the module's subtree. +

+In example 32_subtree +an extension of the 24_led example: the whole led control section with the +microcontroller and the two LEDs are packed into a subtree. The root of the +subtree is led_ctrl.rs and is almost the same circuit as main.rs in +24_led. The change is that the 2-channel MCU controlled LED subtree is now +commanded through SPI. +

+A new root sheet is added on top, called main.rs, which adds U5, the main +microcontroller, then creates two instances of the led control subtree and +hooks up U5's SPI to control both led_ctrl microcontrollers (using different +slave select signals). +

+Sheet instance tree will look like: +

+main.rs (SPI master)
+ |
+ +- S1: led_ctrl.rs (SPI slave 2 channel LED control)
+ |  |
+ |  +- S1/S1: led.rs (LED and FET)
+ |  |
+ |  +- S1/S2: led.rs (LED and FET)
+ |
+ +- S2: led_ctrl.rs (SPI slave 2 channel LED control)
+    |
+    +- S2/S1: led.rs (LED and FET)
+    |
+    +- S2/S2: led.rs (LED and FET)
+
+ +

+The expert feature, subtree net, can be observed on sheet led_ctrl.rs. It's +the v/blink_enable net. This used to be a global net in example 24_led, so +that it didn't need to have a dedicated terminal on the sheet ref syms. In +this example we need the same, except that blink_enable can not be fully global +because then the two led_ctrl sheets (S1 and S2) would share the same led_ctrl +net. What is needed instead is a subtree local network, which means that +on the level of S1 and S2 these are two separate networks, but in the subtree +under S1 and in the other subtree under S2 the network is accessible without +having to use sheet terminals. +

+The practical implementation is: +

    +
  • on the top of the subtree, on led_ctrl.rs, the net is referenced with the + v/ prefix, which means it's a subtree net: visible downward but isn't merged + upward +
  • on subsheets under led_ctrl.rs, the net is referenced with the ^/ prefix, + which means the net is search upward, preferring a subtree local net and + not a project global nets. +
  • the rest of the nets are the same as before: +
      +
    • global nets like Vcc or gnd or V9V +
    • sheet local nets like ./res_led (which will have 4 instances, named like S1/S2/res_led) +
    • nets passed through sheet ref sym terminals to the child sheet's sheet terminal +
    +
+

+Note: on led_ctrl.rs it's possible to name the blink_enable net without any prefix +and the example will still work. This is because of the search preference of +the auto scope that is used when the name is not prefixed: it will +first search sheet local nets to bind to then starts ascending level by level +looking for a subtree local net, bumping into the same v/blink_enable on +led_ctrl.rs. However, if the search fails (e.g. led_ctrl.rs fails to offer +a subtree local net named blink_enable), the auto will silently create +a global net whereas the ^/ prefixed name will throw an error, which is a +safer choice. + + +

Expert: scope summary and explicit global scoping

+

+A full list of hierarchic name prefixes (and their scopes) can be +found in the design document. +

+The system is designed so that: + +

  • the auto scope, when no prefix is prepended to the net name, + usually does what's expected, searching from local to global, then if + no existing net of the same name is found, creating a new global net. + This is the only addressing used in the flat (non-hierarchic) case and + the most commonly used addressing for non-local objects in the + hierarchic case +
  • it offers an easy to use ./ prefix, which is the most commonly used + local scope prefix in the hierarchic case, locking the given object + into the current sheet +
  • offers a less often used subtree local mechanism for real complicated case, + prefixed with v/ for "search downward" or ^/ for "search upward" +
  • offers the exotic / prefix for explicitly addressing the global scope. +

    +The explicit global scope prefix can be used in the real exotic case when +a (near) bottom child sheet needs to address a project global net not being sure +there was no same named sheet local or subtree local net in the hierarchy. +The auto scope (no prefix) or the ./ or ^/ prefixes would pick up those +intermediate nets, may they exist, not reaching the global scope. The / prefix +turns off the search mechanism and searches right in the project global namespace; +if the object is not found, it is created in the project global namespace. + +

    Expert: hlibrary

    +

    +The simpler usage discussed above, is also the self-contained usage: when +all sheets files of the hierarchy are placed in a single project directory +and all sheets are listed in the project file (as root and aux sheets). +A variation for large projects is placing all sheet files in a directory +tree and have a project file in the top directory, listing all sheets. +

    +This setup is called self-contained because packing up the project starting +from its root directory results in a portable file that can be distributed. +After unpacking on a different system, all files are available and the project +can be compiled. This is because all symbols and devmaps are automatically +embedded in the sheet files, all project-specific configuration embedded in +the project file. +

    +Another use case of hierarchic pages is maintaining a library of child sheets; +for example in IC design it is common to have symbols for blocks like a XOR gate +and then have the "few FET implementation" of that XOR gate as a child sheet +in a library. The advantage is that different projects can share and reuse +the same child sheets. The drawback is that these child sheets are not copied +into the project directory and the project is not self-contained: the +library of child sheets need to be distributed alongside the project. +

    +This option is supported by sch-rnd via path based child sheet references. +Reusable child sheets are placed in the so called hlibrary. This is very +similar to the symbol library, with the search paths configured in the +config node rc/hlibrary_search_paths. Each hlibrary path is a tree of +sheet files and directories on the file system. Child sheets from +sheet ref syms are addressed using the same cschem/child/name +attribute. During project compilation when the given sheet is not +found by name in the project file, sch-rnd announces this in the +message log and automatically searches the hlibrary path and picks the first +file with a matching name. The name is either in the form of "foo.rs" or +just "foo" (sch-rnd automatically matches the .rs or .lht endings). +

    +Example project: +50_hlibrary is +a modified copy if the 20_led example; led.rs is the same child sheet, +referenced as cschem/child/name=led from main.rs +S1 and S2. The file lives in ./hlibrary/, which is a preconfigured standard +hlibrary search path. The file is searched and picked up upon the first +compilation. +

    +Sheets loaded this way are not added to the project file and are +listed as [E] (for external) sheets in the sheet selector. This is a clear +indication that the sheet is not listed in the project file and is automatically +loaded from the hlibrary for a hierarchic design. +

    +The project properties dialog lists external sheets in a separate group +and the toggle button converts an external sheet into an aux sheet, adding +it to the project file sheet listing with its relative path to the project +file. This is useful only if the external sheet is coming from a project-local +hlibrary. + +

    Expert: addressing sheets by path

    +

    +Another way of addressing external child sheets that are not listed in the +project file is path based addressing. This is done by using the sheet +ref sym attribute cschem/child/path instead of cschem/child/name. +The path must be relative to the parent sheet's path on the file system. +The sheet is automatically loaded as an external sheet during compilation. +

    +Example project: +52_path is +a modified copy if the 20_led example; led.rs is the same child sheet, +referenced as cschem/child/path=my_lib/led.rs from main.rs +S1 and S2. The file lives in ./my_lib/, which is not on +hlibrary search path, thus the file is not searched. It is picked up +by a direct file system lookup, using path ./my_lib/led.rs +relative to main.rs. Note: since there is no search, there is also +no file name matching, thus in the path addressing method the exact +file name must be specified, the .rs ending can not be left off. +

    +This method can not be used to address central hlibrary child sheets because of +the relative addressing in the file system. It is useful for large projects +with a local system of child sheets with redundant names, sorted into +subdirectories. In that case the designer may wish to explicitly refer to +the child sheet by relative path instead of by short name depending on +a library search algorithm that may pick the wrong file. + + +

    Expert: addressing sheets by uuid

    +

    +Not yet supported. (TODO) + +

    Expert: non-graphical sheets

    +

    +Non-graphical sheets define object directly in the abstract model, +they do not represent concrete model sheets. Hierarchic mechanisms (like +connecting child sheet terminals to sheet ref sym terminals) depend on +working with concrete model sheets. Thus non-graphical sheets can not +participate in the hierarchy at the moment but can be used as root +sheets in global scope. + + +

    Expert: spice unslotting

    +

    +A special use case for hierarchic designs is "unslotting" a symbol +that was drawn as monolithic symbol. E.g. a dual opamp drawn +as a single symbol can be split up into two separate opamps +This use case is described in + the spice +export plugins documentation. + + + + Index: tags/1.0.5/doc/user/06_features/query/Makefile =================================================================== --- tags/1.0.5/doc/user/06_features/query/Makefile (nonexistent) +++ tags/1.0.5/doc/user/06_features/query/Makefile (revision 10414) @@ -0,0 +1,7 @@ +# Not run atuomatically; execute make after editing the tbl and + +concrete_fields.html: concrete_fields.tbl table.sh + @echo "" > concrete_fields.html + @echo "

    query() fields

    " >> concrete_fields.html + ./table.sh < concrete_fields.tbl >> concrete_fields.html + @echo "" >> concrete_fields.html Index: tags/1.0.5/doc/user/06_features/query/concrete_fields.html =================================================================== --- tags/1.0.5/doc/user/06_features/query/concrete_fields.html (nonexistent) +++ tags/1.0.5/doc/user/06_features/query/concrete_fields.html (revision 10414) @@ -0,0 +1,407 @@ + +

    query() fields

    +

    Concrete objects

    + + + + + + + + + + + + +
    line object fields +
    field + type + description +
    (common) +   + common object fields are available +
    stroke +   + pen fields used for object stroke; e.g. .stroke is the stroke pen name, .stroke.color is stroke pen color +
    x1 + coord + start point x coord +
    y1 + coord + start point y coord +
    x2 + coord + end point x coord +
    y2 + coord + end point y coord +
    length + coord + calculated length +
    length2 + double + square of calculated length (cheaper to calculate) +
    area + double + "ink quantity": approx. area of the line as rendered [coord2] +
    + + + + + + + + + + + + + +
    arc object fields +
    field + type + description +
    (common) +   + common object fields are available +
    stroke +   + pen fields used for object stroke; e.g. .stroke is the stroke pen name, .stroke.color is stroke pen color +
    start + double + start angle [degrees] +
    delta + double + angle span [degrees] +
    x or cx + coord + arc center x coord +
    y or cy + coord + arc center y coord +
    r + coord + arc radius +
    length + coord + calculated length +
    length2 + double + square of calculated length (cheaper to calculate) +
    area + double + "ink quantity": approx. area of the arc as rendered [coord2] +
    + + + + + + + + + + + + + + +
    text object fields +
    field + type + description +
    (common) +   + common object fields are available +
    x or x1 + coord + placement box bottom left +
    y or y1 + coord + placement box bottom left +
    x2 + coord + placement box top right (also used for determining text height) +
    y2 + coord + placement box top right (also used for determining text height) +
    rotation + double + in degrees +
    string + str + text string as specified by the user (may be a dyntext template) +
    render + str + as rendered currently (with dyntext template executed) +
    dyntext + int + 1 if text is dyntext templated, 0 otherwise +
    has_bbox + int + 1 if text is bbox-specified, 0 if height-specified +
    halign + int + horizontal alignment ID +
    + + + + + +
    conn object fields +
    field + type + description +
    (common) +   + common object fields are available +
    conn + list + all objects that are connected by this conn object +
    + + + + + + + + +
    polygon object fields +
    field + type + description +
    (common) +   + common object fields are available +
    stroke +   + pen fields used for object stroke; e.g. .stroke is the stroke pen name, .stroke.color is stroke pen color +
    fill +   + pen fields used for object fill; e.g. .fill is the fill pen name, .fill.color is fill pen color +
    points + int + number of corners +
    area + double + "ink quantity": area of the polygon as rendered [coord2] +
    + + + + + + + + + + +
    group object fields +
    field + type + description +
    (common) +   + common object fields are available +
    x + coord + origin (placement) coord +
    y + coord + origin (placement) coord +
    rotation + double + rotation around origin, in degrees +
    mirx + int + 1 if group is horizontally mirrored, 0 otherwise +
    miry + int + 1 if group is vertically mirrored, 0 otherwise +
    area + double + bbox area of the group as rendered [coord2] +
    +

    Common concrete object fields and types

    +
  • + + + + + + + + + + + +
    types +
    type ID + type name +
    1 + LINE +
    2 + ARC +
    3 + POLY +
    4 + TEXT +
    5 + BITMAP +
    6 + CONN +
    7 + GRP +
    8 + GRP_REF +
    + + + + + + + + +
    horizontal alignment IDs +
    halign ID + alignment name +
    0 + left +
    1 + center +
    2 + right +
    3 + word justify +
    4 + justify +
    + + + + + + + + + + + + + + + + + + + + +
    common fields +
    field + type + description +
    ID + int + object's oid +
    level + int + which level of the hierarchy the object is on; level 0 is the direct group of the sheet; level 1 is an object placed on the sheet +
    bbox.x1 + coord + object's bounding box, leftmost X coordinate +
    bbox.y1 + coord + object's bounding box, bottom Y coordinate +
    bbox.x2 + coord + object's bounding box, rightmost X coordinate +
    bbox.y2 + coord + object's bounding box, top Y coordinate +
    bbox.width + coord + object's bounding box, horizontal size +
    bbox.height + coord + object's bounding box, vertical size +
    type + int + object type ID +
    selected + int + 1 if object is selected, else 0 +
    locked + int + 1 if object is explicitly locked (lock tool), else 0 +
    anylocked + int + 1 if the object is locked in any way (parent is locked or parent is an atomic group, e.g. symbol and object is not a floater) +
    floater + int + 1 if object is a floater, else 0 +
    parent + obj + object's parent group +
    displayer + int + display layer ID the object is rendered on +
    displayer_name + string + display layer name the object is rendered on +
    conn + list + list of objects the current object is connected to via a conn object +
    + + + + + + + + + + + + + +
    pen fields +
    field + type + description +
      + str + without futher fields appended, evaluates to the name of the pen +
    shape + str + round or square +
    is_round + int + 1 if shape is round, else 0 +
    size + coord + pen diameter if shape is round, side length if shape is square +
    color + str + in #rrggbb format +
    dash + int + dash pattern (see design doc) +
    dash_period + coord + dash period (see design doc) +
    font_height + coord + for non-bbox specified text rendered with this pen +
    font_family + str + hint for font selection +
    font_style + str + hint for font selection +
    + Index: tags/1.0.5/doc/user/06_features/query/concrete_fields.tbl =================================================================== --- tags/1.0.5/doc/user/06_features/query/concrete_fields.tbl (nonexistent) +++ tags/1.0.5/doc/user/06_features/query/concrete_fields.tbl (revision 10414) @@ -0,0 +1,131 @@ +# TSV with instructions in first column starting with @ + +@sect Concrete objects + +@table line object fields +@anchor line +@cols field type description +(common)   common object fields are available +stroke   pen fields used for object stroke; e.g. .stroke is the stroke pen name, .stroke.color is stroke pen color +x1 coord start point x coord +y1 coord start point y coord +x2 coord end point x coord +y2 coord end point y coord +length coord calculated length +length2 double square of calculated length (cheaper to calculate) +area double "ink quantity": approx. area of the line as rendered [coord2] + +@table arc object fields +@anchor arc +@cols field type description +(common)   common object fields are available +stroke   pen fields used for object stroke; e.g. .stroke is the stroke pen name, .stroke.color is stroke pen color +start double start angle [degrees] +delta double angle span [degrees] +x or cx coord arc center x coord +y or cy coord arc center y coord +r coord arc radius +length coord calculated length +length2 double square of calculated length (cheaper to calculate) +area double "ink quantity": approx. area of the arc as rendered [coord2] + + +@table text object fields +@anchor text +@cols field type description +(common)   common object fields are available +x or x1 coord placement box bottom left +y or y1 coord placement box bottom left +x2 coord placement box top right (also used for determining text height) +y2 coord placement box top right (also used for determining text height) +rotation double in degrees +string str text string as specified by the user (may be a dyntext template) +render str as rendered currently (with dyntext template executed) +dyntext int 1 if text is dyntext templated, 0 otherwise +has_bbox int 1 if text is bbox-specified, 0 if height-specified +halign int horizontal alignment ID + +@table conn object fields +@anchor conn +@cols field type description +(common)   common object fields are available +conn list all objects that are connected by this conn object + +@table polygon object fields +@anchor polygon +@cols field type description +(common)   common object fields are available +stroke   pen fields used for object stroke; e.g. .stroke is the stroke pen name, .stroke.color is stroke pen color +fill   pen fields used for object fill; e.g. .fill is the fill pen name, .fill.color is fill pen color +points int number of corners +area double "ink quantity": area of the polygon as rendered [coord2] + +@table group object fields +@anchor grp +@cols field type description +(common)   common object fields are available +x coord origin (placement) coord +y coord origin (placement) coord +rotation double rotation around origin, in degrees +mirx int 1 if group is horizontally mirrored, 0 otherwise +miry int 1 if group is vertically mirrored, 0 otherwise +area double bbox area of the group as rendered [coord2] + + +@sect Common concrete object fields and types + +@table types +@anchor types +@cols type ID type name +1 LINE +2 ARC +3 POLY +4 TEXT +5 BITMAP +6 CONN +7 GRP +8 GRP_REF +9 PEN + +@table horizontal alignment IDs +@anchor halign +@cols halign ID alignment name +0 left +1 center +2 right +3 word justify +4 justify + +@table common fields +@anchor common +@cols field type description +ID int object's oid +level int which level of the hierarchy the object is on; level 0 is the direct group of the sheet; level 1 is an object placed on the sheet +bbox.x1 coord object's bounding box, leftmost X coordinate +bbox.y1 coord object's bounding box, bottom Y coordinate +bbox.x2 coord object's bounding box, rightmost X coordinate +bbox.y2 coord object's bounding box, top Y coordinate +bbox.width coord object's bounding box, horizontal size +bbox.height coord object's bounding box, vertical size +type int object type ID +selected int 1 if object is selected, else 0 +locked int 1 if object is explicitly locked (lock tool), else 0 +anylocked int 1 if the object is locked in any way (parent is locked or parent is an atomic group, e.g. symbol and object is not a floater) +floater int 1 if object is a floater, else 0 +parent obj object's parent group +displayer int display layer ID the object is rendered on +displayer_name string display layer name the object is rendered on +conn list list of objects the current object is connected to via a conn object + +@table pen fields +@cols field type description +  str without futher fields appended, evaluates to the name of the pen +shape str round or square +is_round int 1 if shape is round, else 0 +size coord pen diameter if shape is round, side length if shape is square +color str in #rrggbb format +dash int dash pattern (see design doc) +dash_period coord dash period (see design doc) +font_height coord for non-bbox specified text rendered with this pen +font_family str hint for font selection +font_style str hint for font selection Index: tags/1.0.5/doc/user/06_features/query/functions.html =================================================================== --- tags/1.0.5/doc/user/06_features/query/functions.html (nonexistent) +++ tags/1.0.5/doc/user/06_features/query/functions.html (revision 10414) @@ -0,0 +1,151 @@ + + + + +

    Query: advanced search, command line: function calls available

    +

    +Functions listed below can be called from a query expression. + +

    List manipulation

    + +

    llen(lst)

    +

    + Determine length of a list. +

    + Arguments: +

      +
    • lst is the list (should be written as list(lst) to make sure no iteration is done) +
    +

    + Return value: integer length of the list. + + +

    mklist(args...)

    +

    + Create a list of the objects passed. +

    + Arguments: +

    + Variable number of objects. +

    + Return value: the list. + +

    Math & abstract geometry

    + +

    distance(x1, y1, x2, y2)

    +

    + Calculate the distance of two points. +

    + Arguments: +

      +
    • x1: first point, X coordinate +
    • y1: first point, Y coordinate +
    • x2: second point, X coordinate +
    • y2: second point, Y coordinate +
    +

    + Return value: floating point distance value in nanometers. + + +

    abs(number)

    +

    + Returns the absolute value of a number + +

    int(arg)

    +

    + Returns the argument converted to an integer (truncating floating point numbers) + +

    double(arg)

    +

    + Returns the argument converted to a double precision number. + + +

    Object accessors

    + +

    obj_by_idpath(idpath)

    +

    + Returns the object addressed by idpath. +

    + Arguments: +

      +
    • idpath is a string addressing an object on the board +
    +

    + Return value: the addressed object or void. + +

    text_invalid_chars(obj)

    +

    + Returns the number of invalid characters of a text object. An invalid + character is not rendering with the current font of the text (it is out of + range or the font does not have a symbol for the character). +

    + Arguments: +

      +
    • obj is a text object +
    +

    + Return value: a positive integer; 0 means all characters would render properly + +

    Misc

    + +

    action(args...)

    +

    + Execute a pcb-rnd action. +

    + Arguments: variable nunmber of objects and constants. +

    + Return value: invalid on error, or the return value of the action. + +

    coord(str)

    +

    + Converts str to coordinates. Useful when using attribute values. +

    + Arguments: +

      +
    • str is a string (number with units) or a numeric value (taken as nanometers) +
    +

    + Return value: integer length of the list. + +

    isvoid(value)

    +

    + Checks whether value is void (invalid). +

    + Arguments: +

      +
    • value is any value, typically a function call +
    +

    + Return value: 1 if value is void (invalid), 0 otherwise. + +

    getconf(path)

    +

    + Fetch the value of a config node +

    + Arguments: +

      +
    • path is a conf node path, e.g. editor/grid +
    +

    + Return value: invalid if the config node doesn't exist, else the value of + the config node (converted to the most appropriate data type). + +

    violation(i1, v1, ..., iN, vN)

    +

    + Build a DRC violation report (a list object). +

    + Arguments (a variable number of pairs of instruction and value): +

      +
    • i is an instruction, see below. +
    • v is a value (a constant or an object) +
    +

    + Instruction is one of the following constants: +

      +
    • DRCGRP1 - the following v is an object, part of group 1 of offending objects +
    • DRCGRP2 - the following v is an object, part of group 2 of offending objects +
    • DRCEXPECT - the following v is a numeric value that represent the expected value +
    • DRCMEASURE - the following v is a numeric value that represent the measured value that mismatches the expected value +
    +

    + Return value: a list suitable for the drc_query to process. Index: tags/1.0.5/doc/user/06_features/query/index.html =================================================================== --- tags/1.0.5/doc/user/06_features/query/index.html (nonexistent) +++ tags/1.0.5/doc/user/06_features/query/index.html (revision 10414) @@ -0,0 +1,27 @@ + + + +

    Query: data query language

    +

    +The query language is a powerful domain specific, declarative scripting +language that can: +

      +
    • list concrete and abstract objects +
    • iterate over them +
    • evaluate complex logical expressions using them +
    • selecting/unselecting/printing or drc-reporting objects depending on the result of the evaluation. +
    +

    +This chapter describes the query language and its use. The chapter is +split up to multiple sub-chapters: +

    + + +

    +A CLI/scripting tutorial in pcb-rnd doc is +also available (note: objects and field names differ in pcb-rnd). + Index: tags/1.0.5/doc/user/06_features/query/table.sh =================================================================== --- tags/1.0.5/doc/user/06_features/query/table.sh (nonexistent) +++ tags/1.0.5/doc/user/06_features/query/table.sh (revision 10414) @@ -0,0 +1,74 @@ +#!/bin/sh + +# convert table description to html + +awk -F "[\t]" ' + +BEGIN { + q="\"" +} + +function open_tbl( n) +{ + if (is_open) return + + print "" + if (anchor != "") + print " " + else + print " " + print " " + for(n = 0; n < cols; n++) + print "
    " name + + print "
    " COL[n] + + is_open=1 +} + +function close_tbl() +{ + if (!is_open) return + print "
    " +} + +/^[ \t]*#/ { next } + +($1 == "@sect") { + close_tbl(); + $1="" + print "

    " $0 "

    " + next +} + +($1 == "@table") { + close_tbl(); + name = $2 + is_open = 0 + anchor = "" + cols = 0 + next +} + +($1 == "@anchor") { anchor = $2; next } + +($1 == "@cols") { + cols = 0 + for(n = 2; n <= NF; n++) { + COL[cols] = $n + cols++ + } + next +} + +(NF > 1) { + open_tbl() + print " " + for(n = 1; n <= NF; n++) + print " " $n +} + +END { + close_tbl() +} +' Property changes on: tags/1.0.5/doc/user/06_features/query/table.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/1.0.5/doc/user/06_features/scripting/examples/Makefile =================================================================== --- tags/1.0.5/doc/user/06_features/scripting/examples/Makefile (nonexistent) +++ tags/1.0.5/doc/user/06_features/scripting/examples/Makefile (revision 10414) @@ -0,0 +1,4 @@ +all: index.html + +index.html: list util/rosetta_genpages.sh + cd util && ./rosetta_genpages.sh Index: tags/1.0.5/doc/user/06_features/scripting/examples/autolabel/ID.desc =================================================================== --- tags/1.0.5/doc/user/06_features/scripting/examples/autolabel/ID.desc (nonexistent) +++ tags/1.0.5/doc/user/06_features/scripting/examples/autolabel/ID.desc (revision 10414) @@ -0,0 +1,2 @@ +Place text objects (dyntext floaters) displaying the name of wire-nets and +symbols if they don't have it already. Index: tags/1.0.5/doc/user/06_features/scripting/examples/autolabel/ID.name =================================================================== --- tags/1.0.5/doc/user/06_features/scripting/examples/autolabel/ID.name (nonexistent) +++ tags/1.0.5/doc/user/06_features/scripting/examples/autolabel/ID.name (revision 10414) @@ -0,0 +1 @@ +Auto-place missing labels Index: tags/1.0.5/doc/user/06_features/scripting/examples/autolabel/autolabel.fawk =================================================================== --- tags/1.0.5/doc/user/06_features/scripting/examples/autolabel/autolabel.fawk (nonexistent) +++ tags/1.0.5/doc/user/06_features/scripting/examples/autolabel/autolabel.fawk (revision 10414) @@ -0,0 +1,134 @@ +# Create a text object for the label; addr is the textual oidpath of a group, +# lcx and lcy are the center of the longest line within the group if the group +# is a wire-net. +function autolabel_grp(oidpp, lcx, lcy, addr,role,txt_ptr) +{ + addr = "object:" @ oidpp; + role = propget(addr, "a/role"); + + # place text with pen and location depending on parent type + if (role == "wire-net") + txt_ptr = drawtext("retptr", addr, lcx+0, lcy+0, "%../A.name%", "wire"); + else if (role == "symbol") + txt_ptr = drawtext("retptr", addr, 0, 0, "%../A.name%", "sym-primary"); + + # make new text object a dyntext floater + if (txt_ptr != "") { + propset("objbin", txt_ptr, "p/text/dyntext", 1); + propset("objbin", txt_ptr, "p/floater", 1); + } +} + +# User callable action; only the first argument should be passed +function autolabel(scope ,list,oid,par,GRPS,LINE,addr,role,dyntext,textstr,oidpp,oaddr,x1,y1,x2,y2) +{ + # fawk: make sure GRPS and LINE are arrays, just in case no group is found and + # the first loop doesn't write them. + GRPS[]; + LINE[]; + + # create a list for finding target objects + list = idplist("alloc"); + + # build the list depending on scope; deal with only text objects, and only + # those that are not locked in any way (e.g. symbol's non-floaters are locked) + if ((scope == "") || (scope == "selected")) + query("append", list, "!(@.anylocked) && (@.p.selected)"); + else if (scope == "all") + query("append", list, "!(@.anylocked)"); + else { + idplist("free", list); + message("ERROR", "autolabel: first argument must be all or selected"); + return; + } + + # batch all operations together into a single undo serial so they are + # undone atomically: do not increase undo serial while doing rotations + undo("FreezeSerial"); + + # iterate over the list of text objects found, always moving the first + # into oidp + for(oidp = idplist("pop", list); oidp != ""; oidp = idplist("pop", list)) { + oaddr = addr = "object:" @ idp("print", oidp); + dyntext = propget(addr, "p/text/dyntext"); + textstr = propget(addr, "p/text/text"); + type = getobjtype(oidp); + role = propget(addr, "a/role"); + + # if role is unset, we may have hit a child object of a group + # switch to the parent + if (role == "") { + par = getparentgrp(oidp); + idp("free", oidp); + oidp = par; + if (oidp != "") + role = propget("object:" @ idp("print", oidp), "a/role"); + } + + # Store object address in textual form in an array for each group + # that is suitable for our action. The textual form of the address is + # safe to remember (until the objects are deleted), we can free oidp. + # Indexing an array with the group address guarantees we remember every + # candidate group only once. Keep only symbols and wire-nets. First + if ((role == "symbol") || (role == "wire-net")) { + addr = idp("print", oidp); + + # The value for each group is set to 0 once the group is mapped, or + # 1 if a dyntext printing the name is found + if (dyntext && (textstr == "%../A.name%")) { + GRPS[addr] = 1; + } + else if (!(addr in GRPS)) + GRPS[addr] = 0; + + # also remember longest line per group; for wirenets this is where + # we place the label + if (type == "line") { + x1 = propget(oaddr, "p/line/x1"); + y1 = propget(oaddr, "p/line/y1"); + x2 = propget(oaddr, "p/line/x2"); + y2 = propget(oaddr, "p/line/y2"); + llen = (x2-x1) * (x2-x1) + (y2-y1) * (y2-y1); + + # remember longest line only; +0 is for the case the array lookup + # returns NIL + if (llen > LINE[addr, "len"]+0) { + LINE[addr, "len"] = llen; + LINE[addr, "cx"] = (x2+x1)/2; + LINE[addr, "cy"] = (y2+y1)/2; + } + } + } + + + # need to free oid path to avoid memory leak + if (oidp != "") + idp("free", oidp); + } + + # need to free empty list to avoid memory leak + idplist("free", list); + + # visit each candidate group only once, call autolabel_grp() if the group + # doesn't already have a label + for(oidpp in GRPS) + if (GRPS[oidpp] == 0) + autolabel_grp(oidpp, LINE[oidpp, "cx"], LINE[oidpp, "cy"]); + + # batch all operations together into a single undo serial so they are + # undone atomically: allow increasing serials again, increase once so + # the whole batch has its own unique serial number + undo("UnFreezeSerial"); + undo("IncSerial"); +} + +# Runs once when the script is ran +function main(ARGV) +{ + # register action called directly by the user + fgw_func_reg(autolabel); + + # create a menu with the hotkey {p s a} + cookie = scriptcookie(); + createmenu("/main_menu/Plugins/script/auto create labels on selected nets or symbols", "autolabel(selected)", "Create labels (floater dyntext objects) to selected nets/symbols", cookie, "p;s;a"); +} Index: tags/1.0.5/doc/user/06_features/scripting/examples/autolabel/autolabel.html =================================================================== --- tags/1.0.5/doc/user/06_features/scripting/examples/autolabel/autolabel.html (nonexistent) +++ tags/1.0.5/doc/user/06_features/scripting/examples/autolabel/autolabel.html (revision 10414) @@ -0,0 +1,31 @@ +Place text objects (dyntext floaters) displaying the name of wire-nets and +symbols if they don't have it already. +

    +The action creates a list of objects using query(), including only selected +or all objects, depending on scope. This list is then searched through for: +

      +
    • a group with role=symbol or role=wire-net +
    • else any object whose parent is such a group +
    +

    +Matching groups are collected in GRPS[] by their idpath. When child objects +are found, they are checked for two things: +

      +
    • when text: if it's a dyntext printing the name of the group, this is noted in the GRPS[] array (value 1) so a redundant label is not auto-created +
    • when line: the center point of the longest line is remembered per group in LINE[]; this is where a wire-net label is placed +
    +

    +At the end of the action a second loop iterates over the collected GRPS[] +and calls the helper function autolabel_grp() on the ones that need a label. +The helper function then will create the text object for the label. The new +text object is created within the (symbol or wirenet) group. +

    +How to test: +

      +
    • load the script +
    • place a few symbols, delete theyr labels +
    • draw a few nets, name them, but do not place floaters on the name +
    • select nets and symbols +
    • invoke the script from menu or with hotkey {p s a} or using action AutoLabel(selected) +
    • labels are placed on wires and symbols that did not have floaters with their name attribute +
    Index: tags/1.0.5/doc/user/06_features/scripting/examples/divider/ID.desc =================================================================== --- tags/1.0.5/doc/user/06_features/scripting/examples/divider/ID.desc (nonexistent) +++ tags/1.0.5/doc/user/06_features/scripting/examples/divider/ID.desc (revision 10414) @@ -0,0 +1,3 @@ +Select two resistors that form a voltage divider and calculate output +voltage or tune resistor values when output voltage is changed. Can +modify resistor values on the drawing. Index: tags/1.0.5/doc/user/06_features/scripting/examples/divider/ID.name =================================================================== --- tags/1.0.5/doc/user/06_features/scripting/examples/divider/ID.name (nonexistent) +++ tags/1.0.5/doc/user/06_features/scripting/examples/divider/ID.name (revision 10414) @@ -0,0 +1 @@ +voltage divider calculator Index: tags/1.0.5/doc/user/06_features/scripting/examples/divider/divider.fawk =================================================================== --- tags/1.0.5/doc/user/06_features/scripting/examples/divider/divider.fawk (nonexistent) +++ tags/1.0.5/doc/user/06_features/scripting/examples/divider/divider.fawk (revision 10414) @@ -0,0 +1,211 @@ +# Convert a resistor value to numeric (ohm). Formats accepted: +# number +# number suffix (e.g. 5.1k) +# suffix in number (e.g. 4k7) +function getrval(str, n,v,c,tmp,mult) +{ + tmp = ""; + mult = 1; + v = length(str); + for(n = 1; n <= v; n++) { + c = substr(str, n, 1); + if ((c == "k") || (c == "k")) { + c = "."; + mult=1000; + } + else if (c == "M") { + c = "."; + mult=1000000; + } + else if (c == "m") { + c = "."; + mult=1/1000; + } + else if (c == "u") { + c = "."; + mult=1/1000000; + } + tmp = tmp @ c; + } + + return tmp * mult; +} + + +# Truncate trailing zeros after the decimal dot +function setrval(str, n,v,c,dot,good) +{ + str = str @ ""; + v = length(str); + for(n = 1; n <= v; n++) { + c = substr(str, n, 1); + if (c == ".") { + dot = 1; + good = n; + } + else if (dot && (c != "0")) + good = n; + else if (!dot) + good = n; + } + return substr(str, 1, good); +} + + +# Calculate output voltage from input voltages and resistances +function calc_outv() +{ + outv = voltage[2] + (voltage[1] - voltage[2]) * value[2] / (value[1] + value[2]); +} + +# Calculate output voltage and refresh the dialog +function divider_recalc_outv() +{ + # first read current values from the dialog + value[1] = dad("divdlg", "get", w_val[1]); + value[2] = dad("divdlg", "get", w_val[2]); + voltage[1] = dad("divdlg", "get", w_vol[1]); + voltage[2] = dad("divdlg", "get", w_vol[2]); + + calc_outv(); + + dad("divdlg", "set", w_outv, outv+0); +} + +# Exclusive locking mechanism: make sure exactly one lock checkboxe is active +# Caclulate dst's lock value based on src's lock value (both dst and src are +# in range of 1..2) +function divider_recalc_lock(dst, src ,val) +{ + val = dad("divdlg", "get", w_lock[src+0]); + dad("divdlg", "set", w_lock[dst+0], (!val) + 0); +} + +# Recalculate resistor a resistor value based on output voltage and all +# other inputs. Locks determine which resistor is recalculated. +function divider_recalc_resistor( ,idx,tmp) +{ + outv = dad("divdlg", "get", w_outv); + + # cache common voltage component + tmp = (outv - voltage[2]) / (voltage[1] - voltage[2]); + + # figure which one to recalc + if (dad("divdlg", "get", w_lock[1]) == 0) { + value[1] = value[2] * (1-tmp) / tmp; + dad("divdlg", "set", w_val[1], value[1]); + } + else { + value[2] = value[1] *tmp / (1-tmp); + dad("divdlg", "set", w_val[2], value[2]); + } +} + +# User callable action +function divider( list,obj,R1,R2,refdes,res) +{ + list = idplist("alloc"); + + # search resistors: they are GRP objects with role==symbol and name attribute + # starting with R (as a convention). Accept only selected objects. + query("append", list, "(@.type == GRP) && (@.a.role == \"symbol\") && (@.a.name ~ \"^R\") && (@.p.selected)"); + + if (idplist("length", list) != 2) { + message("ERROR", "divider() requires exactly 2 resistors selected"); + return; + } + + # save the idpath of the two resistors in textual format + R1 = idplist("pop", list); + R2 = idplist("pop", list); + R1i = idp("print", R1); + R2i = idp("print", R2); + + # free binary idpaths and the idpath list + idp("free", R1); + idp("free", R2); + idplist("free", list); + + + # retrieve refdes (name) and value attributes + refdes[1] = propget("object:" @ R1i, "a/name"); + refdes[2] = propget("object:" @ R2i, "a/name"); + orig[1] = value[1] = getrval(propget("object:" @ R1i, "a/value")); + orig[2] = value[2] = getrval(propget("object:" @ R2i, "a/value")); + calc_outv(); + + # create the dialog box + dad("divdlg", "new"); + dad("divdlg", "begin_vbox"); + dad("divdlg", "label", "Calculate resistor divider"); + dad("divdlg", "begin_table", 4); + dad("divdlg", "label", "resistor"); + dad("divdlg", "label", "locked"); + dad("divdlg", "label", "resistance"); + dad("divdlg", "label", "voltage"); + + dad("divdlg", "label", refdes[1]); + w_lock[1] = dad("divdlg", "bool"); + dad("divdlg", "default", 1); + dad("divdlg", "onchange", "divider_recalc_lock(2, 1)"); + w_val[1] = dad("divdlg", "real", 0, 10000000); + dad("divdlg", "default", value[1]+0); + dad("divdlg", "onchange", "divider_recalc_outv()"); + w_vol[1] = dad("divdlg", "real", 0, 10000000); ; + dad("divdlg", "default", voltage[1]); + dad("divdlg", "onchange", "divider_recalc_outv()"); + + dad("divdlg", "label", refdes[2]); + w_lock[2] = dad("divdlg", "bool"); + dad("divdlg", "default", 0); + dad("divdlg", "onchange", "divider_recalc_lock(1, 2)"); + w_val[2] = dad("divdlg", "real", 0, 10000000); + dad("divdlg", "default", value[2]+0); + dad("divdlg", "onchange", "divider_recalc_outv()"); + w_vol[2] = dad("divdlg", "real", 0, 10000000); + dad("divdlg", "default", voltage[2]); + dad("divdlg", "onchange", "divider_recalc_outv()"); + dad("divdlg", "end"); + dad("divdlg", "begin_hbox"); + dad("divdlg", "label", "output voltage:"); + w_outv = dad("divdlg", "real", 0, 10000000); + dad("divdlg", "default", outv); + dad("divdlg", "onchange", "divider_recalc_resistor()"); + dad("divdlg", "end"); + dad("divdlg", "button_closes", "cancel", -1, "set & close", 0); + dad("divdlg", "end"); + + res = dad("divdlg", "run_modal", "Resistor divider", ""); + + # res == 0 means clicked "set & close", as specified in button_closes above + if (res == 0) { + # write back only those values that differ from the originally read-out ones + # this reduces noise in the undo buffer and accidental conversion of + # numeric formats, e.g. 4k7 to 4700 + if (value[1] != orig[1]) + propset("object:" @ R1i, "a/value", setrval(value[1])); + if (value[2] != orig[2]) + propset("object:" @ R2i, "a/value", setrval(value[2])); + } +} + +# Runs once when the script is ran +function main(ARGV) +{ + # default voltages values; this is something we can not read out from + # the drawing + voltage[1] = 3.3; + voltage[2] = 0; + + # register user callable action + fgw_func_reg(divider); + + # register internal actions the dialog box will call back + fgw_func_reg(divider_recalc_outv); + fgw_func_reg(divider_recalc_lock); + fgw_func_reg(divider_recalc_resistor); + + # create a menu with the hotkey {p s d} + cookie = scriptcookie(); + createmenu("/main_menu/Plugins/script/resistor divider", "divider()", "Invokes resistor divider calculator", cookie, "p;s;d"); +} Index: tags/1.0.5/doc/user/06_features/scripting/examples/divider/divider.html =================================================================== --- tags/1.0.5/doc/user/06_features/scripting/examples/divider/divider.html (nonexistent) +++ tags/1.0.5/doc/user/06_features/scripting/examples/divider/divider.html (revision 10414) @@ -0,0 +1,24 @@ +Select two resistors that form a voltage divider and calculate output +voltage or tune resistor values when output voltage is changed. +

    +The script picks up exactly two resistors from the selection and presents +a dialog box where the user can change values. The calculator will recalculate +the resulting value upon changes. If the user clicks on "set & close", +the script writes back resulting resistor values. +

    +Note: +0 in fawk (and in awk) triggers a conversion to numeric value. This +is used to make sure arrays are indexed with numbers and numeric widgets are +loaded with numbers. +

    +How to test: +

      +
    • load the script +
    • draw a voltage dicider using two resistor +
    • name the resistor, make sure their name start with R +
    • select the two resistor, but no other resistor (selecting wires and + non-R symbols is okay) +
    • invoke the script from menu or with hotkey {p s d} +
    • change resistor values and input voltages to see output voltage recalculated +
    • change output voltage to see the non-locked resistor value recalculated +
    • click "set & close" to copy back the new resistor value(s) to the drawing +
    Index: tags/1.0.5/doc/user/06_features/scripting/examples/index.html =================================================================== --- tags/1.0.5/doc/user/06_features/scripting/examples/index.html (nonexistent) +++ tags/1.0.5/doc/user/06_features/scripting/examples/index.html (revision 10414) @@ -0,0 +1,51 @@ + + + + sch-rnd rosetta + + + + +

    sch-rnd scripting - examples

    +

    +This is a collection of sch-rnd example scripts implemented in fawk. The purpose +is to demonstrate sch-rnd's scripting API. Each script focuses on a single +scripting feature. +

    +Each example comes with an explanation, written in plain English about what the +scripts do, step by step. +

    +To learn scripting basics, please refer to the + +scripting rosetta doc of pcb-rnd. pcb-rnd also has + +documentation on how to load and run scripts, +the same works in sch-rnd. + + + +

    Index of examples

    + + + + + + + + +
    example description +
    Auto-place missing labels + Place text objects (dyntext floaters) displaying the name of wire-nets and
    symbols if they don't have it already. +
    Zillion(): create a lot of copies + Create a lot of copies of the selection in a matrix groeing right and up
    next to the selection. +
    quick attr (assisted attribute edit) + Quick attribute dialog for choosing the value of the tolerance attribute from
    a list of a few predefined values (e.g. 1% or 5%) for assisted attribute
    editing. +
    TextAutoRotate + Rotate non-locked text objects to make sure they are readable from bottom and
    right. +
    voltage divider calculator + Select two resistors that form a voltage divider and calculate output
    voltage or tune resistor values when output voltage is changed. Can
    modify resistor values on the drawing. +
    + + + + Index: tags/1.0.5/doc/user/06_features/scripting/examples/list =================================================================== --- tags/1.0.5/doc/user/06_features/scripting/examples/list (nonexistent) +++ tags/1.0.5/doc/user/06_features/scripting/examples/list (revision 10414) @@ -0,0 +1,5 @@ +autolabel +zillion +quick_attr +textarot +divider \ No newline at end of file Index: tags/1.0.5/doc/user/06_features/scripting/examples/quick_attr/ID.desc =================================================================== --- tags/1.0.5/doc/user/06_features/scripting/examples/quick_attr/ID.desc (nonexistent) +++ tags/1.0.5/doc/user/06_features/scripting/examples/quick_attr/ID.desc (revision 10414) @@ -0,0 +1,7 @@ +Quick attribute dialog for choosing the value of the tolerance attribute from +a list of a few predefined values (e.g. 1% or 5%) for assisted attribute +editing. + + + + Index: tags/1.0.5/doc/user/06_features/scripting/examples/quick_attr/ID.name =================================================================== --- tags/1.0.5/doc/user/06_features/scripting/examples/quick_attr/ID.name (nonexistent) +++ tags/1.0.5/doc/user/06_features/scripting/examples/quick_attr/ID.name (revision 10414) @@ -0,0 +1 @@ +quick attr (assisted attribute edit) Index: tags/1.0.5/doc/user/06_features/scripting/examples/quick_attr/index.html =================================================================== --- tags/1.0.5/doc/user/06_features/scripting/examples/quick_attr/index.html (nonexistent) +++ tags/1.0.5/doc/user/06_features/scripting/examples/quick_attr/index.html (revision 10414) @@ -0,0 +1,31 @@ + + + + sch-rnd scripting example: quick attr (assisted attribute edit) + + + + + <-- back to the index of scripting examples +

    quick attr (assisted attribute edit)

    +Quick attribute dialog for choosing the value of the tolerance attribute from +a list of a few predefined values (e.g. 1% or 5%) for assisted attribute +editing. +
    Example implementation
    +quick_attr.fawk +
    Explanation, step by step
    +Creates a quick attribute edit for the "tolerance" attribute and lets the user select from a list of a few common values (0.1%, 1%, 5%, 10%) using a GUI. +

    Registers the action quick_attr_tolerance() - because of the name of the action, the property editor and attribute edit dialogs will call this action when the user clicks on assisted edit. +

    When quick_attr_tolerance() is called, it first queries the original tolerance value using propget() and checks if the value is present in the array of known tolerances. If so, it saves the index of the value, because the enum widget communicates in integer indices. The same for loop also builds a flat list of values in a string for initializing the enum. +

    Next the dialog box is created using the DAD API. The change callback of the enum is made to call our own action qa_tolerance_remember() which is used to remember the last selected value in a script-global variable. After running the dialog box in modal mode (which is required by the quick attr infrastructure), set the new value as symbol attribute using propset(). The return value of the function is as defined by the quick attr infrastructure. +

    How to test: +

      +
    • load the script +
    • place a resistor symbol +
    • hover over it and type {a t} +
    • select tolerance value, click OK +
    • open the attribute editor using {a a} (or from the right click menu on the symbol), look at the tolerance attribute, select it, click the floater +
    • clicking the assisted edit button while the tolerance attribute is selected will invoke the script too
    + + + Index: tags/1.0.5/doc/user/06_features/scripting/examples/quick_attr/quick_attr.fawk =================================================================== --- tags/1.0.5/doc/user/06_features/scripting/examples/quick_attr/quick_attr.fawk (nonexistent) +++ tags/1.0.5/doc/user/06_features/scripting/examples/quick_attr/quick_attr.fawk (revision 10414) @@ -0,0 +1,66 @@ +# preset a dialog box and set the attribute +function quick_attr_tolerance(grp, attr_key, TOLS,tols,i,currv) +{ + # this one is global, selecting qa_tolerance_remember() will store selection here + lastval = 0; + + # Common tolerance values + TOLS[0] = "0.1%"; + TOLS[1] = "1%"; + TOLS[2] = "5%"; + TOLS[3] = "10%"; + + currv = propget("objbin", grp, "a/tolerance"); + + # Have it in an str as well for the enum, plus look up init_idx + # using the current value of the attribute + tols = TOLS[0]; + for(i = 1; TOLS[i] != ""; i++) { + tols = tols @ "\t" @ TOLS[i]; + if (currv == TOLS[i]) + lastval = i; + } + + # create the dialog box + dad("toldi", "new"); + dad("toldi", "begin_vbox"); + dad("toldi", "label", "Choose tolerance:"); + w_tol = dad("toldi", "enum", tols); + dad("toldi", "onchange", "qa_tolerance_remember()"); + dad("toldi", "default", lastval); + dad("toldi", "button_closes", "cancel", -1, "ok", 0); + dad("toldi", "end"); + + # run the dialog box as modal, so that the attribute can not be changed, + # elsewhere, a second instance can not be open + res = dad("toldi", "run_modal", "Tolerance value", ""); + + # res is -1 when cancel is clicked and 0 for ok, as set in "button_closes" + # above; when clicked ok, fetch result and set the attribute accordingly + if (res == 0) + propset("objbin", grp, "a/tolerance", TOLS[lastval]); + + # Return a 1 to indicate everything went well and trigger a refresh + # Return 0 to indicate no error but no change + # Return -1 to indicate error + return 1; +} + +# Executed when a new tolerance value is selected; remembers the index of +# the new value in a global fawk variable +function qa_tolerance_remember() +{ + lastval = dad("toldi", "get", w_tol); +} + +# Runs once when the script is ran +function main(ARGV) { + # register actions: the first is called directly by the user, the second + # is called back from the dialog box + fgw_func_reg(quick_attr_tolerance); + fgw_func_reg(qa_tolerance_remember); + + # create a menu with the hotkey {a t} + cookie = scriptcookie(); + createmenu("/main_menu/Plugins/script/assisted edit symbol tolerance", "quickattr(object, tolerance)", "Invokes assisted/quick attribute edit for the tolerance attribute", cookie, "a;t"); +} Index: tags/1.0.5/doc/user/06_features/scripting/examples/quick_attr/quick_attr.html =================================================================== --- tags/1.0.5/doc/user/06_features/scripting/examples/quick_attr/quick_attr.html (nonexistent) +++ tags/1.0.5/doc/user/06_features/scripting/examples/quick_attr/quick_attr.html (revision 10414) @@ -0,0 +1,30 @@ +Creates a quick attribute edit for the "tolerance" attribute and lets the +user select from a list of a few common values (0.1%, 1%, 5%, 10%) using a +GUI. +

    +Registers the action quick_attr_tolerance() - because of the name of the +action, the property editor and attribute edit dialogs will call this action +when the user clicks on assisted edit. +

    +When quick_attr_tolerance() is called, it first queries the original tolerance +value using propget() and checks if the value is present in the array of known +tolerances. If so, it saves the index of the value, because the enum widget +communicates in integer indices. The same for loop also builds a flat list +of values in a string for initializing the enum. +

    +Next the dialog box is created using the DAD API. The change callback of +the enum is made to call our own action qa_tolerance_remember() which +is used to remember the last selected value in a script-global variable. +After running the dialog box in modal mode (which is required by the quick +attr infrastructure), set the new value as symbol attribute using propset(). +The return value of the function is as defined by the quick attr infrastructure. +

    +How to test: +

      +
    • load the script +
    • place a resistor symbol +
    • hover over it and type {a t} +
    • select tolerance value, click OK +
    • open the attribute editor using {a a} (or from the right click menu on the symbol), look at the tolerance attribute, select it, click the floater +
    • clicking the assisted edit button while the tolerance attribute is selected will invoke the script too +
    Index: tags/1.0.5/doc/user/06_features/scripting/examples/textarot/ID.desc =================================================================== --- tags/1.0.5/doc/user/06_features/scripting/examples/textarot/ID.desc (nonexistent) +++ tags/1.0.5/doc/user/06_features/scripting/examples/textarot/ID.desc (revision 10414) @@ -0,0 +1,2 @@ +Rotate non-locked text objects to make sure they are readable from bottom and +right. Index: tags/1.0.5/doc/user/06_features/scripting/examples/textarot/ID.name =================================================================== --- tags/1.0.5/doc/user/06_features/scripting/examples/textarot/ID.name (nonexistent) +++ tags/1.0.5/doc/user/06_features/scripting/examples/textarot/ID.name (revision 10414) @@ -0,0 +1 @@ +TextAutoRotate Index: tags/1.0.5/doc/user/06_features/scripting/examples/textarot/textarot.fawk =================================================================== --- tags/1.0.5/doc/user/06_features/scripting/examples/textarot/textarot.fawk (nonexistent) +++ tags/1.0.5/doc/user/06_features/scripting/examples/textarot/textarot.fawk (revision 10414) @@ -0,0 +1,76 @@ +# User callable action; only the first argument should be passed +function textautorotate(scope ,list,oid,addr,mirx,miry,rot,fixit) +{ + + # create a list for finding target objects + list = idplist("alloc"); + + # build the list depending on scope; deal with only text objects, and only + # those that are not locked in any way (e.g. symbol's non-floaters are locked) + if ((scope == "") || (scope == "selected")) + query("append", list, "(@.type == TEXT) && !(@.anylocked) && (@.p.selected)"); + else if (scope == "all") + query("append", list, "(@.type == TEXT) && !(@.anylocked)"); + else { + idplist("free", list); + message("ERROR", "TextAutoRotate: first argument must be all or selected"); + return; + } + + # batch all operations together into a single undo serial so they are + # undone atomically: do not increase undo serial while doing rotations + undo("FreezeSerial"); + + # iterate over the list of text objects found, always moving the first + # into oidp + for(oidp = idplist("pop", list); oidp != ""; oidp = idplist("pop", list)) { + + # retrieve installed mirror and rotation state; installed means + # how the object really ended up, also considering parent transformations + addr = "object:" @ idp("print", oidp); + mirx = propget(addr, "p/text/inst/mirx"); + miry = propget(addr, "p/text/inst/miry"); + rot = propget(addr, "p/text/inst/rot"); + + # figure if we need to fix it, looking at the combination of mirrors + # and rotation + fixit = 0; + if ((mirx + miry == 1) && (rot > 45) && (rot < 225)) + fixit = 1; + if ((mirx + miry != 1) && (rot > 135)) + fixit = 1; + + # When need to fix, do a 2*90 deg rotation around the bounding box center + # of the object. It's safer to use rotate90 with 2 steps than an arbitrary + # rotate with 180 degree: rotate90 doesn't do any sin() or cos() so it is + # harder to introduce rounding errors in coords + if (fixit) { + cx = propget(addr, "p/bbox/cx"); + cy = propget(addr, "p/bbox/cy"); + rotate90("idpath", 2, oidp, cx, cy); + } + + # need to free oid path to avoid memory leak + idp("free", oidp); + } + + # need to free empty list to avoid memory leak + idplist("free", list); + + # batch all operations together into a single undo serial so they are + # undone atomically: allow increasing serials again, increase once so + # the whole batch has its own unique serial number + undo("UnFreezeSerial"); + undo("IncSerial"); +} + +# Runs once when the script is ran +function main(ARGV) +{ + # register action called directly by the user + fgw_func_reg(textautorotate); + + # create a menu with the hotkey {p s r} + cookie = scriptcookie(); + createmenu("/main_menu/Plugins/script/auto rotate selected text for readability", "TextAutoRotate(selected)", "Rotate selected text so they are always readable from bottom and right", cookie, "p;s;r"); +} Index: tags/1.0.5/doc/user/06_features/scripting/examples/textarot/textarot.html =================================================================== --- tags/1.0.5/doc/user/06_features/scripting/examples/textarot/textarot.html (nonexistent) +++ tags/1.0.5/doc/user/06_features/scripting/examples/textarot/textarot.html (revision 10414) @@ -0,0 +1,20 @@ +Rotate non-locked text objects to make sure they are readable from bottom and +right. The script registers a single action which has the usual scope argument +that can be "all" or "selected". +

    +Depending on scope, the action lists target text objects using query(), then +it processes the list looking at each object id. If the object has the +combination of rotation and mirrorings so that it is not readable from the +bottom or right, it is rotated 180 degrees in-place. In-place rotation is +achieved by rotating around the bounding box center of the object. +

    +How to test: +

      +
    • load the script +
    • place a few text objects, rotate and mirror them +
    • place symbols, rotate and mirror them +
    • draw some wires, use {a a} to name the nets, create floater of the name +
    • select everything +
    • invoke the script from menu or with hotkey {p s r} or using action TextAutoRotate(selected) +
    • some of the text objects will be rotated to match the bottom/right rule +
    Index: tags/1.0.5/doc/user/06_features/scripting/examples/util/Makefile =================================================================== --- tags/1.0.5/doc/user/06_features/scripting/examples/util/Makefile (nonexistent) +++ tags/1.0.5/doc/user/06_features/scripting/examples/util/Makefile (revision 10414) @@ -0,0 +1 @@ +all: Index: tags/1.0.5/doc/user/06_features/scripting/examples/util/index.templ.html =================================================================== --- tags/1.0.5/doc/user/06_features/scripting/examples/util/index.templ.html (nonexistent) +++ tags/1.0.5/doc/user/06_features/scripting/examples/util/index.templ.html (revision 10414) @@ -0,0 +1,32 @@ + + + + sch-rnd rosetta + + + + +

    sch-rnd scripting - examples

    +

    +This is a collection of sch-rnd example scripts implemented in fawk. The purpose +is to demonstrate sch-rnd's scripting API. Each script focuses on a single +scripting feature. +

    +Each example comes with an explanation, written in plain English about what the +scripts do, step by step. +

    +To learn scripting basics, please refer to the + +scripting rosetta doc of pcb-rnd. pcb-rnd also has + +documentation on how to load and run scripts, +the same works in sch-rnd. + + + +

    Index of examples

    + + + + + Index: tags/1.0.5/doc/user/06_features/scripting/examples/util/rosetta_genpages.sh =================================================================== --- tags/1.0.5/doc/user/06_features/scripting/examples/util/rosetta_genpages.sh (nonexistent) +++ tags/1.0.5/doc/user/06_features/scripting/examples/util/rosetta_genpages.sh (revision 10414) @@ -0,0 +1,177 @@ +#!/bin/sh + +clean_id() +{ + tr "\r\n" "~" | sed ' +s/~*$//; +s/|/\&pipe;/g; +s/&/\&/g; +s//\>/g; +s/"/\"/g; +s/'\''/\'/g; +s/~\+/
    /g; +' + echo "" +} + +genpage() +{ + local dir scripts name desc html + + dir="$1" + scripts="$2" + + name=`cat $dir/ID.name` + desc=`cat $dir/ID.desc` + html=`ls $dir/*.html | grep -v index.html` + ./tags < "$html" | awk -v "fn_ref=../packages/XREF" -v "scripts=$scripts" -v "name=$name" -v "desc=$desc" ' + BEGIN { + while((getline < fn_ref) > 0) { + REF[$2] = $3 + } + print "" + print "" + print "" + print " sch-rnd scripting example:", name, "" + print " " + print "" + print "" + print "" + print " <-- back to the index of scripting examples" + print "

    " name "

    " + print desc + + print "
    Example implementation
    " + v = split(scripts, S, "[\r\n]+") + for(n = 1; n <= v; n++) { + lang=S[n] + sub("^ex[.]", "", lang) + if (n != 1) + print " | " + print "" lang "" + } + + print "
    Explanation, step by step
    " + } + /^/ { + gsub("", "", $0) + name=$0 + gsub("[ \t]*", "", name) + if (name in REF) { + link_begin="" + link_end = "" + } + else { + link_begin="" + link_end="" + } + print "" link_begin $0 link_end "" + next + } + + { print $0 } + + END { + print "" + print "" + } + + ' > "$dir/index.html" +} + +gen_index() +{ + + awk -v "template=$1" ' + BEGIN { + FS="[|]" + q = "\"" + LANGS["rb"] = "ruby" + LANGS["pl"] = "perl" + LANGS["py"] = "python" + LANGS["stt"] = "stutter" + LANGS["scm"] = "scheme" + } + + ($1 == "scripts") { + s = $3 + gsub("ex[.]", "", s) + v = split(s, S, " ") + s = "" + for(n = 1; n <= v; n++) { + if (S[n] in LANGS) + s = s " " LANGS[S[n]] + else + s = s " " S[n] + } + DATA[$2, $1] = s + next + } + + ($1 == "name") { + if (names == "") + names = $2 + else + names = names "|" $2 + } + + + { + # DATA[script, name] = "hello world" + DATA[$2, $1] = $3 + } + + function generate(cmd ,N,n,v,name,level) { + if (cmd == "index") { + print "" + print "" + print "
    example description" + v = split(names, N, "[|]") + for(n = 1; n <= v; n++) { + name = N[n] + print "
    " DATA[name, "name"] "" + print " " DATA[name, "desc"] + } + print "
    " + } + else + print "Do not know how to generate " cmd > "/dev/stderr" + } + + END { + FS="" + while((getline < template) > 0) { + if (match($0, "]*>")) { + print substr($0, 1, RSTART-1) + cmd=substr($0, RSTART+8, RLENGTH-9) + sub("^[ \t]*", "", cmd) + generate(cmd) + print substr($0, RSTART+RLENGTH) + } + else + print $0 + } + } + ' + +} + +list=`cat ../list` +for n in $list +do + if test -d "../$n" + then + bn=`basename $n` + scripts=`cd ../$n && ls *.fawk` + genpage "../$n" "$scripts" + echo -n "desc|$bn|" + clean_id < ../$n/ID.desc + echo -n "name|$bn|" + clean_id < ../$n/ID.name + echo -n "scripts|$bn|" + echo $scripts + fi +done | gen_index index.templ.html > ../index.html + + Property changes on: tags/1.0.5/doc/user/06_features/scripting/examples/util/rosetta_genpages.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/1.0.5/doc/user/06_features/scripting/examples/util/tags =================================================================== --- tags/1.0.5/doc/user/06_features/scripting/examples/util/tags (nonexistent) +++ tags/1.0.5/doc/user/06_features/scripting/examples/util/tags (revision 10414) @@ -0,0 +1,4 @@ +#!/bin/sh + +tr "\n" " " | sed "s@\(<[^/]\)@\n\1@g;s@\(]*>\)@\1\n@g" + Property changes on: tags/1.0.5/doc/user/06_features/scripting/examples/util/tags ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/1.0.5/doc/user/06_features/scripting/examples/zillion/ID.desc =================================================================== --- tags/1.0.5/doc/user/06_features/scripting/examples/zillion/ID.desc (nonexistent) +++ tags/1.0.5/doc/user/06_features/scripting/examples/zillion/ID.desc (revision 10414) @@ -0,0 +1,3 @@ +Create a lot of copies of the selection in a matrix groeing right and up +next to the selection. + Index: tags/1.0.5/doc/user/06_features/scripting/examples/zillion/ID.name =================================================================== --- tags/1.0.5/doc/user/06_features/scripting/examples/zillion/ID.name (nonexistent) +++ tags/1.0.5/doc/user/06_features/scripting/examples/zillion/ID.name (revision 10414) @@ -0,0 +1 @@ +Zillion(): create a lot of copies Index: tags/1.0.5/doc/user/06_features/scripting/examples/zillion/zillion.fawk =================================================================== --- tags/1.0.5/doc/user/06_features/scripting/examples/zillion/zillion.fawk (nonexistent) +++ tags/1.0.5/doc/user/06_features/scripting/examples/zillion/zillion.fawk (revision 10414) @@ -0,0 +1,139 @@ +# GUI callback when nx or ny value is changed; "which" is x or y to indicate +# which value is being changed, "other" is the opposite index +function zillion_gui_chg(which, other) +{ + # remember the new value + GUI[which] = dad("zdlg", "get", W[which]); + + # make sure we are not going to do an 1x1 copy + if ((GUI[which] == 1) && (dad("zdlg", "get", W[other]) == 1)) + dad("zdlg", "set", W[other], 2); +} + +# dialog box for setting nx and ny when they are not given in arguments +# save widget IDs in script-global W["x"] and W["y"], save results in +# script-global GUI["x"] and GUI["y"] +function zillion_gui() +{ + dad("zdlg", "new"); + dad("zdlg", "begin_vbox"); + dad("zdlg", "begin_hbox"); + dad("zdlg", "label", "nx"); + W["x"] = dad("zdlg", "integer", 1, 1000); + dad("zdlg", "default", GUI["x"]); + dad("zdlg", "onchange", "zillion_gui_chg(x, y)"); + dad("zdlg", "end"); + dad("zdlg", "begin_hbox"); + dad("zdlg", "label", "ny"); + W["y"] = dad("zdlg", "integer", 1, 1000); + dad("zdlg", "default", GUI["y"]); + dad("zdlg", "onchange", "zillion_gui_chg(y, x)"); + dad("zdlg", "end"); + dad("zdlg", "button_closes", "cancel", -1, "Do it!", 0); + dad("zdlg", "end"); + + return dad("zdlg", "run_modal", "Zillion copies", ""); +} + +# User callable action +function zillion(nx, ny, x,y,dx,dy,list,oidp,addr,x1,y1,x2,y2,bbx1,bby1,bbx2,bby2,ox,oy) +{ + + # if number of copies is not specified, present a dialog for setting them + if (nx == "") { + GUI["x"] = GUI["y"] = 3; + if (zillion_gui() != 0) + return; + nx = GUI["x"]; + ny = GUI["y"]; + } + else { + # when ny is not specified, assume 1 for a single row of copies + if (ny == "") + ny = 1; + + # input validation: we need more than an 1x1 array + nx = int(nx); + ny = int(ny); + if ((nx < 1) || (ny < 1) || (nx+ny == 2)) { + message("ERROR", "zillion(): arguments must be integers >= 1 and there must be more than 1 copies"); + return 1; + } + } + + # create a list for all selected objects for the bbox caclulation + list = idplist("alloc"); + + # calculate bbox of selection of first-level objects (objects directly on + # the sheet, not within groups like symbols or wirenets) + query("append", list, "(@.p.selected) && (@.level == 1)"); + + # iterate over the list of text objects found, always moving the first + # into oidp + bbx1 = bby1 = +100000000; + bbx2 = bby2 = -100000000; + for(oidp = idplist("pop", list); oidp != ""; oidp = idplist("pop", list)) { + addr = "object:" @ idp("print", oidp); + x1 = propget(addr, "p/bbox/x1"); + y1 = propget(addr, "p/bbox/y1"); + x2 = propget(addr, "p/bbox/x2"); + y2 = propget(addr, "p/bbox/y2"); + if (x1 < bbx1) bbx1 = x1; + if (y1 < bby1) bby1 = y1; + if (x2 > bbx2) bbx2 = x2; + if (y2 > bby2) bby2 = y2; + } + + # need to free empty list to avoid memory leak + idplist("free", list); + + + # calculate displacement: width and height rounded to 4000 with some margin + dx = bbx2-bbx1; + dy = bby2-bby1; + dx = int(dx/4000+1)*4000; + dy = int(dy/4000+1)*4000; + + # calculate buffer origin, again 4000 rounded to make sure everything lands + # aligned at the end + ox = int(bbx1/4000+1)*4000; + oy = int(bby1/4000+1)*4000; + + # batch all operations together into a single undo serial so they are + # undone atomically: do not increase undo serial while doing rotations + undo("FreezeSerial"); + + # make a copy of the selection, grab at ox;oy + buffercopy(ox, oy); + + # create an array of copies, grown to right and up; skip the copy at + # 0;0 so that we do not paste over the original input + for(y = 0; y < ny; y++) { + for(x = 0; x < nx; x++) { + if (x+y > 0) { + bufferpaste(ox + dx*x, oy + dy*y); + } + } + } + + + # batch all operations together into a single undo serial so they are + # undone atomically: allow increasing serials again, increase once so + # the whole batch has its own unique serial number + undo("UnFreezeSerial"); + undo("IncSerial"); +} + +# Runs once when the script is ran +function main(ARGV) +{ + # register action called directly by the user + fgw_func_reg(zillion); + + # register action called back yb gui widgets + fgw_func_reg(zillion_gui_chg); + + # create a menu with the hotkey {p s z} + cookie = scriptcookie(); + createmenu("/main_menu/Plugins/script/make a lot of copies", "zillion([x, y])", "Make a lot of copies of selected objects", cookie, "p;s;z"); +} Index: tags/1.0.5/doc/user/06_features/scripting/examples/zillion/zillion.html =================================================================== --- tags/1.0.5/doc/user/06_features/scripting/examples/zillion/zillion.html (nonexistent) +++ tags/1.0.5/doc/user/06_features/scripting/examples/zillion/zillion.html (revision 10414) @@ -0,0 +1,29 @@ +Create a lot of copies of the selection in a matrix groeing right and up +next to the selection. +

    +The action runs a query() to find all first-level selected objects and calculate +their bounding box union. This is the smallest boxaround all selected objects. +This needs to deal with first-levle objects only: objects on deeper level +(e.g. within symbols or wirenets) are specified relative to their parent +which would result in low coordinates; these objects are also calculated in +the parent group's bbox so it is enough to deal with the parent (top level) +groups. +

    +Using the bbox an origin ("grab point") and an offset (dx, dy) are caclulated, +all rounded to 4k grid. Then a loop copies selection to a nx * ny matrix +starting from the original selection. Copies are placed n*dx and n*dy away, +so there is no overlap with the original selection. +

    +If the user did not specify nx and ny as parameters, a modal dialog box is +popped up so these values an be specified. The dialog box doesn't permit +setting the matrix to 1x1, in such case one of the sizes is increased to 2. +

    +How to test: +

      +
    • load the script +
    • place a few objects and select them +
    • invoke the script from menu or with hotkey {p s z} or using action Zillion +
    • use the dialog box to set the number of copies +
    • click on the "do it" button +
    • optional: if a lot of symbols are created, select them and use renumber(selected) to get them uniquely named +
    Index: tags/1.0.5/doc/user/06_features/simulation/fields.html =================================================================== --- tags/1.0.5/doc/user/06_features/simulation/fields.html (nonexistent) +++ tags/1.0.5/doc/user/06_features/simulation/fields.html (revision 10414) @@ -0,0 +1,136 @@ + + + + + + + + + + +

    Simulation setup details

    +

    Analyses

    +

    Below is a table of all analysis types supported. The first column goes in analysis/type. +

    +
    analysis name description x axis +
    op + op: dc operating point + N/A +
    tran_lin + transient (linear) + linear, time [s] +
    ac_dec + ac (dec) + logarithmic (decade), freq [Hz] +
    ac_oct + ac (oct) + logarithmic (octal), freq [Hz] +
    ac_lin + ac (linear) + linear, freq [Hz] +
    dc_lin + dc (linear) + linear, input value +
    dc_disto_dec + dc distortion (dec) + logarithmic (decade), freq [Hz] +
    dc_disto_oct + dc distortion (oct) + logarithmic (octal), freq [Hz] +
    dc_disto_lin + dc distortion (lin) + linear, freq [Hz] +
    dc_noise_dec + dc noise (lin) + linear, n/a (noise) +
    previous + previous analysis + N/A +
    +

    Presentations

    +

    The following presentation types are available (these go in presentation/type): +

      +
    • print +
    • plot +
    +

    Modifications

    +

    Below is a table of all modification types supported. The first column is the node name used for hash nodes in the mods subtree. +

    +
    modification name +
    add +
    omit +
    edit_attr +
    disconn +
    temp +
    +

    'Add' modification fields

    +

    Below is a table of all device types supported when adding a component from mods. The first column goes in the add mod's device node. +

    +
    modification name can have AC can have tdf (time-dependent func) +
    V + yes + yes +
    I + yes + yes +
    R + no + no +
    C + no + no +
    L + no + no +
    +

    'Add' modification tdf subtree

    +

    Below is a table of all tdf types supported when adding a component that has tdf capability. First column goes in add/tdf, parameters go in add/tdf_params/ +

    +
    tdf name params +
    none + +
      +
    + +
    pulse + +
      +
    • V1 (Initial value [V,A]) +
    • V2 (Pulsed value [V,A]) +
    • TD (Delay time [sec]) optional +
    • TR (Rise time [sec]) optional +
    • TF (Fall time [sec]) optional +
    • PW (Pulse width [sec]) optional +
    • PER (Period [sec]) optional +
    + +
    sin + +
      +
    • VO (Offset (vertical) [V,A]) +
    • VA (Amplitude [V,A]) +
    • FREQ (Frequency [Hz]) optional +
    • TD (Delay [sec]) optional +
    • THETA (Damping factor [sec]) optional +
    + +
    exp + +
      +
    • V1 (Initial value [V,A]) +
    • V2 (Pulsed value [V,A]) +
    • TD1 (rise delay time [sec]) optional +
    • TAU1 (rise time constant [sec]) optional +
    • TD2 (fall delay time [sec]) optional +
    • TAU2 (fall time constant [sec]) optional +
    + +
    pwl + +
      +
    • TAB (space sep list of time value pairs [sec V,A]) +
    • r (repeat initial section [sec]) optional +
    • td (delay the whole signal [sec]) optional +
    + +
    Index: tags/1.0.5/doc/user/06_features/simulation/index.html =================================================================== --- tags/1.0.5/doc/user/06_features/simulation/index.html (nonexistent) +++ tags/1.0.5/doc/user/06_features/simulation/index.html (revision 10414) @@ -0,0 +1,287 @@ + + + +

    Simulation

    +

    +In this context, simulation means circuit simulation using a lumped element +model of the circuit generated from the abstract model. More practically, +simulation means SPICE simulation. +

    +There are two levels of the implementation: +

      +
    • low level, which requires more knowledge on SPICE syntax, plus requires + the drawing to be decorated with SPICE-specific symbols +
    • high level, which is further away from the SPICE syntax and is designed + to operate on drawings without having to add extra SPICE or simulation + specific symbols (sources, probes, commands, etc.) +
    +

    +The high level simulation is recommended if: +

      +
    • you are new to circuit simulation +
    • sheets drawn for a production workflow (e.g. PCB workflow) should be + simulated without having to add SPICE decoration and without having to + copy out the relevant part +
    • can run ngspice from sch-rnd so you do not need to use shell or to write + scripts for quick iterations; results are displayed within sch-rnd + (when used from GUI) +
    • works with both GUI (dialog boxes) and CLI (actions) +
    +

    +The low level simulation is recommended if: +

      +
    • you already have a lot of experience with spice and the SPICE syntax +
    • you want maximum flexibility on the SPICE side (arbitrary commands) +
    • you do not mind making your drawing simulation-specific +
    • sch-rnd does not run the simulator, merely exports the netlist; you + will need to run the simulator using the netlist (from a shell, maybe + using scripts, or a Makefile) +
    +

    +The easiest way to learn both the low and the high level simulation is +the tutorial + +

    High level simulation

    +

    +The high level sim differs a lot from the classic "drawn for spice" +schematics model. It really models how circuits are tested in real life: +

      +
    • the drawing is for the real board, typically done for the PCB workflow +
    • multiple different "simulation setups" can be defined +
    • a setup includes test bench configuration, which describes which parts + of the circuit should be included in the simulation, so you do not need + to simulate the whole circuit and you do not need to copy out the + relevant part into a separate sheet for simulation +
    • a setup includes instructions for modifications for the test: adding + sources or resistors (e.g. load) or capacitors or inductances; removing + parts; disconnecting pins; changing attributes (e.g. value of + components); +
    • a setup includes output configuration that contains commands for + SPICE to run different analyses and also contains instructions to + sch-rnd on how to present the output of those runs. +
    +

    All this remembered in sim setup config so you don't need to modify your +production board for sim testing. +

    +The configuration stored for high level simulation has the following logical +structure: +

      +
    • simulation setup #1 +
    • test bench configuration; this allows running the + simulation on parts of the drawing instead of the whole drawing +
    • 0 or more text-specified modifications that are performed before the netlist export: +
        +
      • add components (e.g. sources, load resistors/capacitors/inductors) +
          +
        • device type +
        • device parameters (e.g. dc, ac, time-dependent-function components for sources, resistance/capacitance/inductance for discretes) +
        +
      • remove components +
      • break existing connections +
      • change component attributes +
      • change global states (e.g. temperature) +
      +
    • 0 or more output configurations + +
    • simulation setup #2 +
      • (same fields as above)
      +
    • simulation setup #3 +
      • (same fields as above)
      +
    • ... +
    +

    +On the bottom of the dialog there are buttons for: +

      +
    • selecting the simulation view to use, which also specifies the + simulator to use (only sim_ngspice is available at the moment); + this information is not part of the configuration saved +
    • activating the simulation; this means switching to a sheet of the + project the simulation is for, switching to the view + selected for the simulation, enabling the test bench configured + and triggering a compilation to get it all displayed. CLI + alternative: SimActivate() action. +
    • running the simulation; this activates the simulation, compiles + immediately, executes the simulator in the background and + presents the results in the 3rd tab. CLI alternative: SimRun() + action. +
    +

    +The GUI variant with the run button is designed to be suitable for quick +turnaround circuit tuning: single-click button that can re-generate all +the plots in-place in the non-modal simulation setup dialog; this means +you can keep the window open, make changes to your production circuit +and run the simulation instantly to see the result. + +

    Properties, addressing

    +

    +In the list of properties for presentation and in the positive and negative +connection of an add modification, node addresses are used. A node +address is either the name of an abstract network or a pair of +abstract component and port name, e.g. CN2-4 means "port 4 +of component CN2". +

    +Note: port name means the name the port is listed by in the abstract +model, which is typically the original terminal name, and not the +"pin number", or the calculated display/name attribute. For example using +a polarized symbol, e.g. a diode it is typically A and C (not 1 and 2); +or using a transistor symbol, the port names are B, E, C (and not 1, 2 and 3). +Tip: switch to the raw view to reveal the original port names or use the +abstract model dialog to find them. + +

    config subtree in project.lht

    +

    +All high level simulation config data is stored in the plugins/sim/setups +subtree on the project role (in project.lht). In theory the config system +allows storing the setups subtree in any config source; in practice the +GUI depends on it is stored in the project file. An advanced user may +choose to store sim setup config elsewhere and do the configuration manually, +not using the simulation setup dialog. +

    +The setups subtree structure documented in the appendix. + + +

    Actions: high level sim automation

    +

    +It is possible to run the high level simulation without GUI, using actions. +The system works the same, using the same simulation setups, running the +simulator in the background, but instead of presenting the results on the screen, +saving them in self-contained files. The user then should run 3rd party scripts +and software to parse this file and present the results. +

    +Action SimActivate(setup_name, view_name) performs the same as +the 'activate' button on the GUI: it sets up the configuration and view to +match the named simulation setup. Setup_name is the name of one of the +sim setups from the plugins/sim/setups config subtree and view_name is +the name of a view that has a sim_* plugin in it, e.g. sim_ngpsice. +View_name is used to select the simulation backend (simulation software). +

    +Action SimRun(setup_name, view_name, [output_filename]) +performs the same as the 'run' button on the GUI, saving the output in +a contained plain text file. +Output is saved in sim.txt if no file name is specified in the 3rd argument. + +

    Old sheet files, missing views

    +

    +As of sch-rnd 1.0.2, the default config contains a view called sim_ngspice which +is set up as a target for the high level sim to work with ngspice-30 or newer. +Sheets and project created before 1.0.2 will typically lack this view. Adding +the view is trivial either in the view GUI and in the project file. The +most important aspects is to include target_sim_ngspice at the end of the +engine list ad include std_forge before that. +

    +As of 1.0.2, the ordered engine list for the sim_ngspice view is: +

      +
    1. std_forge +
    2. std_cschem +
    3. std_devmap +
    4. target_sim_ngspice +
    +

    +Std_forge is used to operate the test benching mechanism and target_sim_ngspice +is the engine that generates the spice export and runs ngspice in the background. +The other engines are just standard functionality the user would generally +expect to work (std_cschem for things like the connect attribute, std_devmap +for the devmap and portmap mechanisms). + +

    Low level (raw) simulation

    +

    +The low level, raw, simulation mechanism is used to enable an sch-rnd project +to export to circuit simulation, e.g. spice. The high level simulation is +built on top of the low level. +

    +The low level simulation consists of: +

      +
    • a set of conventional attributes + and mechanisms built on top of them +
    • a set of the target_spice + plugin which tunes the compilation so that the abstract model is + usable for spice netlist export +
    • a view, normally called spice_raw, which uses target_spice as the target + engine +
    +

    +The normal workflow is: +

      +
    • set the view to spice_raw +
    • fill in all relevant attributes in symbols +
    • add extra symbols (e.g. voltage sources) +
    • compile and export using the spice export format +
    • maybe edit the exported file (e.g. gnucap requires that because of incompatibility) +
    • run a spice simulator on the exported file +
    +

    +The extra symbols drawn for spice simulation may interfere with other workflows, +e.g. if the same project is used as a source for a PCB workflow. There are +multiple mechanisms to deal with this: +

      +
    • the classic approach: draw spice-related extras on separate sheet and do not include that sheet in workflows different than spice +
    • use test benching or project stances in general to omit them +
    • the PCB workflow will automatically omit any component from the export that does not have a footprint attribute +
    + +

    Test benching

    +

    +The test bench mechanism is responsible for selecting parts of the circuit +for simulation. Test benching operates on project level. It is implemented +using the test_bench project stance and +forge-if/test_bench attribute +in symbols and wirenets to conditionally omit objects that are not part of +the currently selected test bench. + +

    Test benching using the GUI

    +

    +On the user interface, defining named test benches are done using the +File menu, project submenu, project stances submenu; in the +project stances dialog select the test_bench stance and click +Edit... then enter a new test bench name; it is created and saved in +the project config immediately. +

    +Grouping object into test benches can be done on the GUI by selecting +the given objects, then Select menu, Change selected objects submenu, Testbench +affiliation submenu. This opens the test bench quick edit dialog which +presents a matrix of checkboxes for all selected symbols vs. all +project stances available at the time of opening the window. Ticking a checkbox +means the given object is part of the given test bench. +

    +After filling in the matrix for a few symbols, changing the test bench stance +in the project stances dialog will expose the mechanism: +

      +
    • if the test_bench stance is set to a named test bench, any symbol that + has test bench affiliation but does not include the currently set test + bench becomes omitted, which is indicated using a red cross; + this is the case when a partial circuit is to be simulated; by default + symbols not affiliated with any test benches are present included in + all test benches +
    • if the test_bench stance is empty, the whole circuit is simulated +
    + +

    Test benching in the config

    +

    +The project stance test_bench is part of the config tree: /stances/test_bench +is a string containing the name of the currently activated test bench; +/stances/test_bench_values is an array of all known test bench names. These +shall be set on the project role (so they are part of the project file). The +GUI expects and edits them on the project role. +

    +Symbol test bench affiliation is controlled by the symbol attribute +forge-if/test_bench. +It could be an arbitrary forge script, but the GUI expects a script +in the following structure: +

    +(stance.test_bench != "") && (stance.test_bench != "foo") && (stance.test_bench != "bar")
    +scalar,omit
    +sub,^.*$,yes,omit
    +
    +

    +For the GUI to understand, the expression in the first line must: +

      +
    • start with (stance.test_bench != "") +
    • must list 1 or more && (stance.test_bench != "name") sections with different test bench names +
    Index: tags/1.0.5/doc/user/06_features/simulation/src/Makefile =================================================================== --- tags/1.0.5/doc/user/06_features/simulation/src/Makefile (nonexistent) +++ tags/1.0.5/doc/user/06_features/simulation/src/Makefile (revision 10414) @@ -0,0 +1,14 @@ +all: ../fields.html + +TRUNK=../../../../.. + +include $(TRUNK)/Makefile.conf +include $(LIBRND_MAK) + +CFLAGS = -I$(TRUNK)/src -I$(TRUNK)/src_3rd $(CFLAGS_LIBRND) +LDFLAGS = $(LDFLAGS_LIBRND) -lrnd-core -lrnd-3rd $(LDFLAGS_LIBRND_FUNGW) + +gen: gen.c + +../fields.html: gen + ./gen > ../fields.html \ No newline at end of file Index: tags/1.0.5/doc/user/06_features/simulation/src/gen.c =================================================================== --- tags/1.0.5/doc/user/06_features/simulation/src/gen.c (nonexistent) +++ tags/1.0.5/doc/user/06_features/simulation/src/gen.c (revision 10414) @@ -0,0 +1,113 @@ +#include +#include + +#define DOC_ONLY +#include "../../../../../src/plugins/sim/sim.c" + +void csch_sheet_bbox_update(csch_sheet_t *sheet) {} + +static const char *logname(int l) +{ + switch(l) { + case -1: return "none (no plot)"; + case 0: return "linear"; + case 8: return "logarithmic (octal)"; + case 10: return "logarithmic (decade)"; + } +} +static const char *yesno(int b) +{ + switch(b) { + case 1: return "yes"; + case 0: return "no"; + default: return "N/A"; + } +} + +int main() +{ + int n; + + printf("\n"); + printf("\n\n\n\n\n\n\n\n"); + printf("\n"); + printf("

    Simulation setup details

    \n"); + + + printf("

    Analyses

    \n"); + printf("

    Below is a table of all analysis types supported. The first column goes in analysis/type.\n"); + + printf("

    \n"); + printf("
    analysis name description x axis\n"); + + for(n = 0; sch_siman_names[n] != NULL; n++) { + printf("
    %s\n", sch_siman_names[n]); + printf(" %s\n", sch_siman_description[n]); + if (sch_siman_x_axis_log[n] == -1) + printf(" N/A\n"); + else + printf(" %s, %s\n", logname(sch_siman_x_axis_log[n]), sch_siman_x_axis_name[n]); + } + printf("
    \n"); + + printf("

    Presentations

    \n"); + printf("

    The following presentation types are available (these go in presentation/type):\n"); + printf("

      \n"); + for(n = 0; sch_simpres_names[n] != NULL; n++) + printf("
    • %s\n", sch_simpres_names[n]); + printf("
    \n"); + + printf("

    Modifications

    \n"); + printf("

    Below is a table of all modification types supported. The first column is the node name used for hash nodes in the mods subtree.\n"); + + printf("

    \n"); + printf("
    modification name\n"); + + for(n = 0; sch_simmod_type_names[n] != NULL; n++) { + printf("
    %s\n", sch_simmod_type_names[n]); + } + printf("
    \n"); + + printf("

    'Add' modification fields

    \n"); + printf("

    Below is a table of all device types supported when adding a component from mods. The first column goes in the add mod's device node.\n"); + + printf("

    \n"); + printf("
    modification name can have AC can have tdf (time-dependent func)\n"); + + for(n = 0; sch_simmod_dev_names[n] != NULL; n++) { + printf("
    %s\n", sch_simmod_dev_names[n]); + printf(" %s\n", yesno(sch_sim_device_has_ac[n])); + printf(" %s\n", yesno(sch_sim_device_has_tdf[n])); + + } + printf("
    \n"); + + printf("

    'Add' modification tdf subtree

    \n"); + printf("

    Below is a table of all tdf types supported when adding a component that has tdf capability. First column goes in add/tdf, parameters go in add/tdf_params/\n"); + + printf("

    \n"); + printf("
    tdf name params \n"); + + for(n = 0; sch_simmod_tdf_names[n] != NULL; n++) { + const sch_sim_mod_tdf_param_t *p = sch_sim_mod_tdf_params[n]; + + printf("
    %s\n", sch_simmod_tdf_names[n]); + printf(" "); + if (p != NULL) { + printf("\n
      \n"); + for(; p->name != NULL; p++) { + printf("
    • %s (%s)", p->name, p->desc); + if (p->optional) + printf(" optional"); + printf("\n"); + } + printf("
    \n"); + } + else + printf("(no parametres)"); + printf("\n"); + } + printf("
    \n"); + + +} Index: tags/1.0.5/doc/user/06_features/symbol_lib/Makefile =================================================================== --- tags/1.0.5/doc/user/06_features/symbol_lib/Makefile (nonexistent) +++ tags/1.0.5/doc/user/06_features/symbol_lib/Makefile (revision 10414) @@ -0,0 +1,20 @@ +TRUNK=../../../.. +SYMDIR=$(TRUNK)/library/symbol +HELP2HTML_EXE=$(TRUNK)/util/parametric_help.sh +HELP2HTML=$(HELP2HTML_EXE) -v header=1 -v footer=1 +HTMLS = \ + mech/switch.html\ + mech/connector.html + + +all: parametric.html + +parametric.html: $(HTMLS) ./gen_para_html.sh + ./gen_para_html.sh $(HTMLS) > parametric.html + +mech/switch.html: $(HELP2HTML_EXE) $(SYMDIR)/mech/switch + $(SYMDIR)/mech/switch --help | $(HELP2HTML) -v "content=switch()" > mech/switch.html + +mech/connector.html: $(HELP2HTML_EXE) $(SYMDIR)/mech/connector + $(SYMDIR)/mech/connector --help | $(HELP2HTML) -v "content=connector()" > mech/connector.html + Index: tags/1.0.5/doc/user/06_features/symbol_lib/gen_para_html.sh =================================================================== --- tags/1.0.5/doc/user/06_features/symbol_lib/gen_para_html.sh (nonexistent) +++ tags/1.0.5/doc/user/06_features/symbol_lib/gen_para_html.sh (revision 10414) @@ -0,0 +1,21 @@ +#!/bin/sh + +echo ' + + +

    sch-rnd standard lib parametric symbols

    +
      +' + +for fn in "$@" +do + tmp=${fn##*/} + sym=${tmp%%.html} + echo "
    • $sym() " +done + +echo ' +
    + + +' \ No newline at end of file Property changes on: tags/1.0.5/doc/user/06_features/symbol_lib/gen_para_html.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/1.0.5/doc/user/06_features/symbol_lib/mech/connector.html =================================================================== --- tags/1.0.5/doc/user/06_features/symbol_lib/mech/connector.html (nonexistent) +++ tags/1.0.5/doc/user/06_features/symbol_lib/mech/connector.html (revision 10414) @@ -0,0 +1,81 @@ + Generate pin-array connectors (e.g. headers). +

    + Generate a connectors that consits of an array of evenly spaced terminals and a frame. +

    connector()

    + +
    name man
    dat
    ory
    description value (bold: default) +
    ny + yes +number of pins (in vertical direction) + +  +
    nx +   +number of columns (in horizontal direction; e.g. single row connectors have 1, headers have 2) + +  +
    eshift +   +double pin spacing, shift even rows or columns by 1 spacing (optional; default: don't shift) + + +
    +x +shift columns (vertical) + +  +
    +y +shift rows (horizontal) + +  +
    + +none + +do not shift anything + +  +
    +
    etrunc +   +truncate the last pin of a shifted row or column + +Boolean: yes/no, true/false, 1/0 +; Default: false +
    + +
    true: +  +false: +  +
    +  +
    sequence +   +pin numbering sequence + + +
    + +normal + +increase by y first, then by x + +  +
    +pivot +increase by x first, then by y + +  +
    +zigzag +"dip-style" numbering in zig-zag: number odd x rows by y ascending, even x rows by y descending + +  +
    +
    +

    Example

    + connector(2, 3) + + Index: tags/1.0.5/doc/user/06_features/symbol_lib/mech/switch.html =================================================================== --- tags/1.0.5/doc/user/06_features/symbol_lib/mech/switch.html (nonexistent) +++ tags/1.0.5/doc/user/06_features/symbol_lib/mech/switch.html (revision 10414) @@ -0,0 +1,44 @@ + Generate a switchs or push button +

    + Generate a switchs or push button with arbitrary number of throws and poles. +

    switch()

    + +
    name man
    dat
    ory
    description value (bold: default) +
    pole + yes +number of poles (mechanically coupled parallel copies of the switch section) + +  +
    throw + yes +number of throws (positions or output terminals for the single input terminal, per switch section) + +  +
    style + yes +graphics for the switching element between terminals + + +
    + +switch + +static switch with 2 or more states +
    +rotary +terminals arranged in rotary switch style +
    +push +push button, off by default (two-state) +
    +invpush +push button, on by default (two-state) +
    +relay +same as switch, but includes relay coil on top +
    +
    +

    Example

    + switch(2, 3) + + Index: tags/1.0.5/doc/user/06_features/symbol_lib/parametric.html =================================================================== --- tags/1.0.5/doc/user/06_features/symbol_lib/parametric.html (nonexistent) +++ tags/1.0.5/doc/user/06_features/symbol_lib/parametric.html (revision 10414) @@ -0,0 +1,13 @@ + + + +

    sch-rnd standard lib parametric symbols

    + + + + Index: tags/1.0.5/doc/user/07_io/alien/index.html =================================================================== --- tags/1.0.5/doc/user/07_io/alien/index.html (nonexistent) +++ tags/1.0.5/doc/user/07_io/alien/index.html (revision 10414) @@ -0,0 +1,86 @@ + + + +

    Alien file formats: common

    +

    +This section deals with some common aspects on handling alien (non-native) +file formats (load/save, import/export). + +

    Sheet load postproc: config

    +

    +The data model of different schematics capture tools differ a lot. Most +notably the name and interpretation of attributes vary. A typical example +is: geda/gschem uses the refdes attribute to name symbols while +sch-rnd uses the name attribute. Loading a gschem sheet +(using the io_geda plugin) won't result in a netlistable sheet without renaming +all refdes attributes to name attributes. +

    +sch-rnd provides a flexible, configurable sheet postprocessing. When an io_ +plugin supports it, it has a list type config node called postproc_sheet_load, +which contains pattern-action pairs. The pattern is a valid query script that +is ran on the concrete model of the sheet after load. Whenever it yields +a matching object, the object is marked and the corresponding action is executed. +The action is expected to make the necessary modification on the marked object. +

    +For example above refdes-to-name translation for io_geda is configured in +two pairs in config node plugins.io_geda.postproc_sheet_load: + +

    +{(@.a.refdes != "")};                                {propset(@, rename/a/refdes, name)}
    +{(@.type == TEXT)  && (@.text == "%../A.refdes%")};  {propset(@, p/text/text, "%../A.name%")}
    +
    + +

    +The first one runs on any object that has a non-empty refdes attribute. It +does not have to check for the object being a group (GRP), because only groups +have attribute in our model. +

    +If it triggers, the group (typically symbol) has a refdes attribute, the +corresponding action, a propset() is ran. The first argument of the +propset is @, which defines the scope to be the object marked. Without +this scoping, propset would run on all selected objects, which would also +work because the code also makes sure only the marked object is selected, however +searching for selection is time consuming. Then the propset goes and +renames the refdes attribute to name. +

    +The second rule edits the text string of attribute printout floaters. These +floaters are dyntext and refer to the attribute by attribute name, which was +originally refdes. The query expression matches text objects that +have the exact reference text insertedby io_geda for the refdes attribute. +The corresponding propset action simply changes the value of the text string +to refer to the name attribute. +

    +There is no limit on how many pattern-action pairs can be configured. However, +it will take time to run all them after each sheet load from the given format. +The pairs are executed in order; the config node is an ordered list, config +files can use + +prepend or append subtrees to modify an existing list without +overwriting it. +

    +Whether a given io_ plugin supports sheet postproc or not depends on +whehter it has the postproc_sheet_load node defined in its config +subtree. + +

    Sheet load postproc: generic scripting

    +

    +An alternative to the above configured sheet post processing is using +an user script. After the above mechanism ran, the code also calls the +an action whose name is the io plugin's name suffixed with _postproc_sheet_load. +For example loading a gschem sheet with io_geda, the action name is +io_geda_postproc_sheet_load. No error is thrown if the action does not +exist. +

    +The action then can be implemented in a plugin or in an user script and +go and visit and modify object in any order and with any method it sees fit. +

    +Limitations: +

      +
    • Only one action per io plugin can be registered, so if there are two scripts + providing the io_geda_postproc_sheet_load action, only one will run +
    • With librnd 4.0.0 there is a limitation that will be fixed later: + permascripts are not loaded before the sheet if the sheet is loaded + from the command line. This means an user script action postprocessor + will work only when the sheet is loaded from the GUI. + +
    Index: tags/1.0.5/doc/user/07_io/export_abst/index.html =================================================================== --- tags/1.0.5/doc/user/07_io/export_abst/index.html (nonexistent) +++ tags/1.0.5/doc/user/07_io/export_abst/index.html (revision 10414) @@ -0,0 +1,19 @@ + + + +

    io_abst

    +

    +Type: debug dump. +

    +Prints the abstract model in "cschem abstract model v1" format, which is +a positional, line oriented, indented tree structured plain text file. + +

    Attribute usage

    +

    +Every attribute of every object is printed. No attribute is interpreted. + +

    Omit and DNP

    +

    +The plugin ignores display/omit or display/dnp and exports +every object from the abstract model. The omit and dnp attribute values +are exported too. Index: tags/1.0.5/doc/user/07_io/export_bom/index.html =================================================================== --- tags/1.0.5/doc/user/07_io/export_bom/index.html (nonexistent) +++ tags/1.0.5/doc/user/07_io/export_bom/index.html (revision 10414) @@ -0,0 +1,34 @@ + + + +

    export_bom

    +

    +Type: component count list. +

    +Exports Bill of Materials, which is a list of components to purchase for +building the circuit, typically sorted by component type. Output format +is controlled by user configured templates. +

    +The templating system is the same as +pcb-rnd's export_bom, with the following local differences: +

      +
    • sym used instead of subc, e.g. "sym.a.device"; more generally, "subcircuit" replaced with "symbol" +
    • there's no %author% and %title% +
    + +

    Attribute usage

    +

    +Any attribute that is named by the template. +

    +Extra attributes with export name are not exported, since the +output is generated using templates that name attributes explicitly. + +

    Omit and DNP

    +

    +The plugin will not export components and networks that have the +display/omit or display/dnp attribute set. + + + + + Index: tags/1.0.5/doc/user/07_io/export_spice/auto_bride.html =================================================================== --- tags/1.0.5/doc/user/07_io/export_spice/auto_bride.html (nonexistent) +++ tags/1.0.5/doc/user/07_io/export_spice/auto_bride.html (revision 10414) @@ -0,0 +1,61 @@ + + + +

    target_spice: automatic bridge

    +

    +In some cases invisible bridges need to be inserted at ports. A typical +example is ngspice mixed mode simulation (releases before 2023) +where ADC or DAC components have to be applied in between the analog and +the digital side of the circuit. It would be possible to add these +converters manually on the schematics, but that'd clutter the drawing. +An alternative approach is using automatic bridges specified in +terminal attributes. +

    +The relevant terminal attributes are spice/bridge/model and spice/bridge/dir. +When spice/bridge/model is present, it names a spice model (in +the sheet local spice lib or in the external spice lib) that is placed +at the port by target_spice. This placement happens in the abstract mode: +first the original network connection is cut at the port, then a new instance +of the converter is inserted, connected to the original network +and a new network segment is introduced to connect the other port of the +converter and the original port. +

    +What instance really means depends on the config node +plugins/target_spice/bridges, which should be one of the following +string values: +

      +
    • vector: for ngspice it is enough to create one component per + converter type and it acts as a multi-slot or multi-port converter + array with vector input and vector output. +
    • scalar: for xyce a discrete converter needs to be placed per + port. +
    • none: ignore the spice/bridge attributes and do not create + any converter or bridge; this assumes the models are all analog or + the spice implementation handles conversion automatically. +
    +

    +The converter is assumed to have only 2 ports, one input and one output. +Order of the connections, or in other words direction of the converter +matters. This can be controlled by the optional spice/bridge/dir +terminal attribute, which should be either "n1p2" or "p1n2". The former +means "original network on port 1 of the converter, original port on +port 2 of the converter", the latter is the opposite. When spice/bridge/dir +is not specified, the code makes an educated guess by the model name, +which should contain either "adc" or "dac", assuming the attribute +is placed on the terminal of a digital port connected to an analog net. +

    +For example, on the drawing below U1 is a digital device that has two ports, +one input, one output. The input port has spice/bridge/model set to +bridge_adc_ttl, the outpout port has it set to bridge_dac_ttl; +spice/bridge/dir is not set. These models are shipped with sch-rnd stock spice +lib. +

    + +

    +Since directions are not set, they are assumed n1p2 for *adc* on the input +and p1n2 for the *dac* on the output. This means the adc's port1 is +connected to the original network (orig_analog_1), port2 to the original +(digital) port of U1, while on the dac port1 is connected to U1's port and +port 2 is to the original network (orig_analog_2). Two dummy networks are +introduced. These are all shown in the abstract model and end up on the +exported netlist, but they are not graphically visible on the drawing. Index: tags/1.0.5/doc/user/07_io/export_spice/bridge.svg =================================================================== --- tags/1.0.5/doc/user/07_io/export_spice/bridge.svg (nonexistent) +++ tags/1.0.5/doc/user/07_io/export_spice/bridge.svg (revision 10414) @@ -0,0 +1,540 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/1.0.5/doc/user/07_io/export_spice/elect0.html =================================================================== --- tags/1.0.5/doc/user/07_io/export_spice/elect0.html (nonexistent) +++ tags/1.0.5/doc/user/07_io/export_spice/elect0.html (revision 10414) @@ -0,0 +1,40 @@ + + + +

    target_spice: election of "node 0"

    +

    +

    +A valid spice circuit must have a ground network, which is considered +potential 0. All other voltages are normally measured against this +potential. In spice terminology this is called node 0. +

    +The plugin export_spice will look for a net that has the spice/gnd +attribute set. When found, this net is renamed to 0 on the output (but +not in the abstract model). +

    +The target_spice plugin attempts to guarantee there is a spice/gnd net at +the end of the compilation process. First it looks through all nets to +find one that already has spice/gnd set during compilation (e.g. from the +concrete model). This gives the user a chance to explicitly select a gnd +net by setting a wirenet attribute. This is useful for circuits with +multiple different ground networks (digital ground, analog ground, power +ground, etc.) +

    +If target_spice did not find a spice/gnd net, it will elect one and set +the spice/gnd attribute on the elected net. The election scores each net +and the net with the highest score wins. If the net name is "gnd" (not +case sensitive), it gets the highest score (and confidence). Else if it +contains "gnd" or "GND" (case sensitive), it gets the second highest +score. Else the score is proportional to the number of ports connected to +the net (in other words, it is assumed that the net with the most number +of connections is the best choice for gnd). When the code was not confident +in the choice, an error message is also generated, asking the user to +explicitly set spice/gnd. +

    +In practice, for the simple cases, for majority of the boards, this works +without any network attribute, because there will be a net called "gnd" +or "GND", which will get the highest score with high confidence. If the +situation is more complex, the code will throw an error and the user should +add the spice/gnd attribute to a net. + + Index: tags/1.0.5/doc/user/07_io/export_spice/index.html =================================================================== --- tags/1.0.5/doc/user/07_io/export_spice/index.html (nonexistent) +++ tags/1.0.5/doc/user/07_io/export_spice/index.html (revision 10414) @@ -0,0 +1,58 @@ + + + +

    Spice export

    +

    +This chapter of the user manual is dealing with the raw spice workflow, +assuming the user wants to understand the process on the spice level. +There's an alternative, a higher level abstraction, called sim. Both +are also covered by the simulation +tutorial. + +

    +Raw spice export topics: +

    + +

    Standard features of export_spice

    +

    +Type: netlist. + +

    Attribute usage

    +

    +For components the following attributes are used to construct file-format +specified fields: +

      +
    • network's spice/gnd is used to select the ground network, node 0 +
    • component's device is printed as comment when debug is enabled +
    • component's display/value (fallback: value) +
    • component's display/spice/params (fallback: spice/parans) +
    • component's spice/model +
    • component's spice/model_card +
    • component's spice/model_card_uname +
    • component's spice/file_header +
    • component's spice/model_include +
    • component's spice/command +
    +

    +Extra attributes with export name are not exported: the file format +is positional and does not support arbitrary attributes. + +

    Omit and DNP

    +

    +The plugin will not export components and networks that have the +display/omit attribute set. +

    +The plugin ignores DNP. + + + + + + + Index: tags/1.0.5/doc/user/07_io/export_spice/model.html =================================================================== --- tags/1.0.5/doc/user/07_io/export_spice/model.html (nonexistent) +++ tags/1.0.5/doc/user/07_io/export_spice/model.html (revision 10414) @@ -0,0 +1,101 @@ + + + +

    Spice models

    + +

    What is spice model

    +

    +A model in spice is really two things: +

      +
    • the code that implements how to simulate the given thing (e.g. an npn transistor) +
    • a set of parameters to this model to get the behavior match a specific existing device type +
    +

    +The former, the code, is typically provided as part of the simulator software, +at least for the most common, basic component types. The latter, model +parameters, is specified by the user (normally acquired from the device +vendor or constructed from the datasheet or measurements). + +

    How to specify the model

    +

    +Concrete symbols are compile into abstract components; export_spice will +write a spice instance line for each named component in the abstract model. +Anything more complicated than passives and sources will need to have +a spice model named in the instance line. +

    +There are different strategies how this spice model name is generated. + +

    sch-rnd's spice lib reference

    +

    +If the symbol has a spice/model attribute, the value of this attribute is +a model name. In sch-rnd reusable spice models are kept in the spice +library, which is very much like the symbol or devmap library: a +directory tree that holds spice models, one model per file, models +identified by file name. Spice export files are self-contained and +do not rely on external model files. This is achieved by sch-rnd +copying the content of these spice model files from the library into +the output file. +

    +Furthermore there's a sheet-local library, just like with devmap (and +optionally with symbols), so any spice model used by the sheet is also saved +in the sheet so the sheet is self-contained (and portable) too. +

    +The following rules apply to the model files in the sch-rnd spice library. +One model file shall contain only one .model or one .subckt. The file name +shall match the name of the .model or .subckt in the file. The name +from spice/model is first searched in all sch-rnd spice libraries in a case +sensitive manner without suffix; if not found, searched again with .mod +suffix; if not found searched again with .prm suffix. The convention +is to name .model files *.prm and .sibckt files *.mod. +

    +Note: the model is copied only once (per unique model name) into the +sheet-local spice lib and to the spice netlist export. +

    +If spice/model_card is specifed, that overrides spice/model (so spice/model +is ignored in that case). + + +

    symbol-embedded spice-card

    +

    +Also called inline spice-card. The whole spice model is specified as a +multiline string in the symbol attribute called spice/model_card. The model +is named with an unique name and copied in the output spice netlist. +

    +On the output spice netlist the model is created as many times as specified +in different symbols. +

    +If specified, overrides spice/model_card. + + +

    spice-level include

    +

    +The above two resulted in both self-contained sheets and self-contained +spice netlist exports. That is, if the sheet is shared, a different user +on a different system could export the same spice netlist, without assuming +any spice model library installed. If the exported spice netlist is shared, +it can be ran through a spice implementation without depending on any +external file (model library). The advantage of this is clearly portability, +while the drawback is larger files and files that need update if the model +is changed (fixed) in the spice lib. +

    +A non-self-contained method is specifying the following two +attributes for a symbol, without specifying spice/model_card or +spice/model: +

      +
    • spice/model_card_uname should contain the name of the model; + export_spice will use this as the model reference from the + generated component instance, without trying to do anything to + make the model available in the file +
    • spice/model_include is a file name or path to the model file + or model library file; a model library file contains multiple models. + Export_spice will generate a single .INCLUDE line on top of the + exported netlist per unique spice/model_include values. +
    +

    +Once the exported file is ran through a spice implementation, the spice +software will employ its own search method for each .INCLUDE and load +the referenced spice lib file from wherever. +

    +This is the weakest method, if spice/model or spice/model_card is specified, +that may modify spice/model_card_uname and will write a model into the +output file. Index: tags/1.0.5/doc/user/07_io/export_spice/pinout.html =================================================================== --- tags/1.0.5/doc/user/07_io/export_spice/pinout.html (nonexistent) +++ tags/1.0.5/doc/user/07_io/export_spice/pinout.html (revision 10414) @@ -0,0 +1,135 @@ + + + +

    Spice pin numbers

    + +

    What is a spice pin number

    +

    +At the very end of the process, export_spice takes each component in the +abstract model, iterates over all ports of the given component and sorts +them by their pin number. The result should be a continous array +numbered from 1 (else an error is generated). Then it iterates over this +sorted array to export the net name each port is connected to. +

    +For export_spice the pin number of a port is one of these +(it will use the first it finds): +

      +
    • display/name (this is what's displayed on the drawing normally) +
    • display/pinnum +
    • name +
    • pinnum +
    +

    +One step back, target_spice generates display/name by choosing the first +existing attribute for a port from these attributes: +

      +
    • spice/pinnum +
    • pinnum +
    • name (the port's name as a final fallback) +
    +

    +Thus the default approach to manage spice node (connection) ordering in +generated (component) instance lines is to specify spice/pinnum as +an integer from 1 up, for each terminal of a symbol. There are multiple +ways to achieve this, each explained below. +

    +Note: other workflows may have different pin numbers for the same ports, +for example pcb/pinnum for the PCB workflow. It's typically the target_* +plugin (configured in the current view) that dispatches the value of a +workflow specific pinnum into display/name. + +

    Different approaches to set spice pin number

    + +

    Implicit from terminal name

    +

    +For the simple symbols like non-polarized two-terminal passives, such +as resistors or coils, terminal names are typically "1" and "2". If nothing +else is set, this becomes display/name and acts perfectly as spice pin +number. + +

    Hardwired in the terminal spice/pinnum

    +

    +Some symbols represent simple, common components that have well established +model pinout in spice. For example BJT or FET transistors, diodes. These +symbols should have spice/pinnum set in their terminals, with attribute +priority set to 31050. +

    +This low priority lets other mechanisms (such as devmap or portmap) +to override the builtin pin number, in case a macromodel (subckt) is chosen +with non-standard pinout. + + +

    Symbol attribute: spice/portmap

    +

    +It is possible to use a generic symbol (such as an opamp) with a custom +model (e.g. a macromodel subckt) that uses a non-standard pinout, as long +as the number of terminals matches the number of ports of the model. The +custom spice pinout can be specified using the normal portmap mechanism via +the array type symbol attribute spice/portmap. + +

    From devmap

    +

    +A devmap typically overwrites the portmap attribute of the component. It +is possible to include spice/pinnum in the devmap, preferrably together +with the symbol attribute spice/model the pinout is for. This method works +for highly specialized custom parts that will always have the same model +for simulation. + +

    Slotting and unslotting

    + +

    Shared ports on slotted symbols

    +

    +For example take the opamp symbol from the stock library: it has +two inputs, one output and two power terminals. These five terminals +match the five ports a typical spice opamp macromodel would expect. +

    +But when it comes to slotting, there is a problem with the power pins. +Take a dual opamp, say lm358: that will be two symbols placed with the +same name (say U15). When exported in a workflow that supports slotted +components (e.g. target_pcb), the abstract model will contain a single U15 +with 8 ports: two times the two input ports, two output ports and one +pair of power ports, shared by both slots. When exporting this to spice, +the output is two components with different names. Each component will have +exactly 5 ports, just like the symbol. +

    +But because on the physical device the power ports are shared between the two +slots, most schematics will connect only one positive and one negative supply +terminal, leaving the other two unconnected. When exporting to target_pcb, +this is masked by the fact the per slot power ports are merged. But with +target_spice there is no such merging as there would be two separate components, +each having the exact connections the corresponding symbol had. +

    +To solve this problem, target_spice offers a terminal attribute called +spice/shared. When this attribute exists, it is copied to the port in the abstract +model; then if the port has this attribute, all ports in all slots of the +same slotted device will share connections. That is, if a power terminal +is connected on only one slot of a symbol, and the power terminal is +spice/shared, the same numbered terminals on all other slots of the same +named symbol will share connections. +

    +Since the attribute name is prefixed with spice/, it's only for target_spice, +other workflows will ignore this terminal attribute. + +

    Unslotting

    +

    +Sometimes a dual opamp is drawn not as a slotted symbol using two single +opamp symnbols, but as a single monolithic symbol that has 8 terminals. For +the PCB workflow the slotted and the monolithic approaches will yeild the +same result, but monoliths need extra steps for the spice workflow, because +spice typically expects each slot to be a separate compontnent. There +are two ways handling this situation. +

    +The spice way is to create a device-specific, monolithic macromodel: a subckt +that has 8 ports and wires them to two instances of the original single-slot +opamp model. +

    +The sch-rnd way is converting to a hierarchic project, create a "device" +sheet that represents the monolithic symbol. In this sheet there should be 8 +sheet ports wired to two single-slot opamps. Attributes like spice/model +and spice/pinnums are present only on the "device" sheet, the monolithic symbol +on the parent sheet will emit an X spice instance calling the subckt that's +generated from the "device" sheet. +

    +Example project provided in +60_spice_unslot. + Index: tags/1.0.5/doc/user/07_io/export_spice/raw.html =================================================================== --- tags/1.0.5/doc/user/07_io/export_spice/raw.html (nonexistent) +++ tags/1.0.5/doc/user/07_io/export_spice/raw.html (revision 10414) @@ -0,0 +1,197 @@ + + + +

    target_spice: raw spice simulation

    +

    + +

    symbol attributes

    +

    + + + + + + + + + + + +
    attribute + descriptioon + +
    spice/params + string; append string at the end of the spice instance line for this symbol; for example + spice/params=dc 0 ac 1 on a 2 terminal voltage source will result + in: V1 netname1 netname2 dc 0 ac 1 + +
    spice/prefix + single character string; prefix the name of the spice instance (component in the abstract model) if it does not + already begin with this prefix; for example a mosfet called Q41 on the + schematics with spice/prefix=M will become M_Q41; for the same + symbol if spice/prefix=Q, the component name will be Q41. When present, + it is exported after the value attribute. +

    + If the model is known and is a subckt, an X prefix is used automatically. + If model is subckt and spice/prefix is also specified, attribute + priorities decide on the final prefix; the subckt X prefix has + the normal plugin priority of target_spice. The user can override + this decision with a spice/prefix of higher priority (e.g. 250). A + symbol would have a spice/prefix attribute at lowest user priority + (31050) so that target_spice can override it with an X if it detects + subckt model. + +

    spice/portmap + An array that is appended to the portmap attribute of the symbol by + the plugin target_spice. Should contain lines that set spice/pinnum + attributes on terminals. See also: pinout options. + +
    spice/model + name a spice model to use. If spice/model_include is not specified, + the model must have a mod (or prm) file in the spice library. This + mod file must be a stand-alone file with a single .model or .subckt + and will be copied in the output netlist. If the file uses .subckt, + a target_spice engine priority spice/prefix=X is added. If + spice/model_include is specified, the model is used without any + model copied to the output for this component (and no spice/prefix=X + set is attempted). The model is searched in the lib first with exact file + name, then with .mod then with .prm appended, all case sensitive. +

    + See also: model options. +

    spice/model_card + specify the whole model card, in-place; sch-rnd will generate a model + in the output using an unique name; when specified, spice/model is + ignored. First word should be either .model or .subckt, with a leading + dot. (Also called inline model card for a symbol.) +

    + See also: model options. + +

    spice/model_card_uname + optional: per-symbol-unique-name used when saving spice/model_card in the + file. Normally generated by target_spice. When this attribute is set, + the value is used for model name for both normal components and + for model/subcircuit compontnets. +

    + See also: model options. + +

    spice/model_include + specify the spice lib or mod file that should be included using .include; + sch-rnd does not edit the path, but makes sure there's only one .include + per unique attribute value +

    + See also: model options. + +

    spice/file_header + print this string on top of the output circuit file, as-is + +
    spice/command + print this string on bottom of the output circuit file, after the netlist; + useful for printing commands + +
    + +

    terminal attributes

    +

    + + + + + +
    attribute + descriptioon + +
    spice/pinnum + integer or [integer], counting from 1; determines the parameter index within the + generated spice instance line, affecting the order of terminal + connections listed for the instance. The list formed from all terminals + that have spice/pinnum must not be sparse. Plugint target_spice takes + all terminals and sort them by their pin numbers (preferring spice/pinnum + then falling back to pinnum then to port name) to generate the final + port name (display/name). The export code takes port names, requireing + integers, sort ports by their names and writes the connections + section of the instance line by the sorted list. As many connections + as many named ports present in the component. +

    + When [integer], the addressed pin is taken as a vector and the current + port is appended to the vector. On the output a [] vector of all the + appended port with this integer is exported. +

    + See also: pinout options. + +

    spice/shared + When set for a terminal in a symbol that has a slot or -slot attribute + set, the terminal is shared among all slots: any connection of the terminal + with the same spice/pinnum in any slot is copied to all other slots for + the same terminal. A typical example is the positive and negative supply + of a dual or quad opamp: spice will get 2 or 4 discrete opamps, but + the power supply will be specified only on one slot. The value of + this attribute does not matter. + See also: pinout options. + +
    spice/bridge/model + Insert a bridge between the pin and the network it is connecting to; + the bridge instance uses model name specified as the value of this + argument. The model is loaded from the spice library (see symbol's + spice/model). Useful for mixed digital/analog simulation when + ADC and DAC bridges have to be placed between the analog and the + digital sections. This can be done explicitly or when a port is + to be connected to an opposite type net, it can be hidden in + the port description using the spice/bridge/model attribute. +
    + + +

    net attributes

    +

    + + + +
    attribute + descriptioon + +
    spice/gnd + if set, the given network would be the true ground, "node 0" in the spice + netlist. Must not be set on multiple nets. If not set, target_spice + elects a "node 0" looking at net names. (The spice netlist format + requires one of the nets dedicated as "node 0" for gnd.) The value of + this attribute does not matter. +
    + +

    +The final spice instance lineis built by appending the following sections +in order, in a single line: +

      +
    • name of the component, perhaps prefixed with the value of attribute + spice/prefix; e.g. M_Q45 +
    • one netname for each port of the component; ports are first ordered + numerically by their display/name (or display/pinnum or name or pinnum) + attribute, then iterated from 1; ports must form a continous list from + 1 to the number of ports the component has; implicitly unconnected + ports are connected to dummy nodes (networks) that are left floating + (and an error is generated) +
    • optionally the value, if there is one specified in + the display/value (or value) attribute; + this is useful for passives (e.g. resistors) +
    • optionally the spice model name, if there is one specified in + the spice/model attribute; + this is useful for non-passives (e.g. transistors, diodes) +
    • optionally extra spice parameters, if specified in + the display/spice/params (or spice/params) attribute if it + exists and is not empty; + this is useful if the model has extra parameters that should be + printed after the model name; generally preferred instead of value + for non-passives. +
    +

    +For example the following is a spice diode instance line, split up and +annotated with source fields in the table below: +

    +D15 gnd sck 1n4148 T=35
    +
    +

    + +
    output D15 gnd sck   1n4148 T=35 +
    section name netnames (value) model name attribute: spice/params +
    +Model name is spice/model_card_uname when presents, or spice/model when not; +spice/model_card_uname is set automatically when model card is copied +from the lib or symbol into the output. Index: tags/1.0.5/doc/user/07_io/export_spice/src/bridge.rs =================================================================== --- tags/1.0.5/doc/user/07_io/export_spice/src/bridge.rs (nonexistent) +++ tags/1.0.5/doc/user/07_io/export_spice/src/bridge.rs (revision 10414) @@ -0,0 +1,328 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=Id/fKeXcFfUWvnGHBKcAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.9 { + uuid=Id/fKeXcFfUWvnGHBKcAAAAF; + x=40000; y=60000; + li:objects { + ha:group.1 { + uuid=Id/fKeXcFfUWvnGHBKcAAAAG; src_uuid=Id/fKeXcFfUWvnGHBKcAAAAD; + x=28000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=output + role=terminal + } + } + ha:group.2 { + uuid=Id/fKeXcFfUWvnGHBKcAAAAH; src_uuid=Id/fKeXcFfUWvnGHBKcAAAAE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=input + role=terminal + } + } + ha:line.3 { x1=4000; y1=8000; x2=4000; y2=-8000; stroke=sym-decor; } + ha:line.4 { x1=4000; y1=-8000; x2=24000; y2=-8000; stroke=sym-decor; } + ha:line.5 { x1=24000; y1=-8000; x2=24000; y2=8000; stroke=sym-decor; } + ha:line.6 { x1=24000; y1=8000; x2=4000; y2=8000; stroke=sym-decor; } + ha:text.7 { x1=8000; y1=0; dyntext=0; stroke=sym-decor; text=digital device; } + ha:text.9 { x1=4000; y1=-11000; dyntext=1; stroke=sym-secondary; text=%../A.name%; floater=1; } + } + ha:attrib { + name=U1 + role=symbol + } + } + ha:group.23 { + uuid=Id/fKeXcFfUWvnGHBKcAAAAO; + x=-28000; y=-84000; + li:objects { + ha:line.1 { x1=68000; y1=144000; x2=44000; y2=144000; stroke=wire; } + ha:text.2 { x1=44000; y1=144000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=orig_analog_1 + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.25 { + uuid=Id/fKeXcFfUWvnGHBKcAAAAP; + x=-28000; y=-84000; + li:objects { + ha:line.1 { x1=96000; y1=144000; x2=124000; y2=144000; stroke=wire; } + ha:text.2 { x1=112000; y1=144000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=orig_analog_2 + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.27 { + uuid=Id/fKeXcFfUWvnGHBKcAAAAQ; + x=4000; y=4000; + li:objects { + ha:group.1 { + uuid=Id/fKeXcFfUWvnGHBKcAAAAR; src_uuid=Id/fKeXcFfUWvnGHBKcAAAAI; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=Id/fKeXcFfUWvnGHBKcAAAAS; src_uuid=Id/fKeXcFfUWvnGHBKcAAAAJ; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=5000; y1=-1500; dyntext=0; stroke=sym-decor; text=ADC; } + ha:line.4 { x1=4000; y1=4000; x2=4000; y2=-4000; stroke=sym-decor; } + ha:line.5 { x1=4000; y1=-4000; x2=16000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=16000; y1=0; x2=4000; y2=4000; stroke=sym-decor; } + } + ha:attrib { + name=REFDES + role=symbol + } + } + ha:group.28 { + uuid=Id/fKeXcFfUWvnGHBKcAAAAT; + x=84000; y=4000; + li:objects { + ha:group.1 { + uuid=Id/fKeXcFfUWvnGHBKcAAAAU; src_uuid=Id/fKeXcFfUWvnGHBKcAAAAI; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=Id/fKeXcFfUWvnGHBKcAAAAV; src_uuid=Id/fKeXcFfUWvnGHBKcAAAAJ; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=5000; y1=-1500; dyntext=0; stroke=sym-decor; text=DAC; } + ha:line.4 { x1=4000; y1=4000; x2=4000; y2=-4000; stroke=sym-decor; } + ha:line.5 { x1=4000; y1=-4000; x2=16000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=16000; y1=0; x2=4000; y2=4000; stroke=sym-decor; } + } + ha:attrib { + name=REFDES + role=symbol + } + } + ha:line.29 { x1=52000; y1=48000; x2=52000; y2=32000; stroke=sheet-decor; } + ha:line.30 { x1=52000; y1=32000; x2=48000; y2=32000; stroke=sheet-decor; } + ha:line.31 { x1=48000; y1=32000; x2=54000; y2=20000; stroke=sheet-decor; } + ha:line.32 { x1=54000; y1=20000; x2=60000; y2=32000; stroke=sheet-decor; } + ha:line.33 { x1=60000; y1=32000; x2=56000; y2=32000; stroke=sheet-decor; } + ha:line.34 { x1=56000; y1=32000; x2=56000; y2=48000; stroke=sheet-decor; } + ha:line.35 { x1=56000; y1=48000; x2=52000; y2=48000; stroke=sheet-decor; } + ha:group.36 { + uuid=Id/fKeXcFfUWvnGHBKcAAAAb; src_uuid=Id/fKeXcFfUWvnGHBKcAAAAO; + x=-64000; y=-140000; + li:objects { + ha:line.1 { x1=68000; y1=144000; x2=56000; y2=144000; stroke=wire; } + ha:text.2 { x1=56000; y1=144000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=orig_analog_1 + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.37 { + uuid=Id/fKeXcFfUWvnGHBKcAAAAc; src_uuid=Id/fKeXcFfUWvnGHBKcAAAAP; + x=7000; y=-140000; + li:objects { + ha:line.1 { x1=97000; y1=144000; x2=112000; y2=144000; stroke=wire; } + ha:text.2 { x1=100000; y1=144000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=orig_analog_2 + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.38 { + uuid=Id/fKeXcFfUWvnGHBKcAAAAd; src_uuid=Id/fKeXcFfUWvnGHBKcAAAAF; + x=40000; y=4000; + li:objects { + ha:group.1 { + uuid=Id/fKeXcFfUWvnGHBKcAAAAe; src_uuid=Id/fKeXcFfUWvnGHBKcAAAAD; + x=28000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=output + role=terminal + } + } + ha:group.2 { + uuid=Id/fKeXcFfUWvnGHBKcAAAAf; src_uuid=Id/fKeXcFfUWvnGHBKcAAAAE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=input + role=terminal + } + } + ha:line.3 { x1=4000; y1=8000; x2=4000; y2=-8000; stroke=sym-decor; } + ha:line.4 { x1=4000; y1=-8000; x2=24000; y2=-8000; stroke=sym-decor; } + ha:line.5 { x1=24000; y1=-8000; x2=24000; y2=8000; stroke=sym-decor; } + ha:line.6 { x1=24000; y1=8000; x2=4000; y2=8000; stroke=sym-decor; } + ha:text.7 { x1=8000; y1=0; dyntext=0; stroke=sym-decor; text=digital device; } + ha:text.9 { x1=4000; y1=8000; dyntext=1; stroke=sym-secondary; text=%../A.name%; floater=1; } + } + ha:attrib { + name=U1 + role=symbol + } + } + ha:group.42 { + uuid=Id/fKeXcFfUWvnGHBKcAAAAg; + x=-28000; y=-84000; + li:objects { + ha:line.1 { x1=52000; y1=88000; x2=68000; y2=88000; stroke=wire; } + ha:text.2 { x1=56000; y1=88000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=dummy1 + ha:role = { value=wire-net; prio=0; } + } + } + ha:group.46 { + uuid=Id/fKeXcFfUWvnGHBKcAAAAk; src_uuid=Id/fKeXcFfUWvnGHBKcAAAAg; + x=16000; y=-84000; + li:objects { + ha:line.1 { x1=52000; y1=88000; x2=68000; y2=88000; stroke=wire; } + ha:text.2 { x1=59000; y1=88000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=dummy2 + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.59 { + li:conn { + /2/23/1 + /2/9/2/1 + } + } + ha:connection.60 { + li:conn { + /2/25/1 + /2/9/1/1 + } + } + ha:connection.61 { + li:conn { + /2/36/1 + /2/27/2/1 + } + } + ha:connection.62 { + li:conn { + /2/37/1 + /2/28/1/1 + } + } + ha:connection.63 { + li:conn { + /2/42/1 + /2/27/1/1 + } + } + ha:connection.64 { + li:conn { + /2/42/1 + /2/38/2/1 + } + } + ha:connection.65 { + li:conn { + /2/46/1 + /2/28/2/1 + } + } + ha:connection.66 { + li:conn { + /2/46/1 + /2/38/1/1 + } + } + } + ha:attrib { + maintainer= + page= + print_page=A/4 + title= + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 0 + grid = 1.0240 mm + } + } + } +} Index: tags/1.0.5/doc/user/07_io/export_tedax/index.html =================================================================== --- tags/1.0.5/doc/user/07_io/export_tedax/index.html (nonexistent) +++ tags/1.0.5/doc/user/07_io/export_tedax/index.html (revision 10414) @@ -0,0 +1,49 @@ + + + +

    export_tedax

    +

    +Type: netlist. + +

    netlist export

    +

    +Exports a tEDAx +netlsit, typically used with a PCB workflow. +

    +PCB side pin number is deduced from display/pinnum (or pinnum for fallback). +It either contains a single "pin number" or multiple "pin numbers" separated +by whitespaces. A "pin number" is any printable ASCII character, but no +whitespace or dash. + + +

    Attribute usage

    +

    +For components the following attributes are used to construct file-format +specified fields: +

      +
    • component's display/footprint (fallback: footprint attribute) +
    • component's display/value (fallback: value attribute) +
    • component's display/device (fallback: device attribute) +
    • ports's display/pinname (fallback: port's name) +
    +

    +Attributes that have an export name are exported for: +

      +
    • components +
    • networks +
    + +

    Omit and DNP

    +

    +The plugin will not export components and networks that have the +display/omit attribute set. +

    +The plugin will export objects that have the display/dnp attribute +set. To get the DNP information passed on, use the +export naming mechanism +of a target plugin in the view. + + + + + Index: tags/1.0.5/doc/user/07_io/io_ngrp/index.html =================================================================== --- tags/1.0.5/doc/user/07_io/io_ngrp/index.html (nonexistent) +++ tags/1.0.5/doc/user/07_io/io_ngrp/index.html (revision 10414) @@ -0,0 +1,167 @@ + + + + +

    Non-graphical sheets

    +

    +Sometimes a design is easier specified by text than drawing. Typical examples: +

      +
    • "wiring diagram": there are two large-pin-number components, e.g. two + connectors and a bunch of connections between them (not necessary + 1-to-1 wiring) +
    • "breakout boards": large pin number central component + and mostly 1-to-1 wiring to other, smaller pin number components + (e.g. connectors). +
    • "fpga", "ram": multiple large pin number components, with a lot + of 1-to-1 connections (that would often have the same name as the + terminal on both ends, by the way); for example when connecting + ram to a CPU: D0..D16, A0..A20, etc. +
    +

    +Non-graphical sheets are implemented in plugins and provide different +methods and syntax for specifying abstract components, abstract networks +and their relations. The cschem compiler can use this as an input on the same +level as a graphical sheet. That means, a non-graphical sheet can be an Nth sheet in +a multisheet project. For example draw the power and analog parts on graphical +sheets and have the 28 pin parallel bus connections to the CPU, ram, I/O chips +and connectors specified in one more more non-graphical sheet in the same +project. +

    +Below are different methods and syntax to describe non-graphical sheets. + +

    tEDAx (declarative)

    +

    +tEDAx is very easy to parse, well specified, and is relatively easy to +read and write as human. Implemented by io_ngrp_tedax. +

    +Here are a few small examples, all describing the same "7805 with 2 bypass +caps" circuit using different approaches: +

    +

    +These are not different sets of syntax, but they are all just different usage +and combination of the same few blocks that are all available. As a proper +declarative description, order of blocks or order of attributes/connections +within a block doesn't matter. +

    +The verbose versions are perhaps more practical if there are a lot of attributes +to specify. The compact version is more practical for listing a lot of +connections and few attributes. +

    +Another way of mixing different blocks is big32.tdx, +which is an imaginary CPU board with 2 SRAM chips, an I/O chip and an extension +port. It uses the verbose component description for the chips and capacitors, +also connects power and gnd there and then uses the compact, table-like +description for the address/data/control networks. It's also an example +of combining graphical and non-graphical sheets: U5 is a network of gates +that controls chip-select; it's better drawn for clarity. +

    +Summary of blocks: + +
    block description + cschem_acomp name create a new (abstract) component; name is the name of the component (e.g. "R17"); can add component attributes and create connections from ports of the component to nets + cschem_anet name create a new (abstract) network; name is the name of the net (e.g. "Vcc"); can add net attributes and create connections from the net to ports of components + cschem_acompact compact syntax that can describe both components and nets, multiple of them +
    +

    + +

    +Content of a cschem_acomp block: each line is one of these: +

      +
    • if first field is a dash, the second field is a port number of the current + component and the third field is the name of a net; e.g. "- 4 Vcc" will + connect port 4 to the Vcc net +
    • else the first field is an attribute key and the rest of the fields is an + attribute value; e.g. "footprint 1206" adds a footprint=1206 attribute + to the current component; or "comment hand solder" adds a + comment=hand solder +
    +

    +Content of a cschem_anet block: each line is one of these: +

      +
    • if first field is a dash, the second field is a component name and + the third field is a port name; e.g. "- U12 4" will + connect the current net to port 4 of component U12 +
    • else the first field is an attribute key and the rest of the fields is an + attribute value; e.g. "current 250mA" adds a current=250mA attribute + to the current net; or "comment do not cover with mask" adds a + comment=do not cover with mask +
    +

    +Content of a cschem_acompact block: each line is one of these: +

    + +
    line description + comp cname [attrs...] create a new (abstract) component; cname is the name of the component (e.g. "R17"); followed by zero or more attributes (see below) + net nname [attrs...] create a new (abstract) network; nname is the name of the net (e.g. "Vcc"); followed by zero or more attributes (see below) + conn nname ports... creates one or more connections from the network called nname to ports (see below) +
    +

    +Attrs are specified in key=value syntax, e.g. footprint=1206. +If key or value contains whitespace, it needs to be escaped, +as per tEDAx syntax, using backslash. +

    +Ports are specified in a comp=port syntax, e.g. U12=4 for port 4 of component U12. +If component or port name contains whitespace, it needs to be escaped, +as per tEDAx syntax, using backslash. + + +

    fawk (Turing-complete)

    +

    +In some cases parts of the design can be specified using repetitive patterns. +An easy way to handle this is to write a script that generates a graphical +sheet or a non-graphical sheet using a declarative syntax. +

    +If that script is written in fawk, sch-rnd can run it without having to +generate and parse the declarative intermediate. Implemented by io_ngrp_fawk. +This feature is limited to fawk because: +

      +
    • fawk is always available in librnd +
    • fawk supports execution limit and memory allocation limit so opening + a non-graphical sheet specified as a fawk script is safe, an attacker + won't be able to force sch-rnd into an infinite loop or into allocating + all system memory. +
    +

    +A simple example script, r2r.fawk generates +5 bits of the classic R2R DAC. It can be configured by changing the values +in main(). +

    +The script doesn't emit a netlist or declarative tEDAx non-graphical sheet. +The result can be observed in sch-rnd by loading only the fawk script +as a sheet and using the abstract model dialog. +

    +(An alternative is implementing the cschem functions locally, as vararg +fawk functions and make them print to stdout using fawk_print(). Then the +script can be ran and debugged independently of cschem, using the example +libfawk command line interpreter.) +

    +Functions provided by sch-rnd: + +
    function description +
    acomp_attr(name, key, val, ...); + create a component by name, or add to existing component by that name; + add key=val pairs of attributes; this is a vararg function, + accepting zero or more key,val pairs. + +
    anet_attr(name, key, val, ...); + create a network by name, or add to existing network by that name; + add key=val pairs of attributes; this is a vararg function, + accepting zero or more key,val pairs. + +
    aconn(netname, compname, termname, ...); + create a network by netname, or extend existing network by that name; + connect terminal(s) addressed by (compname-termname); this is a + vararg function, accepting one or more compname,termname pairs. + +
    + + + + + + Index: tags/1.0.5/doc/user/07_io/io_tinycad/index.html =================================================================== --- tags/1.0.5/doc/user/07_io/io_tinycad/index.html (nonexistent) +++ tags/1.0.5/doc/user/07_io/io_tinycad/index.html (revision 10414) @@ -0,0 +1,18 @@ + + + +

    io_tinycad

    +

    + +

    Limitations and knonw bugs

    +

    +

      +
    • no support for arcs in polygon (susbtituted with straight lines) +
    • the implicit titleblock is not imported +
    • slot is kept in tinycad's slot concept, not converted to sch-rnd's slotting; netlist export should be fine, but changing slot on an existing symbol is not easily possible +
    • ellipse objects are line-approximated +
    • [TYC#1] multiline text in note is not supported yet - requires multiline text support in libcschem (planned) +
    • [TYC#3] no support for hatched polygons (they are loaded as filled) +
    • [TYC#4] no support for hatched rectangles (they are loaded as filled) +
    • [TYC#6] is ignored; this is the sheet's visual name printed in the GUI tab in tinycad (sch-rnd always uses the file name) +
    Index: tags/1.0.5/doc/user/07_io/target_pcb/index.html =================================================================== --- tags/1.0.5/doc/user/07_io/target_pcb/index.html (nonexistent) +++ tags/1.0.5/doc/user/07_io/target_pcb/index.html (revision 10414) @@ -0,0 +1,60 @@ + + + + +

    target_pcb - PCB workflow target

    + + +

    Attribute translation

    + +

    Network attribute translation

    +

    +The final display/omit network attribute is derived from the first +available of the following input: +

      +
    • network attribute pcb/omit +
    • network attribute omit +
    • or else display/omit is not set +
    + + +

    Component attribute translation

    +

    +The final display/dnp component attribute is derived from the first +available of the following input: +

      +
    • component attribute pcb/dnp +
    • component attribute dnp +
    • or else display/dnp is not set +
    +

    +The final display/omit component attribute is derived from the first +available of the following input: +

      +
    • component attribute pcb/omit +
    • component attribute omit +
    • or else display/omit is not set +
    + +

    Port attribute translation

    +

    +The final display/name port attribute is derived from the first +available of the following input: +

      +
    • port attribute pcb/pinnum +
    • port attribute pinnum +
    • name of the port object (coming from the name of the concrete term objects) +
    + + +

    Attribute export names

    +

    +The plugin supports the standard attribute export naming mechanism +with the following defaults: +

      +
    • workflow prefix is "pcb" (any pcb:key attribute is exported as key) +
    • display/dnp is named "dnp" for the export +
    • tolerance is named "tolerance" for export (useful for components) +
    • device, footprint and value attributes are not explicitly handled as most export formats will have special casing for those +
    + Index: tags/1.0.5/doc/user/07_io/target_spice/index.html =================================================================== --- tags/1.0.5/doc/user/07_io/target_spice/index.html (nonexistent) +++ tags/1.0.5/doc/user/07_io/target_spice/index.html (revision 10414) @@ -0,0 +1,51 @@ + + + + +

    target_spice - spice sim workflow target

    + + +

    Attribute translation

    + +This section is not a complete description of all translations; for +the full list, see the export spice +document. + + +

    Network attribute translation

    +

    +The final display/omit network attribute is derived from the first +available of the following input: +

      +
    • network attribute spice/omit +
    • network attribute omit +
    • or else display/omit is not set +
    + + +

    Component attribute translation

    +

    +The final display/omit component attribute is derived from the first +available of the following input: +

      +
    • component attribute spice/omit +
    • component attribute omit +
    • or else display/omit is not set +
    + +

    Port attribute translation

    +

    +The final display/name port attribute is derived from the first +available of the following input: +

      +
    • port attribute spice/pinnum +
    • port attribute pinnum +
    • name of the port object (coming from the name of the concrete term objects) +
    + + +

    Attribute export names

    +

    +The plugin supports the standard attribute export naming mechanism +is not applied because the typical spice format does not support +arbitrary named attributes. Index: tags/1.0.5/doc/user/09_appendix/action_details.html =================================================================== --- tags/1.0.5/doc/user/09_appendix/action_details.html (nonexistent) +++ tags/1.0.5/doc/user/09_appendix/action_details.html (revision 10414) @@ -0,0 +1,1086 @@ + + + + + sch-rnd user manual - action details + + + + +

    sch-rnd actions (details)

    + + + +

    FuncmapChange

    +
    +

    + +
    Syntax summary: +FuncmapChange(previous|next|remove, component, port) +FuncmapChange(set, component, port, [newfunc]) +FuncmapChange(setgrp, component, grpname) +
    Help text: +Change the alternate function of a component-port. The setgrp command activates a group by setting all affected ports to that group's funcionality. All arguments are case-sensitive. +
    Registered by: +funcmap +
    +

    +Changes the + +funcmap/name + + attribute on one or more ports of a given component. The component (and port, when needed), needs to be named and is looked up in the abstract model (the project needs to be compiled). The actual change is always made in concrete terminal object(s) looked up from the abstract port objects. If multiple terminals are contributing to the port (source terminals), the change is done to the terminals that already have the + +funcmap/name + + attribute. If none of the source terminals have that attribute, the attribute is created in one of the source terminals randomly chosen. +

    + The first argument is the command to perform. +

    + If the command is + +previous + + or + +next + +, the selected function of the given port is moved one step back or forward on the function list for the port. The function list has the order of functions as they appear in the li:funcmap/ports section of the funcmap file (this differs from the column ordering in the tabular form, which is deduced from function grouping). +

    + If the command is + +set + + and the new function is specified as the 4th argument, the source terminal attribute is changed to that function. The added value of this command compared to the propset() action is that it looks up the terminal object to change and verifies whether the new function is available for the given port. +

    + The + +setgrp + + command modifies multiple terminals so that a whole function group is activated (by function group name). +

    + +

    FuncmapPrintTable

    +
    +

    + +
    Syntax summary: +FuncmapPrintTable(component, [column]) +
    Help text: +Print a table of all alternative port functions for a component If column is specified, sort the table by the named column. +
    Registered by: +funcmap +
    +

    +Prints the function mapping of a component in the standard tabular form to the stdout. Each row is a port, each column is a function group. Cells are function names. The function that's active for a port is wrapped in [[]]. +

    + If the optional second parameter is specified and is a valid column name, the table is sorted by that column. +

    + +

    Quit

    +
    +

    + +
    Syntax summary: +Quit() +
    Help text: +Quits sch-rnd after confirming. +
    Registered by:n/a +
    +

    +If you have unsaved changes, you will be prompted to confirm (or save) before quitting. +

    + +

    RtreeList

    +
    +

    + +
    Syntax summary: +RtreeList[rtree_name, [x1, y1, x2, y2]) +
    Help text: +Return a list of idpaths for objects overlapping with the box specified (empty list if no object is found). Error is indicated by returning nil. If coordinates are not specified the whole tree is searched. +
    Registered by: +act_read +
    +

    +Search all objects of the selected layer's named rtree on the current sheet and return a list of idpaths. +

    + The first argument is a layer name with an optional suffix. A layer name is the same as layer names printed by the GUI, e.g. "wire" or "hub & terminal". Suffix may be "-stroke" or "-fill"; when no suffix is appended, "-stroke" is assumed. All normal objects are in the stroke rtree; polygons with fill enabled are also in the fill rtree. +

    + If coordinates of a box is give, smaller coords first, the search is performed only within that box and any object that has overlapping bounding box (on the given layer) is returned. Otherwise the search is performed on the whole rtree, returning all objects on the layer. +

    + +

    Zoom

    +
    +

    + +
    Syntax summary: +Zoom() +Zoom([+|-|=]factor) +Zoom(x1, y1, x2, y2) +Zoom(?) +Zoom(get) +Zoom(selected) +
    Help text: +GUI zoom +
    Registered by: +sch_rnd_gui +
    +

    +Changes the zoom (magnification) of the view of the sheet. If no arguments are passed, the view is scaled such that the sheet just fits inside the visible window (i.e. "view all"). Otherwise, +factor + specifies a change in zoom factor. It may be prefixed by + ++ + +, + +- + +, + += + + to change how the zoom factor is modified (relative or absolute). The +factor + is a floating point number, such as + +1.5 + + or + +0.75 + +. +

    + Alternatively a box can be specified with 4 coordinates and +zoom + will set the zoom level (and modifies pan) so that the given box of the design is visible and as large as possible in the current window. +

    + Arguments: +

    + + + + + + + + + + + + + + + + + + + +
    + (no argument) + + Without argments: zoom to sheet extents. +
    + +factor + + Values greater than 1.0 cause the sheet to be drawn smaller; more of the sheet will be visible. Values between 0.0 and 1.0 cause the sheet to be drawn bigger; less of the sheet will be visible. +
    + -factor + + Values greater than 1.0 cause the sheet to be drawn bigger; less of the sheet will be visible. Values between 0.0 and 1.0 cause the sheet to be drawn smaller; more of the sheet will be visible. +
    + =factor + + The @var{factor} is an absolute zoom factor; the unit for this value is "PCB units per screen pixel". Since PCB units are nanometer, a +factor + of 1000 means 1 micrometer per pixel (TODO: test this). +
    + x1, y1, x2, y2 + + Zoom to the specified portion of the design, described as a rectangle (using sheet space coordinates) +
    + selected + + Zoom and pan so that all + +selected + + objects are on the screen. +
    + ? + + Print the current zoom level in the message log (as an info line). +
    + get + + Return the zoom level as an FGW_DOUBLE (useful for scripts). +
    + +

    + Note that zoom factors of zero are silently ignored. +

    +

    librnd actions (common to Ringdove)

    + + + +

    AddTimer

    +
    +

    + +
    Syntax summary: +AddTimer(action, period, [repeat], [userdata]) +
    Help text: +Add a new timer +
    Registered by: +script plugin +
    +

    +This action is intended for scripts to create async timers. + +Note: + + timers do not work with the batch HID (no callback issued ever). +

    + Creates a timer that executes an +action + (by name) periodically. +Period + is a real number specified in seconds. Internal timer resolution is in the order of 0.1 second. +

    + If +repeat + is not specified or is less than 1, the timer is repeated indefinitely. If the optional +userdata + string is specified, it is also passed to the action. +

    + The +action + is specified only by a name, call arguments are always the following: +

      + +
    • + now: the current UNIX time in a floating point number +
    • + integer: count back remaining number of calls, including the current call; 1 means this was the last call; 0 means infinite number of calls will follow +
    • + +userdata + or empty string +
    + +

    + +Action + shall return integer 0 on success. If the action does not exist or returns anything else, the timer is uninstalled. +

    + There can be any number of timers in parallel. +

    + +

    AnyLoad

    +
    +

    + +
    Syntax summary: +AnyLoad([path]) +
    Help text: +Load "anything" from path (or offer a file selectio dialog if no path specified) +
    Registered by:n/a +
    +

    +Loads an anyload.lht file or any lihata document that can be handled by the anyload system (mostly settings and setting-like states, e.g. config, vendor drill map, DRC and user scripts). +

    + When called without arguments a file selection dialog is popped up for selecting the file to load. +

    + More info on this mechanism in the + + knowledge pool node of anyload. + + +

    + +

    Benchmark

    +
    +

    + +
    Syntax summary: +Benchmark() +
    Help text: +Benchmark the GUI speed. +
    Registered by:n/a +
    +

    +This action is used to speed-test the GUI rendering. It redraws the current screen as many times as possible in ten seconds. It reports the amount of time needed to draw the screen once, in average. +

    + +

    Center

    +
    +

    + +
    Syntax summary: +Center() +
    Help text: +Moves the pointer to the center of the window. +
    Registered by: +lib_hid_common plugin +
    +

    +Move the pointer to the center of the window, but only if it's currently within the window already. +

    + +

    Cursor

    +
    +

    + +
    Syntax summary: +Cursor(Type,DeltaUp,DeltaRight,Units) +
    Help text: +Move the cursor. +
    Registered by:n/a +
    +

    +This action moves the mouse cursor. Unlike other actions which take coordinates, this action's coordinates are always relative to the user's view of the board. Thus, a positive +DeltaUp + may move the cursor away from the board origin if the board is inverted (flipped, looked from the bottom). +

    + +Type + is one of + +Pan + + or + +Warp + +. + +Pan + + causes the viewport to move such that the crosshair is under the mouse cursor. + +Warp + + causes the mouse cursor to move to be above the crosshair. +

    + +Units + can be one of the following: +

    + + + + + + + + + + + + + +
    +mil +
    +mm +
    +The cursor is moved by that amount, in board units. +
    +grid + +The cursor is moved by that many grid points. +
    +view + +The values are percentages of the viewport's view. Thus, a pan of + +100 + + would scroll the viewport by exactly the width of the current view. +
    +design + + The values are percentages of the board size. Thus, a move of + +50,50 + + moves you halfway across the board. +
    +board + + Same as design (for backward compatibility) +
    + +

    + +

    dowindows

    +
    +

    + +
    Syntax summary:n/a +
    Help text:n/a +
    Registered by:n/a +
    +

    +Argument: +

    + + + + + + + + + + + + + + + + + +
    + 1 +
    + Layout +
    + Open the layout window. Since the layout window is always shown anyway, this has no effect. +
    + 2 +
    + Library +
    + Open the library window. +
    + 3 +
    + Log +
    + Open the log window. +
    + 4 +
    + Netlist +
    + Open the netlist window. +
    + 5 +
    + Preferences +
    + Open the preferences window. +
    + 6 +
    + DRC +
    + Open the DRC violations window. +
    + 7 +
    + Search +
    + Open the advanced search window. +
    + +

    + +

    GetXY

    +
    +

    + +
    Syntax summary: +GetXY([message, [x|y]]) +
    Help text: +Get a coordinate. If x or y specified, the return value of the action is the x or y coordinate. +
    Registered by:n/a +
    +

    +Prompts the user for a coordinate, if one is not already selected. +

    + +

    ListScripts

    +
    +

    + +
    Syntax summary: +ListScripts([pat]) +
    Help text: +List fungw scripts, optionally filtered wiht regex pat. +
    Registered by: +script plugin +
    +

    +Print one line in the log for each currently loaded script. If +pat + is specified, filter the list using +pat + as a case sensitive + +extended regex + + on script ID, file name and language (list only scripts that match with any of these fields). +

    + +

    LiveScript

    +
    +

    + +
    Syntax summary: +LiveScript([new], [name]) +LiveScript(load|save, name, [filame]) +LiveScript(run|stop|rerun|undo, name) +
    Help text: +Manage a live script +
    Registered by: +script plugin +
    +

    +The first argument determines what operation the action performs and how subsequent arguments are interpreted: +

    + + + + + + + + + + + + + + + + + +
    + new, [name] + + Create a new live script and open a new live script dialog. + +name + + is an unique live script name that identifies the window. If not specified, "default" is used" +
    + load, name, [filename] + + Replace the script source in the LiveScript window identified by + +name + + with the content loaded from a file. If + +filename + + is not specified, open a file selector dialog. +
    + save, name, [filename] + + Save the script source in the LiveScript window identified by + +name + + to a file. If + +filename + + is not specified, open a file selector dialog. +
    + run, name + + Run the script in the LiveScript window identified by + +name + +. +
    + stop, name + + Stop the script in the LiveScript window identified by + +name + +, if ti is running in persistent mode. +
    + undo, name + + Undo the "init changes" of the script in the LiveScript window identified by + +name + +. Init changes are those board changes the script has done while running its initialization section. Live script undo is possible only if there was no user edit after the script finished. +
    + rerun, name + + Stop, undo and run the script in the LiveScript window identified by + +name + +. +
    + +

    + +

    LoadScript

    +
    +

    + +
    Syntax summary: +LoadScript(id, filename, [language]) +
    Help text: +Load a fungw script +
    Registered by: +script plugin +
    +

    + +id + is an arbitrary string assigned by the user. +id + must be unique per application session per script and may contain alphanumeric characters and undescrore. +

    + +fn + is the file name of the script, which is a path. Librnd does not do any search, it only opens the path as specified. +

    + +lang + is the scripting language, as in + +fungw plugin name + +. When not specified, the code makes a guess (based on the file name). +

    + +

    Message

    +
    +

    + +
    Syntax summary: +message([ERROR|WARNING|INFO|DEBUG,] message) +
    Help text: +Writes a message to the log window. +
    Registered by:n/a +
    +

    +This action displays a message to the log window. This action is primarily provided for use by scripts and external programs which may interface with the application. If multiple arguments are given, each one is sent to the log window followed by a newline. +

    + If there are 2 or more arguments and the first argument matches, in a case sensitive manner, one of the below keywords, the message is registered on the specified error level. Else the PCB_MSG_INFO error level is used. +

    + + + + + + + + + + + + + +
    +first argument + +erro level +
    +ERROR + + PCB_MSG_ERROR +
    +WARNING + + PCB_MSG_WARNING +
    +INFO + + PCB_MSG_INFO +
    +DEBUG + + PCB_MSG_DEBUG +
    + +

    + +

    onliner

    +
    +

    + +
    Syntax summary:n/a +
    Help text:n/a +
    Registered by:n/a +
    +

    +The +oneliner + action is designed for quick execution of short, trivial scripts, such as a for loop for repeating an action. It supports any scripting language currently availabel through fungw. Each oneliner is an independent script context - variables, functions and other global states do not persist. +

    + This group of actions offers three forms: +

      + +
    • + +oneliner +( +lang +, +script +) - execute the script in the language specified +
    • + lang(script) - shorthand for the above +
    • + lang - switch the command line interpreter to execute one-liners in the given language, until /exit +
    + +

    + For example, a simple calculation using awk can be done in three ways: +

      + +
    • + + +oneliner(awk, 'print 42*3') + + +
    • + + +awk('print 42*3') + + +
    • + + +awk + +, then + +print 42*3 + +, then + +/exit + + +
    + +
    + +

    Pan

    +
    +

    + +
    Syntax summary: +Pan(Mode) +
    Help text: +Start or stop panning (Mode = 1 to start, 0 to stop) +
    Registered by: +lib_hid_common plugin +
    +

    +Start or stop panning. To start call with Mode = 1, to stop call with Mode = 0. +

    + +

    Print

    +
    +

    + +
    Syntax summary: +Print() +
    Help text: +Present the print export dialog for printing the layout from the GUI. +
    Registered by:n/a +
    +

    +Open an export dialog listing all printing plugins, prompt the user for their options, and print the layout. +

    + Available only with GUI HIDs: it's merely a graphical shorthand that in turn calls the export plugin for printing. +

    + +

    PromptFor

    +
    +

    + +
    Syntax summary: +PromptFor([message[,default[,title]]]) +
    Help text: +Prompt for a string. Returns the string (or NULL on cancel) +
    Registered by:n/a +
    +

    +UI-independent way of asking the user for a string. When GUI is available, it is a dialog box, else it's console input. Return value, unlike with other actions, is a string. The return value is NULL on cancel. +

    + +

    ReloadScript

    +
    +

    + +
    Syntax summary: +ReloadScript(id) +
    Help text: +Reload a fungw script +
    Registered by: +script plugin +
    +

    + +id + is the same that was specified for +loadscript +. If loading the new verison of the script fails, +id + is released (can be reused for a new LoadScript). +

    + +

    ScriptCookie

    +
    +

    + +
    Syntax summary: +ScriptCookie() +
    Help text: +Return a cookie specific to the current script instance during script initialization +
    Registered by: +script plugin +
    +

    +The script: +

      + +
    • + may call ScriptCookie() + +during script initialization + + and save the resulting cookie string +
    • + may use the cookie string to register to core application or librnd infrastructure that requires cookie, such as +createmenu + +
    • + can depend on the application to call any unregistering associated with this specific cookie atomatically after script unload ( +preunload +). +
    + +

    + The function can not be called outside of script initialization. The cookie string can be used any time between script load and script unload. +

    + +

    ScriptPersistency

    +
    +

    + +
    Syntax summary: +ScriptPersistency(read|remove) +
    Help text: +Read or remove script persistency data savd on preunload +
    Registered by: +script plugin +
    +

    +When a script is unloaded, its action +preunload + is called. The return value is saved as script persistent data. When the script is loaded again later, it can use +scriptpersistency +( +read +) to read the data saved. +

    + +scriptpersistency +( +remove +) deletes the data from disk. +

    + Note: the data is per script id, not per script file name. +

    + +

    Scroll

    +
    +

    + +
    Syntax summary: +Scroll(up|down|left|right, [pixels]) +
    Help text: +Scroll the viewport. +
    Registered by: +lib_hid_common plugin +
    +

    +Arguments: +

    + + + + + + + +
    + up|down|left|right + + Specifies the direction to scroll +
    + pix + + Optional. Specifies how many pixels to scroll by. If not specified: default pix is 100. +
    + +

    + +

    SetGridOffs

    +
    +

    + +
    Syntax summary: +SetGridOffs(x_offs, y_offs) +
    Help text: +Change grid offset (alignment) to x_offs and y_offs. Offsets should be specified with units. +
    Registered by:n/a +
    +

    +Changes the grid offset to relative or absolute x_offs and y_offs. For non-zero values always use units, e.g. SetGrifOffs(0.5mm, 0.1mm). +

    + The final grid offset alues will be scaled down so they are always between 0 and the current grid size. For example with a 25 mil grid, a value of 7mil will be taken as 7mil offset, but a value of 27 mil will be taken as a 2mil offset. +

    + If an offset starts with + or -, it is taken as relative, which means it is added to the current offset value. +

    + +

    SetUnits

    +
    +

    + +
    Syntax summary: +SetUnits(mm|mil) +
    Help text: +Set the default measurement units. +
    Registered by:n/a +
    +

    + + + + + + + +
    + mil + + Sets the display units to mils (1/1000 inch). +
    + mm + + Sets the display units to millimeters. +
    + +

    + +

    Tool

    +
    +

    + +
    Syntax summary: +Tool(Arc|Arrow|Copy|InsertPoint|Line|Lock|Move|None|PasteBuffer) +Tool(Poly|Rectangle|Remove|Rotate|Text|Thermal|Via) +Tool(Press|Release|Cancel|Stroke) +Tool(Save|Restore) +
    Help text: +Change or use the tool mode. +
    Registered by:n/a +
    +

    +Selects the tool or changes tool related global states. +

    + + + + + + + + + + + + + + + + + + + +
    + <app-specific-tool-name> + + Select the indicated tool. Tool names depend on the application and plugins loaded. For example in pcb-rnd one of the valid tool names is + +Line + +. +
    + Press + + Called when you press the mouse button, or move the mouse. +
    + Release + + Called when you release the mouse button. +
    + Cancel + + Cancels any pending tool activity, allowing you to restart elsewhere. For example, this allows you to start a new line rather than attach a line to the previous line. +
    + Escape + + Similar to Cancel but calling this action a second time will return to the Arrow tool. +
    + Stroke + + If librnd was built with libstroke, this invokes the stroke input method. If not, this will restart a drawing mode if you were drawing, else it will select objects. +
    + Save + + Remembers the current tool. +
    + Restore + + Restores the tool to the last saved tool. +
    + +

    + +

    UnloadScript

    +
    +

    + +
    Syntax summary: +UnloadScript(id) +
    Help text: +Unload a fungw script +
    Registered by: +script plugin +
    +

    + +id + is the same that was specified for +loadscript +. After the call +id + is released (can be reused for a new LoadScript). +

    + + + + Index: tags/1.0.5/doc/user/09_appendix/action_reference.html =================================================================== --- tags/1.0.5/doc/user/09_appendix/action_reference.html (nonexistent) +++ tags/1.0.5/doc/user/09_appendix/action_reference.html (revision 10414) @@ -0,0 +1,289 @@ + + + + sch-rnd user manual + + + + +

    +

    sch-rnd User Manual: Appendix

    +

    +

    Action Reference

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +, + +
    Action Description Syntax Plugin +
    AboutPresent the about boxAbout()sch_dialogs
    AbstractDialogBring up the current project's abstract model dialog. If abstract object id, abst_id is specified, left-side cursor is set at that object initially. If attr_name is specified, right-side cursor is set on that attribute.AbstractDialog([abst_id [,attr_name]])sch_dialogs
    ActionStringExecute a pcb-rnd action parsing a string; syntac: "action(arg,arg,arg)"ActionString(action)script plugin
    AddTimer (RND)Add a new timerAddTimer(action, period, [repeat], [userdata])script plugin
    AnyLoad (RND)Load "anything" from path (or offer a file selectio dialog if no path specified)AnyLoad([path])
    AttributeDialogBring up the Attribute Editor Dialog for an object.AttributeDialog([last-click|parent|sheet|object[:idpath]], [target_key])sch_dialogs
    AttributePickBring up the Attribute Pick Dialog and ask the user to pick an attribute of an object.AttributePick([last-click|parent|object[:idpath]], [target_key])sch_dialogs
    awkExecute a script one-liner using a specific languageOneliner(lang, script)script plugin
    BackannLoad a back annotation file for interactive back annotationBackann([filename])backann plugin
    basExecute a script one-liner using a specific languageOneliner(lang, script)script plugin
    Benchmark (RND)Benchmark the GUI speed.Benchmark()
    BreakupBreakup group(s) found in context named in first arg, place resulting objects in the context named in second arg if present or on sheet if not presentBreakup(selected|buffer|object, group|poly[gon]|all, [sheet|grp-oid])construct plugin
    BrowseScriptsPresent a dialog box for browsing scriptsBrowseScripts()script plugin
    BufferChkChk content of buffer; if first arg is symbol, the first symbol group is saved, if sheet the whole buffer is saved as sheetBufferChk([group|symbol|sheet, [filename], [fmt])
    BufferClearEmpty currently active paste buffer.BufferClear()
    BufferCopyCopy selection to currently active paste buffer.BufferCopy([x, y])
    BufferCutCut selection to currently active paste buffer: copy objects then remove them from the sheet.BufferCut()
    BufferLoadLoad content of buffer; if first arg is symbol, the first symbol group is saved, if sheet the whole buffer is saved as sheetBufferLoad([group|symbol|all, [filename], [fmt])
    BufferPastePaste selection from active paste buffer to the board at crosshair or x;y.BufferPaste([x, y])
    BufferSaveSave content of buffer; if first arg is symbol, the first symbol group is saved, if sheet the whole buffer is saved as sheetBufferSave([group|symbol|all, [filename], [fmt])
    BufferSwitchSwitch content of buffer; if first arg is symbol, the first symbol group is saved, if sheet the whole buffer is saved as sheetBufferSwitch([group|symbol|sheet, [filename], [fmt])
    Center (RND)Moves the pointer to the center of the window.Center()lib_hid_common plugin
    ChkGridSizeReturn 1 if the currently selected grid matches the expected_size. If argument is "none" return 1 if there is no grid.ChkGridSize(expected_size)
    ChkGridSize(none)
    ChkGridUnitsReturn 1 if currently selected grid unit matches the expected (normally mm or mil)ChkGridUnits(expected)
    ChkModeReturn 1 if the currently selected mode is the expected_modeChkMode(expected_mode)
    cli_MessageBoxIntenal: CLI frontend action. Do not use directly.
    cli_PromptForIntenal: CLI frontend action. Do not use directly.
    CommandDisplays the command line input in the status area.Command()lib_hid_common plugin
    CompileProjectCompile the abstract model of the current project, using the current view (or the view named)CompileProject([view_name])project_act
    ConditionalDialogOpen the conditional helper dialog for an object.ConditionalDialog(object, dnp|omit)sch_dialogs
    confPerform various operations on the configuration tree.conf(set, path, value, [role], [policy]) - change a config setting to an absolute value
    conf(delta, path, value, [role], [policy]) - change a config setting by a delta value (numerics-only)
    conf(toggle, path, [role]) - invert boolean value of a flag; if no role given, overwrite the highest prio config
    conf(reset, role) - reset the in-memory lihata of a role
    conf(iseq, path, value) - returns whether the value of a conf item matches value (for menu checked's)
    confgetReturn conf node value or property from the merged in-memory/native storage. Returns nil if node is unset (for value query) or not found. Intended for scripting.ConfGet(path, [value]) - return the value of a conf node; units, colors and lists are returned as string.
    ConfGet(path, desc) - return the human readable description
    ConfGet(path, ArraySize) - number of elements
    ConfGet(path, ReadOnly) - returns 1 if node is read-only, 0 otherwise
    ConfGet(path, ConfRev) - conf (merge) rev number the value last changed
    ConvertConvert objects into a polygon or a group.Convert(selected|buffer|object|list, poly[gon]|group|sym[bol]|term[inal], [oidlist])construct plugin
    CreateMenuCreates a new menu, popup (only path specified) or submenu (at least path and action are specified)CreateMenu(path)
    CreateMenu(path, action, tooltip, cookie, [accel])
    Cursor (RND)Move the cursor.Cursor(Type,DeltaUp,DeltaRight,Units)
    d1debug action for developmentd1()diag plugin
    dadManipulate Dynamic Attribute Dialogsdad(dlgname, new) - create new dialog
    dad(dlgname, label, text) - append a label widget
    dad(dlgname, button, text) - append a button widget
    dad(dlgname, button_closes, label, retval, ...) - standard close buttons
    dad(dlgname, enum, choices) - append an enum (combo box) widget; choices is a tab separated list
    dad(dlgname, bool) - append an checkbox widget (default off)
    dad(dlgname, integer|real|coord, min, max) - append an input field
    dad(dlgname, string) - append a single line text input field
    dad(dlgname, default, val) - set the default value of a widet while creating the dialog
    dad(dlgname, help, tooltip) - set the help (tooltip) text for the current widget
    dad(dlgname, progress) - append a progress bar (set to 0)
    dad(dlgname, preview, cb_act_prefix, minsize_x, minsize_y, [ctx]) - append a preview with a viewbox of 10*10mm, minsize in pixels
    dad(dlgname, tree, cols, istree, [header]) - append tree-table widget; header is like enum values
    dad(dlgname, tree_append, row, cells) - append after row (0 means last item of the root); cells is like enum values; returns a row pointer
    dad(dlgname, tree_append_under, row, cells) - append at the end of the list under row (0 means last item of the root); cells is like enum values; returns a row pointer
    dad(dlgname, tree_insert, row, cells) - insert before row (0 means first item of the root); cells is like enum values; returns a row pointer
    dad(dlgname, begin_hbox) - begin horizontal box
    dad(dlgname, begin_vbox) - begin vertical box
    dad(dlgname, begin_hpane) - begin horizontal paned box
    dad(dlgname, begin_vpane) - begin vertical paned box
    dad(dlgname, begin_table, cols) - begin table layout box
    dad(dlgname, begin_tabbed, tabnames) - begin a view with tabs; tabnames are like choices in an enum; must have as many children widgets as many names it has
    dad(dlgname, end) - end the last begin
    dad(dlgname, flags, flg1, flg2, ...) - change the flags of the last created widget
    dad(dlgname, onchange, action) - set the action to be called on widget change
    dad(dlgname, run, title) - present dlgname as a non-modal dialog
    dad(dlgname, run_modal, title) - present dlgname as a modal dialog
    dad(dlgname, exists) - returns wheter the named dialog exists (0 or 1)
    dad(dlgname, set, widgetID, val) - changes the value of a widget in a running dialog
    dad(dlgname, get, widgetID, [unit]) - return the current value of a widget
    dad(dlgname, iterate) - runs a global GUI iteration (event dispatch, redraw)
    dad(dlgname, raise) - pops up window in front
    dad(dlgname, close) - close the dialog (and return 0 from modal run)
    lib_hid_common plugin
    DevmaplibCleanLocalRemove all local-lib devmaps from the current sheet; they are re-loaded from external libs into the local lib upon the next compilation. Useful to refresh local lib from disk.DevmaplibCleanLocal()devmap
    DevmaplibRehashRebuild the in-memory tree of devmapsDevmaplibRehash()devmap
    DiscardAbstractFree the abstract model of the current project.CompileProject()project_act
    dlg_confval_editPresent a dialog box for editing the value of a conf node at path.dlg_confval_edit(path, idx, role, [modal])lib_hid_common plugin
    DrawArcDraw an arc. Angles are in degrees.DrawArc([noundo], [retptr], scope, cx, cy, r, start_ang, delta_ang, [pen])draw plugin
    DrawCircleDraw a 360 degree arc (full circle).DrawCircle([noundo], [retptr], scope, cx, cy, r, [pen])draw plugin
    DrawGroupCreate a new concrete group. Optionally create key=value string attributes in the new group.DrawGroup([noundo], [retptr], scope, [key, value], [key, value]...)draw plugin
    DrawLineDraw a decoration line.DrawLine([noundo], [retptr], scope, x1, y1, x2, y2, [pen])draw plugin
    DrawReleaseRelease the pointer of an object. Call this after Draw*(retptr,...) when the object is no longer needed. Unreleased objects are leaked. Warning: there is NO reference counting; getting the same object twice will get only one registration, then releasing "one of them" will release both! NEVER keep pointers across invocations.DrawRelease(objptr)draw plugin
    DrawTextCreate a non-bbox-specified text object.DrawText([noundo], [retptr], scope, x, y, text, [pen])draw plugin
    DrawWireDraw a wire on the sheet of scope. Draws junctions and makes connections and merges nets as needed.DrawWire([noundo], [retptr], scope, x1, y1, x2, y2, [pen])draw plugin
    DRCInvoke the DRC check. Results are presented as the argument requests.DRC([list|print|log])libcschem/drc
    duktapeExecute a script one-liner using a specific languageOneliner(lang, script)script plugin
    DumpActionsDump all actions available.DumpActions()
    dumpconfPerform various operations on the configuration tree.dumpconf(native, [verbose], [prefix]) - dump the native (binary) config tree to stdout
    dumpconf(lihata, role, [prefix]) - dump in-memory lihata representation of a config tree
    diag_rnd
    DumpPluginDirsPrint plugins directories in a format digestable by scripts.DumpPluginDirs()
    DumpPluginsPrint plugins loaded in a format digestable by scripts.DumpPlugins()
    DumpVersionDump version in script readable format.DumpVersion()
    EditTextBring up a text quick edit dialog.EditText([object[=idpath]])sch_dialogs
    estutterExecute a script one-liner using a specific languageOneliner(lang, script)script plugin
    EvalConfPerform various operations on the configuration tree.EvalConf(path) - evaluate a config path in different config sources to figure how it ended up in the native databasediag_rnd
    ExecActionFileRun actions from the given file.ExecActionFile(filename)
    ExecCommandRun shell commandSystem(shell_cmd)
    ExportExport the current layout, e.g. Export(png, --dpi, 600)Export(exporter, [exporter-args])
    ExportDialogOpen the export dialog.ExportDialog()lib_hid_common plugin
    ExportProjectDialogOpen the export dialog for exporting the project (all sheets of the project).ExportDialog()sch_rnd_gui
    fawkExecute a script one-liner using a specific languageOneliner(lang, script)script plugin
    fbasExecute a script one-liner using a specific languageOneliner(lang, script)script plugin
    FontFindFinds a font by the same name:style combo pens useFontFind(name, style)diag plugin
    FontInfoTest-render str and return width or height.FontInfo(TextWidth|TextHeight, str, [penname])
    fpasExecute a script one-liner using a specific languageOneliner(lang, script)script plugin
    FsdSimpleFile selection dialog, simplified API; for meaning of the arguments, see the HID API doc.FsdSimple(title, descr, default_file, default_ext, history_tag, [read])lib_hid_common plugin
    FsdTestCentral, DAD based File Selection Dialog demoFsdTest()lib_hid_common plugin
    FullScreenHide widgets to get edit area full screenFullScreen(on|off|toggle)
    FuncmapChangeChange the alternate function of a component-port. The setgrp command activates a group by setting all affected ports to that group's funcionality. All arguments are case-sensitive.FuncmapChange(previous|next|remove, component, port)
    FuncmapChange(set, component, port, [newfunc])
    FuncmapChange(setgrp, component, grpname)
    funcmap
    FuncmapComponentDialogOpen the alternate function mapping dialog for a componentFuncmapComponentDialog(object)funcmap
    FuncmaplibCleanLocalRemove all local-lib funcmaps from the current sheet; they are re-loaded from external libs into the local lib upon the next compilation. Useful to refresh local lib from disk.FuncmaplibCleanLocal()funcmap
    FuncmaplibRehashRebuild the in-memory tree of funcmapsFuncmaplibRehash()funcmap
    FuncmapPortDialogOpen the modal dialog for changing the alternate function of a port. FuncmapPortDialog(object, component, port)funcmap
    FuncmapPrintTablePrint a table of all alternative port functions for a component If column is specified, sort the table by the named column.FuncmapPrintTable(component, [column])funcmap
    GetObjTypeReturn the type of the object named in oidpath as a string.GetObjType([root_data,] idpath)act_read
    GetParentGrpReturn the oidpath of the immediate parent group of an objectGetParentGrp([root_data,] idpath)act_read
    GetValueConvert a coordinate value. Returns an unitless double or FGW_ERR_ARG_CONV. The 3rd parameter controls whether to require relative coordinates (+- prefix). Wraps rnd_get_value_ex().GetValue(input, units, relative, default_unit)act_read
    GetXY (RND)Get a coordinate. If x or y specified, the return value of the action is the x or y coordinate.GetXY([message, [x|y]])
    GridSet the grid.grid(set, [name:]size[@offs][!unit])
    grid(+|up)
    grid(-|down)
    grid(#N)
    grid(idx, N)
    grid(get)
    grid(ask)
    gui_FallbackColorPickIntenal: GUI frontend action. Do not use directly.lib_hid_common plugin
    gui_MayOverwriteFileIntenal: GUI frontend action. Do not use directly.lib_hid_common plugin
    gui_MessageBoxIntenal: GUI frontend action. Do not use directly.lib_hid_common plugin
    gui_PromptForIntenal: GUI frontend action. Do not use directly.lib_hid_common plugin
    HelpOn-line action helpHelp()
    IDPBasic idpath manipulation.IDP([print|free|dup], idpath)act_read
    IDPListBasic idpath list manipulation.IDPList(alloc)
    IDPList(free|clear|print|dup|length, list)
    IDPList(get|pop|remove, list, idx)
    IDPList(prepend|append|push, list, idpath)
    act_read
    InfoBarFileChangedPresent the "file changed" warning info bar with buttons to reload or cancelInfoBarFileChanged(open|close)sch_dialogs
    IntegrityRun data integrity checks on current sheet.Integrity()libcschem/integrity.c
    ircnon-modal, single-instance, single-server, single-channel irc window for online supportirc()irc plugin
    javascriptExecute a script one-liner using a specific languageOneliner(lang, script)script plugin
    jsExecute a script one-liner using a specific languageOneliner(lang, script)script plugin
    LibraryDialogBring up the library dialog. Default lib_type_name is "symbol". "Sheet" is the sheet's local library (one dialog per sheet), "global" is all symbols mapped for any sheet seen in this session. In modal mode returns the tree path of the selected entry.LibraryDialog([lib_type_name, [sheet|global, [modal]]])sch_dialogs
    ListScripts (RND)List fungw scripts, optionally filtered wiht regex pat.ListScripts([pat])script plugin
    LiveScript (RND)Manage a live scriptLiveScript([new], [name])
    LiveScript(load|save, name, [filame])
    LiveScript(run|stop|rerun|undo, name)
    script plugin
    LoadLoad a project or a schematics sheet from a user-selected file.Load()
    Load(Project|Sheet)
    sch_rnd_gui
    LoadFromLoad project or sheet data from a file.LoadFrom(Sheet|Project,filename[,format])plug_io_act
    LoadScript (RND)Load a fungw scriptLoadScript(id, filename, [language])script plugin
    LogManages the central, in-memory log.Log(clear, [fromID, [toID])
    Log(export, [filename, [text|lihata])
    LogDialogOpen the log dialog.LogDialog()lib_hid_common plugin
    LogGuiLog() action GUI sectionLogGui(export, [filename, [text|lihata])
    luaExecute a script one-liner using a specific languageOneliner(lang, script)script plugin
    ManagePluginsManage plugins dialog.ManagePlugins()lib_hid_common plugin
    mawkExecute a script one-liner using a specific languageOneliner(lang, script)script plugin
    MenuDebugMenu debug helpers: save the merged menu in a fileMenuDebug(save, path)
    MenuPatchManage menu patchesMenuPatch(load, cookie, path, desc)
    MenuPatch(unload, cookie)
    MenuPatch(list)
    MenuPatch(InhibitInc|InhibitDec)
    Message (RND)Writes a message to the log window.message([ERROR|WARNING|INFO|DEBUG,] message)
    MessageBoxOpen a modal message dialog box with title and label. If icon string is not empty, display the named icon on the left. Present one or more window close buttons with different text and return value.MessageBox(icon, title, label, button_txt, button_retval, ...)
    MirrorMirror object or buffer. Default target is auto. Default direction is horizontal.Mirror([object|buffer|auto], [horizontal|vertical])sch_rnd_gui
    ModeChange or use the tool mode.Tool(Arc|Arrow|Copy|InsertPoint|Line|Lock|Move|None|PasteBuffer)
    Tool(Poly|Rectangle|Remove|Rotate|Text|Thermal|Via)
    Tool(Press|Release|Cancel|Stroke)
    Tool(Save|Restore)
    MoveCursorToMove the cursor to absolute coords, pan the view as needed.MoveCursorTo(x,y)
    mrubyExecute a script one-liner using a specific languageOneliner(lang, script)script plugin
    NewCreate a new sheet. Scope is a project path or @ for current project.New([scope, [root|aux|unlisted]])
    OnelinerExecute a script one-liner using a specific languageOneliner(lang, script)script plugin
    Pan (RND)Start or stop panning (Mode = 1 to start, 0 to stop)Pan(Mode)lib_hid_common plugin
    pasExecute a script one-liner using a specific languageOneliner(lang, script)script plugin
    pcb_acosscript plugin
    pcb_asinscript plugin
    pcb_atan2script plugin
    pcb_atanscript plugin
    pcb_cosscript plugin
    pcb_randscript plugin
    pcb_sinscript plugin
    pcb_sqrtscript plugin
    pcb_srandscript plugin
    pcb_tanscript plugin
    PenDialogBring up a modal pen selecton dialog. If idpath is specified, list pens starting from the group addressed by idpath. If second argument is non-modal, the dialog is not modal; else it is modal and the user selected pen is returned (as idpath). If recursive is set, map pens of parents as well. If ret_name is set, return the name of the selected pen (or NULL on no selection) instead of the usual integer return. If init_pen_name is supplied, the cursor is set to that pen.PenDialog([object[=idpath]], [non-modal], [recursive], [ret_name], [init_pen_name])sch_dialogs
    perlExecute a script one-liner using a specific languageOneliner(lang, script)script plugin
    PlaceAttribPlace an attribute floater dyntextPlaceAttrib([sheet|buffer])place plugin
    PlaceTerminalPlace a terminal group template PlaceTerminal([sheet|buffer])place plugin
    PlotTestOpen the plot test dialogPlotTest()sim_gui
    PopupBring up the popup menu specified by MenuName, optionally modified with the object type under the cursor.Popup(MenuName, [obj-type])sch_rnd_gui
    PreferencesPresent the preferences dialog, optionally opening the tab requested.Preferences([tabname])lib_hid_common plugin
    Print (RND)Present the print export dialog for printing the layout from the GUI.Print()
    PrintActionsPrint all actions available.PrintActions()
    PrintCopyrightPrint copyright notice.PrintCopyright()
    PrintDialogOpen the print dialog.PrintDialog()lib_hid_common plugin
    PrintFilesPrint files currently loaded.PrintFiles()
    PrintGUIOpen the print dialog.PrintDialog()sch_dialogs
    PrintPathsPrint full paths and search paths.PrintPaths()
    PrintUsagePrint command line arguments of sch-rnd or a plugin loaded.PrintUsage()
    PrintUsage(plugin)
    PrintVersionPrint version.PrintVersion()
    ProjectDialogBring up a modal project edit dialog for editing file listings of a project.ProjectDialog()sch_dialogs
    ProjectLoadPartialLoad sheet's missing files (or in other words, load the project file of the sheet)ProjectLoadPartial([@])
    ProjectNewCreate a new projectProjectNew([path])
    ProjectSheetTypeChange the type of a sheet (addressed by its full path) in a project, making the necessary modifications in the project fileProjectSheetType(@, sheet_fullpath, root|aux|unlisted|unload)
    PromptFor (RND)Prompt for a string. Returns the string (or NULL on cancel)PromptFor([message[,default[,title]]])
    propeditpropedit(object[:id]|sheet|selection)propedit
    propgetReturn the named property of scope or all selected objects to/by value. Scope is documented at PropEdit().propget([scope], name, [stattype])propedit
    propprintPrint a property map of objects matching the scope. Scope is documented at PropEdit().PropPrint([scope])propedit
    propsetChange the named property of scope or all selected objects to/by value. Scope is documented at PropEdit(). Existing attributes can be renamed to value by using a name rename/a/old_name, where old_name is the current name of the attribute.propset([scope], name, value)propedit
    proptoggleToggle the named property of scope or all selected objects, assuming the property is boolean. Scope is documented at PropEdit(). If create is true, non-existing attributes are created as true.proptoggle([scope], name, [create])propedit
    pyExecute a script one-liner using a specific languageOneliner(lang, script)script plugin
    pythonExecute a script one-liner using a specific languageOneliner(lang, script)script plugin
    queryPerform various queries on concrete model data.query(dump, expr) - dry run: compile and dump an expression
    query(eval|evalidp, expr) - compile and evaluate an expression and print a list of results on stdout
    query(count, expr) - compile and evaluate an expression and return the number of matched objects (-1 on error)
    query(select|unselect|view, expr) - select or unselect or build a view of objects matching an expression
    query(append, idplist, expr) - compile and run expr and append the idpath of resulting objects on idplist
    query plugin
    QueryCompileFieldWith "compile": precompiles textual field name to field ID; with "free": frees the memory allocated for a previously precompiled fieldID.QueryCompileField(compile, fieldname)
    QueryCompileField(free, fieldID)
    query plugin
    QueryObjReturn the value of a field of an object, addressed by the object's idpath and the field's name or precompiled ID. Returns NIL on error.QueryObj(idpath, [.fieldname|fieldID])query plugin
    QuickAttrQuick Attribute Edit on keyQuickAttr(last-click|parent|object[:idpath], key)sch_dialogs
    QuickAttrEditableReturns 1 if obj:key has a quick attribute editQuickAttrEditable(last-click|parent|object[:idpath], key)sch_dialogs
    quick_attr_connectQuick Attribute Edit for core data model's symbol connect attribute (attribute based symbol terminal to network connection table)quick_attr_connect(objptr)std_cschem
    quick_attr_devmapQuick Attribute Edit for devmap using the devmap libraryquick_attr_devmap(objptr)devmap
    quick_attr_forge__if__dnpQuick Attribute Edit for the standard forge-if/dnp attributequick_attr_forge__if__dnp(objptr)sch_dialogs
    quick_attr_forge__if__omitQuick Attribute Edit for the standard forge-if/omit attributequick_attr_forge__if__dnp(objptr)sch_dialogs
    quick_attr_forge__if__test_benchQuick Attribute Edit for core data model's symbol connect attribute (attribute based symbol terminal to network connection table)quick_attr_forge__if__test_bench(objptr)std_forge
    quick_attr_funcmapQuick Attribute Edit for funcmap using the funcmap libraryquick_attr_funcmap(objptr)funcmap
    quick_attr_portmapQuick Attribute Edit for core data model's symbol portmap attribute (attribute based "symbol terminal to network" portmap table)quick_attr_portmap(objptr)devmap
    quick_attr_roleQuick Attribute Edit for core data model's role attributequick_attr_role(objptr)sch_dialogs
    quick_attr_spice__modelQuick Attribute Edit for spice/model using the devmap libraryquick_attr_spice__model(objptr)target_spice/spicelib
    QuitQuits sch-rnd after confirming.Quit()
    RedoRedo recent "undo" operations.redo()libcschem/undo.c
    RedrawRedraw the entire screenRedraw()
    ReloadScript (RND)Reload a fungw scriptReloadScript(id)script plugin
    RemoveMenuRecursively removes a new menu, popup (only path specified) or submenu. RemoveMenu(path, cookie)
    RemoveSelectedRemove all selected objectsRemoveSelected()
    RenumberRename (renumber) selected or all symbols on current sheet or on all sheets of the project. Second argument is the direction of numbering (e.g. rl means right-to-left). If base is specified, it is an integer and is the first number assigned. Non-numerical name prefix is preserved (R, C, etc.)Renumber(Selected|All|SelectedProject|AllProject, lr|rl|tb|bt, [base])renumber
    RenumberDialogOpen the graphical frontend dialog box for the Renumber() action. The dialog box is single instance and non-modal.RenumberDialog()renumber
    ReplaceSymbolReplace target symbol with the first symbol from the bufferReplaceSymbol([object])
    RevertRevert to on-disk version of file(s). Default target is sheet.Revert([sheet|project])
    rnd_acosscript plugin
    rnd_asinscript plugin
    rnd_atan2script plugin
    rnd_atanscript plugin
    rnd_cosscript plugin
    rnd_dlg_xpm_by_nameIntenal: GUI frontend action. Do not use directly.lib_hid_common plugin
    rnd_randscript plugin
    rnd_sinscript plugin
    rnd_sqrtscript plugin
    rnd_srandscript plugin
    rnd_tanscript plugin
    rnd_toolbar_initFor ringdove apps: initialize the toolbar.lib_hid_common plugin
    rnd_toolbar_uninitFor ringdove apps: uninitialize the toolbar.lib_hid_common plugin
    rnd_zoomChange zoom level (relative, absolute, window, ...)Zoom()
    Zoom([+|-|=]factor)
    Zoom(x1, y1, x2, y2)
    Zoom(?)
    Zoom(get)
    lib_hid_common plugin
    Rotate90Rotate object or buffer CCW in 90 degree steps. Default target is auto. Default steps is 1.Rotate90([object|buffer|auto], [steps])
    Rotate90(idpath, steps, idp, x, y)
    sch_rnd_gui
    RotateRotate object or buffer CCW in def degrees. Default target is auto. Default deg is ask (which prompts for a value).Rotate([object|buffer|auto], [deg|ask])sch_rnd_gui
    RtreeListReturn a list of idpaths for objects overlapping with the box specified (empty list if no object is found). Error is indicated by returning nil. If coordinates are not specified the whole tree is searched.RtreeList[rtree_name, [x1, y1, x2, y2])act_read
    rubyExecute a script one-liner using a specific languageOneliner(lang, script)script plugin
    SafeFsclearerrSame as clearerr(3)SafeFsclearerr(f)
    SafeFsFcloseCloses a file previously open using SafeFsFopen()SafeFsFclose(f)
    SafeFsFeofReturns 1 if file has reached EOF, 0 otherwiseSafeFsFeof(f)
    SafeFsFerrorReturns 1 if file had errors, 0 otherwiseSafeFsFerror(f)
    SafeFsFgetsReads and returns a line from f (open with SafeFsFopen()). Stops reading after maxlen (subsequent call will continue reading the same line). Returns nil on error or eof or empty line. Maxlen is 64k by default. Note: string heap allocation is made for maxlen.SafeFsFgets(f, [maxlen])
    SafeFsFileMtimeReturn the last modification time of a file, from Epoch, or -1 on error.SafeFsFileMtime(path)
    SafeFsFileSizeReturn the size of a file in bytes, or -1 on error.SafeFsFileSize(path)
    SafeFsFopenOpens a file using fopen, returns FILE *. If mode is not specified, r is assumed. Returns nil on error.SafeFsFopen(path, [mode])
    SafeFsFputsWrites str to file f (previously opne with SafeFsFopen))SafeFsFputs(f, str)
    SafeFsFreadReads and returns at most len bytes from a file (open with SafeFsFopen()). Returns nil on error or eof or empty line.SafeFsFread(f, len)
    SafeFsFreadSepReads characters that are either all non-seps or all seps. Reads at most maxlen bytes. Returns the string read or nil on eof or error. Seps is a string that contains every separator character. Maxlen is 64k by default.SafeFsFreadSep(f, seps, [maxlen])
    SafeFsFseekSame as fseek(3); whence is a string, one of set, cur or end not specified (set is used when not specified)SafeFsFseek(f, offs, [whence])
    SafeFsFtellSame as ftell(3).SafeFsFtell(f)
    SafeFsIsDirReturn 1 if path exists and is a directory, else return 0.SafeFsIsDir(path)
    SafeFsMkdirMkdir a file from the file system. If mode is a string, it is converted from octal. Return value is the same as mkdir(2)'sSafeFsMkdir(path, mode)
    SafeFsPathSepReturn the system dependet path separator character (normally slash).SafeFsPathSep(path)
    SafeFsReadFileReads a text file into one long string, returned, but at most maxlen bytes. If maxlen is not specified, 64k is used. Returns nil on error or empty file.SafeFsReadFile(path, [maxlen])
    SafeFsRealPathReturns the realpath(3) of path, or NULL on error.SafeFsRealPath(path)
    SafeFsRemoveRemove an object from the file system. Return value is the same as remove(3)'sSafeFsRemove(path)
    SafeFsRenameRename an object on the file system. Return value is the same as rename(2)'sSafeFsRename(old_path, new_path)
    SafeFsRewindSame as rewind(3)SafeFsRewind(f)
    SafeFsSystemRuns cmdline with a shell using librnd safe_fs. Return value is the same integer as system()'sSafeFsSystem(cmdline)
    SafeFsUnlinkUnlink a file from the file system. Return value is the same as unlink(2)'sSafeFsUnlink(path)
    SaveSave a project or a schmeatics sheet trying to preserve original file name.Save()
    Save(Project|Sheet)
    sch_rnd_gui
    SaveAllSave all unsaved sheets in current project (currprj)SaveAll([currprj])
    SaveAsSave a project or a schmeatics sheet using a new file name.SaveAs(Project|Sheet, [filename])sch_rnd_gui
    SaveToSave project or sheet to a file.SaveTo(Sheet|Project,filename[,format])plug_io_act
    SchGetXYReturn the cursor (or crosshair) x or y coord. Msg is a string displayed when cursor coord is requested but cursor is not active (see GetXY()).SchGetXY(cursor|crosshair, msg, X|Y)act_read
    ScriptCookie (RND)Return a cookie specific to the current script instance during script initializationScriptCookie()script plugin
    ScriptPersistency (RND)Read or remove script persistency data savd on preunloadScriptPersistency(read|remove)script plugin
    Scroll (RND)Scroll the viewport.Scroll(up|down|left|right, [pixels])lib_hid_common plugin
    SearchDialogOpen the log dialog.SearchDialog()query plugin
    SearchObjAtReturn the most preferred object at mouse cursor (or crosshair) or x;y coord; search in a raduis of r coords. The unsel variant ignores selected objects. The GuiInspect variant uses the priorities right-click does. Msg is a string displayed when cursor coord is requested but cursor is not active (see GetXY()). Returns nil or an idpath.SearchObjAt[UnSel|GuiInspect](cursor|crosshair, msg, [r])
    SearchObjAt[UnSel|GuiInspect](x, y, [r])
    act_read
    SearchObjAtGuiInspectReturn the most preferred object at mouse cursor (or crosshair) or x;y coord; search in a raduis of r coords. The unsel variant ignores selected objects. The GuiInspect variant uses the priorities right-click does. Msg is a string displayed when cursor coord is requested but cursor is not active (see GetXY()). Returns nil or an idpath.SearchObjAt[UnSel|GuiInspect](cursor|crosshair, msg, [r])
    SearchObjAt[UnSel|GuiInspect](x, y, [r])
    act_read
    SearchObjAtUnselReturn the most preferred object at mouse cursor (or crosshair) or x;y coord; search in a raduis of r coords. The unsel variant ignores selected objects. The GuiInspect variant uses the priorities right-click does. Msg is a string displayed when cursor coord is requested but cursor is not active (see GetXY()). Returns nil or an idpath.SearchObjAt[UnSel|GuiInspect](cursor|crosshair, msg, [r])
    SearchObjAt[UnSel|GuiInspect](x, y, [r])
    act_read
    SelectSelect objects; all=all visible; invert=invert selection; default is all.Select([All|Invert])
    SetGridChange grid size.SetGrid(delta|*mult|/div, [unit])
    SetGridOffs (RND)Change grid offset (alignment) to x_offs and y_offs. Offsets should be specified with units.SetGridOffs(x_offs, y_offs)
    SetUnits (RND)Set the default measurement units.SetUnits(mm|mil)
    SimActivateActivate the simulation for the setup_name+veiw_name combo; setup_name is the name of the sim setup to use, view name is the name of a view that has a suitable sim target. Triggers timed autocompile.SimActivate(setup_name, view_name)sim
    SimDialogOpen the sim(ulation) dialogSimDlg()sim_gui
    SimDlgOpen the sim(ulation) dialogSimDlg()sim_gui
    SimRunActivate and run the simulation, see SimActivate()SimRun(setup_name, view_name, [output_filename])sim
    SimSetupDialogOpen the sim(ulation) setup/run dialog for the named setup in the current projectSimDlg(setup_name)sim_gui
    SimSetupDlgOpen the sim(ulation) setup/run dialog for the named setup in the current projectSimDlg(setup_name)sim_gui
    StanceDialogOpen the current project's stance configuration dialog.StanceDialog()sch_dialogs
    StatusSetTextReplace status printout with text temporarily; turn status printout back on if text is not provided.StatusSetText([text])sch_rnd_gui
    strokeVarious gesture recognition related functionsstroke(gesture, seq)stroke plugin
    sttExecute a script one-liner using a specific languageOneliner(lang, script)script plugin
    SwitchRelativeSwitch to a different sheet by traversing integer steps on the linked list of sheets loadedSwitchRelative(steps)sch_rnd_gui
    SymlibRehashRebuild the in-memory tree of symbol librariesSymlibRehash()
    SymlibReloadAllLocalReplace all local symbols from a newer version of the same symbol from the symbol librarySymlibReloadAllLocal()
    SymLocLibConvert between "embedded" symbols (full copy) and local lib symbol referencesSymLocLib(object[:idpath]|selected, [toref|togrp])symlib_local
    SystemRun shell commandSystem(shell_cmd)
    tclExecute a script one-liner using a specific languageOneliner(lang, script)script plugin
    TestBenchDialogOpen the test bench selector for the current object or for selected objects.TestBenchDialog(object[:oidpath]|selected)std_forge
    TestBenchModifyModify test bench affiliation of object(s), adding or deleting test benches in which the given objects are participating.TestBenchModify(object[:oidpath]|selected, add|del, testbench_name)std_forge
    ToggleFloatersToggle the setting for only-floaters ot lock-floatersToggleFloaters(only|lock)
    Tool (RND)Change or use the tool mode.Tool(Arc|Arrow|Copy|InsertPoint|Line|Lock|Move|None|PasteBuffer)
    Tool(Poly|Rectangle|Remove|Rotate|Text|Thermal|Via)
    Tool(Press|Release|Cancel|Stroke)
    Tool(Save|Restore)
    TreeDialogBring up the sheet's object tree dialog. If object is specified, move cursor to that object in the tree.TreeDialog([object[=idpath]|objarr,vtp0ptr])sch_dialogs
    UndoUndo recent changes.undo()
    undo(ClearList|FreezeSerial|UnfreezeSerial|FreezeAdd|UnfreezeAdd|IncSerial|GetSerial|Above)
    libcschem/undo.c
    UndoDialogOpen the undo dialog.UndoDialog()sch_dialogs
    UndoSplitRenumber undo serials so they can be undone separatelyUndoSplit()diag plugin
    UnloadUnload (close) current project or sheetUnload(Sheet|Project)plug_io_act
    UnloadScript (RND)Unload a fungw scriptUnloadScript(id)script plugin
    UnSelectUnselect all objects. When first argument is omitted or is All, the action operates on the current sheet. When the first argument is AllProject, it operates on all sheets of the current project.UnSelect([All|AllProject])
    ViewDialogBring up a modal dialog for selecting the current view or editing views of the current project.ViewDialog()sch_dialogs
    ZoomGUI zoomZoom()
    Zoom([+|-|=]factor)
    Zoom(x1, y1, x2, y2)
    Zoom(?)
    Zoom(get)
    Zoom(selected)
    sch_rnd_gui
    ZoomToGUI zoomZoom()
    Zoom([+|-|=]factor)
    Zoom(x1, y1, x2, y2)
    Zoom(?)
    Zoom(get)
    Zoom(selected)
    sch_rnd_gui
    +

    RND: this action comes from librnd and is common to all ringdove applications. + + Index: tags/1.0.5/doc/user/09_appendix/action_src/Makefile =================================================================== --- tags/1.0.5/doc/user/09_appendix/action_src/Makefile (nonexistent) +++ tags/1.0.5/doc/user/09_appendix/action_src/Makefile (revision 10414) @@ -0,0 +1,2 @@ +all: + cd ../src && make Index: tags/1.0.5/doc/user/09_appendix/action_src/funcmapchange.html =================================================================== --- tags/1.0.5/doc/user/09_appendix/action_src/funcmapchange.html (nonexistent) +++ tags/1.0.5/doc/user/09_appendix/action_src/funcmapchange.html (revision 10414) @@ -0,0 +1,26 @@ +Changes the funcmap/name attribute on one or more ports of a given +component. The component (and port, when needed), needs to be named and +is looked up in the abstract model (the project needs to be compiled). The +actual change is always made in concrete terminal object(s) looked up from +the abstract port objects. If multiple terminals are contributing to the +port (source terminals), the change is done to the terminals that already +have the funcmap/name attribute. If none of the source terminals have that +attribute, the attribute is created in one of the source terminals randomly +chosen. +

    +The first argument is the command to perform. +

    +If the command is previous or next, the selected function of the +given port is moved one step back or forward on the function list for the port. +The function list has the order of functions as they appear in the +li:funcmap/ports section of the funcmap file (this differs from the +column ordering in the tabular form, which is deduced from function grouping). +

    +If the command is set and the new function is specified as the +4th argument, the source terminal attribute is changed to that function. The +added value of this command compared to the propset() action is that it +looks up the terminal object to change and verifies whether the new function +is available for the given port. +

    +The setgrp command modifies multiple terminals so that a whole function +group is activated (by function group name). Index: tags/1.0.5/doc/user/09_appendix/action_src/funcmapprinttable.html =================================================================== --- tags/1.0.5/doc/user/09_appendix/action_src/funcmapprinttable.html (nonexistent) +++ tags/1.0.5/doc/user/09_appendix/action_src/funcmapprinttable.html (revision 10414) @@ -0,0 +1,8 @@ +Prints the function mapping of a component in the standard tabular form to +the stdout. Each row is a port, each column is a function group. Cells +are function names. The function that's active for a port is wrapped +in [[]]. +

    +If the optional second parameter is specified and is a valid column name, +the table is sorted by that column. + Index: tags/1.0.5/doc/user/09_appendix/action_src/quit.html =================================================================== --- tags/1.0.5/doc/user/09_appendix/action_src/quit.html (nonexistent) +++ tags/1.0.5/doc/user/09_appendix/action_src/quit.html (revision 10414) @@ -0,0 +1,2 @@ +If you have unsaved changes, you will be prompted to confirm (or save) +before quitting. Index: tags/1.0.5/doc/user/09_appendix/action_src/rtreelist.html =================================================================== --- tags/1.0.5/doc/user/09_appendix/action_src/rtreelist.html (nonexistent) +++ tags/1.0.5/doc/user/09_appendix/action_src/rtreelist.html (revision 10414) @@ -0,0 +1,13 @@ +Search all objects of the selected layer's named rtree on the current sheet +and return a list of idpaths. +

    +The first argument is a layer name with an optional suffix. A layer name +is the same as layer names printed by the GUI, e.g. "wire" or +"hub & terminal". Suffix may be "-stroke" or "-fill"; when no +suffix is appended, "-stroke" is assumed. All normal objects are in +the stroke rtree; polygons with fill enabled are also in the fill rtree. +

    +If coordinates of a box is give, smaller coords first, the search +is performed only within that box and any object that has overlapping +bounding box (on the given layer) is returned. Otherwise the search +is performed on the whole rtree, returning all objects on the layer. Index: tags/1.0.5/doc/user/09_appendix/action_src/zoom.html =================================================================== --- tags/1.0.5/doc/user/09_appendix/action_src/zoom.html (nonexistent) +++ tags/1.0.5/doc/user/09_appendix/action_src/zoom.html (revision 10414) @@ -0,0 +1,51 @@ +Changes the zoom (magnification) of the view of the sheet. If no +arguments are passed, the view is scaled such that the sheet just fits +inside the visible window (i.e. "view all"). Otherwise, +factor specifies a change in zoom factor. +It may be prefixed by +, -, = to change how the zoom +factor is modified (relative or absolute). The factor is a +floating point number, such as 1.5 or 0.75. +

    +Alternatively a box can be specified with 4 coordinates and zoom +will set the zoom level (and modifies pan) so that the given box of the +design is visible and as large as possible in the current window. +

    +Arguments: +

    + + +
    (no argument) + Without argments: zoom to sheet extents. + +
    +factor + Values greater than 1.0 cause the sheet to be drawn smaller; more of + the sheet will be visible. Values between 0.0 and 1.0 cause the sheet + to be drawn bigger; less of the sheet will be visible. + +
    -factor + Values greater than 1.0 cause the sheet to be drawn bigger; less of + the sheet will be visible. Values between 0.0 and 1.0 cause the sheet + to be drawn smaller; more of the sheet will be visible. + +
    =factor + The @var{factor} is an absolute zoom factor; the unit for this value + is "PCB units per screen pixel". Since PCB units are nanometer, a + factor of 1000 means 1 micrometer per pixel (TODO: test this). + +
    x1, y1, x2, y2 + Zoom to the specified portion of the design, described as a rectangle + (using sheet space coordinates) + +
    selected + Zoom and pan so that all selected objects are on the screen. + +
    ? + Print the current zoom level in the message log (as an info line). + +
    get + Return the zoom level as an FGW_DOUBLE (useful for scripts). + +
    +

    +Note that zoom factors of zero are silently ignored. + Index: tags/1.0.5/doc/user/09_appendix/export_layers.html =================================================================== --- tags/1.0.5/doc/user/09_appendix/export_layers.html (nonexistent) +++ tags/1.0.5/doc/user/09_appendix/export_layers.html (revision 10414) @@ -0,0 +1,58 @@ + + +

    export plugin --layers

    +

    +Most export plugins offer the same --layers option, both for CLI and for GUI +exporting. When left empty (which is the default value), a predefined +set of layers are exported ("export default visibility"). +

    +When non-empty, it is a comma separated ordered list +of instructions on how to initialize layer visibility for the export (which +will not interfere with the layer visibility on the GUI). The export +layer visibility (ELV) is a bit for each display layer (see the layer +selector, left side of main window, for layer names). If the bit is 1, +the layer is exported, if it is 0, it is omitted from the export. +

    +The ELV starts out with the "export default visibility", then +each element of the list is parsed as an instruction, in order of appearance, +and is applied to the ELV. If an instruction has a ! prefix, the inverse +effect of the instruction is applied. Below is a list of all instructions. +

    + + + + + +
    instruction description +
    gui + overwrite the whole ELV so that it reflects current layer visibility + from the GUI (which does exist even if sch-rnd is ran with the batch + HID or with -x). +
    none + turn off visibility of all layers +
    all + turn on visibility of all layers +
    layer name prefix + turn on the visibility of any layer matching the prefix (case sensitive) + +
    +

    +Examples: + + + + + +
    --layers arg description +
    all + export all layers available +
    all,!bus + export all layers except for bus +
    none,bus,wire + export only bus and wire layers +
    gui,!connections + export as shown on screen, but without connections +
    + + + Index: tags/1.0.5/doc/user/09_appendix/sim_out.html =================================================================== --- tags/1.0.5/doc/user/09_appendix/sim_out.html (nonexistent) +++ tags/1.0.5/doc/user/09_appendix/sim_out.html (revision 10414) @@ -0,0 +1,93 @@ + + + + + pcb-rnd - list of file formats + + + + + +

    pcb-rnd User Manual: Appendix

    +

    +

    SimRun() output file format

    +

    +The file format is a simple line based plain text format with no limit on +line lengths. The file is indented with spaces to indicate the tree +structure. Indentation is stable in the export code, so parsers may depend +on it. However, it's probably more practical to depend on the fact that +the first 1 or 2 words in each line is a string literal that determines the +meaning of the line. Long blocks of embedded data are packed in between +begin/end markers. Begin marks often have human readable explanation at the +end of the line, those shall be ignored by parsers. Other than these, there +are no comments in the file. Empty lines shall be ignored. String literals +are written in bold in this document. +

    +The first line of the file is Simulation setup: followed by the user +assigned name of the simulation setup being exported. There is exactly one +simulation setup exported per file. +

    +Then comes one or more output trees. The output starts with an +Output: line conaining the user assigned name of the output. +Each output tree has three subtrees: analysis, presentation and data. +

    +The analysis subtree is introduced by the analysis line. A config +subtree follows, to describe the analysis configuration. +

    +The presentation subtree is introduced by the presentation line. +A config subtree follows, to describe the presentation configuration, +then a props subtree lists the columns of data. +

    +The props subtree is ontriduced by a props begin line, followed +by 1 or more props, terminated by a props end line. The first prop is +always x: followed by the human readable label of the X axis. The +rest of the props are names of the data columns (y coords). +

    +A config subtree is specified in between a pair of config begin and a +config end lines and contains zero or more key=value lines. +

    +The data subtree starts with data begin and ends with data end. +It contains an arbitrary number of ordered data rows in between. Each row has +exactly as many columns (words) as many props got defined for the presentation. +The first column is always the X coordinate on a two-dimensional plot, the +rest of the columns are Y coordinates for each property (trace). Cells +are in the usual numeric format, without unit. + + +

    +Simulation setup: dc transition
    +
    + Output: time plot all
    +  analysis
    +   config begin
    +    type=tran_lin
    +    incr=1ms
    +    stop=200ms
    +   config end
    +  presentation
    +   config begin
    +    type=plot
    +   config end
    +   props begin (columns)
    +    x: time [s]
    +    in
    +    mid
    +    out
    +  props end
    +  data begin (first column is position on the x axis, the remaining columns are y values)
    +    0.00000000e+00	0.00000000e+00	0.00000000e+00	0.00000000e+00
    +    1.00000000e-08	0.00000000e+00	0.00000000e+00	0.00000000e+00
    +    2.00000000e-08	0.00000000e+00	0.00000000e+00	0.00000000e+00
    +    4.00000000e-08	0.00000000e+00	0.00000000e+00	0.00000000e+00
    +    8.00000000e-08	0.00000000e+00	0.00000000e+00	0.00000000e+00
    +    1.60000000e-07	0.00000000e+00	0.00000000e+00	0.00000000e+00
    +    3.20000000e-07	0.00000000e+00	0.00000000e+00	0.00000000e+00
    +    6.40000000e-07	0.00000000e+00	0.00000000e+00	0.00000000e+00
    +    1.00000000e-06	0.00000000e+00	0.00000000e+00	0.00000000e+00
    +    1.00512483e-06	2.56241633e-02	1.31319437e-08	3.73883304e-15
    +    1.01537450e-06	7.68724899e-02	6.56596959e-08	2.61718227e-14
    +    1.03587383e-06	1.79369143e-01	3.28298121e-07	2.50501430e-13
    +    1.06134248e-06	3.06712393e-01	9.47287438e-07	1.15292938e-12
    +    1.11227978e-06	5.61398892e-01	3.15823226e-06	6.96192034e-12
    + data end
    +
    Index: tags/1.0.5/doc/user/09_appendix/sim_setups.html =================================================================== --- tags/1.0.5/doc/user/09_appendix/sim_setups.html (nonexistent) +++ tags/1.0.5/doc/user/09_appendix/sim_setups.html (revision 10414) @@ -0,0 +1,134 @@ + + + + + pcb-rnd - list of file formats + + + + + +

    pcb-rnd User Manual: Appendix

    +

    +

    config subtree: plugins/sim/setups

    +

    +The sim/setups subtree describes one or more +high level simulation setups +In a project.lht, the subtree is typically placed like this: +

    +ha:coraleda-project-v1 {
    + li:sch-rnd-conf-v1 {
    +  ha:overwrite {
    +   ha:plugins {
    +    ha:sim {
    +     li:setups {
    +     (subtree described in this document)
    +     }
    +    }
    +   }
    +  }
    + }
    +}
    +
    +

    +Note: in this document italic marks variable, user assigned data. The +format is case sensitive. +

    +The setups list contains one or more hash nodes, each describing +a simulation setup. The name of the node is the name of the simulation setup. +The overall structure of a simulation setup hash node is: +

    +ha:name {
    + test_bench = bench_name
    + li:mods {
    +  (mods subtree)
    + }
    + li:output {
    +  (output subtree)
    + }
    +}
    +
    + +

    the mods subtree

    +

    +The mods subtree contains one or more modifications, each is a hash node with +its name determinign what kind of modification is done; thus the name must +be one of the predefined +modifications, e.g. add. +

    +Example modifications: +

    +ha:edit_attr {
    + type = comp
    + name = R2
    + key = blobb
    + value = hello
    +}
    +ha:omit {
    + type = comp
    + name = R3
    +}
    +ha:disconn {
    + comp = R12
    + port = 1
    +}
    +ha:add {
    + device = V
    + ac_value = 3.3
    + value = 0.2
    + name = V3
    + tdf = pulse
    + pos = R1-1
    + neg = R2-2
    + ha:tdf_params {
    +  V1 = 0.2
    +  V2 = 0.8
    +  TD = 4
    + }
    +}
    +
    + +

    edit_attr

    +

    +Type is either comp, port or net and specifies the type of the target object +in the abstract model to edit. Name is the address of the object: for comp(onent) +and net(work) it's the name of the object, for port it's componetname-portname. +Key is the attribute key to edit, value is the new value of the attribute. If +the attribute doesn't exist, it is created. + +

    omit

    +

    +Mark a component or network omitting. Type is the same as in edit_attr, but +shall be either comp or port. Name is the same as in edit_attr. A component +or network omitted means it is not exported (and this is visually indicated +on the sheet). + +

    disconn

    +

    +Disconnect a port from its net; comp specifies the name of the component, +port specifies the name of the port. + +

    add

    +

    +Add a new component to the abstract model. Name is optional; when not +specified, it is autogenerated. Using an explicit name is useful when +the component needs to be referneced, e.g. in some of the analysis for +feeding in the test signal. +

    +pos and neg are the address (network name or comp-port name) of the +positive and negative port connection of the new component. If neg is +not specified, GND is assumed. +

    +The device field is the name of the device type to add, e.g. V for voltage source; +see the device types list. +That table also specifies whether ac_value and tdf may be used. +

    +The value field is the DC value for sources or the component value +for passives. When available (e.g. for sources), ac_value is the optional +AC component, which also identifies which source is used for feeding in +AC signal. +

    +Some component types permit using time-dependant-functions (TDF). For those, +the type of the tdf can be specified in the tdf field and parameters of +the tdf specified in the ha:tdf_params subtree. If no tdf field is specified, +it is assumed to be none. Index: tags/1.0.5/doc/user/09_appendix/src/Makefile =================================================================== --- tags/1.0.5/doc/user/09_appendix/src/Makefile (nonexistent) +++ tags/1.0.5/doc/user/09_appendix/src/Makefile (revision 10414) @@ -0,0 +1,27 @@ +# NOTE: aagraph is at svn://repo.hu/projects/aagraph/trunk + +PCBRND = ../../../../src/sch-rnd +CLEANFILES=../action_details.html ../action_reference.html ../formats.html + +all: $(CLEANFILES) + +include ../../../../Makefile.conf +include $(LIBRND_MAK) + +../action_details.html: ./action_compiler.sh ../action_src/*.html librnd_acts + LIBRND_LIBDIR=$(LIBRND_LIBDIR) ./action_compiler.sh ../action_src/*.html LIBRND librnd_acts/*.html > ../action_details.html + +../action_reference.html : ./dump_actions_to_html.sh $(PCBRND) ../action_details.html librnd_acts + LIBRND_LIBDIR=$(LIBRND_LIBDIR) ./dump_actions_to_html.sh > ../action_reference.html + +../formats.html: ../../../../src/plugins/*/*.pup + APP="pcb-rnd" PLUGINS="../../../../src/plugins" $(LIBRND_LIBDIR)/gen_formats.sh > ../formats.html + +librnd_acts: FORCE + svn checkout svn://svn.repo.hu/librnd/trunk/doc/action librnd_acts + +FORCE: + +clean: + rm $(CLEANFILES) + -rm -rf librnd_acts Index: tags/1.0.5/doc/user/09_appendix/src/action_compiler.sh =================================================================== --- tags/1.0.5/doc/user/09_appendix/src/action_compiler.sh (nonexistent) +++ tags/1.0.5/doc/user/09_appendix/src/action_compiler.sh (revision 10414) @@ -0,0 +1,10 @@ +#!/bin/sh + +APP=sch-rnd + +dump_actions() { + cd ../../../../src/sch-rnd + ./sch-rnd --dump-actions 2>/dev/null +} + +. $LIBRND_LIBDIR/action_compiler.sh Property changes on: tags/1.0.5/doc/user/09_appendix/src/action_compiler.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/1.0.5/doc/user/09_appendix/src/dump_actions_to_html.sh =================================================================== --- tags/1.0.5/doc/user/09_appendix/src/dump_actions_to_html.sh (nonexistent) +++ tags/1.0.5/doc/user/09_appendix/src/dump_actions_to_html.sh (revision 10414) @@ -0,0 +1,29 @@ +#!/bin/sh + +# collates the sch-rnd action table into a html doc page + +asrc="../action_src" +lsrc="librnd_acts" + +. $LIBRND_LIBDIR/dump_actions_to_html.sh + +cd ../../../../src/sch-rnd +sch_rnd_ver=`./sch-rnd --version` +sch_rnd_rev=`svn info ^/ | awk '/Revision:/ { + print $0 + got_rev=1 + exit + } + END { + if (!got_rev) + print "Rev unknown" + } + '` +cd ../../doc/user/09_appendix/src + +print_hdr "sch-rnd" + +( + cd ../../../../src/sch-rnd + ./sch-rnd --dump-actions 2>/dev/null +) | gen Property changes on: tags/1.0.5/doc/user/09_appendix/src/dump_actions_to_html.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/1.0.5/doc/user/Makefile =================================================================== --- tags/1.0.5/doc/user/Makefile (nonexistent) +++ tags/1.0.5/doc/user/Makefile (revision 10414) @@ -0,0 +1,13 @@ +# we do not yet have a proper user manual. + +all: + +install: + +linstall: + +uninstall: + +clean: + +distclean: Index: tags/1.0.5/doc/user/index.html =================================================================== --- tags/1.0.5/doc/user/index.html (nonexistent) +++ tags/1.0.5/doc/user/index.html (revision 10414) @@ -0,0 +1,46 @@ + + + + sch-rnd - documentation + + + + + + + + + + +
    Main + Doc &  Knowledge pool  &  Tutorial + Current state + Events & timeline + sch-rnd [sch-rnd logo] +
    + + +
    + +

    sch-rnd documentation: user manual

    + + + + + Index: tags/1.0.5/font/Makefile =================================================================== --- tags/1.0.5/font/Makefile (nonexistent) +++ tags/1.0.5/font/Makefile (revision 10414) @@ -0,0 +1,31 @@ +ROOT=.. +FONTDIR=$(DATADIR)/font + +all: + +clean: + +distclean: + +install_: + -$(SCCBOX) mkdir -p $(FONTDIR) + $(CPC) "`pwd`/aussiefont-sans-bold" "$(FONTDIR)/aussiefont-sans-bold" + $(CPC) "`pwd`/aussiefont-sans-bold-oblique" "$(FONTDIR)/aussiefont-sans-bold-oblique" + $(CPC) "`pwd`/aussiefont-sans-oblique" "$(FONTDIR)/aussiefont-sans-oblique" + $(CPC) "`pwd`/aussiefont-sans-regular" "$(FONTDIR)/aussiefont-sans-regular" + $(CPC) "`pwd`/aussiefont-serif-bold" "$(FONTDIR)/aussiefont-serif-bold" + $(CPC) "`pwd`/aussiefont-serif-bold-oblique" "$(FONTDIR)/aussiefont-serif-bold-oblique" + $(CPC) "`pwd`/aussiefont-serif-oblique" "$(FONTDIR)/aussiefont-serif-oblique" + $(CPC) "`pwd`/aussiefont-serif-regular" "$(FONTDIR)/aussiefont-serif-regular" + +install: + $(MAKE) install_ CPC="$(SCCBOX) install" + +linstall: + $(MAKE) install_ CPC="$(SCCBOX) linstall" + +uninstall: + $(MAKE) install_ CPC="$(SCCBOX) uninstall" + +include $(ROOT)/Makefile.conf + Index: tags/1.0.5/font/README =================================================================== --- tags/1.0.5/font/README (nonexistent) +++ tags/1.0.5/font/README (revision 10414) @@ -0,0 +1,8 @@ +Standard Ringdove font. + +Copyright: (C) 2022, Erich S. Heinzle +License: GPL2 with font exception + +Stroke font inspired by OSIfont. + +Copied from edakrill (v2). Index: tags/1.0.5/font/aussiefont-sans-bold =================================================================== --- tags/1.0.5/font/aussiefont-sans-bold (nonexistent) +++ tags/1.0.5/font/aussiefont-sans-bold (revision 10414) @@ -0,0 +1,3759 @@ +li:pcb-rnd-font-v1 { + ha:geda_pcb { + id = 0 + ha:symbols { + ha:&09 { + width = 0.685801mm + delta = 0.103633mm + li:objects { + ha:line.0 { + y2 = 36.0mil + thickness = 3.0mil + x1 = 0.0 + x2 = 27.0mil + y1 = 36.0mil + } + ha:line.1 { + y2 = 30.0mil + thickness = 3.0mil + x1 = 27.0mil + x2 = 22.0mil + y1 = 36.0mil + } + ha:line.2 { + y2 = 42.0mil + thickness = 3.0mil + x1 = 27.0mil + x2 = 22.0mil + y1 = 36.0mil + } + ha:line.3 { + y2 = 42.0mil + thickness = 3.0mil + x1 = 0.0 + x2 = 5.0mil + y1 = 36.0mil + } + ha:line.4 { + y2 = 30.0mil + thickness = 3.0mil + x1 = 0.0 + x2 = 5.0mil + y1 = 36.0mil + } + } + height = 1.066801mm + } + ha:&0A { + width = 0.889001mm + delta = 10.0mil + li:objects { + ha:line.0 { + y2 = 10.0mil + thickness = 3.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 40.0mil + } + ha:line.1 { + y2 = 40.0mil + thickness = 3.0mil + x1 = 0.0 + x2 = 15.0mil + y1 = 40.0mil + } + ha:line.2 { + y2 = 45.0mil + thickness = 3.0mil + x1 = 20.0mil + x2 = 20.0mil + y1 = 75.0mil + } + ha:line.3 { + y2 = 45.0mil + thickness = 3.0mil + x1 = 20.0mil + x2 = 35.0mil + y1 = 45.0mil + } + ha:line.4 { + y2 = 60.0mil + thickness = 3.0mil + x1 = 20.0mil + x2 = 30.0mil + y1 = 60.0mil + } + } + height = 1.905001mm + } + ha:&0D { + width = 0.889001mm + delta = 0.253999mm + li:objects { + ha:line.0 { + y2 = 15.0mil + thickness = 3.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 35.0mil + } + ha:line.1 { + y2 = 10.0mil + thickness = 3.0mil + x1 = 5.0mil + x2 = 10.0mil + y1 = 10.0mil + } + ha:line.2 { + y2 = 40.0mil + thickness = 3.0mil + x1 = 5.0mil + x2 = 10.0mil + y1 = 40.0mil + } + ha:line.3 { + y2 = 45.0mil + thickness = 3.0mil + x1 = 20.0mil + x2 = 20.0mil + y1 = 75.0mil + } + ha:line.4 { + y2 = 45.0mil + thickness = 3.0mil + x1 = 20.0mil + x2 = 30.0mil + y1 = 45.0mil + } + ha:line.5 { + y2 = 60.0mil + thickness = 3.0mil + x1 = 20.0mil + x2 = 30.0mil + y1 = 60.0mil + } + ha:line.6 { + y2 = 55.0mil + thickness = 3.0mil + x1 = 35.0mil + x2 = 35.0mil + y1 = 50.0mil + } + ha:line.7 { + y2 = 75.0mil + thickness = 3.0mil + x1 = 30.0mil + x2 = 35.0mil + y1 = 60.0mil + } + ha:simplearc.8 { + thickness = 3.0mil + adelta = -90.000000 + astart = -90.000000 + x = 10.0mil + y = 15.0mil + r = 5.0mil + } + ha:simplearc.9 { + thickness = 3.0mil + adelta = 90.000000 + astart = 270.000000 + x = 5.0mil + y = 15.0mil + r = 5.0mil + } + ha:simplearc.10 { + thickness = 3.0mil + adelta = 90.000000 + astart = 90.000000 + x = 10.0mil + y = 35.0mil + r = 5.0mil + } + ha:simplearc.11 { + thickness = 3.0mil + adelta = -90.000000 + astart = 90.000000 + x = 5.0mil + y = 35.0mil + r = 5.0mil + } + ha:simplearc.12 { + thickness = 3.0mil + adelta = 90.000000 + astart = 90.000000 + x = 30.0mil + y = 55.0mil + r = 5.0mil + } + ha:simplearc.13 { + thickness = 3.0mil + adelta = -90.000000 + astart = -90.000000 + x = 30.0mil + y = 50.0mil + r = 5.0mil + } + } + height = 1.905001mm + } ha:] { + width = 0.152401mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 68.0mil + thickness = 10.75mil + x1 = 6.0mil + x2 = 6.0mil + y1 = 5.0mil + } + ha:line.1 { + y2 = 68.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 6.0mil + y1 = 68.0mil + } + ha:line.2 { + y2 = 5.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 6.0mil + y1 = 5.0mil + } + } + height = 1.727201mm + } + ha:&5c { + width = 0.558801mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 22.0mil + y1 = 11.0mil + } + } + height = 1.574801mm + } + ha:b { + width = 0.584201mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 10.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 17.0mil + y1 = 62.0mil + } + ha:line.2 { + y2 = 56.0mil + thickness = 10.75mil + x1 = 23.0mil + x2 = 23.0mil + y1 = 34.0mil + } + ha:line.3 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 17.0mil + y1 = 28.0mil + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = 90.000000 + astart = 180.000000 + x = 17.0mil + y = 34.0mil + r = 6.0mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = 90.000000 + astart = 90.000000 + x = 17.0mil + y = 56.0mil + r = 6.0mil + } + } + height = 1.574801mm + } + ha:c { + width = 0.431801mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 6.0mil + x2 = 17.0mil + y1 = 62.0mil + } + ha:line.1 { + y2 = 56.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 34.0mil + } + ha:line.2 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 6.0mil + x2 = 17.0mil + y1 = 28.0mil + } + ha:simplearc.3 { + thickness = 10.75mil + adelta = -90.000000 + astart = 0.000000 + x = 6.0mil + y = 34.0mil + r = 6.0mil + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = -90.000000 + astart = 90.000000 + x = 6.0mil + y = 56.0mil + r = 6.0mil + } + } + height = 1.574801mm + } + ha:a { + width = 0.584201mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 4.0mil + x2 = 16.0mil + y1 = 28.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 9.0mil + x2 = 23.0mil + y1 = 62.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 23.0mil + x2 = 23.0mil + y1 = 35.0mil + } + ha:line.3 { + y2 = 44.0mil + thickness = 10.75mil + x1 = 9.0mil + x2 = 23.0mil + y1 = 44.0mil + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = -180.000000 + astart = 90.000000 + x = 9.0mil + y = 53.0mil + r = 9.0mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = 90.000000 + astart = 180.000000 + x = 16.0mil + y = 35.0mil + r = 7.0mil + } + } + height = 1.574801mm + } + ha:e { + width = 0.558801mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 39.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 55.0mil + } + ha:line.1 { + y2 = 45.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 22.0mil + y1 = 45.0mil + } + ha:line.2 { + y2 = 39.0mil + thickness = 10.75mil + x1 = 22.0mil + x2 = 22.0mil + y1 = 45.0mil + } + ha:line.3 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 7.0mil + x2 = 22.0mil + y1 = 62.0mil + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = -180.000000 + astart = 0.000000 + x = 11.0mil + y = 39.0mil + r = 11.0mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = 90.000000 + astart = 0.000000 + x = 7.0mil + y = 55.0mil + r = 7.0mil + } + } + height = 1.574801mm + } + ha:f { + width = 0.431801mm + delta = 0.444474mm + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 13.0mil + x2 = 17.0mil + y1 = 11.0mil + } + ha:line.1 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 17.0mil + y1 = 28.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 6.0mil + x2 = 6.0mil + y1 = 18.0mil + } + ha:simplearc.3 { + thickness = 10.75mil + adelta = -90.000000 + astart = 0.000000 + x = 13.0mil + y = 18.0mil + r = 7.0mil + } + } + height = 1.574801mm + } + ha:d { + width = 0.584201mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 23.0mil + x2 = 23.0mil + y1 = 10.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 6.0mil + x2 = 23.0mil + y1 = 62.0mil + } + ha:line.2 { + y2 = 56.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 34.0mil + } + ha:line.3 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 6.0mil + x2 = 23.0mil + y1 = 28.0mil + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = -90.000000 + astart = 0.000000 + x = 6.0mil + y = 34.0mil + r = 6.0mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = -90.000000 + astart = 90.000000 + x = 6.0mil + y = 56.0mil + r = 6.0mil + } + } + height = 1.574801mm + } + ha:h { + width = 0.584201mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 10.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 23.0mil + x2 = 23.0mil + y1 = 34.0mil + } + ha:line.2 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 17.0mil + y1 = 28.0mil + } + ha:simplearc.3 { + thickness = 10.75mil + adelta = 90.000000 + astart = 180.000000 + x = 17.0mil + y = 34.0mil + r = 6.0mil + } + } + height = 1.574801mm + } + ha:i { + width = 0.001um + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 14.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 11.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 28.0mil + } + } + height = 1.574801mm + } + ha:g { + width = 0.584201mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 23.0mil + x2 = 23.0mil + y1 = 73.0mil + } + ha:line.1 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 6.0mil + x2 = 23.0mil + y1 = 28.0mil + } + ha:line.2 { + y2 = 34.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 56.0mil + } + ha:line.3 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 6.0mil + x2 = 23.0mil + y1 = 62.0mil + } + ha:line.4 { + y2 = 80.0mil + thickness = 10.75mil + x1 = 3.0mil + x2 = 16.0mil + y1 = 80.0mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = 90.000000 + astart = 90.000000 + x = 16.0mil + y = 73.0mil + r = 7.0mil + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = 90.000000 + astart = -0.000000 + x = 6.0mil + y = 56.0mil + r = 6.0mil + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = 90.000000 + astart = -90.000000 + x = 6.0mil + y = 34.0mil + r = 6.0mil + } + } + height = 2.032001mm + } + ha:k { + width = 0.584201mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 11.0mil + } + ha:line.1 { + y2 = 46.0mil + thickness = 10.75mil + x1 = 23.0mil + x2 = 0.0 + y1 = 28.0mil + } + ha:line.2 { + y2 = 0.967678mm + thickness = 10.75mil + x1 = 23.0mil + x2 = 0.256478mm + y1 = 62.0mil + } + } + height = 1.574801mm + } + ha:l { + width = 0.152401mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 56.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 11.0mil + } + ha:simplearc.1 { + thickness = 10.75mil + adelta = 90.000000 + astart = 0.000000 + x = 6.0mil + y = 56.0mil + r = 6.0mil + } + } + height = 1.574801mm + } + ha:j { + width = 0.203202mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 14.0mil + thickness = 10.75mil + x1 = 0.203201mm + x2 = 0.203201mm + y1 = 11.0mil + } + ha:line.1 { + y2 = 72.0mil + thickness = 10.75mil + x1 = 0.203201mm + x2 = 0.203201mm + y1 = 28.0mil + } + ha:simplearc.2 { + thickness = 10.75mil + adelta = -90.000000 + astart = 180.000000 + x = 0.001um + y = 72.0mil + r = 8.0mil + } + } + height = 2.032001mm + } + ha:n { + width = 0.584201mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 14.0mil + y1 = 28.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 23.0mil + x2 = 23.0mil + y1 = 37.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 28.0mil + } + ha:simplearc.3 { + thickness = 10.75mil + adelta = -90.000000 + astart = -90.000000 + x = 14.0mil + y = 37.0mil + r = 9.0mil + } + } + height = 1.574801mm + } + ha:o { + width = 0.579209mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 39.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 51.0mil + } + ha:line.1 { + y2 = 51.0mil + thickness = 10.75mil + x1 = 0.579208mm + x2 = 0.579208mm + y1 = 39.0mil + } + ha:simplearc.2 { + thickness = 10.75mil + adelta = 180.000000 + astart = -0.000000 + x = 0.289604mm + y = 51.0mil + r = 0.289604mm + } + ha:simplearc.3 { + thickness = 10.75mil + adelta = -180.000000 + astart = 0.000000 + x = 0.289604mm + y = 39.0mil + r = 0.289604mm + } + } + height = 1.585005mm + } + ha:m { + width = 0.863601mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 25.0mil + y1 = 28.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 34.0mil + x2 = 34.0mil + y1 = 37.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 28.0mil + } + ha:line.3 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 17.0mil + x2 = 17.0mil + y1 = 28.0mil + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = -90.000000 + astart = -90.000000 + x = 25.0mil + y = 37.0mil + r = 9.0mil + } + } + height = 1.574801mm + } + ha:q { + width = 0.584201mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 23.0mil + x2 = 23.0mil + y1 = 80.0mil + } + ha:line.1 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 23.0mil + x2 = 6.0mil + y1 = 28.0mil + } + ha:line.2 { + y2 = 56.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 34.0mil + } + ha:line.3 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 6.0mil + x2 = 23.0mil + y1 = 62.0mil + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = 90.000000 + astart = 0.000000 + x = 6.0mil + y = 56.0mil + r = 6.0mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = 90.000000 + astart = -90.000000 + x = 6.0mil + y = 34.0mil + r = 6.0mil + } + } + height = 2.032001mm + } + ha:r { + width = 0.431801mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 62.0mil + } + ha:line.1 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 11.0mil + y1 = 28.0mil + } + ha:simplearc.2 { + thickness = 10.75mil + adelta = 90.000000 + astart = 180.000000 + x = 11.0mil + y = 34.0mil + r = 6.0mil + } + } + height = 1.574801mm + } + ha:p { + width = 0.584201mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 80.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 28.0mil + } + ha:line.1 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 17.0mil + y1 = 28.0mil + } + ha:line.2 { + y2 = 56.0mil + thickness = 10.75mil + x1 = 23.0mil + x2 = 23.0mil + y1 = 34.0mil + } + ha:line.3 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 17.0mil + y1 = 62.0mil + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = -90.000000 + astart = 180.000000 + x = 17.0mil + y = 56.0mil + r = 6.0mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = -90.000000 + astart = 270.000000 + x = 17.0mil + y = 34.0mil + r = 6.0mil + } + } + height = 2.032001mm + } + ha:t { + width = 0.431801mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 6.0mil + x2 = 6.0mil + y1 = 11.0mil + } + ha:line.1 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 17.0mil + y1 = 28.0mil + } + } + height = 1.574801mm + } + ha:u { + width = 0.584201mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 55.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 28.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 7.0mil + x2 = 23.0mil + y1 = 62.0mil + } + ha:line.2 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 23.0mil + x2 = 23.0mil + y1 = 62.0mil + } + ha:simplearc.3 { + thickness = 10.75mil + adelta = 90.000000 + astart = 0.000000 + x = 7.0mil + y = 55.0mil + r = 7.0mil + } + } + height = 1.574801mm + } + ha:s { + width = 0.618594mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 1.141047mm + thickness = 10.75mil + x1 = 0.204781mm + x2 = 0.411197mm + y1 = 1.119181mm + } + ha:simplearc.1 { + thickness = 10.75mil + adelta = -17.031080 + astart = 90.000000 + x = 0.380885mm + y = 0.368674mm + r = 47.0mil + } + ha:simplearc.2 { + thickness = 10.75mil + adelta = -186.525031 + astart = 269.133210 + x = 0.407981mm + y = 1.353612mm + r = 0.210612mm + } + ha:simplearc.3 { + thickness = 10.75mil + adelta = -17.605835 + astart = 268.781125 + x = 0.179381mm + y = 75.0mil + r = 47.0mil + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = -180.000000 + astart = 90.000000 + x = 0.204781mm + y = 36.0mil + r = 0.204781mm + } + } + height = 1.564225mm + } + ha:w { + width = 0.914401mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 9.0mil + y1 = 28.0mil + } + ha:line.1 { + y2 = 40.0mil + thickness = 10.75mil + x1 = 9.0mil + x2 = 18.0mil + y1 = 62.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 36.0mil + x2 = 27.0mil + y1 = 28.0mil + } + ha:line.3 { + y2 = 40.0mil + thickness = 10.75mil + x1 = 27.0mil + x2 = 18.0mil + y1 = 62.0mil + } + } + height = 1.574801mm + } + ha:x { + width = 0.558801mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 22.0mil + y1 = 28.0mil + } + ha:line.1 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 22.0mil + y1 = 62.0mil + } + } + height = 1.574801mm + } + ha:v { + width = 0.558801mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 11.0mil + y1 = 28.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 22.0mil + x2 = 11.0mil + y1 = 28.0mil + } + } + height = 1.574801mm + } + ha:z { + width = 0.558801mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 22.0mil + y1 = 28.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 22.0mil + x2 = 0.0 + y1 = 28.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 22.0mil + y1 = 62.0mil + } + } + height = 1.574801mm + } + ha:~ { + width = 0.589861mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 0.922452mm + thickness = 10.75mil + x1 = 0.264009mm + x2 = 0.325852mm + y1 = 0.863007mm + } + ha:simplearc.1 { + thickness = 10.75mil + adelta = -31.668558 + astart = 90.000000 + x = 0.476575mm + y = 0.678111mm + r = 0.287089mm + } + ha:simplearc.2 { + thickness = 10.75mil + adelta = -31.668558 + astart = -90.000000 + x = 0.113286mm + y = 1.107348mm + r = 0.287089mm + } + ha:simplearc.3 { + thickness = 10.75mil + adelta = -19.075098 + astart = 132.273689 + x = 0.316486mm + y = 0.591659mm + r = 16.0mil + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = -19.075098 + astart = 312.273689 + x = 0.273375mm + y = 47.0mil + r = 16.0mil + } + } + height = 0.965201mm + } + ha:y { + width = 0.584201mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 12.0mil + y1 = 28.0mil + } + ha:line.1 { + y2 = 80.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 6.0mil + y1 = 80.0mil + } + ha:line.2 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 6.0mil + x2 = 23.0mil + y1 = 80.0mil + } + } + height = 2.032001mm + } + ha:&7d { + width = 0.279402mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 63.0mil + thickness = 10.75mil + x1 = 0.127001mm + x2 = 0.127001mm + y1 = 42.0mil + } + ha:line.1 { + y2 = 9.0mil + thickness = 10.75mil + x1 = 0.127001mm + x2 = 0.127001mm + y1 = 30.0mil + } + ha:simplearc.2 { + thickness = 10.75mil + adelta = -90.000000 + astart = -90.000000 + x = 0.001um + y = 9.0mil + r = 5.0mil + } + ha:simplearc.3 { + thickness = 10.75mil + adelta = -90.000000 + astart = 90.000000 + x = 0.279401mm + y = 30.0mil + r = 6.0mil + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = 90.000000 + astart = 90.000000 + x = 0.001um + y = 63.0mil + r = 5.0mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = 90.000000 + astart = -90.000000 + x = 0.279401mm + y = 42.0mil + r = 6.0mil + } + } + height = 1.727201mm + } + ha:| { + width = 0.001um + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 71.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 43.0mil + } + ha:line.1 { + y2 = 3.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 31.0mil + } + } + height = 1.803401mm + } + ha:&7b { + width = 0.279402mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 63.0mil + thickness = 10.75mil + x1 = 0.152401mm + x2 = 0.152401mm + y1 = 42.0mil + } + ha:line.1 { + y2 = 30.0mil + thickness = 10.75mil + x1 = 0.152401mm + x2 = 0.152401mm + y1 = 9.0mil + } + ha:simplearc.2 { + thickness = 10.75mil + adelta = 90.000000 + astart = 270.000000 + x = 0.279401mm + y = 9.0mil + r = 5.0mil + } + ha:simplearc.3 { + thickness = 10.75mil + adelta = 90.000000 + astart = 90.000000 + x = 0.001um + y = 30.0mil + r = 6.0mil + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = -90.000000 + astart = 90.000000 + x = 0.279401mm + y = 63.0mil + r = 5.0mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = -90.000000 + astart = 270.000000 + x = 0.001um + y = 42.0mil + r = 6.0mil + } + } + height = 1.727201mm + } + ha:&20 { + width = 0.0 + delta = 0.9874mm + li:objects { + } + height = 0.0 + } + ha:&23 { + width = 0.889001mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 9.0mil + x2 = 9.0mil + y1 = 11.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 26.0mil + x2 = 26.0mil + y1 = 11.0mil + } + ha:line.2 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 35.0mil + y1 = 28.0mil + } + ha:line.3 { + y2 = 45.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 35.0mil + y1 = 45.0mil + } + } + height = 1.574801mm + } + ha:&26 { + width = 0.869177mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 0.579653mm + thickness = 10.75mil + x1 = 0.716776mm + x2 = 0.09087mm + y1 = 62.0mil + } + ha:line.1 { + y2 = 1.266107mm + thickness = 10.75mil + x1 = 0.469006mm + x2 = 0.014123mm + y1 = 0.597619mm + } + ha:line.2 { + y2 = 45.0mil + thickness = 10.75mil + x1 = 0.316401mm + x2 = 0.869176mm + y1 = 1.565466mm + } + ha:simplearc.3 { + thickness = 10.75mil + adelta = 130.556045 + astart = 340.000000 + x = 0.234176mm + y = 53.0mil + r = 0.234176mm + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = 238.570434 + astart = 147.994617 + x = 0.284976mm + y = 19.0mil + r = 0.217017mm + } + } + height = 1.580377mm + } + ha:! { + width = 0.001um + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 45.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 11.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 59.0mil + } + } + height = 1.574801mm + } + ha:" { + width = 0.457201mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 0.0 + thickness = 10.75mil + x1 = 0.0 + x2 = 3.0mil + y1 = 11.0mil + } + ha:line.1 { + y2 = 0.0 + thickness = 10.75mil + x1 = 15.0mil + x2 = 18.0mil + y1 = 11.0mil + } + } + height = 0.279401mm + } + ha:$ { + width = 0.580214mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.299232mm + x2 = 0.299232mm + y1 = 11.0mil + } + ha:line.1 { + y2 = 41.0mil + thickness = 10.75mil + x1 = 0.103269mm + x2 = 0.477032mm + y1 = 0.826602mm + } + ha:simplearc.2 { + thickness = 10.75mil + adelta = -19.653824 + astart = 90.000000 + x = 12.7807874mil + y = 18.0mil + r = 38.0mil + } + ha:simplearc.3 { + thickness = 10.75mil + adelta = -18.434949 + astart = 270.000000 + x = 0.273832mm + y = 55.0mil + r = 38.0mil + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = 168.035280 + astart = 250.000000 + x = 0.217007mm + y = 0.644334mm + r = 0.214844mm + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = 156.595310 + astart = 83.659808 + x = 0.375432mm + y = 48.0mil + r = 0.204781mm + } + } + height = 1.574801mm + } + ha:% { + width = 1.193801mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 46.0mil + x2 = 0.0 + y1 = 11.0mil + } + ha:simplearc.1 { + thickness = 10.75mil + adelta = 360.000000 + astart = 0.000000 + x = 38.0mil + y = 53.0mil + r = 9.0mil + } + ha:simplearc.2 { + thickness = 10.75mil + adelta = 360.000000 + astart = 0.000000 + x = 9.0mil + y = 20.0mil + r = 9.0mil + } + } + height = 1.574801mm + } + ha:' { + width = 0.076201mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 0.0 + thickness = 10.75mil + x1 = 0.0 + x2 = 3.0mil + y1 = 11.0mil + } + } + height = 0.279401mm + } + ha:( { + width = 0.134159mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 47.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 26.0mil + } + ha:simplearc.1 { + thickness = 10.75mil + adelta = 27.979474 + astart = 0.000000 + x = 1.147787mm + y = 47.0mil + r = 1.147787mm + } + ha:simplearc.2 { + thickness = 10.75mil + adelta = -27.979474 + astart = 0.000000 + x = 1.147787mm + y = 26.0mil + r = 1.147787mm + } + } + height = 1.732291mm + } + ha:) { + width = 0.13416mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 47.0mil + thickness = 10.75mil + x1 = 0.134159mm + x2 = 0.134159mm + y1 = 26.0mil + } + ha:simplearc.1 { + thickness = 10.75mil + adelta = -27.979474 + astart = 180.000000 + x = -1.013628mm + y = 47.0mil + r = 1.147787mm + } + ha:simplearc.2 { + thickness = 10.75mil + adelta = 27.979474 + astart = 180.000000 + x = -1.013628mm + y = 26.0mil + r = 1.147787mm + } + } + height = 1.732291mm + } + ha:* { + width = 0.558801mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 51.0mil + thickness = 10.75mil + x1 = 3.0mil + x2 = 19.0mil + y1 = 34.0mil + } + ha:line.1 { + y2 = 43.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 22.0mil + y1 = 43.0mil + } + ha:line.2 { + y2 = 51.0mil + thickness = 10.75mil + x1 = 19.0mil + x2 = 3.0mil + y1 = 34.0mil + } + } + height = 1.295401mm + } + ha:+ { + width = 0.558801mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 43.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 22.0mil + y1 = 43.0mil + } + ha:line.1 { + y2 = 54.0mil + thickness = 10.75mil + x1 = 11.0mil + x2 = 11.0mil + y1 = 32.0mil + } + } + height = 1.371601mm + } + ha:, { + width = 0.076201mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 65.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 3.0mil + y1 = 76.0mil + } + } + height = 1.930401mm + } + ha:- { + width = 0.558801mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 42.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 22.0mil + y1 = 42.0mil + } + } + height = 1.066801mm + } + ha:. { + width = 0.005081mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 60.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.2mil + y1 = 1.60782mm + } + } + height = 1.607821mm + } + ha:0 { + width = 0.609601mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 0.347982mm + thickness = 10.75mil + x1 = 0.224756mm + x2 = 0.177914mm + y1 = 0.29583mm + } + ha:line.1 { + y2 = 1.506218mm + thickness = 10.75mil + x1 = 0.384844mm + x2 = 0.431686mm + y1 = 1.55837mm + } + ha:line.2 { + y2 = 0.347982mm + thickness = 10.75mil + x1 = 0.384844mm + x2 = 0.431686mm + y1 = 0.29583mm + } + ha:line.3 { + y2 = 1.55837mm + thickness = 10.75mil + x1 = 0.177914mm + x2 = 0.224756mm + y1 = 1.506218mm + } + ha:line.4 { + y2 = 37.0mil + thickness = 10.75mil + x1 = 24.0mil + x2 = 24.0mil + y1 = 36.0mil + } + ha:line.5 { + y2 = 37.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 36.0mil + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = 34.875328 + astart = 180.000000 + x = -15.0mil + y = 36.0mil + r = 39.0mil + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = 34.875328 + astart = 0.000000 + x = 39.0mil + y = 37.0mil + r = 39.0mil + } + ha:simplearc.8 { + thickness = 10.75mil + adelta = -34.875328 + astart = 180.000000 + x = -15.0mil + y = 37.0mil + r = 39.0mil + } + ha:simplearc.9 { + thickness = 10.75mil + adelta = -46.397181 + astart = 113.198591 + x = 12.0mil + y = 54.0mil + r = 8.0mil + } + ha:simplearc.10 { + thickness = 10.75mil + adelta = -34.875328 + astart = 0.000000 + x = 39.0mil + y = 36.0mil + r = 39.0mil + } + ha:simplearc.11 { + thickness = 10.75mil + adelta = -46.397181 + astart = 293.198591 + x = 12.0mil + y = 19.0mil + r = 8.0mil + } + } + height = 1.574801mm + } + ha:1 { + width = 0.279401mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 11.0mil + y1 = 22.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 11.0mil + x2 = 11.0mil + y1 = 11.0mil + } + } + height = 1.574801mm + } + ha:2 { + width = 0.59396mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.009759mm + x2 = 0.568559mm + y1 = 62.0mil + } + ha:line.1 { + y2 = 0.741018mm + thickness = 10.75mil + x1 = 0.009759mm + x2 = 0.550523mm + y1 = 62.0mil + } + ha:simplearc.2 { + thickness = 10.75mil + adelta = -192.528808 + astart = 341.565051 + x = 0.289159mm + y = 23.0mil + r = 12.0mil + } + } + height = 1.574801mm + } + ha:3 { + width = 0.584201mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 13.0mil + y1 = 11.0mil + } + ha:line.1 { + y2 = 34.0mil + thickness = 10.75mil + x1 = 5.0mil + x2 = 13.0mil + y1 = 34.0mil + } + ha:line.2 { + y2 = 50.0mil + thickness = 10.75mil + x1 = 23.0mil + x2 = 23.0mil + y1 = 45.0mil + } + ha:line.3 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 11.0mil + y1 = 62.0mil + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = 90.000000 + astart = 90.000000 + x = 11.0mil + y = 50.0mil + r = 12.0mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = 90.000000 + astart = 180.000000 + x = 12.0mil + y = 45.0mil + r = 11.0mil + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = -90.000000 + astart = 180.000000 + x = 10.0mil + y = 21.0mil + r = 13.0mil + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = -90.000000 + astart = -90.000000 + x = 13.0mil + y = 21.0mil + r = 10.0mil + } + } + height = 1.574801mm + } + ha:4 { + width = 0.711201mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 51.0mil + thickness = 10.75mil + x1 = 11.0mil + x2 = 0.0 + y1 = 11.0mil + } + ha:line.1 { + y2 = 51.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 28.0mil + y1 = 51.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 19.0mil + x2 = 19.0mil + y1 = 39.0mil + } + } + height = 1.574801mm + } + ha:5 { + width = 0.584201mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 23.0mil + x2 = 0.0 + y1 = 11.0mil + } + ha:line.1 { + y2 = 34.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 11.0mil + } + ha:line.2 { + y2 = 34.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 11.0mil + y1 = 34.0mil + } + ha:line.3 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 11.0mil + x2 = 0.0 + y1 = 62.0mil + } + ha:line.4 { + y2 = 46.0mil + thickness = 10.75mil + x1 = 23.0mil + x2 = 23.0mil + y1 = 50.0mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = 90.000000 + astart = 90.000000 + x = 11.0mil + y = 50.0mil + r = 12.0mil + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = -90.000000 + astart = -90.000000 + x = 11.0mil + y = 46.0mil + r = 12.0mil + } + } + height = 1.574801mm + } + ha:6 { + width = 0.584201mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 34.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 13.0mil + y1 = 34.0mil + } + ha:line.1 { + y2 = 52.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 30.0mil + } + ha:line.2 { + y2 = 44.0mil + thickness = 10.75mil + x1 = 23.0mil + x2 = 23.0mil + y1 = 52.0mil + } + ha:line.3 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 10.0mil + x2 = 13.0mil + y1 = 62.0mil + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = -83.659808 + astart = 0.000000 + x = 19.0mil + y = 30.0mil + r = 19.0mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = 90.000000 + astart = 90.000000 + x = 13.0mil + y = 52.0mil + r = 10.0mil + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = -90.000000 + astart = 90.000000 + x = 10.0mil + y = 52.0mil + r = 10.0mil + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = -90.000000 + astart = -90.000000 + x = 13.0mil + y = 44.0mil + r = 10.0mil + } + } + height = 1.574801mm + } + ha:7 { + width = 0.584201mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 17.0mil + } + ha:line.1 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 23.0mil + y1 = 11.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 23.0mil + x2 = 12.0mil + y1 = 11.0mil + } + } + height = 1.574801mm + } + ha:8 { + width = 0.609601mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 25.0mil + thickness = 10.75mil + x1 = 1.0mil + x2 = 1.0mil + y1 = 20.0mil + } + ha:line.1 { + y2 = 52.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 44.0mil + } + ha:line.2 { + y2 = 25.0mil + thickness = 10.75mil + x1 = 23.0mil + x2 = 23.0mil + y1 = 20.0mil + } + ha:line.3 { + y2 = 52.0mil + thickness = 10.75mil + x1 = 24.0mil + x2 = 24.0mil + y1 = 44.0mil + } + ha:line.4 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 10.0mil + x2 = 14.0mil + y1 = 11.0mil + } + ha:line.5 { + y2 = 34.0mil + thickness = 10.75mil + x1 = 10.0mil + x2 = 14.0mil + y1 = 34.0mil + } + ha:line.6 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 10.0mil + x2 = 14.0mil + y1 = 62.0mil + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = -90.000000 + astart = 270.000000 + x = 14.0mil + y = 20.0mil + r = 9.0mil + } + ha:simplearc.8 { + thickness = 10.75mil + adelta = 90.000000 + astart = 90.000000 + x = 14.0mil + y = 52.0mil + r = 10.0mil + } + ha:simplearc.9 { + thickness = 10.75mil + adelta = -90.000000 + astart = 270.000000 + x = 14.0mil + y = 44.0mil + r = 10.0mil + } + ha:simplearc.10 { + thickness = 10.75mil + adelta = 90.000000 + astart = 90.000000 + x = 14.0mil + y = 25.0mil + r = 9.0mil + } + ha:simplearc.11 { + thickness = 10.75mil + adelta = 90.000000 + astart = -90.000000 + x = 10.0mil + y = 20.0mil + r = 9.0mil + } + ha:simplearc.12 { + thickness = 10.75mil + adelta = -90.000000 + astart = 90.000000 + x = 10.0mil + y = 52.0mil + r = 10.0mil + } + ha:simplearc.13 { + thickness = 10.75mil + adelta = 90.000000 + astart = -90.000000 + x = 10.0mil + y = 44.0mil + r = 10.0mil + } + ha:simplearc.14 { + thickness = 10.75mil + adelta = -90.000000 + astart = 90.000000 + x = 10.0mil + y = 25.0mil + r = 9.0mil + } + } + height = 1.574801mm + } + ha:9 { + width = 0.584201mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 39.0mil + thickness = 10.75mil + x1 = 10.0mil + x2 = 23.0mil + y1 = 39.0mil + } + ha:line.1 { + y2 = 43.0mil + thickness = 10.75mil + x1 = 23.0mil + x2 = 23.0mil + y1 = 21.0mil + } + ha:line.2 { + y2 = 29.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 21.0mil + } + ha:line.3 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 10.0mil + x2 = 13.0mil + y1 = 11.0mil + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = -83.659808 + astart = 180.000000 + x = 4.0mil + y = 43.0mil + r = 19.0mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = 90.000000 + astart = 270.000000 + x = 10.0mil + y = 21.0mil + r = 10.0mil + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = -90.000000 + astart = 270.000000 + x = 13.0mil + y = 21.0mil + r = 10.0mil + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = -90.000000 + astart = 90.000000 + x = 10.0mil + y = 29.0mil + r = 10.0mil + } + } + height = 1.571849mm + } + ha:< { + width = 0.558801mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 34.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 22.0mil + y1 = 42.0mil + } + ha:line.1 { + y2 = 50.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 22.0mil + y1 = 42.0mil + } + } + height = 1.270001mm + } + ha:> { + width = 0.558801mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 34.0mil + thickness = 10.75mil + x1 = 22.0mil + x2 = 0.0 + y1 = 42.0mil + } + ha:line.1 { + y2 = 50.0mil + thickness = 10.75mil + x1 = 22.0mil + x2 = 0.0 + y1 = 42.0mil + } + } + height = 1.270001mm + } + ha:? { + width = 0.583743mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.304342mm + x2 = 0.304342mm + y1 = 60.0mil + } + ha:line.1 { + y2 = 38.0mil + thickness = 10.75mil + x1 = 0.304342mm + x2 = 0.304342mm + y1 = 45.0mil + } + ha:line.2 { + y2 = 0.71041mm + thickness = 10.75mil + x1 = 0.384171mm + x2 = 0.48144mm + y1 = 0.791634mm + } + ha:line.3 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 12.9819685mil + x2 = 0.405942mm + y1 = 11.0mil + } + ha:line.4 { + y2 = 20.0mil + thickness = 10.75mil + x1 = 0.583742mm + x2 = 0.583742mm + y1 = 17.0mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = 90.000000 + astart = 180.000000 + x = 0.405942mm + y = 18.0mil + r = 7.0mil + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = -48.366461 + astart = 180.000000 + x = 0.278942mm + y = 19.0mil + r = 12.0mil + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = 25.641006 + astart = -90.000000 + x = 12.9819685mil + y = 41.0mil + r = 30.0mil + } + ha:simplearc.8 { + thickness = 10.75mil + adelta = -49.398705 + astart = 0.000000 + x = 0.532942mm + y = 38.0mil + r = 9.0mil + } + } + height = 1.574801mm + } + ha:@ { + width = 1.143001mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 54.0mil + thickness = 10.75mil + x1 = 20.0mil + x2 = 24.0mil + y1 = 54.0mil + } + ha:line.1 { + y2 = 26.0mil + thickness = 10.75mil + x1 = 14.0mil + x2 = 14.0mil + y1 = 47.0mil + } + ha:line.2 { + y2 = 19.0mil + thickness = 10.75mil + x1 = 21.0mil + x2 = 31.0mil + y1 = 19.0mil + } + ha:line.3 { + y2 = 47.0mil + thickness = 10.75mil + x1 = 31.0mil + x2 = 31.0mil + y1 = 19.0mil + } + ha:line.4 { + y2 = 19.0mil + thickness = 10.75mil + x1 = 45.0mil + x2 = 45.0mil + y1 = 47.0mil + } + ha:line.5 { + y2 = 2.0mil + thickness = 10.75mil + x1 = 17.0mil + x2 = 28.0mil + y1 = 2.0mil + } + ha:line.6 { + y2 = 54.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 19.0mil + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = 96.709837 + astart = -0.000000 + x = 17.0mil + y = 54.0mil + r = 17.0mil + } + ha:simplearc.8 { + thickness = 10.75mil + adelta = -90.000000 + astart = 0.000000 + x = 17.0mil + y = 19.0mil + r = 17.0mil + } + ha:simplearc.9 { + thickness = 10.75mil + adelta = 90.000000 + astart = 180.000000 + x = 28.0mil + y = 19.0mil + r = 17.0mil + } + ha:simplearc.10 { + thickness = 10.75mil + adelta = 180.000000 + astart = 0.000000 + x = 38.0mil + y = 47.0mil + r = 7.0mil + } + ha:simplearc.11 { + thickness = 10.75mil + adelta = -90.000000 + astart = 180.000000 + x = 24.0mil + y = 47.0mil + r = 7.0mil + } + ha:simplearc.12 { + thickness = 10.75mil + adelta = 90.000000 + astart = -0.000000 + x = 21.0mil + y = 47.0mil + r = 7.0mil + } + ha:simplearc.13 { + thickness = 10.75mil + adelta = -90.000000 + astart = 0.000000 + x = 21.0mil + y = 26.0mil + r = 7.0mil + } + } + height = 1.803401mm + } + ha:A { + width = 0.863601mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 17.0mil + y1 = 62.0mil + } + ha:line.1 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 34.0mil + x2 = 17.0mil + y1 = 62.0mil + } + ha:line.2 { + y2 = 48.0mil + thickness = 10.75mil + x1 = 0.118533mm + x2 = 0.745066mm + y1 = 48.0mil + } + } + height = 1.574801mm + } + ha:B { + width = 0.711201mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 62.0mil + } + ha:line.1 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 15.0mil + y1 = 11.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 16.0mil + x2 = 0.0 + y1 = 62.0mil + } + ha:line.3 { + y2 = 51.0mil + thickness = 10.75mil + x1 = 28.0mil + x2 = 28.0mil + y1 = 47.0mil + } + ha:line.4 { + y2 = 34.0mil + thickness = 10.75mil + x1 = 14.0mil + x2 = 0.0 + y1 = 34.0mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = -90.000000 + astart = -90.000000 + x = 14.0mil + y = 48.0mil + r = 14.0mil + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = -90.000000 + astart = 180.000000 + x = 14.0mil + y = 22.0mil + r = 12.0mil + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = -90.000000 + astart = 180.000000 + x = 16.0mil + y = 50.0mil + r = 12.0mil + } + ha:simplearc.8 { + thickness = 10.75mil + adelta = -90.000000 + astart = -90.000000 + x = 15.0mil + y = 22.0mil + r = 11.0mil + } + } + height = 1.574801mm + } + ha:C { + width = 0.584201mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 10.0mil + x2 = 23.0mil + y1 = 11.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 10.0mil + x2 = 23.0mil + y1 = 62.0mil + } + ha:line.2 { + y2 = 52.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 21.0mil + } + ha:simplearc.3 { + thickness = 10.75mil + adelta = 90.000000 + astart = -0.000000 + x = 10.0mil + y = 52.0mil + r = 10.0mil + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = -90.000000 + astart = 0.000000 + x = 10.0mil + y = 21.0mil + r = 10.0mil + } + } + height = 1.574801mm + } + ha:D { + width = 0.711201mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 18.0mil + y1 = 11.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 18.0mil + y1 = 62.0mil + } + ha:line.2 { + y2 = 52.0mil + thickness = 10.75mil + x1 = 28.0mil + x2 = 28.0mil + y1 = 21.0mil + } + ha:line.3 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 11.0mil + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = -90.000000 + astart = 180.000000 + x = 18.0mil + y = 52.0mil + r = 10.0mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = 90.000000 + astart = 180.000000 + x = 18.0mil + y = 21.0mil + r = 10.0mil + } + } + height = 1.574801mm + } + ha:E { + width = 0.558801mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 62.0mil + } + ha:line.1 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 22.0mil + y1 = 11.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 22.0mil + x2 = 0.0 + y1 = 62.0mil + } + ha:line.3 { + y2 = 34.0mil + thickness = 10.75mil + x1 = 17.0mil + x2 = 0.0 + y1 = 34.0mil + } + } + height = 1.574801mm + } + ha:F { + width = 0.558801mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 62.0mil + } + ha:line.1 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 22.0mil + y1 = 11.0mil + } + ha:line.2 { + y2 = 34.0mil + thickness = 10.75mil + x1 = 22.0mil + x2 = 0.0 + y1 = 34.0mil + } + } + height = 1.574801mm + } + ha:G { + width = 0.711201mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 10.0mil + x2 = 28.0mil + y1 = 11.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 10.0mil + x2 = 28.0mil + y1 = 62.0mil + } + ha:line.2 { + y2 = 52.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 21.0mil + } + ha:line.3 { + y2 = 34.0mil + thickness = 10.75mil + x1 = 19.0mil + x2 = 28.0mil + y1 = 34.0mil + } + ha:line.4 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 28.0mil + x2 = 28.0mil + y1 = 34.0mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = 90.000000 + astart = 0.000000 + x = 10.0mil + y = 52.0mil + r = 10.0mil + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = -90.000000 + astart = 0.000000 + x = 10.0mil + y = 21.0mil + r = 10.0mil + } + } + height = 1.574801mm + } + ha:H { + width = 0.736601mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 62.0mil + } + ha:line.1 { + y2 = 34.0mil + thickness = 10.75mil + x1 = 28.0mil + x2 = 0.0 + y1 = 34.0mil + } + ha:line.2 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 29.0mil + x2 = 29.0mil + y1 = 62.0mil + } + } + height = 1.574801mm + } + ha:I { + width = 0.001um + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 62.0mil + } + } + height = 1.574801mm + } + ha:J { + width = 0.457201mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 18.0mil + x2 = 18.0mil + y1 = 52.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 8.0mil + x2 = 0.0 + y1 = 62.0mil + } + ha:simplearc.2 { + thickness = 10.75mil + adelta = 90.000000 + astart = 90.000000 + x = 8.0mil + y = 52.0mil + r = 10.0mil + } + } + height = 1.574801mm + } + ha:K { + width = 0.736601mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 62.0mil + } + ha:line.1 { + y2 = 42.0mil + thickness = 10.75mil + x1 = 29.0mil + x2 = 0.0 + y1 = 11.0mil + } + ha:line.2 { + y2 = 0.764963mm + thickness = 10.75mil + x1 = 29.0mil + x2 = 0.282363mm + y1 = 62.0mil + } + } + height = 1.574801mm + } + ha:L { + width = 0.558801mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 62.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 22.0mil + y1 = 62.0mil + } + } + height = 1.574801mm + } + ha:M { + width = 0.863601mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 62.0mil + } + ha:line.1 { + y2 = 40.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 17.0mil + y1 = 11.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 34.0mil + x2 = 34.0mil + y1 = 11.0mil + } + ha:line.3 { + y2 = 40.0mil + thickness = 10.75mil + x1 = 34.0mil + x2 = 17.0mil + y1 = 11.0mil + } + } + height = 1.574801mm + } + ha:&2f { + width = 0.558801mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 22.0mil + x2 = 0.0 + y1 = 11.0mil + } + } + height = 1.574801mm + } + ha:&3a { + width = 0.001um + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 31.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 33.0mil + } + ha:line.1 { + y2 = 54.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 56.0mil + } + } + height = 1.422401mm + } + ha:&3b { + width = 0.076201mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 56.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 3.0mil + y1 = 67.0mil + } + ha:line.1 { + y2 = 33.0mil + thickness = 10.75mil + x1 = 3.0mil + x2 = 3.0mil + y1 = 35.0mil + } + } + height = 1.701801mm + } + ha:&3d { + width = 0.584201mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 34.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 23.0mil + y1 = 34.0mil + } + ha:line.1 { + y2 = 51.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 23.0mil + y1 = 51.0mil + } + } + height = 1.295401mm + } + ha:O { + width = 0.736601mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 12.0mil + x2 = 17.0mil + y1 = 11.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 12.0mil + x2 = 17.0mil + y1 = 62.0mil + } + ha:line.2 { + y2 = 50.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 23.0mil + } + ha:line.3 { + y2 = 23.0mil + thickness = 10.75mil + x1 = 29.0mil + x2 = 29.0mil + y1 = 50.0mil + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = 90.000000 + astart = -180.000000 + x = 17.0mil + y = 23.0mil + r = 12.0mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = -90.000000 + astart = 180.000000 + x = 17.0mil + y = 50.0mil + r = 12.0mil + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = 90.000000 + astart = -0.000000 + x = 12.0mil + y = 50.0mil + r = 12.0mil + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = -90.000000 + astart = 0.000000 + x = 12.0mil + y = 23.0mil + r = 12.0mil + } + } + height = 1.574801mm + } + ha:P { + width = 0.711201mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 62.0mil + } + ha:line.1 { + y2 = 39.0mil + thickness = 10.75mil + x1 = 16.0mil + x2 = 0.0 + y1 = 39.0mil + } + ha:line.2 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 16.0mil + x2 = 0.0 + y1 = 11.0mil + } + ha:line.3 { + y2 = 27.0mil + thickness = 10.75mil + x1 = 28.0mil + x2 = 28.0mil + y1 = 23.0mil + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = 90.000000 + astart = -180.000000 + x = 16.0mil + y = 23.0mil + r = 12.0mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = -90.000000 + astart = 180.000000 + x = 16.0mil + y = 27.0mil + r = 12.0mil + } + } + height = 1.574801mm + } + ha:N { + width = 0.736601mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 62.0mil + } + ha:line.1 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 29.0mil + x2 = 29.0mil + y1 = 62.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 29.0mil + y1 = 11.0mil + } + } + height = 1.574801mm + } + ha:R { + width = 0.711201mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 62.0mil + } + ha:line.1 { + y2 = 39.0mil + thickness = 10.75mil + x1 = 16.0mil + x2 = 0.0 + y1 = 39.0mil + } + ha:line.2 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 16.0mil + x2 = 0.0 + y1 = 11.0mil + } + ha:line.3 { + y2 = 27.0mil + thickness = 10.75mil + x1 = 28.0mil + x2 = 28.0mil + y1 = 23.0mil + } + ha:line.4 { + y2 = 39.0mil + thickness = 10.75mil + x1 = 28.0mil + x2 = 17.0mil + y1 = 62.0mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = 90.000000 + astart = -180.000000 + x = 16.0mil + y = 23.0mil + r = 12.0mil + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = -90.000000 + astart = 180.000000 + x = 16.0mil + y = 27.0mil + r = 12.0mil + } + } + height = 1.574801mm + } + ha:S { + width = 0.736601mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 15.0mil + x2 = 21.0mil + y1 = 62.0mil + } + ha:line.1 { + y2 = 0.845249mm + thickness = 10.75mil + x1 = 0.583676mm + x2 = 0.200637mm + y1 = 1.042223mm + } + ha:line.2 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 11.0mil + x2 = 15.0mil + y1 = 11.0mil + } + ha:line.3 { + y2 = 52.0mil + thickness = 10.75mil + x1 = 29.0mil + x2 = 29.0mil + y1 = 54.0mil + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = 57.528808 + astart = 180.000000 + x = 16.0mil + y = 52.0mil + r = 13.0mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = 90.000000 + astart = 90.000000 + x = 21.0mil + y = 54.0mil + r = 8.0mil + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = 70.016893 + astart = 0.000000 + x = 12.0mil + y = 22.0mil + r = 12.0mil + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = -90.000000 + astart = 0.000000 + x = 11.0mil + y = 22.0mil + r = 11.0mil + } + ha:simplearc.8 { + thickness = 10.75mil + adelta = -30.068583 + astart = 270.000000 + x = 15.0mil + y = 33.0mil + r = 22.0mil + } + ha:simplearc.9 { + thickness = 10.75mil + adelta = -41.185925 + astart = 90.000000 + x = 15.0mil + y = 40.0mil + r = 22.0mil + } + } + height = 1.574801mm + } + ha:Q { + width = 0.889001mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 12.0mil + x2 = 17.0mil + y1 = 11.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 12.0mil + x2 = 17.0mil + y1 = 62.0mil + } + ha:line.2 { + y2 = 50.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 23.0mil + } + ha:line.3 { + y2 = 23.0mil + thickness = 10.75mil + x1 = 29.0mil + x2 = 29.0mil + y1 = 50.0mil + } + ha:line.4 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 23.0mil + x2 = 35.0mil + y1 = 51.0mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = 90.000000 + astart = -180.000000 + x = 17.0mil + y = 23.0mil + r = 12.0mil + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = -90.000000 + astart = 180.000000 + x = 17.0mil + y = 50.0mil + r = 12.0mil + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = 90.000000 + astart = -0.000000 + x = 12.0mil + y = 50.0mil + r = 12.0mil + } + ha:simplearc.8 { + thickness = 10.75mil + adelta = -90.000000 + astart = 0.000000 + x = 12.0mil + y = 23.0mil + r = 12.0mil + } + } + height = 1.574801mm + } + ha:U { + width = 0.736601mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 12.0mil + x2 = 16.0mil + y1 = 62.0mil + } + ha:line.1 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 49.0mil + } + ha:line.2 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 29.0mil + x2 = 29.0mil + y1 = 49.0mil + } + ha:simplearc.3 { + thickness = 10.75mil + adelta = -90.000000 + astart = 180.000000 + x = 16.0mil + y = 49.0mil + r = 13.0mil + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = 90.000000 + astart = 0.000000 + x = 13.0mil + y = 49.0mil + r = 13.0mil + } + } + height = 1.574801mm + } + ha:V { + width = 0.914401mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 18.0mil + y1 = 11.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 36.0mil + x2 = 18.0mil + y1 = 11.0mil + } + } + height = 1.574801mm + } + ha:T { + width = 0.736601mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 15.0mil + x2 = 15.0mil + y1 = 62.0mil + } + ha:line.1 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 29.0mil + y1 = 11.0mil + } + } + height = 1.574801mm + } + ha:X { + width = 0.889001mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 35.0mil + y1 = 11.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 35.0mil + x2 = 0.0 + y1 = 11.0mil + } + } + height = 1.574801mm + } + ha:Y { + width = 0.863601mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 35.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 17.0mil + y1 = 11.0mil + } + ha:line.1 { + y2 = 35.0mil + thickness = 10.75mil + x1 = 34.0mil + x2 = 17.0mil + y1 = 11.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 17.0mil + x2 = 17.0mil + y1 = 35.0mil + } + } + height = 1.574801mm + } + ha:W { + width = 1.117601mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 11.0mil + y1 = 11.0mil + } + ha:line.1 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 11.0mil + x2 = 22.0mil + y1 = 62.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 44.0mil + x2 = 33.0mil + y1 = 11.0mil + } + ha:line.3 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 33.0mil + x2 = 22.0mil + y1 = 62.0mil + } + } + height = 1.574801mm + } + ha:[ { + width = 0.152401mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 68.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 5.0mil + } + ha:line.1 { + y2 = 68.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 6.0mil + y1 = 68.0mil + } + ha:line.2 { + y2 = 5.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 6.0mil + y1 = 5.0mil + } + } + height = 1.727201mm + } + ha:^ { + width = 0.406401mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 0.0 + thickness = 10.75mil + x1 = 0.0 + x2 = 8.0mil + y1 = 9.0mil + } + ha:line.1 { + y2 = 0.0 + thickness = 10.75mil + x1 = 16.0mil + x2 = 8.0mil + y1 = 9.0mil + } + } + height = 0.228601mm + } + ha:Z { + width = 0.711201mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 28.0mil + y1 = 11.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 28.0mil + y1 = 62.0mil + } + ha:line.2 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 28.0mil + y1 = 62.0mil + } + } + height = 1.574801mm + } + ha:` { + width = 0.279401mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 10.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 11.0mil + y1 = 2.0mil + } + } + height = 0.254001mm + } + ha:_ { + width = 0.609601mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 68.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 24.0mil + y1 = 68.0mil + } + } + height = 1.727201mm + } + } + cell_width = 1.193801mm + cell_height = 2.032001mm + } +} Index: tags/1.0.5/font/aussiefont-sans-bold-oblique =================================================================== --- tags/1.0.5/font/aussiefont-sans-bold-oblique (nonexistent) +++ tags/1.0.5/font/aussiefont-sans-bold-oblique (revision 10414) @@ -0,0 +1,3897 @@ +li:pcb-rnd-font-v1 { + ha:geda_pcb { + id = 0 + ha:symbols { + ha:&09 { + width = 0.685801mm + delta = 0.103633mm + li:objects { + ha:line.0 { + y2 = 36.0mil + thickness = 3.0mil + x1 = 0.0 + x2 = 27.0mil + y1 = 36.0mil + } + ha:line.1 { + y2 = 30.0mil + thickness = 3.0mil + x1 = 27.0mil + x2 = 22.0mil + y1 = 36.0mil + } + ha:line.2 { + y2 = 42.0mil + thickness = 3.0mil + x1 = 27.0mil + x2 = 22.0mil + y1 = 36.0mil + } + ha:line.3 { + y2 = 42.0mil + thickness = 3.0mil + x1 = 0.0 + x2 = 5.0mil + y1 = 36.0mil + } + ha:line.4 { + y2 = 30.0mil + thickness = 3.0mil + x1 = 0.0 + x2 = 5.0mil + y1 = 36.0mil + } + } + height = 1.066801mm + } + ha:&0A { + width = 0.889001mm + delta = 10.0mil + li:objects { + ha:line.0 { + y2 = 10.0mil + thickness = 3.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 40.0mil + } + ha:line.1 { + y2 = 40.0mil + thickness = 3.0mil + x1 = 0.0 + x2 = 15.0mil + y1 = 40.0mil + } + ha:line.2 { + y2 = 45.0mil + thickness = 3.0mil + x1 = 20.0mil + x2 = 20.0mil + y1 = 75.0mil + } + ha:line.3 { + y2 = 45.0mil + thickness = 3.0mil + x1 = 20.0mil + x2 = 35.0mil + y1 = 45.0mil + } + ha:line.4 { + y2 = 60.0mil + thickness = 3.0mil + x1 = 20.0mil + x2 = 30.0mil + y1 = 60.0mil + } + } + height = 1.905001mm + } + ha:&0D { + width = 0.889001mm + delta = 0.253999mm + li:objects { + ha:line.0 { + y2 = 15.0mil + thickness = 3.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 35.0mil + } + ha:line.1 { + y2 = 10.0mil + thickness = 3.0mil + x1 = 5.0mil + x2 = 10.0mil + y1 = 10.0mil + } + ha:line.2 { + y2 = 40.0mil + thickness = 3.0mil + x1 = 5.0mil + x2 = 10.0mil + y1 = 40.0mil + } + ha:line.3 { + y2 = 45.0mil + thickness = 3.0mil + x1 = 20.0mil + x2 = 20.0mil + y1 = 75.0mil + } + ha:line.4 { + y2 = 45.0mil + thickness = 3.0mil + x1 = 20.0mil + x2 = 30.0mil + y1 = 45.0mil + } + ha:line.5 { + y2 = 60.0mil + thickness = 3.0mil + x1 = 20.0mil + x2 = 30.0mil + y1 = 60.0mil + } + ha:line.6 { + y2 = 55.0mil + thickness = 3.0mil + x1 = 35.0mil + x2 = 35.0mil + y1 = 50.0mil + } + ha:line.7 { + y2 = 75.0mil + thickness = 3.0mil + x1 = 30.0mil + x2 = 35.0mil + y1 = 60.0mil + } + ha:simplearc.8 { + thickness = 3.0mil + adelta = -90.000000 + astart = -90.000000 + x = 10.0mil + y = 15.0mil + r = 5.0mil + } + ha:simplearc.9 { + thickness = 3.0mil + adelta = 90.000000 + astart = 270.000000 + x = 5.0mil + y = 15.0mil + r = 5.0mil + } + ha:simplearc.10 { + thickness = 3.0mil + adelta = 90.000000 + astart = 90.000000 + x = 10.0mil + y = 35.0mil + r = 5.0mil + } + ha:simplearc.11 { + thickness = 3.0mil + adelta = -90.000000 + astart = 90.000000 + x = 5.0mil + y = 35.0mil + r = 5.0mil + } + ha:simplearc.12 { + thickness = 3.0mil + adelta = 90.000000 + astart = 90.000000 + x = 30.0mil + y = 55.0mil + r = 5.0mil + } + ha:simplearc.13 { + thickness = 3.0mil + adelta = -90.000000 + astart = -90.000000 + x = 30.0mil + y = 50.0mil + r = 5.0mil + } + } + height = 1.905001mm + } ha:] { + width = 0.415977mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 68.0mil + thickness = 10.75mil + x1 = 0.415976mm + x2 = 6.36mil + y1 = 5.0mil + } + ha:line.1 { + y2 = 68.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 6.36mil + y1 = 68.0mil + } + ha:line.2 { + y2 = 5.0mil + thickness = 10.75mil + x1 = 0.254432mm + x2 = 0.415976mm + y1 = 5.0mil + } + } + height = 1.727201mm + } + ha:&5c { + width = 0.38636mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.386359mm + y1 = 11.0mil + } + } + height = 1.574801mm + } + ha:b { + width = 0.731521mm + delta = 0.345606mm + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.210007mm + x2 = 0.0 + y1 = 10.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.457708mm + y1 = 62.0mil + } + ha:line.2 { + y2 = 56.0mil + thickness = 10.75mil + x1 = 0.730614mm + x2 = 0.643484mm + y1 = 0.863401mm + } + ha:line.3 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 0.137312mm + x2 = 0.59502mm + y1 = 28.0mil + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = 78.560593 + astart = 90.000000 + x = 0.457708mm + y = 54.52mil + r = 7.48mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = -96.605083 + astart = -90.000000 + x = 0.59502mm + y = 0.8477mm + r = 0.1365mm + } + } + height = 1.574801mm + } + ha:c { + width = 0.568417mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.134939mm + x2 = 0.431103mm + y1 = 62.0mil + } + ha:line.1 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 0.272252mm + x2 = 0.568416mm + y1 = 28.0mil + } + ha:line.2 { + y2 = 1.41732mm + thickness = 10.75mil + x1 = 0.08824mm + x2 = 0.00188mm + y1 = 34.0mil + } + ha:simplearc.3 { + thickness = 10.75mil + adelta = 78.560593 + astart = 270.000000 + x = 0.273812mm + y = 0.901192mm + r = 7.48mil + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = -96.605083 + astart = 90.000000 + x = 0.1365mm + y = 1.4383mm + r = 0.1365mm + } + } + height = 1.574801mm + } + ha:a { + width = 0.695301mm + delta = 0.345606mm + li:objects { + ha:line.0 { + y2 = 44.0mil + thickness = 10.75mil + x1 = 0.277365mm + x2 = 0.654301mm + y1 = 44.0mil + } + ha:line.1 { + y2 = 0.711217mm + thickness = 10.75mil + x1 = 0.207362mm + x2 = 0.56093mm + y1 = 28.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.692812mm + x2 = 0.581606mm + y1 = 0.873642mm + } + ha:line.3 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.16911mm + x2 = 0.581954mm + y1 = 62.0mil + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = 90.000000 + astart = 0.000000 + x = 6.7mil + y = 1.40462mm + r = 6.7mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = -90.000000 + astart = 0.000000 + x = 11.3mil + y = 1.40462mm + r = 11.3mil + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = -100.061922 + astart = 269.106007 + x = 22.0mil + y = 0.8477mm + r = 0.1365mm + } + } + height = 1.574801mm + } + ha:e { + width = 0.657861mm + delta = 0.345606mm + li:objects { + ha:line.0 { + y2 = 39.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.064618mm + y1 = 55.0mil + } + ha:line.1 { + y2 = 45.0mil + thickness = 10.75mil + x1 = 1.59mil + x2 = 24.91mil + y1 = 45.0mil + } + ha:line.2 { + y2 = 39.0mil + thickness = 10.75mil + x1 = 24.91mil + x2 = 0.656946mm + y1 = 45.0mil + } + ha:line.3 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.160198mm + x2 = 0.564058mm + y1 = 62.0mil + } + ha:line.4 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 15.5mil + x2 = 15.9mil + y1 = 28.0mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = -80.753887 + astart = 350.753887 + x = 15.5mil + y = 41.1mil + r = 0.33274mm + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = -95.826342 + astart = -90.000000 + x = 15.9mil + y = 38.0mil + r = 10.0mil + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = -96.270309 + astart = 90.000000 + x = 0.160198mm + y = 1.414602mm + r = 0.160198mm + } + } + height = 1.574801mm + } + ha:f { + width = 0.526365mm + delta = 0.478117mm + li:objects { + ha:line.0 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.457708mm + y1 = 28.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 7.95mil + x2 = 0.024232mm + y1 = 18.0mil + } + ha:line.2 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.418668mm + x2 = 0.526364mm + y1 = 11.0mil + } + ha:simplearc.3 { + thickness = 10.75mil + adelta = 78.560593 + astart = 270.000000 + x = 0.393852mm + y = 0.471932mm + r = 7.48mil + } + } + height = 1.574801mm + } + ha:d { + width = 0.805028mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.805027mm + x2 = 0.59502mm + y1 = 10.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.137312mm + x2 = 0.59502mm + y1 = 62.0mil + } + ha:line.2 { + y2 = 56.0mil + thickness = 10.75mil + x1 = 0.088849mm + x2 = 0.0 + y1 = 34.0mil + } + ha:line.3 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 0.274625mm + x2 = 0.732333mm + y1 = 28.0mil + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = 78.560593 + astart = 270.000000 + x = 0.276185mm + y = 0.901192mm + r = 7.48mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = -96.605083 + astart = 90.000000 + x = 0.138873mm + y = 1.4383mm + r = 0.1365mm + } + } + height = 1.574801mm + } + ha:h { + width = 0.733401mm + delta = 0.345606mm + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.210007mm + x2 = 0.0 + y1 = 10.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.732333mm + x2 = 0.619252mm + y1 = 34.0mil + } + ha:line.2 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 0.137312mm + x2 = 0.59502mm + y1 = 28.0mil + } + ha:simplearc.3 { + thickness = 10.75mil + adelta = -96.605083 + astart = 270.000000 + x = 23.5mil + y = 0.8477mm + r = 0.1365mm + } + } + height = 1.574801mm + } + ha:i { + width = 0.20597mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 14.0mil + thickness = 10.75mil + x1 = 0.205969mm + x2 = 0.193853mm + y1 = 11.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.137312mm + x2 = 0.0 + y1 = 28.0mil + } + } + height = 1.574801mm + } + ha:g { + width = 0.748488mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 0.56675mm + x2 = 0.748487mm + y1 = 73.0mil + } + ha:line.1 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 0.290779mm + x2 = 0.748487mm + y1 = 28.0mil + } + ha:line.2 { + y2 = 34.0mil + thickness = 10.75mil + x1 = 0.016154mm + x2 = 0.105004mm + y1 = 56.0mil + } + ha:line.3 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.153467mm + x2 = 0.611175mm + y1 = 62.0mil + } + ha:line.4 { + y2 = 80.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.350012mm + y1 = 80.0mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = 78.715635 + astart = 90.000000 + x = 0.350012mm + y = 71.28mil + r = 8.72mil + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = 78.560593 + astart = 270.000000 + x = 0.290779mm + y = 0.901192mm + r = 7.48mil + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = -96.605083 + astart = 90.000000 + x = 0.153467mm + y = 1.4383mm + r = 0.1365mm + } + } + height = 2.032001mm + } + ha:k { + width = 0.756565mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.205969mm + x2 = 0.0 + y1 = 11.0mil + } + ha:line.1 { + y2 = 46.0mil + thickness = 10.75mil + x1 = 0.756564mm + x2 = 0.064618mm + y1 = 28.0mil + } + ha:line.2 { + y2 = 0.967678mm + thickness = 10.75mil + x1 = 0.619252mm + x2 = 0.3684mm + y1 = 62.0mil + } + } + height = 1.574801mm + } + ha:l { + width = 0.19006mm + delta = 0.452666mm + li:objects { + ha:line.0 { + y2 = 1.433012mm + thickness = 10.75mil + x1 = 0.190059mm + x2 = 0.0 + y1 = 11.0mil + } + ha:simplearc.1 { + thickness = 10.75mil + adelta = 61.228002 + astart = 0.000000 + x = 0.16002mm + y = 1.433012mm + r = 0.16002mm + } + } + height = 1.573277mm + } + ha:j { + width = 0.495971mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 14.0mil + thickness = 10.75mil + x1 = 0.49597mm + x2 = 0.483855mm + y1 = 11.0mil + } + ha:line.1 { + y2 = 72.0mil + thickness = 10.75mil + x1 = 0.424774mm + x2 = 0.247076mm + y1 = 28.0mil + } + ha:simplearc.2 { + thickness = 10.75mil + adelta = -62.238442 + astart = 160.839827 + x = -0.046345mm + y = 68.0mil + r = 0.30988mm + } + } + height = 2.033595mm + } + ha:n { + width = 0.720218mm + delta = 0.345986mm + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.137312mm + x2 = 0.0 + y1 = 28.0mil + } + ha:line.1 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 0.137312mm + x2 = 0.534568mm + y1 = 28.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 28.355mil + x2 = 0.619252mm + y1 = 37.0mil + } + ha:simplearc.3 { + thickness = 10.75mil + adelta = -96.309371 + astart = -90.000000 + x = 0.514248mm + y = 0.916788mm + r = 0.205588mm + } + } + height = 1.574801mm + } + ha:o { + width = 0.665796mm + delta = 0.345606mm + li:objects { + ha:line.0 { + y2 = 39.0mil + thickness = 10.75mil + x1 = 0.527um + x2 = 0.047351mm + y1 = 1.315513mm + } + ha:line.1 { + y2 = 1.30302mm + thickness = 10.75mil + x1 = 0.665269mm + x2 = 0.618445mm + y1 = 0.975567mm + } + ha:simplearc.2 { + thickness = 10.75mil + adelta = 1.505021 + astart = 2.060728 + x = 1.718468mm + y = 1.25476mm + r = 67.7mil + } + ha:simplearc.3 { + thickness = 10.75mil + adelta = -79.646680 + astart = 90.000000 + x = 0.265588mm + y = 51.7mil + r = 0.26924mm + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = 77.035491 + astart = 90.000000 + x = 0.265588mm + y = 48.0mil + r = 14.3mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = 1.505021 + astart = 182.060728 + x = -1.052672mm + y = 1.03886mm + r = 67.7mil + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = -79.646680 + astart = -90.000000 + x = 0.400208mm + y = 38.6mil + r = 0.26924mm + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = 77.035491 + astart = -90.000000 + x = 0.400208mm + y = 1.07442mm + r = 14.3mil + } + } + height = 1.582421mm + } + ha:m { + width = 1.016382mm + delta = 0.345986mm + li:objects { + ha:line.0 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 0.137312mm + x2 = 0.810412mm + y1 = 28.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 40.015mil + x2 = 0.915416mm + y1 = 37.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.137312mm + x2 = 0.0 + y1 = 28.0mil + } + ha:line.3 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.59502mm + x2 = 0.457708mm + y1 = 28.0mil + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = -96.309371 + astart = -90.000000 + x = 0.810412mm + y = 0.916788mm + r = 0.205588mm + } + } + height = 1.574801mm + } + ha:q { + width = 0.732334mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 0.522326mm + x2 = 0.732333mm + y1 = 80.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.137312mm + x2 = 0.59502mm + y1 = 62.0mil + } + ha:line.2 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 0.732333mm + x2 = 0.274625mm + y1 = 28.0mil + } + ha:line.3 { + y2 = 56.6mil + thickness = 10.75mil + x1 = 0.088849mm + x2 = 0.0 + y1 = 34.0mil + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = 78.560593 + astart = 270.000000 + x = 10.8119685mil + y = 0.901192mm + r = 7.48mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = -96.605083 + astart = 90.000000 + x = 0.137312mm + y = 1.4383mm + r = 0.1365mm + } + } + height = 2.032001mm + } + ha:r { + width = 0.570841mm + delta = 0.345606mm + li:objects { + ha:line.0 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.137312mm + y1 = 62.0mil + } + ha:line.1 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 0.137312mm + x2 = 0.433476mm + y1 = 28.0mil + } + ha:simplearc.2 { + thickness = 10.75mil + adelta = -96.605083 + astart = 270.000000 + x = 17.1mil + y = 0.8477mm + r = 0.1365mm + } + } + height = 1.574801mm + } + ha:p { + width = 0.805181mm + delta = 0.346417mm + li:objects { + ha:line.0 { + y2 = 80.0mil + thickness = 10.75mil + x1 = 0.210007mm + x2 = 0.0 + y1 = 28.0mil + } + ha:line.1 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 0.210007mm + x2 = 0.667715mm + y1 = 28.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.072695mm + x2 = 0.530403mm + y1 = 62.0mil + } + ha:line.3 { + y2 = 0.84836mm + thickness = 10.75mil + x1 = 0.716774mm + x2 = 0.80518mm + y1 = 1.422489mm + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = -96.605083 + astart = 270.000000 + x = 0.667868mm + y = 0.8477mm + r = 0.1365mm + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = 78.560593 + astart = 90.000000 + x = 0.530556mm + y = 54.52mil + r = 7.48mil + } + } + height = 2.032001mm + } + ha:t { + width = 0.457709mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.2302mm + x2 = 0.024232mm + y1 = 11.0mil + } + ha:line.1 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.457708mm + y1 = 28.0mil + } + } + height = 1.574801mm + } + ha:u { + width = 0.730175mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 1.422599mm + thickness = 10.75mil + x1 = 0.110922mm + x2 = 0.906um + y1 = 28.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.1365mm + x2 = 0.592862mm + y1 = 62.0mil + } + ha:line.2 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 0.592862mm + x2 = 0.730174mm + y1 = 62.0mil + } + ha:simplearc.3 { + thickness = 10.75mil + adelta = -96.605083 + astart = 90.000000 + x = 0.1365mm + y = 1.4383mm + r = 0.1365mm + } + } + height = 1.574801mm + } + ha:s { + width = 0.678282mm + delta = 0.345606mm + li:objects { + ha:line.0 { + y2 = 1.14046mm + thickness = 10.75mil + x1 = 0.243891mm + x2 = 0.452171mm + y1 = 44.0mil + } + ha:simplearc.1 { + thickness = 10.75mil + adelta = 90.000000 + astart = 180.000000 + x = 0.454711mm + y = 52.2mil + r = 0.18542mm + } + ha:simplearc.2 { + thickness = 10.75mil + adelta = -16.619264 + astart = 90.000000 + x = 0.398831mm + y = 0.17272mm + r = 1.39446mm + } + ha:simplearc.3 { + thickness = 10.75mil + adelta = -90.000000 + astart = 180.000000 + x = 0.398831mm + y = 52.2mil + r = 0.240697mm + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = -16.619264 + astart = -90.000000 + x = 0.279451mm + y = 82.9mil + r = 1.39446mm + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = -90.000000 + astart = 0.000000 + x = 0.279451mm + y = 36.7mil + r = 0.22098mm + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = 90.000000 + astart = 0.000000 + x = 0.243891mm + y = 36.7mil + r = 0.18542mm + } + } + height = 1.567181mm + } + ha:w { + width = 0.969265mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.105004mm + y1 = 28.0mil + } + ha:line.1 { + y2 = 40.0mil + thickness = 10.75mil + x1 = 0.105004mm + x2 = 0.436169mm + y1 = 62.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.969264mm + x2 = 0.589636mm + y1 = 28.0mil + } + ha:line.3 { + y2 = 40.0mil + thickness = 10.75mil + x1 = 0.589636mm + x2 = 0.436169mm + y1 = 62.0mil + } + } + height = 1.574801mm + } + ha:x { + width = 0.729641mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.137312mm + x2 = 23.32mil + y1 = 28.0mil + } + ha:line.1 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.72964mm + y1 = 62.0mil + } + } + height = 1.574801mm + } + ha:v { + width = 0.592329mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.158852mm + y1 = 28.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 23.32mil + x2 = 0.158852mm + y1 = 28.0mil + } + } + height = 1.574801mm + } + ha:z { + width = 0.729641mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 0.137312mm + x2 = 0.72964mm + y1 = 28.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.72964mm + x2 = 0.0 + y1 = 28.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 23.32mil + y1 = 62.0mil + } + } + height = 1.574801mm + } + ha:~ { + width = 0.623277mm + delta = 0.345606mm + li:objects { + ha:simplearc.0 { + thickness = 10.75mil + adelta = 51.095862 + astart = 90.000000 + x = 0.471077mm + y = 0.764957mm + r = 7.7mil + } + ha:simplearc.1 { + thickness = 10.75mil + adelta = -48.632951 + astart = 90.000000 + x = 0.471077mm + y = 0.742097mm + r = 0.21844mm + } + ha:simplearc.2 { + thickness = 10.75mil + adelta = 51.095862 + astart = -90.000000 + x = 0.1522mm + y = 40.0mil + r = 7.7mil + } + ha:simplearc.3 { + thickness = 10.75mil + adelta = -48.632951 + astart = -90.000000 + x = 0.1522mm + y = 1.03886mm + r = 0.21844mm + } + } + height = 0.960538mm + } + ha:y { + width = 0.82926mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.210007mm + x2 = 0.395783mm + y1 = 28.0mil + } + ha:line.1 { + y2 = 80.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 6.36mil + y1 = 80.0mil + } + ha:line.2 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 6.36mil + x2 = 0.829259mm + y1 = 80.0mil + } + } + height = 2.032001mm + } + ha:&7d { + width = 0.425665mm + delta = 0.345606mm + li:objects { + ha:line.0 { + y2 = 0.256341mm + thickness = 10.75mil + x1 = 0.285812mm + x2 = 0.366516mm + y1 = 30.0mil + } + ha:line.1 { + y2 = 1.030105mm + thickness = 10.75mil + x1 = 0.160158mm + x2 = 0.247703mm + y1 = 1.56972mm + } + ha:simplearc.2 { + thickness = 10.75mil + adelta = -90.000000 + astart = 90.000000 + x = 0.425664mm + y = 0.77216mm + r = 5.5mil + } + ha:simplearc.3 { + thickness = 10.75mil + adelta = 67.203479 + astart = 270.000000 + x = 0.425664mm + y = 43.5mil + r = 0.19304mm + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = 70.509921 + astart = 98.050671 + x = -0.026608mm + y = 60.42mil + r = 7.48mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = -85.868748 + astart = 259.263665 + x = 0.232624mm + y = 0.23556mm + r = 0.1365mm + } + } + height = 1.722788mm + } + ha:| { + width = 0.274626mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 71.0mil + thickness = 10.75mil + x1 = 0.113081mm + x2 = 0.0 + y1 = 43.0mil + } + ha:line.1 { + y2 = 3.0mil + thickness = 10.75mil + x1 = 6.36mil + x2 = 0.274625mm + y1 = 31.0mil + } + } + height = 1.803401mm + } + ha:&7b { + width = 0.425665mm + delta = 0.345606mm + li:objects { + ha:line.0 { + y2 = 1.569919mm + thickness = 10.75mil + x1 = 0.139853mm + x2 = 0.059149mm + y1 = 1.06426mm + } + ha:line.1 { + y2 = 0.796155mm + thickness = 10.75mil + x1 = 0.265507mm + x2 = 0.177962mm + y1 = 0.25654mm + } + ha:simplearc.2 { + thickness = 10.75mil + adelta = -90.000000 + astart = -90.000000 + x = 0.001um + y = 41.5mil + r = 5.5mil + } + ha:simplearc.3 { + thickness = 10.75mil + adelta = 67.203479 + astart = 90.000000 + x = 0.001um + y = 0.72136mm + r = 0.19304mm + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = 70.509921 + astart = 278.050671 + x = 0.452273mm + y = 11.48mil + r = 7.48mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = -85.868748 + astart = 79.263665 + x = 0.193041mm + y = 1.5907mm + r = 0.1365mm + } + } + height = 1.724811mm + } + ha:&20 { + width = 0.0 + delta = 0.9874mm + li:objects { + } + height = 0.0 + } + ha:&23 { + width = 1.010997mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.379628mm + x2 = 0.17366mm + y1 = 11.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.837336mm + x2 = 0.631368mm + y1 = 11.0mil + } + ha:line.2 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 0.068656mm + x2 = 1.010996mm + y1 = 28.0mil + } + ha:line.3 { + y2 = 45.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 37.1mil + y1 = 45.0mil + } + } + height = 1.574801mm + } + ha:&26 { + width = 0.955782mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 1.266107mm + thickness = 10.75mil + x1 = 0.613237mm + x2 = 0.029851mm + y1 = 0.592539mm + } + ha:line.1 { + y2 = 0.58928mm + thickness = 10.75mil + x1 = 0.725581mm + x2 = 8.9mil + y1 = 62.0mil + } + ha:line.2 { + y2 = 45.0mil + thickness = 10.75mil + x1 = 0.26015mm + x2 = 0.955781mm + y1 = 1.564839mm + } + ha:line.3 { + y2 = 11.4mil + thickness = 10.75mil + x1 = 18.8mil + x2 = 16.1mil + y1 = 0.289578mm + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = -114.341090 + astart = 24.341090 + x = 16.6mil + y = 19.8mil + r = 8.4mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = -132.075532 + astart = 270.806929 + x = 0.48006mm + y = 18.5mil + r = 0.18034mm + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = -30.398728 + astart = 0.000000 + x = 0.22098mm + y = 54.2mil + r = 0.22098mm + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = -108.245855 + astart = 108.245855 + x = 0.19812mm + y = 54.2mil + r = 0.19812mm + } + } + height = 1.574801mm + } + ha:! { + width = 0.20597mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 45.0mil + thickness = 10.75mil + x1 = 0.205969mm + x2 = 0.068656mm + y1 = 11.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.012116mm + x2 = 0.0 + y1 = 59.0mil + } + } + height = 1.574801mm + } + ha:" { + width = 0.529058mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 0.0 + thickness = 10.75mil + x1 = 0.0 + x2 = 0.125197mm + y1 = 11.0mil + } + ha:line.1 { + y2 = 0.0 + thickness = 10.75mil + x1 = 15.9mil + x2 = 0.529057mm + y1 = 11.0mil + } + } + height = 0.279401mm + } + ha:$ { + width = 0.76017mm + delta = 0.345606mm + li:objects { + ha:line.0 { + y2 = 39.74mil + thickness = 10.75mil + x1 = 0.244948mm + x2 = 0.536057mm + y1 = 0.852937mm + } + ha:line.1 { + y2 = 1.573276mm + thickness = 10.75mil + x1 = 0.494147mm + x2 = 0.288178mm + y1 = 0.277876mm + } + ha:simplearc.2 { + thickness = 10.75mil + adelta = -13.889035 + astart = 270.825530 + x = 0.362305mm + y = 2.190496mm + r = 1.76022mm + } + ha:simplearc.3 { + thickness = 10.75mil + adelta = 63.145579 + astart = 0.000000 + x = 0.347065mm + y = 25.64mil + r = 8.9mil + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = -90.000000 + astart = 0.000000 + x = 0.336905mm + y = 0.648716mm + r = 8.5mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = -13.889035 + astart = 90.825530 + x = 0.397865mm + y = -0.339344mm + r = 1.76022mm + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = 57.355360 + astart = 180.000000 + x = 0.413105mm + y = 47.24mil + r = 8.9mil + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = -90.000000 + astart = 180.000000 + x = 0.423265mm + y = 47.34mil + r = 8.5mil + } + } + height = 1.573277mm + } + ha:% { + width = 1.444474mm + delta = 0.479744mm + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 1.444473mm + x2 = 0.0 + y1 = 11.0mil + } + ha:simplearc.1 { + thickness = 10.75mil + adelta = 92.779167 + astart = 267.220833 + x = 42.7mil + y = 1.39192mm + r = 10.4mil + } + ha:simplearc.2 { + thickness = 10.75mil + adelta = 94.398705 + astart = 180.000000 + x = 44.2mil + y = 51.6mil + r = 7.2mil + } + ha:simplearc.3 { + thickness = 10.75mil + adelta = 92.779167 + astart = 87.220833 + x = 41.0mil + y = 51.7mil + r = 10.4mil + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = 94.398705 + astart = 0.000000 + x = 39.5mil + y = 1.39446mm + r = 7.2mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = 92.779167 + astart = 267.220833 + x = 17.1mil + y = 21.5mil + r = 10.4mil + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = 94.398705 + astart = 180.000000 + x = 18.6mil + y = 18.3mil + r = 7.2mil + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = 92.779167 + astart = 87.220833 + x = 15.4mil + y = 0.46736mm + r = 10.4mil + } + ha:simplearc.8 { + thickness = 10.75mil + adelta = 94.398705 + astart = 0.000000 + x = 13.9mil + y = 21.6mil + r = 7.2mil + } + } + height = 1.577341mm + } + ha:' { + width = 0.125198mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 0.0 + thickness = 10.75mil + x1 = 0.0 + x2 = 0.125197mm + y1 = 11.0mil + } + } + height = 0.279401mm + } + ha:( { + width = 0.336347mm + delta = 0.345606mm + li:objects { + ha:line.0 { + y2 = 1.2787mm + thickness = 10.75mil + x1 = 0.101022mm + x2 = 0.00636mm + y1 = 0.655586mm + } + ha:simplearc.1 { + thickness = 10.75mil + adelta = -32.083745 + astart = 352.278174 + x = 45.2mil + y = 0.79756mm + r = 41.6mil + } + ha:simplearc.2 { + thickness = 10.75mil + adelta = 31.611030 + astart = 352.937397 + x = 33.0mil + y = 1.38176mm + r = 33.0mil + } + } + height = 1.730001mm + } + ha:) { + width = 0.336348mm + delta = 0.345606mm + li:objects { + ha:line.0 { + y2 = 0.574696mm + thickness = 10.75mil + x1 = 0.235325mm + x2 = 0.329987mm + y1 = 1.19781mm + } + ha:simplearc.1 { + thickness = 10.75mil + adelta = -32.083745 + astart = 172.278174 + x = -0.811733mm + y = 1.055836mm + r = 41.6mil + } + ha:simplearc.2 { + thickness = 10.75mil + adelta = 31.611030 + astart = 172.937397 + x = -0.501853mm + y = 0.471636mm + r = 33.0mil + } + } + height = 1.732281mm + } + ha:* { + width = 0.592329mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 51.0mil + thickness = 10.75mil + x1 = 0.117119mm + x2 = 0.479247mm + y1 = 34.0mil + } + ha:line.1 { + y2 = 43.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 23.32mil + y1 = 43.0mil + } + ha:line.2 { + y2 = 51.0mil + thickness = 10.75mil + x1 = 0.547903mm + x2 = 0.048463mm + y1 = 34.0mil + } + } + height = 1.295401mm + } + ha:+ { + width = 0.592329mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 43.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 23.32mil + y1 = 43.0mil + } + ha:line.1 { + y2 = 54.0mil + thickness = 10.75mil + x1 = 0.340589mm + x2 = 0.251739mm + y1 = 32.0mil + } + } + height = 1.371601mm + } + ha:, { + width = 0.125198mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 65.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.125197mm + y1 = 76.0mil + } + } + height = 1.930401mm + } + ha:- { + width = 0.592329mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 42.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 23.32mil + y1 = 42.0mil + } + } + height = 1.066801mm + } + ha:. { + width = 0.018713mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 60.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.018712mm + y1 = 1.60782mm + } + } + height = 1.607821mm + } + ha:0 { + width = 0.670561mm + delta = 0.345606mm + li:objects { + ha:simplearc.0 { + thickness = 10.75mil + adelta = -59.264512 + astart = 90.000000 + x = 8.5mil + y = 1.45542mm + r = 0.11684mm + } + ha:simplearc.1 { + thickness = 10.75mil + adelta = 43.667780 + astart = 90.000000 + x = 8.5mil + y = 1.34112mm + r = 0.23114mm + } + ha:simplearc.2 { + thickness = 10.75mil + adelta = -43.549373 + astart = 180.000000 + x = -0.39624mm + y = 0.77216mm + r = 42.0mil + } + ha:simplearc.3 { + thickness = 10.75mil + adelta = 30.353941 + astart = 180.000000 + x = -0.20574mm + y = 0.77216mm + r = 34.5mil + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = -59.264512 + astart = -90.000000 + x = 0.45466mm + y = 0.39624mm + r = 0.11684mm + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = 43.667780 + astart = -90.000000 + x = 0.45466mm + y = 20.1mil + r = 0.23114mm + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = -43.549373 + astart = 0.000000 + x = 42.0mil + y = 42.5mil + r = 42.0mil + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = 30.353941 + astart = 0.000000 + x = 34.5mil + y = 42.5mil + r = 34.5mil + } + } + height = 1.572261mm + } + ha:1 { + width = 0.34059mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.340589mm + y1 = 22.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.340589mm + x2 = 0.13462mm + y1 = 11.0mil + } + } + height = 1.574801mm + } + ha:2 { + width = 0.780023mm + delta = 0.345606mm + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 23.32mil + y1 = 62.0mil + } + ha:line.1 { + y2 = 0.721548mm + thickness = 10.75mil + x1 = 0.0 + x2 = 0.717149mm + y1 = 62.0mil + } + ha:simplearc.2 { + thickness = 10.75mil + adelta = 59.379667 + astart = -90.000000 + x = 0.522471mm + y = 0.700881mm + r = 0.420871mm + } + ha:simplearc.3 { + thickness = 10.75mil + adelta = -37.733329 + astart = 180.000000 + x = 0.479383mm + y = 0.537561mm + r = 0.300639mm + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = -90.000000 + astart = -90.000000 + x = 0.522471mm + y = 0.537561mm + r = 0.257551mm + } + } + height = 1.574801mm + } + ha:3 { + width = 0.787401mm + delta = 0.345606mm + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.205969mm + x2 = 0.555981mm + y1 = 11.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 11.66mil + y1 = 62.0mil + } + ha:line.2 { + y2 = 34.0mil + thickness = 10.75mil + x1 = 0.47682mm + x2 = 0.436169mm + y1 = 0.866301mm + } + ha:line.3 { + y2 = 34.0mil + thickness = 10.75mil + x1 = 0.247701mm + x2 = 0.463093mm + y1 = 34.0mil + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = 56.309932 + astart = 90.000000 + x = 15.8mil + y = 19.0mil + r = 15.0mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = -41.427263 + astart = 180.000000 + x = 0.510819mm + y = 0.510819mm + r = 0.276581mm + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = -90.000000 + astart = -90.000000 + x = 0.555981mm + y = 0.510819mm + r = 0.231419mm + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = 67.453710 + astart = 90.000000 + x = 11.66mil + y = 1.203249mm + r = 0.371551mm + } + ha:simplearc.8 { + thickness = 10.75mil + adelta = -17.603639 + astart = 180.000000 + x = -0.196911mm + y = 1.074185mm + r = 0.881615mm + } + ha:simplearc.9 { + thickness = 10.75mil + adelta = -90.000000 + astart = -90.000000 + x = 0.47682mm + y = 1.074185mm + r = 0.207884mm + } + } + height = 1.574801mm + } + ha:4 { + width = 0.753873mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 51.0mil + thickness = 10.75mil + x1 = 0.457708mm + x2 = 0.0 + y1 = 11.0mil + } + ha:line.1 { + y2 = 51.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.753872mm + y1 = 51.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.560019mm + x2 = 0.467131mm + y1 = 39.0mil + } + } + height = 1.574801mm + } + ha:5 { + width = 0.825222mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.825221mm + x2 = 0.205969mm + y1 = 11.0mil + } + ha:line.1 { + y2 = 34.0mil + thickness = 10.75mil + x1 = 0.205969mm + x2 = 0.113081mm + y1 = 11.0mil + } + ha:line.2 { + y2 = 34.0mil + thickness = 10.75mil + x1 = 0.113081mm + x2 = 0.409245mm + y1 = 34.0mil + } + ha:line.3 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.380498mm + x2 = 0.0 + y1 = 1.573394mm + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = -70.344464 + astart = 180.000000 + x = 0.225755mm + y = 1.140155mm + r = 0.460045mm + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = -90.000000 + astart = -90.000000 + x = 0.409245mm + y = 1.140155mm + r = 0.276555mm + } + } + height = 1.574801mm + } + ha:6 { + width = 0.651562mm + delta = 0.345606mm + li:objects { + ha:line.0 { + y2 = 34.0mil + thickness = 10.75mil + x1 = 0.072695mm + x2 = 0.422707mm + y1 = 34.0mil + } + ha:line.1 { + y2 = 52.0mil + thickness = 10.75mil + x1 = 4.0mil + x2 = 0.0 + y1 = 27.0mil + } + ha:line.2 { + y2 = 1.092454mm + thickness = 10.75mil + x1 = 0.614373mm + x2 = 0.651561mm + y1 = 1.319923mm + } + ha:line.3 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.228854mm + x2 = 0.309626mm + y1 = 62.0mil + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = -68.630916 + astart = 342.245445 + x = 0.656895mm + y = 34.0mil + r = 23.0mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = -96.270387 + astart = 90.000000 + x = 0.228854mm + y = 52.99mil + r = 0.228854mm + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = 79.815149 + astart = 90.000000 + x = 0.309626mm + y = 49.81mil + r = 0.309626mm + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = -90.000000 + astart = -90.000000 + x = 0.422707mm + y = 1.092454mm + r = 0.228854mm + } + } + height = 1.574801mm + } + ha:7 { + width = 0.643485mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.024232mm + y1 = 17.0mil + } + ha:line.1 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.024232mm + x2 = 0.643484mm + y1 = 11.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.643484mm + x2 = 5.565mil + y1 = 11.0mil + } + } + height = 1.574801mm + } + ha:8 { + width = 0.751841mm + delta = 0.345606mm + li:objects { + ha:line.0 { + y2 = 53.0mil + thickness = 10.75mil + x1 = 2.0mil + x2 = 0.0 + y1 = 42.0mil + } + ha:line.1 { + y2 = 34.0mil + thickness = 10.75mil + x1 = 0.341935mm + x2 = 0.449631mm + y1 = 34.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.228854mm + x2 = 13.25mil + y1 = 62.0mil + } + ha:line.3 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.434823mm + x2 = 0.542519mm + y1 = 11.0mil + } + ha:line.4 { + y2 = 0.687656mm + thickness = 10.75mil + x1 = 29.6mil + x2 = 0.714565mm + y1 = 20.0mil + } + ha:line.5 { + y2 = 25.0mil + thickness = 10.75mil + x1 = 0.173241mm + x2 = 0.135966mm + y1 = 0.455344mm + } + ha:line.6 { + y2 = 1.372325mm + thickness = 10.75mil + x1 = 27.0mil + x2 = 0.636795mm + y1 = 1.092454mm + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = 67.850877 + astart = 90.000000 + x = 0.452983mm + y = 0.581177mm + r = 0.282423mm + } + ha:simplearc.8 { + thickness = 10.75mil + adelta = 85.179363 + astart = 180.000000 + x = 20.6mil + y = 20.0mil + r = 9.0mil + } + ha:simplearc.9 { + thickness = 10.75mil + adelta = 67.850877 + astart = -90.000000 + x = 0.434823mm + y = 0.561823mm + r = 0.282423mm + } + ha:simplearc.10 { + thickness = 10.75mil + adelta = 90.000000 + astart = 0.000000 + x = 0.364566mm + y = 25.0mil + r = 9.0mil + } + ha:simplearc.11 { + thickness = 10.75mil + adelta = -90.000000 + astart = 270.000000 + x = 0.456946mm + y = 1.092454mm + r = 0.228854mm + } + ha:simplearc.12 { + thickness = 10.75mil + adelta = 67.988717 + astart = 270.000000 + x = 0.351045mm + y = 46.77854331mil + r = 12.75mil + } + ha:simplearc.13 { + thickness = 10.75mil + adelta = 67.988717 + astart = 90.000000 + x = 13.25mil + y = 49.25mil + r = 12.75mil + } + ha:simplearc.14 { + thickness = 10.75mil + adelta = -90.000000 + astart = 90.000000 + x = 0.228854mm + y = 52.99mil + r = 0.228854mm + } + } + height = 1.574801mm + } + ha:9 { + width = 0.651562mm + delta = 0.345606mm + li:objects { + ha:line.0 { + y2 = 0.990238mm + thickness = 10.75mil + x1 = 0.228854mm + x2 = 0.578866mm + y1 = 0.990238mm + } + ha:line.1 { + y2 = 0.533038mm + thickness = 10.75mil + x1 = 0.549961mm + x2 = 0.651561mm + y1 = 1.168038mm + } + ha:line.2 { + y2 = 0.761384mm + thickness = 10.75mil + x1 = 0.037188mm + x2 = 0.0 + y1 = 0.533915mm + } + ha:line.3 { + y2 = 0.279038mm + thickness = 10.75mil + x1 = 0.341935mm + x2 = 0.422707mm + y1 = 0.279038mm + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = -68.630916 + astart = 162.245445 + x = -0.21mil + y = 0.990238mm + r = 23.0mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = -96.270387 + astart = 270.000000 + x = 0.422707mm + y = 0.507892mm + r = 0.228854mm + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = 79.815149 + astart = 270.000000 + x = 0.341935mm + y = 0.588664mm + r = 0.309626mm + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = -90.000000 + astart = 90.000000 + x = 0.228854mm + y = 0.761384mm + r = 0.228854mm + } + } + height = 1.573276mm + } + ha:< { + width = 0.624638mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 34.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.624637mm + y1 = 42.0mil + } + ha:line.1 { + y2 = 50.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.560019mm + y1 = 42.0mil + } + } + height = 1.270001mm + } + ha:> { + width = 0.624638mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 34.0mil + thickness = 10.75mil + x1 = 0.624637mm + x2 = 0.064618mm + y1 = 42.0mil + } + ha:line.1 { + y2 = 50.0mil + thickness = 10.75mil + x1 = 0.624637mm + x2 = 0.0 + y1 = 42.0mil + } + } + height = 1.270001mm + } + ha:? { + width = 0.605773mm + delta = 0.345606mm + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.140432mm + x2 = 0.132355mm + y1 = 60.0mil + } + ha:line.1 { + y2 = 38.6mil + thickness = 10.75mil + x1 = 0.201011mm + x2 = 0.227312mm + y1 = 1.14046mm + } + ha:line.2 { + y2 = 0.567117mm + thickness = 10.75mil + x1 = 0.531535mm + x2 = 0.576337mm + y1 = 0.636503mm + } + ha:line.3 { + y2 = 27.8mil + thickness = 10.75mil + x1 = 0.372092mm + x2 = 0.458452mm + y1 = 30.3mil + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = 17.272585 + astart = -90.000000 + x = 0.417812mm + y = 66.4mil + r = 1.40716mm + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = -20.872164 + astart = 145.218995 + x = 0.325574mm + y = 0.493457mm + r = 0.250763mm + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = -33.690068 + astart = 180.000000 + x = 0.430512mm + y = 18.5mil + r = 6.9mil + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = -41.552840 + astart = 345.768542 + x = 0.577832mm + y = 42.1mil + r = 14.3mil + } + ha:simplearc.8 { + thickness = 10.75mil + adelta = -90.000000 + astart = -90.000000 + x = 0.417812mm + y = 0.46736mm + r = 7.4mil + } + } + height = 1.574801mm + } + ha:@ { + width = 1.37171mm + delta = 0.346146mm + li:objects { + ha:line.0 { + y2 = 26.0mil + thickness = 10.75mil + x1 = 0.413824mm + x2 = 0.498635mm + y1 = 47.0mil + } + ha:line.1 { + y2 = 19.0mil + thickness = 10.75mil + x1 = 0.715373mm + x2 = 0.984613mm + y1 = 19.0mil + } + ha:line.2 { + y2 = 47.0mil + thickness = 10.75mil + x1 = 0.984613mm + x2 = 0.871532mm + y1 = 19.0mil + } + ha:line.3 { + y2 = 2.0mil + thickness = 10.75mil + x1 = 0.676333mm + x2 = 0.972497mm + y1 = 2.0mil + } + ha:line.4 { + y2 = 1.41732mm + thickness = 10.75mil + x1 = 0.149969mm + x2 = 0.003538mm + y1 = 19.0mil + } + ha:line.5 { + y2 = 0.42926mm + thickness = 10.75mil + x1 = 1.248468mm + x2 = 1.371709mm + y1 = 47.0mil + } + ha:line.6 { + y2 = 70.9mil + thickness = 10.75mil + x1 = 0.25654mm + x2 = 0.44958mm + y1 = 70.0mil + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = -90.000000 + astart = 90.000000 + x = 41.0mil + y = 47.2mil + r = 0.17272mm + } + ha:simplearc.8 { + thickness = 10.75mil + adelta = 80.073754 + astart = 90.000000 + x = 41.0mil + y = 1.16332mm + r = 0.20828mm + } + ha:simplearc.9 { + thickness = 10.75mil + adelta = 70.448005 + astart = 90.000000 + x = 23.5mil + y = 42.5mil + r = 0.29464mm + } + ha:simplearc.10 { + thickness = 10.75mil + adelta = -90.000000 + astart = 90.000000 + x = 23.5mil + y = 1.19126mm + r = 7.2mil + } + ha:simplearc.11 { + thickness = 10.75mil + adelta = 87.153067 + astart = 351.448170 + x = 0.32004mm + y = 57.7mil + r = 0.32004mm + } + ha:simplearc.12 { + thickness = 10.75mil + adelta = 78.876123 + astart = -90.000000 + x = 0.715373mm + y = 0.702673mm + r = 0.220073mm + } + ha:simplearc.13 { + thickness = 10.75mil + adelta = 78.736107 + astart = -90.000000 + x = 0.676333mm + y = 0.587433mm + r = 0.536633mm + } + ha:simplearc.14 { + thickness = 10.75mil + adelta = -87.335143 + astart = -90.000000 + x = 0.972497mm + y = 0.449903mm + r = 0.399103mm + } + } + height = 1.800861mm + } + ha:A { + width = 0.915417mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.663677mm + y1 = 62.0mil + } + ha:line.1 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.915416mm + x2 = 0.663677mm + y1 = 62.0mil + } + ha:line.2 { + y2 = 48.0mil + thickness = 10.75mil + x1 = 0.182185mm + x2 = 0.84631mm + y1 = 48.0mil + } + } + height = 1.574801mm + } + ha:B { + width = 0.863197mm + delta = 0.345606mm + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.205969mm + y1 = 62.0mil + } + ha:line.1 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.205969mm + x2 = 0.609829mm + y1 = 11.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 16.96mil + x2 = 0.0 + y1 = 62.0mil + } + ha:line.3 { + y2 = 34.0mil + thickness = 10.75mil + x1 = 0.490017mm + x2 = 0.113081mm + y1 = 34.0mil + } + ha:line.4 { + y2 = 49.6mil + thickness = 10.75mil + x1 = 0.80732mm + x2 = 0.79756mm + y1 = 47.5165748mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = -78.618860 + astart = -90.000000 + x = 0.609829mm + y = 0.535711mm + r = 0.256311mm + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = 87.345804 + astart = 90.000000 + x = 0.48768mm + y = 19.1mil + r = 14.8mil + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = 80.528338 + astart = 90.000000 + x = 0.422072mm + y = 1.194232mm + r = 0.380568mm + } + ha:simplearc.8 { + thickness = 10.75mil + adelta = -103.760785 + astart = -90.000000 + x = 21.1mil + y = 1.14046mm + r = 11.0mil + } + } + height = 1.574801mm + } + ha:C { + width = 0.787376mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.437363mm + x2 = 0.787375mm + y1 = 11.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.231394mm + x2 = 22.89mil + y1 = 62.0mil + } + ha:line.2 { + y2 = 1.34366mm + thickness = 10.75mil + x1 = 0.127737mm + x2 = 0.0 + y1 = 21.0mil + } + ha:simplearc.3 { + thickness = 10.75mil + adelta = -90.000000 + astart = 90.000000 + x = 0.231394mm + y = 52.89mil + r = 0.231394mm + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = 78.336927 + astart = -90.000000 + x = 0.437363mm + y = 0.594843mm + r = 0.315443mm + } + } + height = 1.574801mm + } + ha:D { + width = 0.922021mm + delta = 0.345606mm + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.205969mm + x2 = 0.690601mm + y1 = 11.0mil + } + ha:line.1 { + y2 = 52.2mil + thickness = 10.75mil + x1 = 0.921995mm + x2 = 0.794258mm + y1 = 20.1mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.205969mm + x2 = 0.0 + y1 = 11.0mil + } + ha:line.3 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.484632mm + y1 = 62.0mil + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = -90.000000 + astart = 270.000000 + x = 27.19mil + y = 20.21mil + r = 0.231394mm + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = 78.336927 + astart = 90.000000 + x = 0.484657mm + y = 1.261897mm + r = 0.315443mm + } + } + height = 1.577341mm + } + ha:E { + width = 0.798298mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.205969mm + y1 = 62.0mil + } + ha:line.1 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.205969mm + x2 = 0.798297mm + y1 = 11.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 23.32mil + x2 = 0.0 + y1 = 62.0mil + } + ha:line.3 { + y2 = 34.0mil + thickness = 10.75mil + x1 = 0.570789mm + x2 = 0.113081mm + y1 = 34.0mil + } + } + height = 1.574801mm + } + ha:F { + width = 0.798298mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.205969mm + y1 = 62.0mil + } + ha:line.1 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.205969mm + x2 = 0.798297mm + y1 = 11.0mil + } + ha:line.2 { + y2 = 34.0mil + thickness = 10.75mil + x1 = 0.705409mm + x2 = 0.113081mm + y1 = 34.0mil + } + } + height = 1.574801mm + } + ha:G { + width = 0.921996mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.437363mm + x2 = 0.921995mm + y1 = 11.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.231394mm + x2 = 28.19mil + y1 = 62.0mil + } + ha:line.2 { + y2 = 52.89mil + thickness = 10.75mil + x1 = 0.127737mm + x2 = 0.0 + y1 = 21.0mil + } + ha:line.3 { + y2 = 34.0mil + thickness = 10.75mil + x1 = 0.586791mm + x2 = 0.829107mm + y1 = 34.0mil + } + ha:line.4 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.829107mm + x2 = 28.19mil + y1 = 34.0mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = -90.000000 + astart = 90.000000 + x = 0.231394mm + y = 52.89mil + r = 0.231394mm + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = 78.336927 + astart = 270.000000 + x = 0.437363mm + y = 0.594843mm + r = 0.315443mm + } + } + height = 1.574801mm + } + ha:H { + width = 0.986766mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.205969mm + y1 = 62.0mil + } + ha:line.1 { + y2 = 34.0mil + thickness = 10.75mil + x1 = 0.866953mm + x2 = 0.113081mm + y1 = 34.0mil + } + ha:line.2 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.780796mm + x2 = 0.986765mm + y1 = 62.0mil + } + } + height = 1.574801mm + } + ha:I { + width = 0.20597mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.205969mm + y1 = 62.0mil + } + } + height = 1.574801mm + } + ha:J { + width = 0.690602mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 20.67mil + x2 = 0.690601mm + y1 = 52.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 8.48mil + x2 = 0.0 + y1 = 62.0mil + } + ha:simplearc.2 { + thickness = 10.75mil + adelta = 78.708251 + astart = 90.000000 + x = 8.48mil + y = 1.259332mm + r = 0.315468mm + } + } + height = 1.574801mm + } + ha:K { + width = 0.986766mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.205969mm + y1 = 62.0mil + } + ha:line.1 { + y2 = 42.0mil + thickness = 10.75mil + x1 = 0.986765mm + x2 = 3.18mil + y1 = 11.0mil + } + ha:line.2 { + y2 = 0.764963mm + thickness = 10.75mil + x1 = 0.780796mm + x2 = 0.428069mm + y1 = 62.0mil + } + } + height = 1.574801mm + } + ha:L { + width = 0.592329mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.205969mm + y1 = 62.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 23.32mil + y1 = 62.0mil + } + } + height = 1.574801mm + } + ha:M { + width = 1.121386mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.205969mm + y1 = 62.0mil + } + ha:line.1 { + y2 = 40.0mil + thickness = 10.75mil + x1 = 0.205969mm + x2 = 0.546557mm + y1 = 11.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 1.121385mm + x2 = 0.915416mm + y1 = 11.0mil + } + ha:line.3 { + y2 = 40.0mil + thickness = 10.75mil + x1 = 1.121385mm + x2 = 0.546557mm + y1 = 11.0mil + } + } + height = 1.574801mm + } + ha:&2f { + width = 0.798298mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.798297mm + x2 = 0.0 + y1 = 11.0mil + } + } + height = 1.574801mm + } + ha:&3a { + width = 0.100966mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 31.0mil + thickness = 10.75mil + x1 = 0.092888mm + x2 = 3.975mil + y1 = 33.0mil + } + ha:line.1 { + y2 = 54.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.008077mm + y1 = 56.0mil + } + } + height = 1.422401mm + } + ha:&3b { + width = 0.218085mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 56.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.125197mm + y1 = 67.0mil + } + ha:line.1 { + y2 = 33.0mil + thickness = 10.75mil + x1 = 0.210007mm + x2 = 0.218084mm + y1 = 35.0mil + } + } + height = 1.701801mm + } + ha:&3d { + width = 0.687909mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 34.0mil + thickness = 10.75mil + x1 = 0.068656mm + x2 = 0.687908mm + y1 = 34.0mil + } + ha:line.1 { + y2 = 51.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.619252mm + y1 = 51.0mil + } + } + height = 1.295401mm + } + ha:O { + width = 0.894081mm + delta = 0.345606mm + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.483133mm + x2 = 0.617753mm + y1 = 11.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.276327mm + x2 = 0.410947mm + y1 = 62.0mil + } + ha:line.2 { + y2 = 51.1mil + thickness = 10.75mil + x1 = 0.114331mm + x2 = 0.0 + y1 = 0.564941mm + } + ha:line.3 { + y2 = 21.8mil + thickness = 10.75mil + x1 = 0.779749mm + x2 = 35.2mil + y1 = 1.289259mm + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = 75.196020 + astart = 90.000000 + x = 16.1mil + y = 1.19126mm + r = 0.38354mm + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = -90.000000 + astart = 90.000000 + x = 10.8mil + y = 51.2mil + r = 10.8mil + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = 75.196020 + astart = -90.000000 + x = 19.1mil + y = 26.1mil + r = 0.38354mm + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = -90.000000 + astart = -90.000000 + x = 0.61976mm + y = 21.8mil + r = 10.8mil + } + } + height = 1.574801mm + } + ha:P { + width = 0.916941mm + delta = 0.345606mm + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.205969mm + y1 = 62.0mil + } + ha:line.1 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.636753mm + x2 = 0.205969mm + y1 = 11.0mil + } + ha:line.2 { + y2 = 39.0mil + thickness = 10.75mil + x1 = 0.523672mm + x2 = 0.092888mm + y1 = 39.0mil + } + ha:line.3 { + y2 = 26.6mil + thickness = 10.75mil + x1 = 0.90892mm + x2 = 0.89916mm + y1 = 0.622721mm + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = 80.528338 + astart = 90.000000 + x = 0.523672mm + y = 0.610032mm + r = 0.380568mm + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = -103.760785 + astart = -90.000000 + x = 25.1mil + y = 0.55626mm + r = 11.0mil + } + } + height = 1.574801mm + } + ha:N { + width = 0.986766mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.205969mm + y1 = 62.0mil + } + ha:line.1 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.780796mm + x2 = 0.986765mm + y1 = 62.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.205969mm + x2 = 0.780796mm + y1 = 11.0mil + } + } + height = 1.574801mm + } + ha:R { + width = 0.914401mm + delta = 0.345606mm + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.205969mm + y1 = 62.0mil + } + ha:line.1 { + y2 = 39.0mil + thickness = 10.75mil + x1 = 0.523672mm + x2 = 0.092888mm + y1 = 39.0mil + } + ha:line.2 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.636753mm + x2 = 0.205969mm + y1 = 11.0mil + } + ha:line.3 { + y2 = 39.0mil + thickness = 10.75mil + x1 = 0.753872mm + x2 = 0.550596mm + y1 = 62.0mil + } + ha:line.4 { + y2 = 26.6mil + thickness = 10.75mil + x1 = 0.90638mm + x2 = 0.89662mm + y1 = 0.622721mm + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = 80.528338 + astart = 90.000000 + x = 0.521132mm + y = 0.610032mm + r = 0.380568mm + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = -103.760785 + astart = -90.000000 + x = 25.0mil + y = 0.55626mm + r = 11.0mil + } + } + height = 1.574801mm + } + ha:S { + width = 0.864331mm + delta = 0.345606mm + li:objects { + ha:line.0 { + y2 = 41.0mil + thickness = 10.75mil + x1 = 0.255247mm + x2 = 0.665635mm + y1 = 0.819137mm + } + ha:simplearc.1 { + thickness = 10.75mil + adelta = -47.997193 + astart = 180.000000 + x = 0.449536mm + y = 1.264838mm + r = 0.345522mm + } + ha:simplearc.2 { + thickness = 10.75mil + adelta = -58.233191 + astart = 111.607450 + x = 0.416715mm + y = 34.5mil + r = 27.5mil + } + ha:simplearc.3 { + thickness = 10.75mil + adelta = 63.432338 + astart = 178.228530 + x = 0.551335mm + y = 49.5mil + r = 0.24384mm + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = -27.159796 + astart = -90.000000 + x = 0.564035mm + y = 0.93726mm + r = 0.65786mm + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = 69.520750 + astart = 262.470073 + x = 0.510695mm + y = 26.8mil + r = 15.9mil + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = 86.104823 + astart = 335.556045 + x = 0.370995mm + y = 23.8mil + r = 0.24384mm + } + } + height = 1.574801mm + } + ha:Q { + width = 0.896418mm + delta = 0.347942mm + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.617753mm + x2 = 0.896417mm + y1 = 51.0mil + } + ha:line.1 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.483133mm + x2 = 0.617753mm + y1 = 11.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.276327mm + x2 = 0.410947mm + y1 = 62.0mil + } + ha:line.3 { + y2 = 51.1mil + thickness = 10.75mil + x1 = 0.114331mm + x2 = 0.0 + y1 = 0.564941mm + } + ha:line.4 { + y2 = 21.8mil + thickness = 10.75mil + x1 = 0.779749mm + x2 = 35.2mil + y1 = 1.289259mm + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = 75.196020 + astart = 90.000000 + x = 16.1mil + y = 1.19126mm + r = 0.38354mm + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = -90.000000 + astart = 90.000000 + x = 10.8mil + y = 51.2mil + r = 10.8mil + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = 75.196020 + astart = -90.000000 + x = 19.1mil + y = 26.1mil + r = 0.38354mm + } + ha:simplearc.8 { + thickness = 10.75mil + adelta = -90.000000 + astart = -90.000000 + x = 0.61976mm + y = 21.8mil + r = 10.8mil + } + } + height = 1.574801mm + } + ha:U { + width = 0.936804mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.1mil + x2 = 0.156007mm + y1 = 49.0mil + } + ha:line.1 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.782463mm + x2 = 0.936803mm + y1 = 1.247098mm + } + ha:line.2 { + y2 = 52.7mil + thickness = 10.75mil + x1 = 0.1mil + x2 = 0.0 + y1 = 49.0mil + } + ha:simplearc.3 { + thickness = 10.75mil + adelta = 67.796888 + astart = 359.432734 + x = 0.22098mm + y = 52.2mil + r = 0.22098mm + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = 93.961205 + astart = 68.198591 + x = 0.33274mm + y = 1.10236mm + r = 18.6mil + } + } + height = 1.574801mm + } + ha:V { + width = 0.969265mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.278663mm + y1 = 11.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.969264mm + x2 = 0.278663mm + y1 = 11.0mil + } + } + height = 1.574801mm + } + ha:T { + width = 0.780797mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.197891mm + x2 = 15.9mil + y1 = 62.0mil + } + ha:line.1 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.780796mm + y1 = 11.0mil + } + } + height = 1.574801mm + } + ha:X { + width = 1.14831mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.205969mm + x2 = 37.1mil + y1 = 11.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 1.148309mm + x2 = 0.0 + y1 = 11.0mil + } + } + height = 1.574801mm + } + ha:Y { + width = 0.915417mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 35.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.360782mm + y1 = 11.0mil + } + ha:line.1 { + y2 = 35.0mil + thickness = 10.75mil + x1 = 0.915416mm + x2 = 0.360782mm + y1 = 11.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.360782mm + x2 = 0.251739mm + y1 = 35.0mil + } + } + height = 1.574801mm + } + ha:W { + width = 1.184657mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.090195mm + y1 = 11.0mil + } + ha:line.1 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 0.090195mm + x2 = 0.523672mm + y1 = 62.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 46.64mil + x2 = 0.682523mm + y1 = 11.0mil + } + ha:line.3 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 0.682523mm + x2 = 0.523672mm + y1 = 62.0mil + } + } + height = 1.574801mm + } + ha:[ { + width = 0.415977mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 68.0mil + thickness = 10.75mil + x1 = 0.254432mm + x2 = 0.0 + y1 = 5.0mil + } + ha:line.1 { + y2 = 68.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 6.36mil + y1 = 68.0mil + } + ha:line.2 { + y2 = 5.0mil + thickness = 10.75mil + x1 = 0.254432mm + x2 = 0.415976mm + y1 = 5.0mil + } + } + height = 1.727201mm + } + ha:^ { + width = 0.430785mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 0.0 + thickness = 10.75mil + x1 = 0.0 + x2 = 0.251739mm + y1 = 9.0mil + } + ha:line.1 { + y2 = 0.0 + thickness = 10.75mil + x1 = 16.96mil + x2 = 0.251739mm + y1 = 9.0mil + } + } + height = 0.228601mm + } + ha:Z { + width = 0.959842mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.205969mm + x2 = 0.959841mm + y1 = 11.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.753872mm + y1 = 62.0mil + } + ha:line.2 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.959841mm + y1 = 62.0mil + } + } + height = 1.574801mm + } + ha:` { + width = 0.263856mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 10.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.263855mm + y1 = 2.0mil + } + } + height = 0.254001mm + } + ha:_ { + width = 0.646177mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 68.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 25.44mil + y1 = 68.0mil + } + } + height = 1.727201mm + } + } + cell_width = 1.444474mm + cell_height = 2.033595mm + } +} Index: tags/1.0.5/font/aussiefont-sans-oblique =================================================================== --- tags/1.0.5/font/aussiefont-sans-oblique (nonexistent) +++ tags/1.0.5/font/aussiefont-sans-oblique (revision 10414) @@ -0,0 +1,3897 @@ +li:pcb-rnd-font-v1 { + ha:geda_pcb { + id = 0 + ha:symbols { + ha:&09 { + width = 0.685801mm + delta = 0.103633mm + li:objects { + ha:line.0 { + y2 = 36.0mil + thickness = 3.0mil + x1 = 0.0 + x2 = 27.0mil + y1 = 36.0mil + } + ha:line.1 { + y2 = 30.0mil + thickness = 3.0mil + x1 = 27.0mil + x2 = 22.0mil + y1 = 36.0mil + } + ha:line.2 { + y2 = 42.0mil + thickness = 3.0mil + x1 = 27.0mil + x2 = 22.0mil + y1 = 36.0mil + } + ha:line.3 { + y2 = 42.0mil + thickness = 3.0mil + x1 = 0.0 + x2 = 5.0mil + y1 = 36.0mil + } + ha:line.4 { + y2 = 30.0mil + thickness = 3.0mil + x1 = 0.0 + x2 = 5.0mil + y1 = 36.0mil + } + } + height = 1.066801mm + } + ha:&0A { + width = 0.889001mm + delta = 10.0mil + li:objects { + ha:line.0 { + y2 = 10.0mil + thickness = 3.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 40.0mil + } + ha:line.1 { + y2 = 40.0mil + thickness = 3.0mil + x1 = 0.0 + x2 = 15.0mil + y1 = 40.0mil + } + ha:line.2 { + y2 = 45.0mil + thickness = 3.0mil + x1 = 20.0mil + x2 = 20.0mil + y1 = 75.0mil + } + ha:line.3 { + y2 = 45.0mil + thickness = 3.0mil + x1 = 20.0mil + x2 = 35.0mil + y1 = 45.0mil + } + ha:line.4 { + y2 = 60.0mil + thickness = 3.0mil + x1 = 20.0mil + x2 = 30.0mil + y1 = 60.0mil + } + } + height = 1.905001mm + } + ha:&0D { + width = 0.889001mm + delta = 0.253999mm + li:objects { + ha:line.0 { + y2 = 15.0mil + thickness = 3.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 35.0mil + } + ha:line.1 { + y2 = 10.0mil + thickness = 3.0mil + x1 = 5.0mil + x2 = 10.0mil + y1 = 10.0mil + } + ha:line.2 { + y2 = 40.0mil + thickness = 3.0mil + x1 = 5.0mil + x2 = 10.0mil + y1 = 40.0mil + } + ha:line.3 { + y2 = 45.0mil + thickness = 3.0mil + x1 = 20.0mil + x2 = 20.0mil + y1 = 75.0mil + } + ha:line.4 { + y2 = 45.0mil + thickness = 3.0mil + x1 = 20.0mil + x2 = 30.0mil + y1 = 45.0mil + } + ha:line.5 { + y2 = 60.0mil + thickness = 3.0mil + x1 = 20.0mil + x2 = 30.0mil + y1 = 60.0mil + } + ha:line.6 { + y2 = 55.0mil + thickness = 3.0mil + x1 = 35.0mil + x2 = 35.0mil + y1 = 50.0mil + } + ha:line.7 { + y2 = 75.0mil + thickness = 3.0mil + x1 = 30.0mil + x2 = 35.0mil + y1 = 60.0mil + } + ha:simplearc.8 { + thickness = 3.0mil + adelta = -90.000000 + astart = -90.000000 + x = 10.0mil + y = 15.0mil + r = 5.0mil + } + ha:simplearc.9 { + thickness = 3.0mil + adelta = 90.000000 + astart = 270.000000 + x = 5.0mil + y = 15.0mil + r = 5.0mil + } + ha:simplearc.10 { + thickness = 3.0mil + adelta = 90.000000 + astart = 90.000000 + x = 10.0mil + y = 35.0mil + r = 5.0mil + } + ha:simplearc.11 { + thickness = 3.0mil + adelta = -90.000000 + astart = 90.000000 + x = 5.0mil + y = 35.0mil + r = 5.0mil + } + ha:simplearc.12 { + thickness = 3.0mil + adelta = 90.000000 + astart = 90.000000 + x = 30.0mil + y = 55.0mil + r = 5.0mil + } + ha:simplearc.13 { + thickness = 3.0mil + adelta = -90.000000 + astart = -90.000000 + x = 30.0mil + y = 50.0mil + r = 5.0mil + } + } + height = 1.905001mm + } ha:] { + width = 0.415977mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 68.0mil + thickness = 8.0mil + x1 = 0.415976mm + x2 = 6.36mil + y1 = 5.0mil + } + ha:line.1 { + y2 = 68.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 6.36mil + y1 = 68.0mil + } + ha:line.2 { + y2 = 5.0mil + thickness = 8.0mil + x1 = 0.254432mm + x2 = 0.415976mm + y1 = 5.0mil + } + } + height = 1.727201mm + } + ha:&5c { + width = 0.38636mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.386359mm + y1 = 11.0mil + } + } + height = 1.574801mm + } + ha:b { + width = 0.731521mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.210007mm + x2 = 0.0 + y1 = 10.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.457708mm + y1 = 62.0mil + } + ha:line.2 { + y2 = 56.0mil + thickness = 8.0mil + x1 = 0.730614mm + x2 = 0.643484mm + y1 = 0.863401mm + } + ha:line.3 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 0.137312mm + x2 = 0.59502mm + y1 = 28.0mil + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = 78.560593 + astart = 90.000000 + x = 0.457708mm + y = 54.52mil + r = 7.48mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = -96.605083 + astart = -90.000000 + x = 0.59502mm + y = 0.8477mm + r = 0.1365mm + } + } + height = 1.574801mm + } + ha:c { + width = 0.568417mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.134939mm + x2 = 0.431103mm + y1 = 62.0mil + } + ha:line.1 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 0.272252mm + x2 = 0.568416mm + y1 = 28.0mil + } + ha:line.2 { + y2 = 1.41732mm + thickness = 8.0mil + x1 = 0.08824mm + x2 = 0.00188mm + y1 = 34.0mil + } + ha:simplearc.3 { + thickness = 8.0mil + adelta = 78.560593 + astart = 270.000000 + x = 0.273812mm + y = 0.901192mm + r = 7.48mil + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = -96.605083 + astart = 90.000000 + x = 0.1365mm + y = 1.4383mm + r = 0.1365mm + } + } + height = 1.574801mm + } + ha:a { + width = 0.695301mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 44.0mil + thickness = 8.0mil + x1 = 0.277365mm + x2 = 0.654301mm + y1 = 44.0mil + } + ha:line.1 { + y2 = 0.711217mm + thickness = 8.0mil + x1 = 0.207362mm + x2 = 0.56093mm + y1 = 28.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.692812mm + x2 = 0.581606mm + y1 = 0.873642mm + } + ha:line.3 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.16911mm + x2 = 0.581954mm + y1 = 62.0mil + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = 90.000000 + astart = 0.000000 + x = 6.7mil + y = 1.40462mm + r = 6.7mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = -90.000000 + astart = 0.000000 + x = 11.3mil + y = 1.40462mm + r = 11.3mil + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = -100.061922 + astart = 269.106007 + x = 22.0mil + y = 0.8477mm + r = 0.1365mm + } + } + height = 1.574801mm + } + ha:e { + width = 0.657861mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 39.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.064618mm + y1 = 55.0mil + } + ha:line.1 { + y2 = 45.0mil + thickness = 8.0mil + x1 = 1.59mil + x2 = 24.91mil + y1 = 45.0mil + } + ha:line.2 { + y2 = 39.0mil + thickness = 8.0mil + x1 = 24.91mil + x2 = 0.656946mm + y1 = 45.0mil + } + ha:line.3 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.160198mm + x2 = 0.564058mm + y1 = 62.0mil + } + ha:line.4 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 15.5mil + x2 = 15.9mil + y1 = 28.0mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = -80.753887 + astart = 350.753887 + x = 15.5mil + y = 41.1mil + r = 0.33274mm + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = -95.826342 + astart = -90.000000 + x = 15.9mil + y = 38.0mil + r = 10.0mil + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = -96.270309 + astart = 90.000000 + x = 0.160198mm + y = 1.414602mm + r = 0.160198mm + } + } + height = 1.574801mm + } + ha:f { + width = 0.526365mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.457708mm + y1 = 28.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 7.95mil + x2 = 0.024232mm + y1 = 18.0mil + } + ha:line.2 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.418668mm + x2 = 0.526364mm + y1 = 11.0mil + } + ha:simplearc.3 { + thickness = 8.0mil + adelta = 78.560593 + astart = 270.000000 + x = 0.393852mm + y = 0.471932mm + r = 7.48mil + } + } + height = 1.574801mm + } + ha:d { + width = 0.805028mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.805027mm + x2 = 0.59502mm + y1 = 10.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.137312mm + x2 = 0.59502mm + y1 = 62.0mil + } + ha:line.2 { + y2 = 56.0mil + thickness = 8.0mil + x1 = 0.088849mm + x2 = 0.0 + y1 = 34.0mil + } + ha:line.3 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 0.274625mm + x2 = 0.732333mm + y1 = 28.0mil + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = 78.560593 + astart = 270.000000 + x = 0.276185mm + y = 0.901192mm + r = 7.48mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = -96.605083 + astart = 90.000000 + x = 0.138873mm + y = 1.4383mm + r = 0.1365mm + } + } + height = 1.574801mm + } + ha:h { + width = 0.733401mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.210007mm + x2 = 0.0 + y1 = 10.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.732333mm + x2 = 0.619252mm + y1 = 34.0mil + } + ha:line.2 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 0.137312mm + x2 = 0.59502mm + y1 = 28.0mil + } + ha:simplearc.3 { + thickness = 8.0mil + adelta = -96.605083 + astart = 270.000000 + x = 23.5mil + y = 0.8477mm + r = 0.1365mm + } + } + height = 1.574801mm + } + ha:i { + width = 0.20597mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 14.0mil + thickness = 8.0mil + x1 = 0.205969mm + x2 = 0.193853mm + y1 = 11.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.137312mm + x2 = 0.0 + y1 = 28.0mil + } + } + height = 1.574801mm + } + ha:g { + width = 0.748488mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 0.56675mm + x2 = 0.748487mm + y1 = 73.0mil + } + ha:line.1 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 0.290779mm + x2 = 0.748487mm + y1 = 28.0mil + } + ha:line.2 { + y2 = 34.0mil + thickness = 8.0mil + x1 = 0.016154mm + x2 = 0.105004mm + y1 = 56.0mil + } + ha:line.3 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.153467mm + x2 = 0.611175mm + y1 = 62.0mil + } + ha:line.4 { + y2 = 80.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.350012mm + y1 = 80.0mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = 78.715635 + astart = 90.000000 + x = 0.350012mm + y = 71.28mil + r = 8.72mil + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = 78.560593 + astart = 270.000000 + x = 0.290779mm + y = 0.901192mm + r = 7.48mil + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = -96.605083 + astart = 90.000000 + x = 0.153467mm + y = 1.4383mm + r = 0.1365mm + } + } + height = 2.032001mm + } + ha:k { + width = 0.756565mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.205969mm + x2 = 0.0 + y1 = 11.0mil + } + ha:line.1 { + y2 = 46.0mil + thickness = 8.0mil + x1 = 0.756564mm + x2 = 0.064618mm + y1 = 28.0mil + } + ha:line.2 { + y2 = 0.967678mm + thickness = 8.0mil + x1 = 0.619252mm + x2 = 0.3684mm + y1 = 62.0mil + } + } + height = 1.574801mm + } + ha:l { + width = 0.19006mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 1.433012mm + thickness = 8.0mil + x1 = 0.190059mm + x2 = 0.0 + y1 = 11.0mil + } + ha:simplearc.1 { + thickness = 8.0mil + adelta = 61.228002 + astart = 0.000000 + x = 0.16002mm + y = 1.433012mm + r = 0.16002mm + } + } + height = 1.573277mm + } + ha:j { + width = 0.495971mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 14.0mil + thickness = 8.0mil + x1 = 0.49597mm + x2 = 0.483855mm + y1 = 11.0mil + } + ha:line.1 { + y2 = 72.0mil + thickness = 8.0mil + x1 = 0.424774mm + x2 = 0.247076mm + y1 = 28.0mil + } + ha:simplearc.2 { + thickness = 8.0mil + adelta = -62.238442 + astart = 160.839827 + x = -0.046345mm + y = 68.0mil + r = 0.30988mm + } + } + height = 2.033595mm + } + ha:n { + width = 0.720218mm + delta = 0.17818mm + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.137312mm + x2 = 0.0 + y1 = 28.0mil + } + ha:line.1 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 0.137312mm + x2 = 0.534568mm + y1 = 28.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 28.355mil + x2 = 0.619252mm + y1 = 37.0mil + } + ha:simplearc.3 { + thickness = 8.0mil + adelta = -96.309371 + astart = -90.000000 + x = 0.514248mm + y = 0.916788mm + r = 0.205588mm + } + } + height = 1.574801mm + } + ha:o { + width = 0.665796mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 39.0mil + thickness = 8.0mil + x1 = 0.527um + x2 = 0.047351mm + y1 = 1.315513mm + } + ha:line.1 { + y2 = 1.30302mm + thickness = 8.0mil + x1 = 0.665269mm + x2 = 0.618445mm + y1 = 0.975567mm + } + ha:simplearc.2 { + thickness = 8.0mil + adelta = 1.505021 + astart = 2.060728 + x = 1.718468mm + y = 1.25476mm + r = 67.7mil + } + ha:simplearc.3 { + thickness = 8.0mil + adelta = -79.646680 + astart = 90.000000 + x = 0.265588mm + y = 51.7mil + r = 0.26924mm + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = 77.035491 + astart = 90.000000 + x = 0.265588mm + y = 48.0mil + r = 14.3mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = 1.505021 + astart = 182.060728 + x = -1.052672mm + y = 1.03886mm + r = 67.7mil + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = -79.646680 + astart = -90.000000 + x = 0.400208mm + y = 38.6mil + r = 0.26924mm + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = 77.035491 + astart = -90.000000 + x = 0.400208mm + y = 1.07442mm + r = 14.3mil + } + } + height = 1.582421mm + } + ha:m { + width = 1.016382mm + delta = 0.17818mm + li:objects { + ha:line.0 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 0.137312mm + x2 = 0.810412mm + y1 = 28.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 40.015mil + x2 = 0.915416mm + y1 = 37.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.137312mm + x2 = 0.0 + y1 = 28.0mil + } + ha:line.3 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.59502mm + x2 = 0.457708mm + y1 = 28.0mil + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = -96.309371 + astart = -90.000000 + x = 0.810412mm + y = 0.916788mm + r = 0.205588mm + } + } + height = 1.574801mm + } + ha:q { + width = 0.732334mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 0.522326mm + x2 = 0.732333mm + y1 = 80.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.137312mm + x2 = 0.59502mm + y1 = 62.0mil + } + ha:line.2 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 0.732333mm + x2 = 0.274625mm + y1 = 28.0mil + } + ha:line.3 { + y2 = 56.6mil + thickness = 8.0mil + x1 = 0.088849mm + x2 = 0.0 + y1 = 34.0mil + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = 78.560593 + astart = 270.000000 + x = 10.8119685mil + y = 0.901192mm + r = 7.48mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = -96.605083 + astart = 90.000000 + x = 0.137312mm + y = 1.4383mm + r = 0.1365mm + } + } + height = 2.032001mm + } + ha:r { + width = 0.570841mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.137312mm + y1 = 62.0mil + } + ha:line.1 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 0.137312mm + x2 = 0.433476mm + y1 = 28.0mil + } + ha:simplearc.2 { + thickness = 8.0mil + adelta = -96.605083 + astart = 270.000000 + x = 17.1mil + y = 0.8477mm + r = 0.1365mm + } + } + height = 1.574801mm + } + ha:p { + width = 0.805181mm + delta = 0.178611mm + li:objects { + ha:line.0 { + y2 = 80.0mil + thickness = 8.0mil + x1 = 0.210007mm + x2 = 0.0 + y1 = 28.0mil + } + ha:line.1 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 0.210007mm + x2 = 0.667715mm + y1 = 28.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.072695mm + x2 = 0.530403mm + y1 = 62.0mil + } + ha:line.3 { + y2 = 0.84836mm + thickness = 8.0mil + x1 = 0.716774mm + x2 = 0.80518mm + y1 = 1.422489mm + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = -96.605083 + astart = 270.000000 + x = 0.667868mm + y = 0.8477mm + r = 0.1365mm + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = 78.560593 + astart = 90.000000 + x = 0.530556mm + y = 54.52mil + r = 7.48mil + } + } + height = 2.032001mm + } + ha:t { + width = 0.457709mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.2302mm + x2 = 0.024232mm + y1 = 11.0mil + } + ha:line.1 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.457708mm + y1 = 28.0mil + } + } + height = 1.574801mm + } + ha:u { + width = 0.730175mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 1.422599mm + thickness = 8.0mil + x1 = 0.110922mm + x2 = 0.906um + y1 = 28.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.1365mm + x2 = 0.592862mm + y1 = 62.0mil + } + ha:line.2 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 0.592862mm + x2 = 0.730174mm + y1 = 62.0mil + } + ha:simplearc.3 { + thickness = 8.0mil + adelta = -96.605083 + astart = 90.000000 + x = 0.1365mm + y = 1.4383mm + r = 0.1365mm + } + } + height = 1.574801mm + } + ha:s { + width = 0.678282mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 1.14046mm + thickness = 8.0mil + x1 = 0.243891mm + x2 = 0.452171mm + y1 = 44.0mil + } + ha:simplearc.1 { + thickness = 8.0mil + adelta = 90.000000 + astart = 180.000000 + x = 0.454711mm + y = 52.2mil + r = 0.18542mm + } + ha:simplearc.2 { + thickness = 8.0mil + adelta = -16.619264 + astart = 90.000000 + x = 0.398831mm + y = 0.17272mm + r = 1.39446mm + } + ha:simplearc.3 { + thickness = 8.0mil + adelta = -90.000000 + astart = 180.000000 + x = 0.398831mm + y = 52.2mil + r = 0.240697mm + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = -16.619264 + astart = -90.000000 + x = 0.279451mm + y = 82.9mil + r = 1.39446mm + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = -90.000000 + astart = 0.000000 + x = 0.279451mm + y = 36.7mil + r = 0.22098mm + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = 90.000000 + astart = 0.000000 + x = 0.243891mm + y = 36.7mil + r = 0.18542mm + } + } + height = 1.567181mm + } + ha:w { + width = 0.969265mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.105004mm + y1 = 28.0mil + } + ha:line.1 { + y2 = 40.0mil + thickness = 8.0mil + x1 = 0.105004mm + x2 = 0.436169mm + y1 = 62.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.969264mm + x2 = 0.589636mm + y1 = 28.0mil + } + ha:line.3 { + y2 = 40.0mil + thickness = 8.0mil + x1 = 0.589636mm + x2 = 0.436169mm + y1 = 62.0mil + } + } + height = 1.574801mm + } + ha:x { + width = 0.729641mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.137312mm + x2 = 23.32mil + y1 = 28.0mil + } + ha:line.1 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.72964mm + y1 = 62.0mil + } + } + height = 1.574801mm + } + ha:v { + width = 0.592329mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.158852mm + y1 = 28.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 23.32mil + x2 = 0.158852mm + y1 = 28.0mil + } + } + height = 1.574801mm + } + ha:z { + width = 0.729641mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 0.137312mm + x2 = 0.72964mm + y1 = 28.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.72964mm + x2 = 0.0 + y1 = 28.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 23.32mil + y1 = 62.0mil + } + } + height = 1.574801mm + } + ha:~ { + width = 0.623277mm + delta = 7.0mil + li:objects { + ha:simplearc.0 { + thickness = 8.0mil + adelta = 51.095862 + astart = 90.000000 + x = 0.471077mm + y = 0.764957mm + r = 7.7mil + } + ha:simplearc.1 { + thickness = 8.0mil + adelta = -48.632951 + astart = 90.000000 + x = 0.471077mm + y = 0.742097mm + r = 0.21844mm + } + ha:simplearc.2 { + thickness = 8.0mil + adelta = 51.095862 + astart = -90.000000 + x = 0.1522mm + y = 40.0mil + r = 7.7mil + } + ha:simplearc.3 { + thickness = 8.0mil + adelta = -48.632951 + astart = -90.000000 + x = 0.1522mm + y = 1.03886mm + r = 0.21844mm + } + } + height = 0.960538mm + } + ha:y { + width = 0.82926mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.210007mm + x2 = 0.395783mm + y1 = 28.0mil + } + ha:line.1 { + y2 = 80.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 6.36mil + y1 = 80.0mil + } + ha:line.2 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 6.36mil + x2 = 0.829259mm + y1 = 80.0mil + } + } + height = 2.032001mm + } + ha:&7d { + width = 0.425665mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 0.256341mm + thickness = 8.0mil + x1 = 0.285812mm + x2 = 0.366516mm + y1 = 30.0mil + } + ha:line.1 { + y2 = 1.030105mm + thickness = 8.0mil + x1 = 0.160158mm + x2 = 0.247703mm + y1 = 1.56972mm + } + ha:simplearc.2 { + thickness = 8.0mil + adelta = -90.000000 + astart = 90.000000 + x = 0.425664mm + y = 0.77216mm + r = 5.5mil + } + ha:simplearc.3 { + thickness = 8.0mil + adelta = 67.203479 + astart = 270.000000 + x = 0.425664mm + y = 43.5mil + r = 0.19304mm + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = 70.509921 + astart = 98.050671 + x = -0.026608mm + y = 60.42mil + r = 7.48mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = -85.868748 + astart = 259.263665 + x = 0.232624mm + y = 0.23556mm + r = 0.1365mm + } + } + height = 1.722788mm + } + ha:| { + width = 0.274626mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 71.0mil + thickness = 8.0mil + x1 = 0.113081mm + x2 = 0.0 + y1 = 43.0mil + } + ha:line.1 { + y2 = 3.0mil + thickness = 8.0mil + x1 = 6.36mil + x2 = 0.274625mm + y1 = 31.0mil + } + } + height = 1.803401mm + } + ha:&7b { + width = 0.425665mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 1.569919mm + thickness = 8.0mil + x1 = 0.139853mm + x2 = 0.059149mm + y1 = 1.06426mm + } + ha:line.1 { + y2 = 0.796155mm + thickness = 8.0mil + x1 = 0.265507mm + x2 = 0.177962mm + y1 = 0.25654mm + } + ha:simplearc.2 { + thickness = 8.0mil + adelta = -90.000000 + astart = -90.000000 + x = 0.001um + y = 41.5mil + r = 5.5mil + } + ha:simplearc.3 { + thickness = 8.0mil + adelta = 67.203479 + astart = 90.000000 + x = 0.001um + y = 0.72136mm + r = 0.19304mm + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = 70.509921 + astart = 278.050671 + x = 0.452273mm + y = 11.48mil + r = 7.48mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = -85.868748 + astart = 79.263665 + x = 0.193041mm + y = 1.5907mm + r = 0.1365mm + } + } + height = 1.724811mm + } + ha:&20 { + width = 0.0 + delta = 31.0mil + li:objects { + } + height = 0.0 + } + ha:&23 { + width = 1.010997mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.379628mm + x2 = 0.17366mm + y1 = 11.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.837336mm + x2 = 0.631368mm + y1 = 11.0mil + } + ha:line.2 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 0.068656mm + x2 = 1.010996mm + y1 = 28.0mil + } + ha:line.3 { + y2 = 45.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 37.1mil + y1 = 45.0mil + } + } + height = 1.574801mm + } + ha:&26 { + width = 0.955782mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 1.266107mm + thickness = 8.0mil + x1 = 0.613237mm + x2 = 0.029851mm + y1 = 0.592539mm + } + ha:line.1 { + y2 = 0.58928mm + thickness = 8.0mil + x1 = 0.725581mm + x2 = 8.9mil + y1 = 62.0mil + } + ha:line.2 { + y2 = 45.0mil + thickness = 8.0mil + x1 = 0.26015mm + x2 = 0.955781mm + y1 = 1.564839mm + } + ha:line.3 { + y2 = 11.4mil + thickness = 8.0mil + x1 = 18.8mil + x2 = 16.1mil + y1 = 0.289578mm + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = -114.341090 + astart = 24.341090 + x = 16.6mil + y = 19.8mil + r = 8.4mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = -132.075532 + astart = 270.806929 + x = 0.48006mm + y = 18.5mil + r = 0.18034mm + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = -30.398728 + astart = 0.000000 + x = 0.22098mm + y = 54.2mil + r = 0.22098mm + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = -108.245855 + astart = 108.245855 + x = 0.19812mm + y = 54.2mil + r = 0.19812mm + } + } + height = 1.574801mm + } + ha:! { + width = 0.20597mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 45.0mil + thickness = 8.0mil + x1 = 0.205969mm + x2 = 0.068656mm + y1 = 11.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.012116mm + x2 = 0.0 + y1 = 59.0mil + } + } + height = 1.574801mm + } + ha:" { + width = 0.529058mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 0.0 + thickness = 8.0mil + x1 = 0.0 + x2 = 0.125197mm + y1 = 11.0mil + } + ha:line.1 { + y2 = 0.0 + thickness = 8.0mil + x1 = 15.9mil + x2 = 0.529057mm + y1 = 11.0mil + } + } + height = 0.279401mm + } + ha:$ { + width = 0.76017mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 39.74mil + thickness = 8.0mil + x1 = 0.244948mm + x2 = 0.536057mm + y1 = 0.852937mm + } + ha:line.1 { + y2 = 1.573276mm + thickness = 8.0mil + x1 = 0.494147mm + x2 = 0.288178mm + y1 = 0.277876mm + } + ha:simplearc.2 { + thickness = 8.0mil + adelta = -13.889035 + astart = 270.825530 + x = 0.362305mm + y = 2.190496mm + r = 1.76022mm + } + ha:simplearc.3 { + thickness = 8.0mil + adelta = 63.145579 + astart = 0.000000 + x = 0.347065mm + y = 25.64mil + r = 8.9mil + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = -90.000000 + astart = 0.000000 + x = 0.336905mm + y = 0.648716mm + r = 8.5mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = -13.889035 + astart = 90.825530 + x = 0.397865mm + y = -0.339344mm + r = 1.76022mm + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = 57.355360 + astart = 180.000000 + x = 0.413105mm + y = 47.24mil + r = 8.9mil + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = -90.000000 + astart = 180.000000 + x = 0.423265mm + y = 47.34mil + r = 8.5mil + } + } + height = 1.573277mm + } + ha:% { + width = 1.444474mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 1.444473mm + x2 = 0.0 + y1 = 11.0mil + } + ha:simplearc.1 { + thickness = 8.0mil + adelta = 92.779167 + astart = 267.220833 + x = 42.7mil + y = 1.39192mm + r = 10.4mil + } + ha:simplearc.2 { + thickness = 8.0mil + adelta = 94.398705 + astart = 180.000000 + x = 44.2mil + y = 51.6mil + r = 7.2mil + } + ha:simplearc.3 { + thickness = 8.0mil + adelta = 92.779167 + astart = 87.220833 + x = 41.0mil + y = 51.7mil + r = 10.4mil + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = 94.398705 + astart = 0.000000 + x = 39.5mil + y = 1.39446mm + r = 7.2mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = 92.779167 + astart = 267.220833 + x = 17.1mil + y = 21.5mil + r = 10.4mil + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = 94.398705 + astart = 180.000000 + x = 18.6mil + y = 18.3mil + r = 7.2mil + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = 92.779167 + astart = 87.220833 + x = 15.4mil + y = 0.46736mm + r = 10.4mil + } + ha:simplearc.8 { + thickness = 8.0mil + adelta = 94.398705 + astart = 0.000000 + x = 13.9mil + y = 21.6mil + r = 7.2mil + } + } + height = 1.577341mm + } + ha:' { + width = 0.125198mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 0.0 + thickness = 8.0mil + x1 = 0.0 + x2 = 0.125197mm + y1 = 11.0mil + } + } + height = 0.279401mm + } + ha:( { + width = 0.336347mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 1.2787mm + thickness = 8.0mil + x1 = 0.101022mm + x2 = 0.00636mm + y1 = 0.655586mm + } + ha:simplearc.1 { + thickness = 8.0mil + adelta = -32.083745 + astart = 352.278174 + x = 45.2mil + y = 0.79756mm + r = 41.6mil + } + ha:simplearc.2 { + thickness = 8.0mil + adelta = 31.611030 + astart = 352.937397 + x = 33.0mil + y = 1.38176mm + r = 33.0mil + } + } + height = 1.730001mm + } + ha:) { + width = 0.336348mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 0.574696mm + thickness = 8.0mil + x1 = 0.235325mm + x2 = 0.329987mm + y1 = 1.19781mm + } + ha:simplearc.1 { + thickness = 8.0mil + adelta = -32.083745 + astart = 172.278174 + x = -0.811733mm + y = 1.055836mm + r = 41.6mil + } + ha:simplearc.2 { + thickness = 8.0mil + adelta = 31.611030 + astart = 172.937397 + x = -0.501853mm + y = 0.471636mm + r = 33.0mil + } + } + height = 1.732281mm + } + ha:* { + width = 0.592329mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 51.0mil + thickness = 8.0mil + x1 = 0.117119mm + x2 = 0.479247mm + y1 = 34.0mil + } + ha:line.1 { + y2 = 43.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 23.32mil + y1 = 43.0mil + } + ha:line.2 { + y2 = 51.0mil + thickness = 8.0mil + x1 = 0.547903mm + x2 = 0.048463mm + y1 = 34.0mil + } + } + height = 1.295401mm + } + ha:+ { + width = 0.592329mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 43.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 23.32mil + y1 = 43.0mil + } + ha:line.1 { + y2 = 54.0mil + thickness = 8.0mil + x1 = 0.340589mm + x2 = 0.251739mm + y1 = 32.0mil + } + } + height = 1.371601mm + } + ha:, { + width = 0.125198mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 65.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.125197mm + y1 = 76.0mil + } + } + height = 1.930401mm + } + ha:- { + width = 0.592329mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 42.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 23.32mil + y1 = 42.0mil + } + } + height = 1.066801mm + } + ha:. { + width = 0.018713mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 60.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.018712mm + y1 = 1.60782mm + } + } + height = 1.607821mm + } + ha:0 { + width = 0.670561mm + delta = 7.0mil + li:objects { + ha:simplearc.0 { + thickness = 8.0mil + adelta = -59.264512 + astart = 90.000000 + x = 8.5mil + y = 1.45542mm + r = 0.11684mm + } + ha:simplearc.1 { + thickness = 8.0mil + adelta = 43.667780 + astart = 90.000000 + x = 8.5mil + y = 1.34112mm + r = 0.23114mm + } + ha:simplearc.2 { + thickness = 8.0mil + adelta = -43.549373 + astart = 180.000000 + x = -0.39624mm + y = 0.77216mm + r = 42.0mil + } + ha:simplearc.3 { + thickness = 8.0mil + adelta = 30.353941 + astart = 180.000000 + x = -0.20574mm + y = 0.77216mm + r = 34.5mil + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = -59.264512 + astart = -90.000000 + x = 0.45466mm + y = 0.39624mm + r = 0.11684mm + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = 43.667780 + astart = -90.000000 + x = 0.45466mm + y = 20.1mil + r = 0.23114mm + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = -43.549373 + astart = 0.000000 + x = 42.0mil + y = 42.5mil + r = 42.0mil + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = 30.353941 + astart = 0.000000 + x = 34.5mil + y = 42.5mil + r = 34.5mil + } + } + height = 1.572261mm + } + ha:1 { + width = 0.34059mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.340589mm + y1 = 22.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.340589mm + x2 = 0.13462mm + y1 = 11.0mil + } + } + height = 1.574801mm + } + ha:2 { + width = 0.780023mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 23.32mil + y1 = 62.0mil + } + ha:line.1 { + y2 = 0.721548mm + thickness = 8.0mil + x1 = 0.0 + x2 = 0.717149mm + y1 = 62.0mil + } + ha:simplearc.2 { + thickness = 8.0mil + adelta = 59.379667 + astart = -90.000000 + x = 0.522471mm + y = 0.700881mm + r = 0.420871mm + } + ha:simplearc.3 { + thickness = 8.0mil + adelta = -37.733329 + astart = 180.000000 + x = 0.479383mm + y = 0.537561mm + r = 0.300639mm + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = -90.000000 + astart = -90.000000 + x = 0.522471mm + y = 0.537561mm + r = 0.257551mm + } + } + height = 1.574801mm + } + ha:3 { + width = 0.787401mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.205969mm + x2 = 0.555981mm + y1 = 11.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 11.66mil + y1 = 62.0mil + } + ha:line.2 { + y2 = 34.0mil + thickness = 8.0mil + x1 = 0.47682mm + x2 = 0.436169mm + y1 = 0.866301mm + } + ha:line.3 { + y2 = 34.0mil + thickness = 8.0mil + x1 = 0.247701mm + x2 = 0.463093mm + y1 = 34.0mil + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = 56.309932 + astart = 90.000000 + x = 15.8mil + y = 19.0mil + r = 15.0mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = -41.427263 + astart = 180.000000 + x = 0.510819mm + y = 0.510819mm + r = 0.276581mm + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = -90.000000 + astart = -90.000000 + x = 0.555981mm + y = 0.510819mm + r = 0.231419mm + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = 67.453710 + astart = 90.000000 + x = 11.66mil + y = 1.203249mm + r = 0.371551mm + } + ha:simplearc.8 { + thickness = 8.0mil + adelta = -17.603639 + astart = 180.000000 + x = -0.196911mm + y = 1.074185mm + r = 0.881615mm + } + ha:simplearc.9 { + thickness = 8.0mil + adelta = -90.000000 + astart = -90.000000 + x = 0.47682mm + y = 1.074185mm + r = 0.207884mm + } + } + height = 1.574801mm + } + ha:4 { + width = 0.753873mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 51.0mil + thickness = 8.0mil + x1 = 0.457708mm + x2 = 0.0 + y1 = 11.0mil + } + ha:line.1 { + y2 = 51.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.753872mm + y1 = 51.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.560019mm + x2 = 0.467131mm + y1 = 39.0mil + } + } + height = 1.574801mm + } + ha:5 { + width = 0.825222mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.825221mm + x2 = 0.205969mm + y1 = 11.0mil + } + ha:line.1 { + y2 = 34.0mil + thickness = 8.0mil + x1 = 0.205969mm + x2 = 0.113081mm + y1 = 11.0mil + } + ha:line.2 { + y2 = 34.0mil + thickness = 8.0mil + x1 = 0.113081mm + x2 = 0.409245mm + y1 = 34.0mil + } + ha:line.3 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.380498mm + x2 = 0.0 + y1 = 1.573394mm + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = -70.344464 + astart = 180.000000 + x = 0.225755mm + y = 1.140155mm + r = 0.460045mm + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = -90.000000 + astart = -90.000000 + x = 0.409245mm + y = 1.140155mm + r = 0.276555mm + } + } + height = 1.574801mm + } + ha:6 { + width = 0.651562mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 34.0mil + thickness = 8.0mil + x1 = 0.072695mm + x2 = 0.422707mm + y1 = 34.0mil + } + ha:line.1 { + y2 = 52.0mil + thickness = 8.0mil + x1 = 4.0mil + x2 = 0.0 + y1 = 27.0mil + } + ha:line.2 { + y2 = 1.092454mm + thickness = 8.0mil + x1 = 0.614373mm + x2 = 0.651561mm + y1 = 1.319923mm + } + ha:line.3 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.228854mm + x2 = 0.309626mm + y1 = 62.0mil + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = -68.630916 + astart = 342.245445 + x = 0.656895mm + y = 34.0mil + r = 23.0mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = -96.270387 + astart = 90.000000 + x = 0.228854mm + y = 52.99mil + r = 0.228854mm + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = 79.815149 + astart = 90.000000 + x = 0.309626mm + y = 49.81mil + r = 0.309626mm + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = -90.000000 + astart = -90.000000 + x = 0.422707mm + y = 1.092454mm + r = 0.228854mm + } + } + height = 1.574801mm + } + ha:7 { + width = 0.643485mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.024232mm + y1 = 17.0mil + } + ha:line.1 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.024232mm + x2 = 0.643484mm + y1 = 11.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.643484mm + x2 = 5.565mil + y1 = 11.0mil + } + } + height = 1.574801mm + } + ha:8 { + width = 0.751841mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 53.0mil + thickness = 8.0mil + x1 = 2.0mil + x2 = 0.0 + y1 = 42.0mil + } + ha:line.1 { + y2 = 34.0mil + thickness = 8.0mil + x1 = 0.341935mm + x2 = 0.449631mm + y1 = 34.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.228854mm + x2 = 13.25mil + y1 = 62.0mil + } + ha:line.3 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.434823mm + x2 = 0.542519mm + y1 = 11.0mil + } + ha:line.4 { + y2 = 0.687656mm + thickness = 8.0mil + x1 = 29.6mil + x2 = 0.714565mm + y1 = 20.0mil + } + ha:line.5 { + y2 = 25.0mil + thickness = 8.0mil + x1 = 0.173241mm + x2 = 0.135966mm + y1 = 0.455344mm + } + ha:line.6 { + y2 = 1.372325mm + thickness = 8.0mil + x1 = 27.0mil + x2 = 0.636795mm + y1 = 1.092454mm + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = 67.850877 + astart = 90.000000 + x = 0.452983mm + y = 0.581177mm + r = 0.282423mm + } + ha:simplearc.8 { + thickness = 8.0mil + adelta = 85.179363 + astart = 180.000000 + x = 20.6mil + y = 20.0mil + r = 9.0mil + } + ha:simplearc.9 { + thickness = 8.0mil + adelta = 67.850877 + astart = -90.000000 + x = 0.434823mm + y = 0.561823mm + r = 0.282423mm + } + ha:simplearc.10 { + thickness = 8.0mil + adelta = 90.000000 + astart = 0.000000 + x = 0.364566mm + y = 25.0mil + r = 9.0mil + } + ha:simplearc.11 { + thickness = 8.0mil + adelta = -90.000000 + astart = 270.000000 + x = 0.456946mm + y = 1.092454mm + r = 0.228854mm + } + ha:simplearc.12 { + thickness = 8.0mil + adelta = 67.988717 + astart = 270.000000 + x = 0.351045mm + y = 46.77854331mil + r = 12.75mil + } + ha:simplearc.13 { + thickness = 8.0mil + adelta = 67.988717 + astart = 90.000000 + x = 13.25mil + y = 49.25mil + r = 12.75mil + } + ha:simplearc.14 { + thickness = 8.0mil + adelta = -90.000000 + astart = 90.000000 + x = 0.228854mm + y = 52.99mil + r = 0.228854mm + } + } + height = 1.574801mm + } + ha:9 { + width = 0.651562mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 0.990238mm + thickness = 8.0mil + x1 = 0.228854mm + x2 = 0.578866mm + y1 = 0.990238mm + } + ha:line.1 { + y2 = 0.533038mm + thickness = 8.0mil + x1 = 0.549961mm + x2 = 0.651561mm + y1 = 1.168038mm + } + ha:line.2 { + y2 = 0.761384mm + thickness = 8.0mil + x1 = 0.037188mm + x2 = 0.0 + y1 = 0.533915mm + } + ha:line.3 { + y2 = 0.279038mm + thickness = 8.0mil + x1 = 0.341935mm + x2 = 0.422707mm + y1 = 0.279038mm + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = -68.630916 + astart = 162.245445 + x = -0.21mil + y = 0.990238mm + r = 23.0mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = -96.270387 + astart = 270.000000 + x = 0.422707mm + y = 0.507892mm + r = 0.228854mm + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = 79.815149 + astart = 270.000000 + x = 0.341935mm + y = 0.588664mm + r = 0.309626mm + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = -90.000000 + astart = 90.000000 + x = 0.228854mm + y = 0.761384mm + r = 0.228854mm + } + } + height = 1.573276mm + } + ha:< { + width = 0.624638mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 34.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.624637mm + y1 = 42.0mil + } + ha:line.1 { + y2 = 50.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.560019mm + y1 = 42.0mil + } + } + height = 1.270001mm + } + ha:> { + width = 0.624638mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 34.0mil + thickness = 8.0mil + x1 = 0.624637mm + x2 = 0.064618mm + y1 = 42.0mil + } + ha:line.1 { + y2 = 50.0mil + thickness = 8.0mil + x1 = 0.624637mm + x2 = 0.0 + y1 = 42.0mil + } + } + height = 1.270001mm + } + ha:? { + width = 0.605773mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.140432mm + x2 = 0.132355mm + y1 = 60.0mil + } + ha:line.1 { + y2 = 38.6mil + thickness = 8.0mil + x1 = 0.201011mm + x2 = 0.227312mm + y1 = 1.14046mm + } + ha:line.2 { + y2 = 0.567117mm + thickness = 8.0mil + x1 = 0.531535mm + x2 = 0.576337mm + y1 = 0.636503mm + } + ha:line.3 { + y2 = 27.8mil + thickness = 8.0mil + x1 = 0.372092mm + x2 = 0.458452mm + y1 = 30.3mil + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = 17.272585 + astart = -90.000000 + x = 0.417812mm + y = 66.4mil + r = 1.40716mm + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = -20.872164 + astart = 145.218995 + x = 0.325574mm + y = 0.493457mm + r = 0.250763mm + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = -33.690068 + astart = 180.000000 + x = 0.430512mm + y = 18.5mil + r = 6.9mil + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = -41.552840 + astart = 345.768542 + x = 0.577832mm + y = 42.1mil + r = 14.3mil + } + ha:simplearc.8 { + thickness = 8.0mil + adelta = -90.000000 + astart = -90.000000 + x = 0.417812mm + y = 0.46736mm + r = 7.4mil + } + } + height = 1.574801mm + } + ha:@ { + width = 1.37171mm + delta = 0.17834mm + li:objects { + ha:line.0 { + y2 = 26.0mil + thickness = 8.0mil + x1 = 0.413824mm + x2 = 0.498635mm + y1 = 47.0mil + } + ha:line.1 { + y2 = 19.0mil + thickness = 8.0mil + x1 = 0.715373mm + x2 = 0.984613mm + y1 = 19.0mil + } + ha:line.2 { + y2 = 47.0mil + thickness = 8.0mil + x1 = 0.984613mm + x2 = 0.871532mm + y1 = 19.0mil + } + ha:line.3 { + y2 = 2.0mil + thickness = 8.0mil + x1 = 0.676333mm + x2 = 0.972497mm + y1 = 2.0mil + } + ha:line.4 { + y2 = 1.41732mm + thickness = 8.0mil + x1 = 0.149969mm + x2 = 0.003538mm + y1 = 19.0mil + } + ha:line.5 { + y2 = 0.42926mm + thickness = 8.0mil + x1 = 1.248468mm + x2 = 1.371709mm + y1 = 47.0mil + } + ha:line.6 { + y2 = 70.9mil + thickness = 8.0mil + x1 = 0.25654mm + x2 = 0.44958mm + y1 = 70.0mil + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = -90.000000 + astart = 90.000000 + x = 41.0mil + y = 47.2mil + r = 0.17272mm + } + ha:simplearc.8 { + thickness = 8.0mil + adelta = 80.073754 + astart = 90.000000 + x = 41.0mil + y = 1.16332mm + r = 0.20828mm + } + ha:simplearc.9 { + thickness = 8.0mil + adelta = 70.448005 + astart = 90.000000 + x = 23.5mil + y = 42.5mil + r = 0.29464mm + } + ha:simplearc.10 { + thickness = 8.0mil + adelta = -90.000000 + astart = 90.000000 + x = 23.5mil + y = 1.19126mm + r = 7.2mil + } + ha:simplearc.11 { + thickness = 8.0mil + adelta = 87.153067 + astart = 351.448170 + x = 0.32004mm + y = 57.7mil + r = 0.32004mm + } + ha:simplearc.12 { + thickness = 8.0mil + adelta = 78.876123 + astart = -90.000000 + x = 0.715373mm + y = 0.702673mm + r = 0.220073mm + } + ha:simplearc.13 { + thickness = 8.0mil + adelta = 78.736107 + astart = -90.000000 + x = 0.676333mm + y = 0.587433mm + r = 0.536633mm + } + ha:simplearc.14 { + thickness = 8.0mil + adelta = -87.335143 + astart = -90.000000 + x = 0.972497mm + y = 0.449903mm + r = 0.399103mm + } + } + height = 1.800861mm + } + ha:A { + width = 0.915417mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.663677mm + y1 = 62.0mil + } + ha:line.1 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.915416mm + x2 = 0.663677mm + y1 = 62.0mil + } + ha:line.2 { + y2 = 48.0mil + thickness = 8.0mil + x1 = 0.182185mm + x2 = 0.84631mm + y1 = 48.0mil + } + } + height = 1.574801mm + } + ha:B { + width = 0.863197mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.205969mm + y1 = 62.0mil + } + ha:line.1 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.205969mm + x2 = 0.609829mm + y1 = 11.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 16.96mil + x2 = 0.0 + y1 = 62.0mil + } + ha:line.3 { + y2 = 34.0mil + thickness = 8.0mil + x1 = 0.490017mm + x2 = 0.113081mm + y1 = 34.0mil + } + ha:line.4 { + y2 = 49.6mil + thickness = 8.0mil + x1 = 0.80732mm + x2 = 0.79756mm + y1 = 47.5165748mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = -78.618860 + astart = -90.000000 + x = 0.609829mm + y = 0.535711mm + r = 0.256311mm + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = 87.345804 + astart = 90.000000 + x = 0.48768mm + y = 19.1mil + r = 14.8mil + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = 80.528338 + astart = 90.000000 + x = 0.422072mm + y = 1.194232mm + r = 0.380568mm + } + ha:simplearc.8 { + thickness = 8.0mil + adelta = -103.760785 + astart = -90.000000 + x = 21.1mil + y = 1.14046mm + r = 11.0mil + } + } + height = 1.574801mm + } + ha:C { + width = 0.787376mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.437363mm + x2 = 0.787375mm + y1 = 11.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.231394mm + x2 = 22.89mil + y1 = 62.0mil + } + ha:line.2 { + y2 = 1.34366mm + thickness = 8.0mil + x1 = 0.127737mm + x2 = 0.0 + y1 = 21.0mil + } + ha:simplearc.3 { + thickness = 8.0mil + adelta = -90.000000 + astart = 90.000000 + x = 0.231394mm + y = 52.89mil + r = 0.231394mm + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = 78.336927 + astart = -90.000000 + x = 0.437363mm + y = 0.594843mm + r = 0.315443mm + } + } + height = 1.574801mm + } + ha:D { + width = 0.922021mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.205969mm + x2 = 0.690601mm + y1 = 11.0mil + } + ha:line.1 { + y2 = 52.2mil + thickness = 8.0mil + x1 = 0.921995mm + x2 = 0.794258mm + y1 = 20.1mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.205969mm + x2 = 0.0 + y1 = 11.0mil + } + ha:line.3 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.484632mm + y1 = 62.0mil + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = -90.000000 + astart = 270.000000 + x = 27.19mil + y = 20.21mil + r = 0.231394mm + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = 78.336927 + astart = 90.000000 + x = 0.484657mm + y = 1.261897mm + r = 0.315443mm + } + } + height = 1.577341mm + } + ha:E { + width = 0.798298mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.205969mm + y1 = 62.0mil + } + ha:line.1 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.205969mm + x2 = 0.798297mm + y1 = 11.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 23.32mil + x2 = 0.0 + y1 = 62.0mil + } + ha:line.3 { + y2 = 34.0mil + thickness = 8.0mil + x1 = 0.570789mm + x2 = 0.113081mm + y1 = 34.0mil + } + } + height = 1.574801mm + } + ha:F { + width = 0.798298mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.205969mm + y1 = 62.0mil + } + ha:line.1 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.205969mm + x2 = 0.798297mm + y1 = 11.0mil + } + ha:line.2 { + y2 = 34.0mil + thickness = 8.0mil + x1 = 0.705409mm + x2 = 0.113081mm + y1 = 34.0mil + } + } + height = 1.574801mm + } + ha:G { + width = 0.921996mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.437363mm + x2 = 0.921995mm + y1 = 11.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.231394mm + x2 = 28.19mil + y1 = 62.0mil + } + ha:line.2 { + y2 = 52.89mil + thickness = 8.0mil + x1 = 0.127737mm + x2 = 0.0 + y1 = 21.0mil + } + ha:line.3 { + y2 = 34.0mil + thickness = 8.0mil + x1 = 0.586791mm + x2 = 0.829107mm + y1 = 34.0mil + } + ha:line.4 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.829107mm + x2 = 28.19mil + y1 = 34.0mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = -90.000000 + astart = 90.000000 + x = 0.231394mm + y = 52.89mil + r = 0.231394mm + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = 78.336927 + astart = 270.000000 + x = 0.437363mm + y = 0.594843mm + r = 0.315443mm + } + } + height = 1.574801mm + } + ha:H { + width = 0.986766mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.205969mm + y1 = 62.0mil + } + ha:line.1 { + y2 = 34.0mil + thickness = 8.0mil + x1 = 0.866953mm + x2 = 0.113081mm + y1 = 34.0mil + } + ha:line.2 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.780796mm + x2 = 0.986765mm + y1 = 62.0mil + } + } + height = 1.574801mm + } + ha:I { + width = 0.20597mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.205969mm + y1 = 62.0mil + } + } + height = 1.574801mm + } + ha:J { + width = 0.690602mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 20.67mil + x2 = 0.690601mm + y1 = 52.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 8.48mil + x2 = 0.0 + y1 = 62.0mil + } + ha:simplearc.2 { + thickness = 8.0mil + adelta = 78.708251 + astart = 90.000000 + x = 8.48mil + y = 1.259332mm + r = 0.315468mm + } + } + height = 1.574801mm + } + ha:K { + width = 0.986766mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.205969mm + y1 = 62.0mil + } + ha:line.1 { + y2 = 42.0mil + thickness = 8.0mil + x1 = 0.986765mm + x2 = 3.18mil + y1 = 11.0mil + } + ha:line.2 { + y2 = 0.764963mm + thickness = 8.0mil + x1 = 0.780796mm + x2 = 0.428069mm + y1 = 62.0mil + } + } + height = 1.574801mm + } + ha:L { + width = 0.592329mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.205969mm + y1 = 62.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 23.32mil + y1 = 62.0mil + } + } + height = 1.574801mm + } + ha:M { + width = 1.121386mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.205969mm + y1 = 62.0mil + } + ha:line.1 { + y2 = 40.0mil + thickness = 8.0mil + x1 = 0.205969mm + x2 = 0.546557mm + y1 = 11.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 1.121385mm + x2 = 0.915416mm + y1 = 11.0mil + } + ha:line.3 { + y2 = 40.0mil + thickness = 8.0mil + x1 = 1.121385mm + x2 = 0.546557mm + y1 = 11.0mil + } + } + height = 1.574801mm + } + ha:&2f { + width = 0.798298mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.798297mm + x2 = 0.0 + y1 = 11.0mil + } + } + height = 1.574801mm + } + ha:&3a { + width = 0.100966mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 31.0mil + thickness = 8.0mil + x1 = 0.092888mm + x2 = 3.975mil + y1 = 33.0mil + } + ha:line.1 { + y2 = 54.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.008077mm + y1 = 56.0mil + } + } + height = 1.422401mm + } + ha:&3b { + width = 0.218085mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 56.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.125197mm + y1 = 67.0mil + } + ha:line.1 { + y2 = 33.0mil + thickness = 8.0mil + x1 = 0.210007mm + x2 = 0.218084mm + y1 = 35.0mil + } + } + height = 1.701801mm + } + ha:&3d { + width = 0.687909mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 34.0mil + thickness = 8.0mil + x1 = 0.068656mm + x2 = 0.687908mm + y1 = 34.0mil + } + ha:line.1 { + y2 = 51.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.619252mm + y1 = 51.0mil + } + } + height = 1.295401mm + } + ha:O { + width = 0.894081mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.483133mm + x2 = 0.617753mm + y1 = 11.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.276327mm + x2 = 0.410947mm + y1 = 62.0mil + } + ha:line.2 { + y2 = 51.1mil + thickness = 8.0mil + x1 = 0.114331mm + x2 = 0.0 + y1 = 0.564941mm + } + ha:line.3 { + y2 = 21.8mil + thickness = 8.0mil + x1 = 0.779749mm + x2 = 35.2mil + y1 = 1.289259mm + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = 75.196020 + astart = 90.000000 + x = 16.1mil + y = 1.19126mm + r = 0.38354mm + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = -90.000000 + astart = 90.000000 + x = 10.8mil + y = 51.2mil + r = 10.8mil + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = 75.196020 + astart = -90.000000 + x = 19.1mil + y = 26.1mil + r = 0.38354mm + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = -90.000000 + astart = -90.000000 + x = 0.61976mm + y = 21.8mil + r = 10.8mil + } + } + height = 1.574801mm + } + ha:P { + width = 0.916941mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.205969mm + y1 = 62.0mil + } + ha:line.1 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.636753mm + x2 = 0.205969mm + y1 = 11.0mil + } + ha:line.2 { + y2 = 39.0mil + thickness = 8.0mil + x1 = 0.523672mm + x2 = 0.092888mm + y1 = 39.0mil + } + ha:line.3 { + y2 = 26.6mil + thickness = 8.0mil + x1 = 0.90892mm + x2 = 0.89916mm + y1 = 0.622721mm + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = 80.528338 + astart = 90.000000 + x = 0.523672mm + y = 0.610032mm + r = 0.380568mm + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = -103.760785 + astart = -90.000000 + x = 25.1mil + y = 0.55626mm + r = 11.0mil + } + } + height = 1.574801mm + } + ha:N { + width = 0.986766mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.205969mm + y1 = 62.0mil + } + ha:line.1 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.780796mm + x2 = 0.986765mm + y1 = 62.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.205969mm + x2 = 0.780796mm + y1 = 11.0mil + } + } + height = 1.574801mm + } + ha:R { + width = 0.914401mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.205969mm + y1 = 62.0mil + } + ha:line.1 { + y2 = 39.0mil + thickness = 8.0mil + x1 = 0.523672mm + x2 = 0.092888mm + y1 = 39.0mil + } + ha:line.2 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.636753mm + x2 = 0.205969mm + y1 = 11.0mil + } + ha:line.3 { + y2 = 39.0mil + thickness = 8.0mil + x1 = 0.753872mm + x2 = 0.550596mm + y1 = 62.0mil + } + ha:line.4 { + y2 = 26.6mil + thickness = 8.0mil + x1 = 0.90638mm + x2 = 0.89662mm + y1 = 0.622721mm + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = 80.528338 + astart = 90.000000 + x = 0.521132mm + y = 0.610032mm + r = 0.380568mm + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = -103.760785 + astart = -90.000000 + x = 25.0mil + y = 0.55626mm + r = 11.0mil + } + } + height = 1.574801mm + } + ha:S { + width = 0.864331mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 41.0mil + thickness = 8.0mil + x1 = 0.255247mm + x2 = 0.665635mm + y1 = 0.819137mm + } + ha:simplearc.1 { + thickness = 8.0mil + adelta = -47.997193 + astart = 180.000000 + x = 0.449536mm + y = 1.264838mm + r = 0.345522mm + } + ha:simplearc.2 { + thickness = 8.0mil + adelta = -58.233191 + astart = 111.607450 + x = 0.416715mm + y = 34.5mil + r = 27.5mil + } + ha:simplearc.3 { + thickness = 8.0mil + adelta = 63.432338 + astart = 178.228530 + x = 0.551335mm + y = 49.5mil + r = 0.24384mm + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = -27.159796 + astart = -90.000000 + x = 0.564035mm + y = 0.93726mm + r = 0.65786mm + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = 69.520750 + astart = 262.470073 + x = 0.510695mm + y = 26.8mil + r = 15.9mil + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = 86.104823 + astart = 335.556045 + x = 0.370995mm + y = 23.8mil + r = 0.24384mm + } + } + height = 1.574801mm + } + ha:Q { + width = 0.896418mm + delta = 0.180136mm + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.617753mm + x2 = 0.896417mm + y1 = 51.0mil + } + ha:line.1 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.483133mm + x2 = 0.617753mm + y1 = 11.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.276327mm + x2 = 0.410947mm + y1 = 62.0mil + } + ha:line.3 { + y2 = 51.1mil + thickness = 8.0mil + x1 = 0.114331mm + x2 = 0.0 + y1 = 0.564941mm + } + ha:line.4 { + y2 = 21.8mil + thickness = 8.0mil + x1 = 0.779749mm + x2 = 35.2mil + y1 = 1.289259mm + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = 75.196020 + astart = 90.000000 + x = 16.1mil + y = 1.19126mm + r = 0.38354mm + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = -90.000000 + astart = 90.000000 + x = 10.8mil + y = 51.2mil + r = 10.8mil + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = 75.196020 + astart = -90.000000 + x = 19.1mil + y = 26.1mil + r = 0.38354mm + } + ha:simplearc.8 { + thickness = 8.0mil + adelta = -90.000000 + astart = -90.000000 + x = 0.61976mm + y = 21.8mil + r = 10.8mil + } + } + height = 1.574801mm + } + ha:U { + width = 0.936804mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.1mil + x2 = 0.156007mm + y1 = 49.0mil + } + ha:line.1 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.782463mm + x2 = 0.936803mm + y1 = 1.247098mm + } + ha:line.2 { + y2 = 52.7mil + thickness = 8.0mil + x1 = 0.1mil + x2 = 0.0 + y1 = 49.0mil + } + ha:simplearc.3 { + thickness = 8.0mil + adelta = 67.796888 + astart = 359.432734 + x = 0.22098mm + y = 52.2mil + r = 0.22098mm + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = 93.961205 + astart = 68.198591 + x = 0.33274mm + y = 1.10236mm + r = 18.6mil + } + } + height = 1.574801mm + } + ha:V { + width = 0.969265mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.278663mm + y1 = 11.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.969264mm + x2 = 0.278663mm + y1 = 11.0mil + } + } + height = 1.574801mm + } + ha:T { + width = 0.780797mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.197891mm + x2 = 15.9mil + y1 = 62.0mil + } + ha:line.1 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.780796mm + y1 = 11.0mil + } + } + height = 1.574801mm + } + ha:X { + width = 1.14831mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.205969mm + x2 = 37.1mil + y1 = 11.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 1.148309mm + x2 = 0.0 + y1 = 11.0mil + } + } + height = 1.574801mm + } + ha:Y { + width = 0.915417mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 35.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.360782mm + y1 = 11.0mil + } + ha:line.1 { + y2 = 35.0mil + thickness = 8.0mil + x1 = 0.915416mm + x2 = 0.360782mm + y1 = 11.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.360782mm + x2 = 0.251739mm + y1 = 35.0mil + } + } + height = 1.574801mm + } + ha:W { + width = 1.184657mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.090195mm + y1 = 11.0mil + } + ha:line.1 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 0.090195mm + x2 = 0.523672mm + y1 = 62.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 46.64mil + x2 = 0.682523mm + y1 = 11.0mil + } + ha:line.3 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 0.682523mm + x2 = 0.523672mm + y1 = 62.0mil + } + } + height = 1.574801mm + } + ha:[ { + width = 0.415977mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 68.0mil + thickness = 8.0mil + x1 = 0.254432mm + x2 = 0.0 + y1 = 5.0mil + } + ha:line.1 { + y2 = 68.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 6.36mil + y1 = 68.0mil + } + ha:line.2 { + y2 = 5.0mil + thickness = 8.0mil + x1 = 0.254432mm + x2 = 0.415976mm + y1 = 5.0mil + } + } + height = 1.727201mm + } + ha:^ { + width = 0.430785mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 0.0 + thickness = 8.0mil + x1 = 0.0 + x2 = 0.251739mm + y1 = 9.0mil + } + ha:line.1 { + y2 = 0.0 + thickness = 8.0mil + x1 = 16.96mil + x2 = 0.251739mm + y1 = 9.0mil + } + } + height = 0.228601mm + } + ha:Z { + width = 0.959842mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.205969mm + x2 = 0.959841mm + y1 = 11.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.753872mm + y1 = 62.0mil + } + ha:line.2 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.959841mm + y1 = 62.0mil + } + } + height = 1.574801mm + } + ha:` { + width = 0.263856mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 10.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.263855mm + y1 = 2.0mil + } + } + height = 0.254001mm + } + ha:_ { + width = 0.646177mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 68.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 25.44mil + y1 = 68.0mil + } + } + height = 1.727201mm + } + } + cell_width = 1.444474mm + cell_height = 2.033595mm + } +} Index: tags/1.0.5/font/aussiefont-sans-regular =================================================================== --- tags/1.0.5/font/aussiefont-sans-regular (nonexistent) +++ tags/1.0.5/font/aussiefont-sans-regular (revision 10414) @@ -0,0 +1,3760 @@ +li:pcb-rnd-font-v1 { + ha:geda_pcb { + id = 0 + ha:symbols { + ha:&09 { + width = 0.685801mm + delta = 0.103633mm + li:objects { + ha:line.0 { + y2 = 36.0mil + thickness = 3.0mil + x1 = 0.0 + x2 = 27.0mil + y1 = 36.0mil + } + ha:line.1 { + y2 = 30.0mil + thickness = 3.0mil + x1 = 27.0mil + x2 = 22.0mil + y1 = 36.0mil + } + ha:line.2 { + y2 = 42.0mil + thickness = 3.0mil + x1 = 27.0mil + x2 = 22.0mil + y1 = 36.0mil + } + ha:line.3 { + y2 = 42.0mil + thickness = 3.0mil + x1 = 0.0 + x2 = 5.0mil + y1 = 36.0mil + } + ha:line.4 { + y2 = 30.0mil + thickness = 3.0mil + x1 = 0.0 + x2 = 5.0mil + y1 = 36.0mil + } + } + height = 1.066801mm + } + ha:&0A { + width = 0.889001mm + delta = 10.0mil + li:objects { + ha:line.0 { + y2 = 10.0mil + thickness = 3.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 40.0mil + } + ha:line.1 { + y2 = 40.0mil + thickness = 3.0mil + x1 = 0.0 + x2 = 15.0mil + y1 = 40.0mil + } + ha:line.2 { + y2 = 45.0mil + thickness = 3.0mil + x1 = 20.0mil + x2 = 20.0mil + y1 = 75.0mil + } + ha:line.3 { + y2 = 45.0mil + thickness = 3.0mil + x1 = 20.0mil + x2 = 35.0mil + y1 = 45.0mil + } + ha:line.4 { + y2 = 60.0mil + thickness = 3.0mil + x1 = 20.0mil + x2 = 30.0mil + y1 = 60.0mil + } + } + height = 1.905001mm + } + ha:&0D { + width = 0.889001mm + delta = 0.253999mm + li:objects { + ha:line.0 { + y2 = 15.0mil + thickness = 3.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 35.0mil + } + ha:line.1 { + y2 = 10.0mil + thickness = 3.0mil + x1 = 5.0mil + x2 = 10.0mil + y1 = 10.0mil + } + ha:line.2 { + y2 = 40.0mil + thickness = 3.0mil + x1 = 5.0mil + x2 = 10.0mil + y1 = 40.0mil + } + ha:line.3 { + y2 = 45.0mil + thickness = 3.0mil + x1 = 20.0mil + x2 = 20.0mil + y1 = 75.0mil + } + ha:line.4 { + y2 = 45.0mil + thickness = 3.0mil + x1 = 20.0mil + x2 = 30.0mil + y1 = 45.0mil + } + ha:line.5 { + y2 = 60.0mil + thickness = 3.0mil + x1 = 20.0mil + x2 = 30.0mil + y1 = 60.0mil + } + ha:line.6 { + y2 = 55.0mil + thickness = 3.0mil + x1 = 35.0mil + x2 = 35.0mil + y1 = 50.0mil + } + ha:line.7 { + y2 = 75.0mil + thickness = 3.0mil + x1 = 30.0mil + x2 = 35.0mil + y1 = 60.0mil + } + ha:simplearc.8 { + thickness = 3.0mil + adelta = -90.000000 + astart = -90.000000 + x = 10.0mil + y = 15.0mil + r = 5.0mil + } + ha:simplearc.9 { + thickness = 3.0mil + adelta = 90.000000 + astart = 270.000000 + x = 5.0mil + y = 15.0mil + r = 5.0mil + } + ha:simplearc.10 { + thickness = 3.0mil + adelta = 90.000000 + astart = 90.000000 + x = 10.0mil + y = 35.0mil + r = 5.0mil + } + ha:simplearc.11 { + thickness = 3.0mil + adelta = -90.000000 + astart = 90.000000 + x = 5.0mil + y = 35.0mil + r = 5.0mil + } + ha:simplearc.12 { + thickness = 3.0mil + adelta = 90.000000 + astart = 90.000000 + x = 30.0mil + y = 55.0mil + r = 5.0mil + } + ha:simplearc.13 { + thickness = 3.0mil + adelta = -90.000000 + astart = -90.000000 + x = 30.0mil + y = 50.0mil + r = 5.0mil + } + } + height = 1.905001mm + } + ha:] { + width = 0.152401mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 68.0mil + thickness = 8.0mil + x1 = 6.0mil + x2 = 6.0mil + y1 = 5.0mil + } + ha:line.1 { + y2 = 68.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 6.0mil + y1 = 68.0mil + } + ha:line.2 { + y2 = 5.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 6.0mil + y1 = 5.0mil + } + } + height = 1.727201mm + } + ha:&5c { + width = 0.558801mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 22.0mil + y1 = 11.0mil + } + } + height = 1.574801mm + } + ha:b { + width = 0.584201mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 10.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 17.0mil + y1 = 62.0mil + } + ha:line.2 { + y2 = 56.0mil + thickness = 8.0mil + x1 = 23.0mil + x2 = 23.0mil + y1 = 34.0mil + } + ha:line.3 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 17.0mil + y1 = 28.0mil + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = 90.000000 + astart = 180.000000 + x = 17.0mil + y = 34.0mil + r = 6.0mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = 90.000000 + astart = 90.000000 + x = 17.0mil + y = 56.0mil + r = 6.0mil + } + } + height = 1.574801mm + } + ha:c { + width = 0.431801mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 6.0mil + x2 = 17.0mil + y1 = 62.0mil + } + ha:line.1 { + y2 = 56.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 34.0mil + } + ha:line.2 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 6.0mil + x2 = 17.0mil + y1 = 28.0mil + } + ha:simplearc.3 { + thickness = 8.0mil + adelta = -90.000000 + astart = 0.000000 + x = 6.0mil + y = 34.0mil + r = 6.0mil + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = -90.000000 + astart = 90.000000 + x = 6.0mil + y = 56.0mil + r = 6.0mil + } + } + height = 1.574801mm + } + ha:a { + width = 0.584201mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 4.0mil + x2 = 16.0mil + y1 = 28.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 9.0mil + x2 = 23.0mil + y1 = 62.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 23.0mil + x2 = 23.0mil + y1 = 35.0mil + } + ha:line.3 { + y2 = 44.0mil + thickness = 8.0mil + x1 = 9.0mil + x2 = 23.0mil + y1 = 44.0mil + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = -180.000000 + astart = 90.000000 + x = 9.0mil + y = 53.0mil + r = 9.0mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = 90.000000 + astart = 180.000000 + x = 16.0mil + y = 35.0mil + r = 7.0mil + } + } + height = 1.574801mm + } + ha:e { + width = 0.558801mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 39.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 55.0mil + } + ha:line.1 { + y2 = 45.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 22.0mil + y1 = 45.0mil + } + ha:line.2 { + y2 = 39.0mil + thickness = 8.0mil + x1 = 22.0mil + x2 = 22.0mil + y1 = 45.0mil + } + ha:line.3 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 7.0mil + x2 = 22.0mil + y1 = 62.0mil + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = -180.000000 + astart = 0.000000 + x = 11.0mil + y = 39.0mil + r = 11.0mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = 90.000000 + astart = 0.000000 + x = 7.0mil + y = 55.0mil + r = 7.0mil + } + } + height = 1.574801mm + } + ha:f { + width = 0.431801mm + delta = 0.279399mm + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 13.0mil + x2 = 17.0mil + y1 = 11.0mil + } + ha:line.1 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 17.0mil + y1 = 28.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 6.0mil + x2 = 6.0mil + y1 = 18.0mil + } + ha:simplearc.3 { + thickness = 8.0mil + adelta = -90.000000 + astart = 0.000000 + x = 13.0mil + y = 18.0mil + r = 7.0mil + } + } + height = 1.574801mm + } + ha:d { + width = 0.584201mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 23.0mil + x2 = 23.0mil + y1 = 10.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 6.0mil + x2 = 23.0mil + y1 = 62.0mil + } + ha:line.2 { + y2 = 56.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 34.0mil + } + ha:line.3 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 6.0mil + x2 = 23.0mil + y1 = 28.0mil + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = -90.000000 + astart = 0.000000 + x = 6.0mil + y = 34.0mil + r = 6.0mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = -90.000000 + astart = 90.000000 + x = 6.0mil + y = 56.0mil + r = 6.0mil + } + } + height = 1.574801mm + } + ha:h { + width = 0.584201mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 10.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 23.0mil + x2 = 23.0mil + y1 = 34.0mil + } + ha:line.2 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 17.0mil + y1 = 28.0mil + } + ha:simplearc.3 { + thickness = 8.0mil + adelta = 90.000000 + astart = 180.000000 + x = 17.0mil + y = 34.0mil + r = 6.0mil + } + } + height = 1.574801mm + } + ha:i { + width = 0.001um + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 14.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 11.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 28.0mil + } + } + height = 1.574801mm + } + ha:g { + width = 0.584201mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 23.0mil + x2 = 23.0mil + y1 = 73.0mil + } + ha:line.1 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 6.0mil + x2 = 23.0mil + y1 = 28.0mil + } + ha:line.2 { + y2 = 34.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 56.0mil + } + ha:line.3 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 6.0mil + x2 = 23.0mil + y1 = 62.0mil + } + ha:line.4 { + y2 = 80.0mil + thickness = 8.0mil + x1 = 3.0mil + x2 = 16.0mil + y1 = 80.0mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = 90.000000 + astart = 90.000000 + x = 16.0mil + y = 73.0mil + r = 7.0mil + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = 90.000000 + astart = -0.000000 + x = 6.0mil + y = 56.0mil + r = 6.0mil + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = 90.000000 + astart = -90.000000 + x = 6.0mil + y = 34.0mil + r = 6.0mil + } + } + height = 2.032001mm + } + ha:k { + width = 0.584201mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 11.0mil + } + ha:line.1 { + y2 = 46.0mil + thickness = 8.0mil + x1 = 23.0mil + x2 = 0.0 + y1 = 28.0mil + } + ha:line.2 { + y2 = 0.967678mm + thickness = 8.0mil + x1 = 23.0mil + x2 = 0.256478mm + y1 = 62.0mil + } + } + height = 1.574801mm + } + ha:l { + width = 0.152401mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 56.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 11.0mil + } + ha:simplearc.1 { + thickness = 8.0mil + adelta = 90.000000 + astart = 0.000000 + x = 6.0mil + y = 56.0mil + r = 6.0mil + } + } + height = 1.574801mm + } + ha:j { + width = 0.203202mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 14.0mil + thickness = 8.0mil + x1 = 0.203201mm + x2 = 0.203201mm + y1 = 11.0mil + } + ha:line.1 { + y2 = 72.0mil + thickness = 8.0mil + x1 = 0.203201mm + x2 = 0.203201mm + y1 = 28.0mil + } + ha:simplearc.2 { + thickness = 8.0mil + adelta = -90.000000 + astart = 180.000000 + x = 0.001um + y = 72.0mil + r = 8.0mil + } + } + height = 2.032001mm + } + ha:n { + width = 0.584201mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 14.0mil + y1 = 28.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 23.0mil + x2 = 23.0mil + y1 = 37.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 28.0mil + } + ha:simplearc.3 { + thickness = 8.0mil + adelta = -90.000000 + astart = -90.000000 + x = 14.0mil + y = 37.0mil + r = 9.0mil + } + } + height = 1.574801mm + } + ha:o { + width = 0.579209mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 39.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 51.0mil + } + ha:line.1 { + y2 = 51.0mil + thickness = 8.0mil + x1 = 0.579208mm + x2 = 0.579208mm + y1 = 39.0mil + } + ha:simplearc.2 { + thickness = 8.0mil + adelta = 180.000000 + astart = -0.000000 + x = 0.289604mm + y = 51.0mil + r = 0.289604mm + } + ha:simplearc.3 { + thickness = 8.0mil + adelta = -180.000000 + astart = 0.000000 + x = 0.289604mm + y = 39.0mil + r = 0.289604mm + } + } + height = 1.585005mm + } + ha:m { + width = 0.863601mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 25.0mil + y1 = 28.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 34.0mil + x2 = 34.0mil + y1 = 37.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 28.0mil + } + ha:line.3 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 17.0mil + x2 = 17.0mil + y1 = 28.0mil + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = -90.000000 + astart = -90.000000 + x = 25.0mil + y = 37.0mil + r = 9.0mil + } + } + height = 1.574801mm + } + ha:q { + width = 0.584201mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 23.0mil + x2 = 23.0mil + y1 = 80.0mil + } + ha:line.1 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 23.0mil + x2 = 6.0mil + y1 = 28.0mil + } + ha:line.2 { + y2 = 56.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 34.0mil + } + ha:line.3 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 6.0mil + x2 = 23.0mil + y1 = 62.0mil + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = 90.000000 + astart = 0.000000 + x = 6.0mil + y = 56.0mil + r = 6.0mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = 90.000000 + astart = -90.000000 + x = 6.0mil + y = 34.0mil + r = 6.0mil + } + } + height = 2.032001mm + } + ha:r { + width = 0.431801mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 62.0mil + } + ha:line.1 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 11.0mil + y1 = 28.0mil + } + ha:simplearc.2 { + thickness = 8.0mil + adelta = 90.000000 + astart = 180.000000 + x = 11.0mil + y = 34.0mil + r = 6.0mil + } + } + height = 1.574801mm + } + ha:p { + width = 0.584201mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 80.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 28.0mil + } + ha:line.1 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 17.0mil + y1 = 28.0mil + } + ha:line.2 { + y2 = 56.0mil + thickness = 8.0mil + x1 = 23.0mil + x2 = 23.0mil + y1 = 34.0mil + } + ha:line.3 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 17.0mil + y1 = 62.0mil + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = -90.000000 + astart = 180.000000 + x = 17.0mil + y = 56.0mil + r = 6.0mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = -90.000000 + astart = 270.000000 + x = 17.0mil + y = 34.0mil + r = 6.0mil + } + } + height = 2.032001mm + } + ha:t { + width = 0.431801mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 6.0mil + x2 = 6.0mil + y1 = 11.0mil + } + ha:line.1 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 17.0mil + y1 = 28.0mil + } + } + height = 1.574801mm + } + ha:u { + width = 0.584201mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 55.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 28.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 7.0mil + x2 = 23.0mil + y1 = 62.0mil + } + ha:line.2 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 23.0mil + x2 = 23.0mil + y1 = 62.0mil + } + ha:simplearc.3 { + thickness = 8.0mil + adelta = 90.000000 + astart = 0.000000 + x = 7.0mil + y = 55.0mil + r = 7.0mil + } + } + height = 1.574801mm + } + ha:s { + width = 0.618594mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 1.141047mm + thickness = 8.0mil + x1 = 0.204781mm + x2 = 0.411197mm + y1 = 1.119181mm + } + ha:simplearc.1 { + thickness = 8.0mil + adelta = -17.031080 + astart = 90.000000 + x = 0.380885mm + y = 0.368674mm + r = 47.0mil + } + ha:simplearc.2 { + thickness = 8.0mil + adelta = -186.525031 + astart = 269.133210 + x = 0.407981mm + y = 1.353612mm + r = 0.210612mm + } + ha:simplearc.3 { + thickness = 8.0mil + adelta = -17.605835 + astart = 268.781125 + x = 0.179381mm + y = 75.0mil + r = 47.0mil + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = -180.000000 + astart = 90.000000 + x = 0.204781mm + y = 36.0mil + r = 0.204781mm + } + } + height = 1.564225mm + } + ha:w { + width = 0.914401mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 9.0mil + y1 = 28.0mil + } + ha:line.1 { + y2 = 40.0mil + thickness = 8.0mil + x1 = 9.0mil + x2 = 18.0mil + y1 = 62.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 36.0mil + x2 = 27.0mil + y1 = 28.0mil + } + ha:line.3 { + y2 = 40.0mil + thickness = 8.0mil + x1 = 27.0mil + x2 = 18.0mil + y1 = 62.0mil + } + } + height = 1.574801mm + } + ha:x { + width = 0.558801mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 22.0mil + y1 = 28.0mil + } + ha:line.1 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 22.0mil + y1 = 62.0mil + } + } + height = 1.574801mm + } + ha:v { + width = 0.558801mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 11.0mil + y1 = 28.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 22.0mil + x2 = 11.0mil + y1 = 28.0mil + } + } + height = 1.574801mm + } + ha:z { + width = 0.558801mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 22.0mil + y1 = 28.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 22.0mil + x2 = 0.0 + y1 = 28.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 22.0mil + y1 = 62.0mil + } + } + height = 1.574801mm + } + ha:~ { + width = 0.589861mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 0.922452mm + thickness = 8.0mil + x1 = 0.264009mm + x2 = 0.325852mm + y1 = 0.863007mm + } + ha:simplearc.1 { + thickness = 8.0mil + adelta = -31.668558 + astart = 90.000000 + x = 0.476575mm + y = 0.678111mm + r = 0.287089mm + } + ha:simplearc.2 { + thickness = 8.0mil + adelta = -31.668558 + astart = -90.000000 + x = 0.113286mm + y = 1.107348mm + r = 0.287089mm + } + ha:simplearc.3 { + thickness = 8.0mil + adelta = -19.075098 + astart = 132.273689 + x = 0.316486mm + y = 0.591659mm + r = 16.0mil + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = -19.075098 + astart = 312.273689 + x = 0.273375mm + y = 47.0mil + r = 16.0mil + } + } + height = 0.965201mm + } + ha:y { + width = 0.584201mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 12.0mil + y1 = 28.0mil + } + ha:line.1 { + y2 = 80.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 6.0mil + y1 = 80.0mil + } + ha:line.2 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 6.0mil + x2 = 23.0mil + y1 = 80.0mil + } + } + height = 2.032001mm + } + ha:&7d { + width = 0.279402mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 63.0mil + thickness = 8.0mil + x1 = 0.127001mm + x2 = 0.127001mm + y1 = 42.0mil + } + ha:line.1 { + y2 = 9.0mil + thickness = 8.0mil + x1 = 0.127001mm + x2 = 0.127001mm + y1 = 30.0mil + } + ha:simplearc.2 { + thickness = 8.0mil + adelta = -90.000000 + astart = -90.000000 + x = 0.001um + y = 9.0mil + r = 5.0mil + } + ha:simplearc.3 { + thickness = 8.0mil + adelta = -90.000000 + astart = 90.000000 + x = 0.279401mm + y = 30.0mil + r = 6.0mil + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = 90.000000 + astart = 90.000000 + x = 0.001um + y = 63.0mil + r = 5.0mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = 90.000000 + astart = -90.000000 + x = 0.279401mm + y = 42.0mil + r = 6.0mil + } + } + height = 1.727201mm + } + ha:| { + width = 0.001um + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 71.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 43.0mil + } + ha:line.1 { + y2 = 3.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 31.0mil + } + } + height = 1.803401mm + } + ha:&7b { + width = 0.279402mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 63.0mil + thickness = 8.0mil + x1 = 0.152401mm + x2 = 0.152401mm + y1 = 42.0mil + } + ha:line.1 { + y2 = 30.0mil + thickness = 8.0mil + x1 = 0.152401mm + x2 = 0.152401mm + y1 = 9.0mil + } + ha:simplearc.2 { + thickness = 8.0mil + adelta = 90.000000 + astart = 270.000000 + x = 0.279401mm + y = 9.0mil + r = 5.0mil + } + ha:simplearc.3 { + thickness = 8.0mil + adelta = 90.000000 + astart = 90.000000 + x = 0.001um + y = 30.0mil + r = 6.0mil + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = -90.000000 + astart = 90.000000 + x = 0.279401mm + y = 63.0mil + r = 5.0mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = -90.000000 + astart = 270.000000 + x = 0.001um + y = 42.0mil + r = 6.0mil + } + } + height = 1.727201mm + } + ha:&20 { + width = 0.0 + delta = 31.0mil + li:objects { + } + height = 0.0 + } + ha:&23 { + width = 0.889001mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 9.0mil + x2 = 9.0mil + y1 = 11.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 26.0mil + x2 = 26.0mil + y1 = 11.0mil + } + ha:line.2 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 35.0mil + y1 = 28.0mil + } + ha:line.3 { + y2 = 45.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 35.0mil + y1 = 45.0mil + } + } + height = 1.574801mm + } + ha:&26 { + width = 0.869177mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 0.579653mm + thickness = 8.0mil + x1 = 0.716776mm + x2 = 0.09087mm + y1 = 62.0mil + } + ha:line.1 { + y2 = 1.266107mm + thickness = 8.0mil + x1 = 0.469006mm + x2 = 0.014123mm + y1 = 0.597619mm + } + ha:line.2 { + y2 = 45.0mil + thickness = 8.0mil + x1 = 0.316401mm + x2 = 0.869176mm + y1 = 1.565466mm + } + ha:simplearc.3 { + thickness = 8.0mil + adelta = 130.556045 + astart = 340.000000 + x = 0.234176mm + y = 53.0mil + r = 0.234176mm + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = 238.570434 + astart = 147.994617 + x = 0.284976mm + y = 19.0mil + r = 0.217017mm + } + } + height = 1.580377mm + } + ha:! { + width = 0.001um + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 45.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 11.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 59.0mil + } + } + height = 1.574801mm + } + ha:" { + width = 0.457201mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 0.0 + thickness = 8.0mil + x1 = 0.0 + x2 = 3.0mil + y1 = 11.0mil + } + ha:line.1 { + y2 = 0.0 + thickness = 8.0mil + x1 = 15.0mil + x2 = 18.0mil + y1 = 11.0mil + } + } + height = 0.279401mm + } + ha:$ { + width = 0.580214mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.299232mm + x2 = 0.299232mm + y1 = 11.0mil + } + ha:line.1 { + y2 = 41.0mil + thickness = 8.0mil + x1 = 0.103269mm + x2 = 0.477032mm + y1 = 0.826602mm + } + ha:simplearc.2 { + thickness = 8.0mil + adelta = -19.653824 + astart = 90.000000 + x = 12.7807874mil + y = 18.0mil + r = 38.0mil + } + ha:simplearc.3 { + thickness = 8.0mil + adelta = -18.434949 + astart = 270.000000 + x = 0.273832mm + y = 55.0mil + r = 38.0mil + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = 168.035280 + astart = 250.000000 + x = 0.217007mm + y = 0.644334mm + r = 0.214844mm + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = 156.595310 + astart = 83.659808 + x = 0.375432mm + y = 48.0mil + r = 0.204781mm + } + } + height = 1.574801mm + } + ha:% { + width = 1.193801mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 46.0mil + x2 = 0.0 + y1 = 11.0mil + } + ha:simplearc.1 { + thickness = 8.0mil + adelta = 360.000000 + astart = 0.000000 + x = 38.0mil + y = 53.0mil + r = 9.0mil + } + ha:simplearc.2 { + thickness = 8.0mil + adelta = 360.000000 + astart = 0.000000 + x = 9.0mil + y = 20.0mil + r = 9.0mil + } + } + height = 1.574801mm + } + ha:' { + width = 0.076201mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 0.0 + thickness = 8.0mil + x1 = 0.0 + x2 = 3.0mil + y1 = 11.0mil + } + } + height = 0.279401mm + } + ha:( { + width = 0.134159mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 47.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 26.0mil + } + ha:simplearc.1 { + thickness = 8.0mil + adelta = 27.979474 + astart = 0.000000 + x = 1.147787mm + y = 47.0mil + r = 1.147787mm + } + ha:simplearc.2 { + thickness = 8.0mil + adelta = -27.979474 + astart = 0.000000 + x = 1.147787mm + y = 26.0mil + r = 1.147787mm + } + } + height = 1.732291mm + } + ha:) { + width = 0.13416mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 47.0mil + thickness = 8.0mil + x1 = 0.134159mm + x2 = 0.134159mm + y1 = 26.0mil + } + ha:simplearc.1 { + thickness = 8.0mil + adelta = -27.979474 + astart = 180.000000 + x = -1.013628mm + y = 47.0mil + r = 1.147787mm + } + ha:simplearc.2 { + thickness = 8.0mil + adelta = 27.979474 + astart = 180.000000 + x = -1.013628mm + y = 26.0mil + r = 1.147787mm + } + } + height = 1.732291mm + } + ha:* { + width = 0.558801mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 51.0mil + thickness = 8.0mil + x1 = 3.0mil + x2 = 19.0mil + y1 = 34.0mil + } + ha:line.1 { + y2 = 43.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 22.0mil + y1 = 43.0mil + } + ha:line.2 { + y2 = 51.0mil + thickness = 8.0mil + x1 = 19.0mil + x2 = 3.0mil + y1 = 34.0mil + } + } + height = 1.295401mm + } + ha:+ { + width = 0.558801mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 43.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 22.0mil + y1 = 43.0mil + } + ha:line.1 { + y2 = 54.0mil + thickness = 8.0mil + x1 = 11.0mil + x2 = 11.0mil + y1 = 32.0mil + } + } + height = 1.371601mm + } + ha:, { + width = 0.076201mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 65.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 3.0mil + y1 = 76.0mil + } + } + height = 1.930401mm + } + ha:- { + width = 0.558801mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 42.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 22.0mil + y1 = 42.0mil + } + } + height = 1.066801mm + } + ha:. { + width = 0.005081mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 60.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.2mil + y1 = 1.60782mm + } + } + height = 1.607821mm + } + ha:0 { + width = 0.609601mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 0.347982mm + thickness = 8.0mil + x1 = 0.224756mm + x2 = 0.177914mm + y1 = 0.29583mm + } + ha:line.1 { + y2 = 1.506218mm + thickness = 8.0mil + x1 = 0.384844mm + x2 = 0.431686mm + y1 = 1.55837mm + } + ha:line.2 { + y2 = 0.347982mm + thickness = 8.0mil + x1 = 0.384844mm + x2 = 0.431686mm + y1 = 0.29583mm + } + ha:line.3 { + y2 = 1.55837mm + thickness = 8.0mil + x1 = 0.177914mm + x2 = 0.224756mm + y1 = 1.506218mm + } + ha:line.4 { + y2 = 37.0mil + thickness = 8.0mil + x1 = 24.0mil + x2 = 24.0mil + y1 = 36.0mil + } + ha:line.5 { + y2 = 37.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 36.0mil + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = 34.875328 + astart = 180.000000 + x = -15.0mil + y = 36.0mil + r = 39.0mil + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = 34.875328 + astart = 0.000000 + x = 39.0mil + y = 37.0mil + r = 39.0mil + } + ha:simplearc.8 { + thickness = 8.0mil + adelta = -34.875328 + astart = 180.000000 + x = -15.0mil + y = 37.0mil + r = 39.0mil + } + ha:simplearc.9 { + thickness = 8.0mil + adelta = -46.397181 + astart = 113.198591 + x = 12.0mil + y = 54.0mil + r = 8.0mil + } + ha:simplearc.10 { + thickness = 8.0mil + adelta = -34.875328 + astart = 0.000000 + x = 39.0mil + y = 36.0mil + r = 39.0mil + } + ha:simplearc.11 { + thickness = 8.0mil + adelta = -46.397181 + astart = 293.198591 + x = 12.0mil + y = 19.0mil + r = 8.0mil + } + } + height = 1.574801mm + } + ha:1 { + width = 0.279401mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 11.0mil + y1 = 22.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 11.0mil + x2 = 11.0mil + y1 = 11.0mil + } + } + height = 1.574801mm + } + ha:2 { + width = 0.59396mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.009759mm + x2 = 0.568559mm + y1 = 62.0mil + } + ha:line.1 { + y2 = 0.741018mm + thickness = 8.0mil + x1 = 0.009759mm + x2 = 0.550523mm + y1 = 62.0mil + } + ha:simplearc.2 { + thickness = 8.0mil + adelta = -192.528808 + astart = 341.565051 + x = 0.289159mm + y = 23.0mil + r = 12.0mil + } + } + height = 1.574801mm + } + ha:3 { + width = 0.584201mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 13.0mil + y1 = 11.0mil + } + ha:line.1 { + y2 = 34.0mil + thickness = 8.0mil + x1 = 5.0mil + x2 = 13.0mil + y1 = 34.0mil + } + ha:line.2 { + y2 = 50.0mil + thickness = 8.0mil + x1 = 23.0mil + x2 = 23.0mil + y1 = 45.0mil + } + ha:line.3 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 11.0mil + y1 = 62.0mil + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = 90.000000 + astart = 90.000000 + x = 11.0mil + y = 50.0mil + r = 12.0mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = 90.000000 + astart = 180.000000 + x = 12.0mil + y = 45.0mil + r = 11.0mil + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = -90.000000 + astart = 180.000000 + x = 10.0mil + y = 21.0mil + r = 13.0mil + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = -90.000000 + astart = -90.000000 + x = 13.0mil + y = 21.0mil + r = 10.0mil + } + } + height = 1.574801mm + } + ha:4 { + width = 0.711201mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 51.0mil + thickness = 8.0mil + x1 = 11.0mil + x2 = 0.0 + y1 = 11.0mil + } + ha:line.1 { + y2 = 51.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 28.0mil + y1 = 51.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 19.0mil + x2 = 19.0mil + y1 = 39.0mil + } + } + height = 1.574801mm + } + ha:5 { + width = 0.584201mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 23.0mil + x2 = 0.0 + y1 = 11.0mil + } + ha:line.1 { + y2 = 34.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 11.0mil + } + ha:line.2 { + y2 = 34.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 11.0mil + y1 = 34.0mil + } + ha:line.3 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 11.0mil + x2 = 0.0 + y1 = 62.0mil + } + ha:line.4 { + y2 = 46.0mil + thickness = 8.0mil + x1 = 23.0mil + x2 = 23.0mil + y1 = 50.0mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = 90.000000 + astart = 90.000000 + x = 11.0mil + y = 50.0mil + r = 12.0mil + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = -90.000000 + astart = -90.000000 + x = 11.0mil + y = 46.0mil + r = 12.0mil + } + } + height = 1.574801mm + } + ha:6 { + width = 0.584201mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 34.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 13.0mil + y1 = 34.0mil + } + ha:line.1 { + y2 = 52.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 30.0mil + } + ha:line.2 { + y2 = 44.0mil + thickness = 8.0mil + x1 = 23.0mil + x2 = 23.0mil + y1 = 52.0mil + } + ha:line.3 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 10.0mil + x2 = 13.0mil + y1 = 62.0mil + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = -83.659808 + astart = 0.000000 + x = 19.0mil + y = 30.0mil + r = 19.0mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = 90.000000 + astart = 90.000000 + x = 13.0mil + y = 52.0mil + r = 10.0mil + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = -90.000000 + astart = 90.000000 + x = 10.0mil + y = 52.0mil + r = 10.0mil + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = -90.000000 + astart = -90.000000 + x = 13.0mil + y = 44.0mil + r = 10.0mil + } + } + height = 1.574801mm + } + ha:7 { + width = 0.584201mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 17.0mil + } + ha:line.1 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 23.0mil + y1 = 11.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 23.0mil + x2 = 12.0mil + y1 = 11.0mil + } + } + height = 1.574801mm + } + ha:8 { + width = 0.609601mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 25.0mil + thickness = 8.0mil + x1 = 1.0mil + x2 = 1.0mil + y1 = 20.0mil + } + ha:line.1 { + y2 = 52.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 44.0mil + } + ha:line.2 { + y2 = 25.0mil + thickness = 8.0mil + x1 = 23.0mil + x2 = 23.0mil + y1 = 20.0mil + } + ha:line.3 { + y2 = 52.0mil + thickness = 8.0mil + x1 = 24.0mil + x2 = 24.0mil + y1 = 44.0mil + } + ha:line.4 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 10.0mil + x2 = 14.0mil + y1 = 11.0mil + } + ha:line.5 { + y2 = 34.0mil + thickness = 8.0mil + x1 = 10.0mil + x2 = 14.0mil + y1 = 34.0mil + } + ha:line.6 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 10.0mil + x2 = 14.0mil + y1 = 62.0mil + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = -90.000000 + astart = 270.000000 + x = 14.0mil + y = 20.0mil + r = 9.0mil + } + ha:simplearc.8 { + thickness = 8.0mil + adelta = 90.000000 + astart = 90.000000 + x = 14.0mil + y = 52.0mil + r = 10.0mil + } + ha:simplearc.9 { + thickness = 8.0mil + adelta = -90.000000 + astart = 270.000000 + x = 14.0mil + y = 44.0mil + r = 10.0mil + } + ha:simplearc.10 { + thickness = 8.0mil + adelta = 90.000000 + astart = 90.000000 + x = 14.0mil + y = 25.0mil + r = 9.0mil + } + ha:simplearc.11 { + thickness = 8.0mil + adelta = 90.000000 + astart = -90.000000 + x = 10.0mil + y = 20.0mil + r = 9.0mil + } + ha:simplearc.12 { + thickness = 8.0mil + adelta = -90.000000 + astart = 90.000000 + x = 10.0mil + y = 52.0mil + r = 10.0mil + } + ha:simplearc.13 { + thickness = 8.0mil + adelta = 90.000000 + astart = -90.000000 + x = 10.0mil + y = 44.0mil + r = 10.0mil + } + ha:simplearc.14 { + thickness = 8.0mil + adelta = -90.000000 + astart = 90.000000 + x = 10.0mil + y = 25.0mil + r = 9.0mil + } + } + height = 1.574801mm + } + ha:9 { + width = 0.584201mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 39.0mil + thickness = 8.0mil + x1 = 10.0mil + x2 = 23.0mil + y1 = 39.0mil + } + ha:line.1 { + y2 = 43.0mil + thickness = 8.0mil + x1 = 23.0mil + x2 = 23.0mil + y1 = 21.0mil + } + ha:line.2 { + y2 = 29.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 21.0mil + } + ha:line.3 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 10.0mil + x2 = 13.0mil + y1 = 11.0mil + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = -83.659808 + astart = 180.000000 + x = 4.0mil + y = 43.0mil + r = 19.0mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = 90.000000 + astart = 270.000000 + x = 10.0mil + y = 21.0mil + r = 10.0mil + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = -90.000000 + astart = 270.000000 + x = 13.0mil + y = 21.0mil + r = 10.0mil + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = -90.000000 + astart = 90.000000 + x = 10.0mil + y = 29.0mil + r = 10.0mil + } + } + height = 1.571849mm + } + ha:< { + width = 0.558801mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 34.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 22.0mil + y1 = 42.0mil + } + ha:line.1 { + y2 = 50.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 22.0mil + y1 = 42.0mil + } + } + height = 1.270001mm + } + ha:> { + width = 0.558801mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 34.0mil + thickness = 8.0mil + x1 = 22.0mil + x2 = 0.0 + y1 = 42.0mil + } + ha:line.1 { + y2 = 50.0mil + thickness = 8.0mil + x1 = 22.0mil + x2 = 0.0 + y1 = 42.0mil + } + } + height = 1.270001mm + } + ha:? { + width = 0.583743mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.304342mm + x2 = 0.304342mm + y1 = 60.0mil + } + ha:line.1 { + y2 = 38.0mil + thickness = 8.0mil + x1 = 0.304342mm + x2 = 0.304342mm + y1 = 45.0mil + } + ha:line.2 { + y2 = 0.71041mm + thickness = 8.0mil + x1 = 0.384171mm + x2 = 0.48144mm + y1 = 0.791634mm + } + ha:line.3 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 12.9819685mil + x2 = 0.405942mm + y1 = 11.0mil + } + ha:line.4 { + y2 = 20.0mil + thickness = 8.0mil + x1 = 0.583742mm + x2 = 0.583742mm + y1 = 17.0mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = 90.000000 + astart = 180.000000 + x = 0.405942mm + y = 18.0mil + r = 7.0mil + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = -48.366461 + astart = 180.000000 + x = 0.278942mm + y = 19.0mil + r = 12.0mil + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = 25.641006 + astart = -90.000000 + x = 12.9819685mil + y = 41.0mil + r = 30.0mil + } + ha:simplearc.8 { + thickness = 8.0mil + adelta = -49.398705 + astart = 0.000000 + x = 0.532942mm + y = 38.0mil + r = 9.0mil + } + } + height = 1.574801mm + } + ha:@ { + width = 1.143001mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 54.0mil + thickness = 8.0mil + x1 = 20.0mil + x2 = 24.0mil + y1 = 54.0mil + } + ha:line.1 { + y2 = 26.0mil + thickness = 8.0mil + x1 = 14.0mil + x2 = 14.0mil + y1 = 47.0mil + } + ha:line.2 { + y2 = 19.0mil + thickness = 8.0mil + x1 = 21.0mil + x2 = 31.0mil + y1 = 19.0mil + } + ha:line.3 { + y2 = 47.0mil + thickness = 8.0mil + x1 = 31.0mil + x2 = 31.0mil + y1 = 19.0mil + } + ha:line.4 { + y2 = 19.0mil + thickness = 8.0mil + x1 = 45.0mil + x2 = 45.0mil + y1 = 47.0mil + } + ha:line.5 { + y2 = 2.0mil + thickness = 8.0mil + x1 = 17.0mil + x2 = 28.0mil + y1 = 2.0mil + } + ha:line.6 { + y2 = 54.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 19.0mil + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = 96.709837 + astart = -0.000000 + x = 17.0mil + y = 54.0mil + r = 17.0mil + } + ha:simplearc.8 { + thickness = 8.0mil + adelta = -90.000000 + astart = 0.000000 + x = 17.0mil + y = 19.0mil + r = 17.0mil + } + ha:simplearc.9 { + thickness = 8.0mil + adelta = 90.000000 + astart = 180.000000 + x = 28.0mil + y = 19.0mil + r = 17.0mil + } + ha:simplearc.10 { + thickness = 8.0mil + adelta = 180.000000 + astart = 0.000000 + x = 38.0mil + y = 47.0mil + r = 7.0mil + } + ha:simplearc.11 { + thickness = 8.0mil + adelta = -90.000000 + astart = 180.000000 + x = 24.0mil + y = 47.0mil + r = 7.0mil + } + ha:simplearc.12 { + thickness = 8.0mil + adelta = 90.000000 + astart = -0.000000 + x = 21.0mil + y = 47.0mil + r = 7.0mil + } + ha:simplearc.13 { + thickness = 8.0mil + adelta = -90.000000 + astart = 0.000000 + x = 21.0mil + y = 26.0mil + r = 7.0mil + } + } + height = 1.803401mm + } + ha:A { + width = 0.863601mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 17.0mil + y1 = 62.0mil + } + ha:line.1 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 34.0mil + x2 = 17.0mil + y1 = 62.0mil + } + ha:line.2 { + y2 = 48.0mil + thickness = 8.0mil + x1 = 0.118533mm + x2 = 0.745066mm + y1 = 48.0mil + } + } + height = 1.574801mm + } + ha:B { + width = 0.711201mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 62.0mil + } + ha:line.1 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 15.0mil + y1 = 11.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 16.0mil + x2 = 0.0 + y1 = 62.0mil + } + ha:line.3 { + y2 = 51.0mil + thickness = 8.0mil + x1 = 28.0mil + x2 = 28.0mil + y1 = 47.0mil + } + ha:line.4 { + y2 = 34.0mil + thickness = 8.0mil + x1 = 14.0mil + x2 = 0.0 + y1 = 34.0mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = -90.000000 + astart = -90.000000 + x = 14.0mil + y = 48.0mil + r = 14.0mil + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = -90.000000 + astart = 180.000000 + x = 14.0mil + y = 22.0mil + r = 12.0mil + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = -90.000000 + astart = 180.000000 + x = 16.0mil + y = 50.0mil + r = 12.0mil + } + ha:simplearc.8 { + thickness = 8.0mil + adelta = -90.000000 + astart = -90.000000 + x = 15.0mil + y = 22.0mil + r = 11.0mil + } + } + height = 1.574801mm + } + ha:C { + width = 0.584201mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 10.0mil + x2 = 23.0mil + y1 = 11.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 10.0mil + x2 = 23.0mil + y1 = 62.0mil + } + ha:line.2 { + y2 = 52.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 21.0mil + } + ha:simplearc.3 { + thickness = 8.0mil + adelta = 90.000000 + astart = -0.000000 + x = 10.0mil + y = 52.0mil + r = 10.0mil + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = -90.000000 + astart = 0.000000 + x = 10.0mil + y = 21.0mil + r = 10.0mil + } + } + height = 1.574801mm + } + ha:D { + width = 0.711201mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 18.0mil + y1 = 11.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 18.0mil + y1 = 62.0mil + } + ha:line.2 { + y2 = 52.0mil + thickness = 8.0mil + x1 = 28.0mil + x2 = 28.0mil + y1 = 21.0mil + } + ha:line.3 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 11.0mil + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = -90.000000 + astart = 180.000000 + x = 18.0mil + y = 52.0mil + r = 10.0mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = 90.000000 + astart = 180.000000 + x = 18.0mil + y = 21.0mil + r = 10.0mil + } + } + height = 1.574801mm + } + ha:E { + width = 0.558801mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 62.0mil + } + ha:line.1 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 22.0mil + y1 = 11.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 22.0mil + x2 = 0.0 + y1 = 62.0mil + } + ha:line.3 { + y2 = 34.0mil + thickness = 8.0mil + x1 = 17.0mil + x2 = 0.0 + y1 = 34.0mil + } + } + height = 1.574801mm + } + ha:F { + width = 0.558801mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 62.0mil + } + ha:line.1 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 22.0mil + y1 = 11.0mil + } + ha:line.2 { + y2 = 34.0mil + thickness = 8.0mil + x1 = 22.0mil + x2 = 0.0 + y1 = 34.0mil + } + } + height = 1.574801mm + } + ha:G { + width = 0.711201mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 10.0mil + x2 = 28.0mil + y1 = 11.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 10.0mil + x2 = 28.0mil + y1 = 62.0mil + } + ha:line.2 { + y2 = 52.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 21.0mil + } + ha:line.3 { + y2 = 34.0mil + thickness = 8.0mil + x1 = 19.0mil + x2 = 28.0mil + y1 = 34.0mil + } + ha:line.4 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 28.0mil + x2 = 28.0mil + y1 = 34.0mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = 90.000000 + astart = 0.000000 + x = 10.0mil + y = 52.0mil + r = 10.0mil + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = -90.000000 + astart = 0.000000 + x = 10.0mil + y = 21.0mil + r = 10.0mil + } + } + height = 1.574801mm + } + ha:H { + width = 0.736601mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 62.0mil + } + ha:line.1 { + y2 = 34.0mil + thickness = 8.0mil + x1 = 28.0mil + x2 = 0.0 + y1 = 34.0mil + } + ha:line.2 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 29.0mil + x2 = 29.0mil + y1 = 62.0mil + } + } + height = 1.574801mm + } + ha:I { + width = 0.001um + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 62.0mil + } + } + height = 1.574801mm + } + ha:J { + width = 0.457201mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 18.0mil + x2 = 18.0mil + y1 = 52.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 8.0mil + x2 = 0.0 + y1 = 62.0mil + } + ha:simplearc.2 { + thickness = 8.0mil + adelta = 90.000000 + astart = 90.000000 + x = 8.0mil + y = 52.0mil + r = 10.0mil + } + } + height = 1.574801mm + } + ha:K { + width = 0.736601mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 62.0mil + } + ha:line.1 { + y2 = 42.0mil + thickness = 8.0mil + x1 = 29.0mil + x2 = 0.0 + y1 = 11.0mil + } + ha:line.2 { + y2 = 0.764963mm + thickness = 8.0mil + x1 = 29.0mil + x2 = 0.282363mm + y1 = 62.0mil + } + } + height = 1.574801mm + } + ha:L { + width = 0.558801mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 62.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 22.0mil + y1 = 62.0mil + } + } + height = 1.574801mm + } + ha:M { + width = 0.863601mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 62.0mil + } + ha:line.1 { + y2 = 40.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 17.0mil + y1 = 11.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 34.0mil + x2 = 34.0mil + y1 = 11.0mil + } + ha:line.3 { + y2 = 40.0mil + thickness = 8.0mil + x1 = 34.0mil + x2 = 17.0mil + y1 = 11.0mil + } + } + height = 1.574801mm + } + ha:&2f { + width = 0.558801mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 22.0mil + x2 = 0.0 + y1 = 11.0mil + } + } + height = 1.574801mm + } + ha:&3a { + width = 0.001um + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 31.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 33.0mil + } + ha:line.1 { + y2 = 54.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 56.0mil + } + } + height = 1.422401mm + } + ha:&3b { + width = 0.076201mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 56.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 3.0mil + y1 = 67.0mil + } + ha:line.1 { + y2 = 33.0mil + thickness = 8.0mil + x1 = 3.0mil + x2 = 3.0mil + y1 = 35.0mil + } + } + height = 1.701801mm + } + ha:&3d { + width = 0.584201mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 34.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 23.0mil + y1 = 34.0mil + } + ha:line.1 { + y2 = 51.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 23.0mil + y1 = 51.0mil + } + } + height = 1.295401mm + } + ha:O { + width = 0.736601mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 12.0mil + x2 = 17.0mil + y1 = 11.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 12.0mil + x2 = 17.0mil + y1 = 62.0mil + } + ha:line.2 { + y2 = 50.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 23.0mil + } + ha:line.3 { + y2 = 23.0mil + thickness = 8.0mil + x1 = 29.0mil + x2 = 29.0mil + y1 = 50.0mil + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = 90.000000 + astart = -180.000000 + x = 17.0mil + y = 23.0mil + r = 12.0mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = -90.000000 + astart = 180.000000 + x = 17.0mil + y = 50.0mil + r = 12.0mil + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = 90.000000 + astart = -0.000000 + x = 12.0mil + y = 50.0mil + r = 12.0mil + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = -90.000000 + astart = 0.000000 + x = 12.0mil + y = 23.0mil + r = 12.0mil + } + } + height = 1.574801mm + } + ha:P { + width = 0.711201mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 62.0mil + } + ha:line.1 { + y2 = 39.0mil + thickness = 8.0mil + x1 = 16.0mil + x2 = 0.0 + y1 = 39.0mil + } + ha:line.2 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 16.0mil + x2 = 0.0 + y1 = 11.0mil + } + ha:line.3 { + y2 = 27.0mil + thickness = 8.0mil + x1 = 28.0mil + x2 = 28.0mil + y1 = 23.0mil + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = 90.000000 + astart = -180.000000 + x = 16.0mil + y = 23.0mil + r = 12.0mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = -90.000000 + astart = 180.000000 + x = 16.0mil + y = 27.0mil + r = 12.0mil + } + } + height = 1.574801mm + } + ha:N { + width = 0.736601mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 62.0mil + } + ha:line.1 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 29.0mil + x2 = 29.0mil + y1 = 62.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 29.0mil + y1 = 11.0mil + } + } + height = 1.574801mm + } + ha:R { + width = 0.711201mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 62.0mil + } + ha:line.1 { + y2 = 39.0mil + thickness = 8.0mil + x1 = 16.0mil + x2 = 0.0 + y1 = 39.0mil + } + ha:line.2 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 16.0mil + x2 = 0.0 + y1 = 11.0mil + } + ha:line.3 { + y2 = 27.0mil + thickness = 8.0mil + x1 = 28.0mil + x2 = 28.0mil + y1 = 23.0mil + } + ha:line.4 { + y2 = 39.0mil + thickness = 8.0mil + x1 = 28.0mil + x2 = 17.0mil + y1 = 62.0mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = 90.000000 + astart = -180.000000 + x = 16.0mil + y = 23.0mil + r = 12.0mil + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = -90.000000 + astart = 180.000000 + x = 16.0mil + y = 27.0mil + r = 12.0mil + } + } + height = 1.574801mm + } + ha:S { + width = 0.736601mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 15.0mil + x2 = 21.0mil + y1 = 62.0mil + } + ha:line.1 { + y2 = 0.845249mm + thickness = 8.0mil + x1 = 0.583676mm + x2 = 0.200637mm + y1 = 1.042223mm + } + ha:line.2 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 11.0mil + x2 = 15.0mil + y1 = 11.0mil + } + ha:line.3 { + y2 = 52.0mil + thickness = 8.0mil + x1 = 29.0mil + x2 = 29.0mil + y1 = 54.0mil + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = 57.528808 + astart = 180.000000 + x = 16.0mil + y = 52.0mil + r = 13.0mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = 90.000000 + astart = 90.000000 + x = 21.0mil + y = 54.0mil + r = 8.0mil + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = 70.016893 + astart = 0.000000 + x = 12.0mil + y = 22.0mil + r = 12.0mil + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = -90.000000 + astart = 0.000000 + x = 11.0mil + y = 22.0mil + r = 11.0mil + } + ha:simplearc.8 { + thickness = 8.0mil + adelta = -30.068583 + astart = 270.000000 + x = 15.0mil + y = 33.0mil + r = 22.0mil + } + ha:simplearc.9 { + thickness = 8.0mil + adelta = -41.185925 + astart = 90.000000 + x = 15.0mil + y = 40.0mil + r = 22.0mil + } + } + height = 1.574801mm + } + ha:Q { + width = 0.889001mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 12.0mil + x2 = 17.0mil + y1 = 11.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 12.0mil + x2 = 17.0mil + y1 = 62.0mil + } + ha:line.2 { + y2 = 50.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 23.0mil + } + ha:line.3 { + y2 = 23.0mil + thickness = 8.0mil + x1 = 29.0mil + x2 = 29.0mil + y1 = 50.0mil + } + ha:line.4 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 23.0mil + x2 = 35.0mil + y1 = 51.0mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = 90.000000 + astart = -180.000000 + x = 17.0mil + y = 23.0mil + r = 12.0mil + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = -90.000000 + astart = 180.000000 + x = 17.0mil + y = 50.0mil + r = 12.0mil + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = 90.000000 + astart = -0.000000 + x = 12.0mil + y = 50.0mil + r = 12.0mil + } + ha:simplearc.8 { + thickness = 8.0mil + adelta = -90.000000 + astart = 0.000000 + x = 12.0mil + y = 23.0mil + r = 12.0mil + } + } + height = 1.574801mm + } + ha:U { + width = 0.736601mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 12.0mil + x2 = 16.0mil + y1 = 62.0mil + } + ha:line.1 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 49.0mil + } + ha:line.2 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 29.0mil + x2 = 29.0mil + y1 = 49.0mil + } + ha:simplearc.3 { + thickness = 8.0mil + adelta = -90.000000 + astart = 180.000000 + x = 16.0mil + y = 49.0mil + r = 13.0mil + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = 90.000000 + astart = 0.000000 + x = 13.0mil + y = 49.0mil + r = 13.0mil + } + } + height = 1.574801mm + } + ha:V { + width = 0.914401mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 18.0mil + y1 = 11.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 36.0mil + x2 = 18.0mil + y1 = 11.0mil + } + } + height = 1.574801mm + } + ha:T { + width = 0.736601mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 15.0mil + x2 = 15.0mil + y1 = 62.0mil + } + ha:line.1 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 29.0mil + y1 = 11.0mil + } + } + height = 1.574801mm + } + ha:X { + width = 0.889001mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 35.0mil + y1 = 11.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 35.0mil + x2 = 0.0 + y1 = 11.0mil + } + } + height = 1.574801mm + } + ha:Y { + width = 0.863601mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 35.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 17.0mil + y1 = 11.0mil + } + ha:line.1 { + y2 = 35.0mil + thickness = 8.0mil + x1 = 34.0mil + x2 = 17.0mil + y1 = 11.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 17.0mil + x2 = 17.0mil + y1 = 35.0mil + } + } + height = 1.574801mm + } + ha:W { + width = 1.117601mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 11.0mil + y1 = 11.0mil + } + ha:line.1 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 11.0mil + x2 = 22.0mil + y1 = 62.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 44.0mil + x2 = 33.0mil + y1 = 11.0mil + } + ha:line.3 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 33.0mil + x2 = 22.0mil + y1 = 62.0mil + } + } + height = 1.574801mm + } + ha:[ { + width = 0.152401mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 68.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 5.0mil + } + ha:line.1 { + y2 = 68.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 6.0mil + y1 = 68.0mil + } + ha:line.2 { + y2 = 5.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 6.0mil + y1 = 5.0mil + } + } + height = 1.727201mm + } + ha:^ { + width = 0.406401mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 0.0 + thickness = 8.0mil + x1 = 0.0 + x2 = 8.0mil + y1 = 9.0mil + } + ha:line.1 { + y2 = 0.0 + thickness = 8.0mil + x1 = 16.0mil + x2 = 8.0mil + y1 = 9.0mil + } + } + height = 0.228601mm + } + ha:Z { + width = 0.711201mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 28.0mil + y1 = 11.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 28.0mil + y1 = 62.0mil + } + ha:line.2 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 28.0mil + y1 = 62.0mil + } + } + height = 1.574801mm + } + ha:` { + width = 0.279401mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 10.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 11.0mil + y1 = 2.0mil + } + } + height = 0.254001mm + } + ha:_ { + width = 0.609601mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 68.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 24.0mil + y1 = 68.0mil + } + } + height = 1.727201mm + } + } + cell_width = 1.193801mm + cell_height = 2.032001mm + } +} Index: tags/1.0.5/font/aussiefont-serif-bold =================================================================== --- tags/1.0.5/font/aussiefont-serif-bold (nonexistent) +++ tags/1.0.5/font/aussiefont-serif-bold (revision 10414) @@ -0,0 +1,4692 @@ +li:pcb-rnd-font-v1 { + ha:geda_pcb { + id = 0 + ha:symbols { + ha:&09 { + width = 0.685801mm + delta = 0.103633mm + li:objects { + ha:line.0 { + y2 = 36.0mil + thickness = 3.0mil + x1 = 0.0 + x2 = 27.0mil + y1 = 36.0mil + } + ha:line.1 { + y2 = 30.0mil + thickness = 3.0mil + x1 = 27.0mil + x2 = 22.0mil + y1 = 36.0mil + } + ha:line.2 { + y2 = 42.0mil + thickness = 3.0mil + x1 = 27.0mil + x2 = 22.0mil + y1 = 36.0mil + } + ha:line.3 { + y2 = 42.0mil + thickness = 3.0mil + x1 = 0.0 + x2 = 5.0mil + y1 = 36.0mil + } + ha:line.4 { + y2 = 30.0mil + thickness = 3.0mil + x1 = 0.0 + x2 = 5.0mil + y1 = 36.0mil + } + } + height = 1.066801mm + } + ha:&0A { + width = 0.889001mm + delta = 10.0mil + li:objects { + ha:line.0 { + y2 = 10.0mil + thickness = 3.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 40.0mil + } + ha:line.1 { + y2 = 40.0mil + thickness = 3.0mil + x1 = 0.0 + x2 = 15.0mil + y1 = 40.0mil + } + ha:line.2 { + y2 = 45.0mil + thickness = 3.0mil + x1 = 20.0mil + x2 = 20.0mil + y1 = 75.0mil + } + ha:line.3 { + y2 = 45.0mil + thickness = 3.0mil + x1 = 20.0mil + x2 = 35.0mil + y1 = 45.0mil + } + ha:line.4 { + y2 = 60.0mil + thickness = 3.0mil + x1 = 20.0mil + x2 = 30.0mil + y1 = 60.0mil + } + } + height = 1.905001mm + } + ha:&0D { + width = 0.889001mm + delta = 0.253999mm + li:objects { + ha:line.0 { + y2 = 15.0mil + thickness = 3.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 35.0mil + } + ha:line.1 { + y2 = 10.0mil + thickness = 3.0mil + x1 = 5.0mil + x2 = 10.0mil + y1 = 10.0mil + } + ha:line.2 { + y2 = 40.0mil + thickness = 3.0mil + x1 = 5.0mil + x2 = 10.0mil + y1 = 40.0mil + } + ha:line.3 { + y2 = 45.0mil + thickness = 3.0mil + x1 = 20.0mil + x2 = 20.0mil + y1 = 75.0mil + } + ha:line.4 { + y2 = 45.0mil + thickness = 3.0mil + x1 = 20.0mil + x2 = 30.0mil + y1 = 45.0mil + } + ha:line.5 { + y2 = 60.0mil + thickness = 3.0mil + x1 = 20.0mil + x2 = 30.0mil + y1 = 60.0mil + } + ha:line.6 { + y2 = 55.0mil + thickness = 3.0mil + x1 = 35.0mil + x2 = 35.0mil + y1 = 50.0mil + } + ha:line.7 { + y2 = 75.0mil + thickness = 3.0mil + x1 = 30.0mil + x2 = 35.0mil + y1 = 60.0mil + } + ha:simplearc.8 { + thickness = 3.0mil + adelta = -90.000000 + astart = -90.000000 + x = 10.0mil + y = 15.0mil + r = 5.0mil + } + ha:simplearc.9 { + thickness = 3.0mil + adelta = 90.000000 + astart = 270.000000 + x = 5.0mil + y = 15.0mil + r = 5.0mil + } + ha:simplearc.10 { + thickness = 3.0mil + adelta = 90.000000 + astart = 90.000000 + x = 10.0mil + y = 35.0mil + r = 5.0mil + } + ha:simplearc.11 { + thickness = 3.0mil + adelta = -90.000000 + astart = 90.000000 + x = 5.0mil + y = 35.0mil + r = 5.0mil + } + ha:simplearc.12 { + thickness = 3.0mil + adelta = 90.000000 + astart = 90.000000 + x = 30.0mil + y = 55.0mil + r = 5.0mil + } + ha:simplearc.13 { + thickness = 3.0mil + adelta = -90.000000 + astart = -90.000000 + x = 30.0mil + y = 50.0mil + r = 5.0mil + } + } + height = 1.905001mm + } ha:] { + width = 0.152401mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 5.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 6.0mil + y1 = 5.0mil + } + ha:line.1 { + y2 = 68.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 6.0mil + y1 = 68.0mil + } + ha:line.2 { + y2 = 68.0mil + thickness = 10.75mil + x1 = 6.0mil + x2 = 6.0mil + y1 = 5.0mil + } + } + height = 1.727201mm + } + ha:&5c { + width = 0.558801mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 22.0mil + y1 = 11.0mil + } + } + height = 1.574801mm + } + ha:b { + width = 0.736601mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 10.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 6.0mil + y1 = 0.252476mm + } + ha:line.1 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 6.0mil + x2 = 23.0mil + y1 = 28.0mil + } + ha:line.2 { + y2 = 56.0mil + thickness = 10.75mil + x1 = 29.0mil + x2 = 29.0mil + y1 = 34.0mil + } + ha:line.3 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 23.0mil + y1 = 1.573276mm + } + ha:line.4 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 6.0mil + x2 = 6.0mil + y1 = 10.0mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = 90.000000 + astart = 90.000000 + x = 23.0mil + y = 56.0mil + r = 6.0mil + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = 90.000000 + astart = 180.000000 + x = 23.0mil + y = 34.0mil + r = 6.0mil + } + } + height = 1.574801mm + } + ha:c { + width = 0.506477mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 0.862076mm + thickness = 10.75mil + x1 = 19.94mil + x2 = 19.94mil + y1 = 27.94mil + } + ha:line.1 { + y2 = 27.94mil + thickness = 10.75mil + x1 = 6.0mil + x2 = 19.94mil + y1 = 28.0mil + } + ha:line.2 { + y2 = 56.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 34.0mil + } + ha:line.3 { + y2 = 1.573276mm + thickness = 10.75mil + x1 = 6.0mil + x2 = 19.94mil + y1 = 62.0mil + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = -90.000000 + astart = 90.000000 + x = 6.0mil + y = 56.0mil + r = 6.0mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = -90.000000 + astart = 0.000000 + x = 6.0mil + y = 34.0mil + r = 6.0mil + } + } + height = 1.574801mm + } + ha:a { + width = 0.735077mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 23.0mil + x2 = 23.0mil + y1 = 35.0mil + } + ha:line.1 { + y2 = 44.0mil + thickness = 10.75mil + x1 = 9.0mil + x2 = 23.0mil + y1 = 44.0mil + } + ha:line.2 { + y2 = 1.573276mm + thickness = 10.75mil + x1 = 9.0mil + x2 = 28.94mil + y1 = 62.0mil + } + ha:line.3 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 4.0mil + x2 = 16.0mil + y1 = 28.0mil + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = 90.000000 + astart = 180.000000 + x = 16.0mil + y = 35.0mil + r = 7.0mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = -180.000000 + astart = 90.000000 + x = 9.0mil + y = 53.0mil + r = 9.0mil + } + } + height = 1.574801mm + } + ha:e { + width = 0.558801mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 7.0mil + x2 = 22.0mil + y1 = 62.0mil + } + ha:line.1 { + y2 = 39.0mil + thickness = 10.75mil + x1 = 22.0mil + x2 = 22.0mil + y1 = 45.0mil + } + ha:line.2 { + y2 = 45.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 22.0mil + y1 = 45.0mil + } + ha:line.3 { + y2 = 39.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 55.0mil + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = 90.000000 + astart = 0.000000 + x = 7.0mil + y = 55.0mil + r = 7.0mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = -180.000000 + astart = 0.000000 + x = 11.0mil + y = 39.0mil + r = 11.0mil + } + } + height = 1.574801mm + } + ha:f { + width = 0.431801mm + delta = 0.444474mm + li:objects { + ha:line.0 { + y2 = 1.573276mm + thickness = 10.75mil + x1 = 0.0 + x2 = 17.0mil + y1 = 1.573276mm + } + ha:line.1 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 6.0mil + x2 = 6.0mil + y1 = 18.0mil + } + ha:line.2 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 17.0mil + y1 = 28.0mil + } + ha:line.3 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 13.0mil + x2 = 17.0mil + y1 = 11.0mil + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = -90.000000 + astart = 0.000000 + x = 13.0mil + y = 18.0mil + r = 7.0mil + } + } + height = 1.574801mm + } + ha:d { + width = 0.735077mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 0.252476mm + thickness = 10.75mil + x1 = 23.0mil + x2 = 16.94mil + y1 = 0.252476mm + } + ha:line.1 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 6.0mil + x2 = 23.0mil + y1 = 28.0mil + } + ha:line.2 { + y2 = 56.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 34.0mil + } + ha:line.3 { + y2 = 1.573276mm + thickness = 10.75mil + x1 = 6.0mil + x2 = 28.94mil + y1 = 62.0mil + } + ha:line.4 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 23.0mil + x2 = 23.0mil + y1 = 10.0mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = -90.000000 + astart = 90.000000 + x = 6.0mil + y = 56.0mil + r = 6.0mil + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = -90.000000 + astart = 0.000000 + x = 6.0mil + y = 34.0mil + r = 6.0mil + } + } + height = 1.574801mm + } + ha:h { + width = 0.965201mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 1.573276mm + thickness = 10.75mil + x1 = 26.0mil + x2 = 38.0mil + y1 = 1.573276mm + } + ha:line.1 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 6.0mil + x2 = 26.0mil + y1 = 27.94mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 32.0mil + x2 = 32.0mil + y1 = 34.0mil + } + ha:line.3 { + y2 = 1.573276mm + thickness = 10.75mil + x1 = 0.0 + x2 = 12.0mil + y1 = 1.573276mm + } + ha:line.4 { + y2 = 0.252476mm + thickness = 10.75mil + x1 = 0.0 + x2 = 6.0mil + y1 = 0.252476mm + } + ha:line.5 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 6.0mil + x2 = 6.0mil + y1 = 10.0mil + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = 90.000000 + astart = 180.000000 + x = 26.0mil + y = 34.0mil + r = 6.0mil + } + } + height = 1.574801mm + } + ha:i { + width = 0.609601mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 1.573276mm + thickness = 10.75mil + x1 = 0.0 + x2 = 24.0mil + y1 = 1.573276mm + } + ha:line.1 { + y2 = 27.94mil + thickness = 10.75mil + x1 = 3.0mil + x2 = 12.0mil + y1 = 27.94mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 12.0mil + x2 = 12.0mil + y1 = 28.0mil + } + ha:line.3 { + y2 = 14.0mil + thickness = 10.75mil + x1 = 12.0mil + x2 = 12.0mil + y1 = 11.0mil + } + } + height = 1.574801mm + } + ha:g { + width = 0.735077mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 80.0mil + thickness = 10.75mil + x1 = 3.0mil + x2 = 16.0mil + y1 = 80.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 6.0mil + x2 = 23.0mil + y1 = 62.0mil + } + ha:line.2 { + y2 = 34.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 56.0mil + } + ha:line.3 { + y2 = 27.94mil + thickness = 10.75mil + x1 = 6.0mil + x2 = 28.94mil + y1 = 28.0mil + } + ha:line.4 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 23.0mil + x2 = 23.0mil + y1 = 73.0mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = 90.000000 + astart = -90.000000 + x = 6.0mil + y = 34.0mil + r = 6.0mil + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = 90.000000 + astart = -0.000000 + x = 6.0mil + y = 56.0mil + r = 6.0mil + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = 90.000000 + astart = 90.000000 + x = 16.0mil + y = 73.0mil + r = 7.0mil + } + } + height = 2.032001mm + } + ha:k { + width = 0.863601mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 27.94mil + thickness = 10.75mil + x1 = 22.0mil + x2 = 34.0mil + y1 = 27.94mil + } + ha:line.1 { + y2 = 1.573276mm + thickness = 10.75mil + x1 = 22.0mil + x2 = 34.0mil + y1 = 1.573276mm + } + ha:line.2 { + y2 = 1.573276mm + thickness = 10.75mil + x1 = 0.0 + x2 = 6.0mil + y1 = 1.573276mm + } + ha:line.3 { + y2 = 0.277876mm + thickness = 10.75mil + x1 = 0.0 + x2 = 6.0mil + y1 = 0.277876mm + } + ha:line.4 { + y2 = 0.967678mm + thickness = 10.75mil + x1 = 29.0mil + x2 = 0.408878mm + y1 = 62.0mil + } + ha:line.5 { + y2 = 46.0mil + thickness = 10.75mil + x1 = 29.0mil + x2 = 6.0mil + y1 = 28.0mil + } + ha:line.6 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 6.0mil + x2 = 6.0mil + y1 = 11.0mil + } + } + height = 1.574801mm + } + ha:l { + width = 0.609601mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 1.573276mm + thickness = 10.75mil + x1 = 0.0 + x2 = 24.0mil + y1 = 1.573276mm + } + ha:line.1 { + y2 = 1.573276mm + thickness = 10.75mil + x1 = 12.06mil + x2 = 12.0mil + y1 = 11.0mil + } + ha:line.2 { + y2 = 0.277876mm + thickness = 10.75mil + x1 = 0.0 + x2 = 12.06mil + y1 = 0.277876mm + } + } + height = 1.573277mm + } + ha:j { + width = 0.357125mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 80.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.153924mm + y1 = 2.030476mm + } + ha:line.1 { + y2 = 0.708152mm + thickness = 10.75mil + x1 = 0.0 + x2 = 14.06mil + y1 = 27.94mil + } + ha:line.2 { + y2 = 72.0mil + thickness = 10.75mil + x1 = 14.06mil + x2 = 14.06mil + y1 = 28.0mil + } + ha:line.3 { + y2 = 14.0mil + thickness = 10.75mil + x1 = 14.06mil + x2 = 14.06mil + y1 = 11.0mil + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = -90.000000 + astart = 180.000000 + x = 0.153924mm + y = 72.0mil + r = 8.0mil + } + } + height = 2.032001mm + } + ha:n { + width = 0.889001mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 1.573276mm + thickness = 10.75mil + x1 = 29.0mil + x2 = 35.0mil + y1 = 1.573276mm + } + ha:line.1 { + y2 = 1.573276mm + thickness = 10.75mil + x1 = 0.0 + x2 = 12.0mil + y1 = 1.573276mm + } + ha:line.2 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 6.0mil + x2 = 6.0mil + y1 = 0.710133mm + } + ha:line.3 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 29.0mil + x2 = 29.0mil + y1 = 37.0mil + } + ha:line.4 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 20.0mil + y1 = 27.94mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = -90.000000 + astart = -90.000000 + x = 20.0mil + y = 37.0mil + r = 9.0mil + } + } + height = 1.574801mm + } + ha:o { + width = 0.630009mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 1.573276mm + thickness = 10.75mil + x1 = 0.264204mm + x2 = 0.365804mm + y1 = 1.573276mm + } + ha:line.1 { + y2 = 27.94mil + thickness = 10.75mil + x1 = 0.264204mm + x2 = 0.365804mm + y1 = 27.94mil + } + ha:line.2 { + y2 = 0.99928mm + thickness = 10.75mil + x1 = 0.630008mm + x2 = 0.630008mm + y1 = 1.283672mm + } + ha:line.3 { + y2 = 1.283672mm + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 0.99928mm + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = -90.000000 + astart = 0.000000 + x = 0.289604mm + y = 0.99928mm + r = 0.289604mm + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = 90.000000 + astart = 180.000000 + x = 0.340404mm + y = 0.99928mm + r = 0.289604mm + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = 90.000000 + astart = -0.000000 + x = 0.289604mm + y = 1.283672mm + r = 0.289604mm + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = -90.000000 + astart = -180.000000 + x = 0.340404mm + y = 1.283672mm + r = 0.289604mm + } + } + height = 1.573277mm + } + ha:m { + width = 1.270001mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 1.573276mm + thickness = 10.75mil + x1 = 44.0mil + x2 = 50.0mil + y1 = 1.573276mm + } + ha:line.1 { + y2 = 1.573276mm + thickness = 10.75mil + x1 = 25.0mil + x2 = 31.0mil + y1 = 1.573276mm + } + ha:line.2 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 44.0mil + x2 = 44.0mil + y1 = 37.0mil + } + ha:line.3 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 25.0mil + x2 = 25.0mil + y1 = 28.0mil + } + ha:line.4 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 12.0mil + y1 = 62.0mil + } + ha:line.5 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.152105mm + x2 = 6.0mil + y1 = 0.70997mm + } + ha:line.6 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 35.0mil + y1 = 27.94mil + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = -90.000000 + astart = -90.000000 + x = 35.0mil + y = 37.0mil + r = 9.0mil + } + } + height = 1.574801mm + } + ha:q { + width = 0.735077mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 2.030476mm + thickness = 10.75mil + x1 = 16.94mil + x2 = 28.94mil + y1 = 2.030476mm + } + ha:line.1 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 6.0mil + x2 = 23.0mil + y1 = 62.0mil + } + ha:line.2 { + y2 = 56.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 34.0mil + } + ha:line.3 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 28.94mil + x2 = 6.0mil + y1 = 27.94mil + } + ha:line.4 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 23.0mil + x2 = 23.0mil + y1 = 80.0mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = 90.000000 + astart = -90.000000 + x = 6.0mil + y = 34.0mil + r = 6.0mil + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = 90.000000 + astart = 0.000000 + x = 6.0mil + y = 56.0mil + r = 6.0mil + } + } + height = 2.032001mm + } + ha:r { + width = 0.584201mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 1.573276mm + thickness = 10.75mil + x1 = 0.0 + x2 = 18.0mil + y1 = 1.573276mm + } + ha:line.1 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 17.0mil + y1 = 28.0mil + } + ha:line.2 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 6.0mil + x2 = 6.0mil + y1 = 62.0mil + } + ha:simplearc.3 { + thickness = 10.75mil + adelta = 90.000000 + astart = 180.000000 + x = 17.0mil + y = 34.0mil + r = 6.0mil + } + } + height = 1.574801mm + } + ha:p { + width = 0.736601mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 2.030476mm + thickness = 10.75mil + x1 = 0.0 + x2 = 12.0mil + y1 = 2.030476mm + } + ha:line.1 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 6.0mil + x2 = 23.0mil + y1 = 62.0mil + } + ha:line.2 { + y2 = 56.0mil + thickness = 10.75mil + x1 = 29.0mil + x2 = 29.0mil + y1 = 34.0mil + } + ha:line.3 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 23.0mil + y1 = 27.94mil + } + ha:line.4 { + y2 = 80.0mil + thickness = 10.75mil + x1 = 6.0mil + x2 = 6.0mil + y1 = 28.0mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = -90.000000 + astart = 270.000000 + x = 23.0mil + y = 34.0mil + r = 6.0mil + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = -90.000000 + astart = 180.000000 + x = 23.0mil + y = 56.0mil + r = 6.0mil + } + } + height = 2.032001mm + } + ha:t { + width = 0.45329mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 17.0mil + y1 = 28.0mil + } + ha:line.1 { + y2 = 1.344676mm + thickness = 10.75mil + x1 = 6.0mil + x2 = 6.0mil + y1 = 11.0mil + } + ha:simplearc.2 { + thickness = 10.75mil + adelta = -108.434949 + astart = 108.434949 + x = 15.0mil + y = 1.344676mm + r = 9.0mil + } + } + height = 1.573277mm + } + ha:u { + width = 0.889001mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 0.708146mm + thickness = 10.75mil + x1 = 23.0mil + x2 = 0.738129mm + y1 = 27.94mil + } + ha:line.1 { + y2 = 27.94mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.153924mm + y1 = 27.94mil + } + ha:line.2 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 29.0mil + x2 = 0.738124mm + y1 = 1.573276mm + } + ha:line.3 { + y2 = 1.573276mm + thickness = 10.75mil + x1 = 13.06mil + x2 = 35.0mil + y1 = 62.0mil + } + ha:line.4 { + y2 = 55.0mil + thickness = 10.75mil + x1 = 0.153924mm + x2 = 0.153924mm + y1 = 28.0mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = 90.000000 + astart = 0.000000 + x = 13.06mil + y = 55.0mil + r = 7.0mil + } + } + height = 1.574801mm + } + ha:s { + width = 0.620118mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 0.862076mm + thickness = 10.75mil + x1 = 24.0mil + x2 = 24.0mil + y1 = 27.94mil + } + ha:line.1 { + y2 = 1.420876mm + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 1.573276mm + } + ha:line.2 { + y2 = 1.141047mm + thickness = 10.75mil + x1 = 0.206305mm + x2 = 0.412721mm + y1 = 1.119181mm + } + ha:simplearc.3 { + thickness = 10.75mil + adelta = -180.000000 + astart = 90.000000 + x = 0.206305mm + y = 36.0mil + r = 0.204781mm + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = -17.605835 + astart = 268.781125 + x = 0.180905mm + y = 75.0mil + r = 47.0mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = -186.525031 + astart = 269.133210 + x = 0.409505mm + y = 1.353612mm + r = 0.210612mm + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = -17.031080 + astart = 90.000000 + x = 0.382409mm + y = 0.368674mm + r = 47.0mil + } + } + height = 1.573277mm + } + ha:w { + width = 1.219201mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 27.94mil + thickness = 10.75mil + x1 = 36.0mil + x2 = 48.0mil + y1 = 27.94mil + } + ha:line.1 { + y2 = 27.94mil + thickness = 10.75mil + x1 = 0.0 + x2 = 12.0mil + y1 = 27.94mil + } + ha:line.2 { + y2 = 40.0mil + thickness = 10.75mil + x1 = 33.0mil + x2 = 24.0mil + y1 = 62.0mil + } + ha:line.3 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 42.0mil + x2 = 33.0mil + y1 = 28.0mil + } + ha:line.4 { + y2 = 40.0mil + thickness = 10.75mil + x1 = 15.0mil + x2 = 24.0mil + y1 = 62.0mil + } + ha:line.5 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 6.0mil + x2 = 15.0mil + y1 = 28.0mil + } + } + height = 1.574801mm + } + ha:x { + width = 0.863601mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 1.573276mm + thickness = 10.75mil + x1 = 22.0mil + x2 = 34.0mil + y1 = 1.573276mm + } + ha:line.1 { + y2 = 1.573276mm + thickness = 10.75mil + x1 = 0.0 + x2 = 12.0mil + y1 = 1.573276mm + } + ha:line.2 { + y2 = 27.94mil + thickness = 10.75mil + x1 = 22.0mil + x2 = 34.0mil + y1 = 27.94mil + } + ha:line.3 { + y2 = 27.94mil + thickness = 10.75mil + x1 = 0.0 + x2 = 12.0mil + y1 = 27.94mil + } + ha:line.4 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 6.0mil + x2 = 28.0mil + y1 = 62.0mil + } + ha:line.5 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 6.0mil + x2 = 28.0mil + y1 = 28.0mil + } + } + height = 1.574801mm + } + ha:v { + width = 0.863601mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 27.94mil + thickness = 10.75mil + x1 = 22.0mil + x2 = 34.0mil + y1 = 27.94mil + } + ha:line.1 { + y2 = 27.94mil + thickness = 10.75mil + x1 = 0.0 + x2 = 12.0mil + y1 = 27.94mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 28.0mil + x2 = 17.0mil + y1 = 28.0mil + } + ha:line.3 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 6.0mil + x2 = 17.0mil + y1 = 28.0mil + } + } + height = 1.574801mm + } + ha:z { + width = 0.609601mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 1.420876mm + thickness = 10.75mil + x1 = 24.0mil + x2 = 24.0mil + y1 = 1.573276mm + } + ha:line.1 { + y2 = 0.862076mm + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 28.0mil + } + ha:line.2 { + y2 = 1.573276mm + thickness = 10.75mil + x1 = 0.0 + x2 = 24.0mil + y1 = 62.0mil + } + ha:line.3 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 24.0mil + x2 = 0.0 + y1 = 27.94mil + } + ha:line.4 { + y2 = 27.94mil + thickness = 10.75mil + x1 = 0.0 + x2 = 24.0mil + y1 = 28.0mil + } + } + height = 1.574801mm + } + ha:~ { + width = 0.589861mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 0.922452mm + thickness = 10.75mil + x1 = 0.264009mm + x2 = 0.325852mm + y1 = 0.863007mm + } + ha:simplearc.1 { + thickness = 10.75mil + adelta = -19.075098 + astart = 312.273689 + x = 0.273375mm + y = 47.0mil + r = 16.0mil + } + ha:simplearc.2 { + thickness = 10.75mil + adelta = -19.075098 + astart = 132.273689 + x = 0.316486mm + y = 0.591659mm + r = 16.0mil + } + ha:simplearc.3 { + thickness = 10.75mil + adelta = -31.668558 + astart = -90.000000 + x = 0.113286mm + y = 1.107348mm + r = 0.287089mm + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = -31.668558 + astart = 90.000000 + x = 0.476575mm + y = 0.678111mm + r = 0.287089mm + } + } + height = 0.965201mm + } + ha:y { + width = 0.889001mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 2.030476mm + thickness = 10.75mil + x1 = 3.0mil + x2 = 21.0mil + y1 = 2.030476mm + } + ha:line.1 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 12.0mil + x2 = 29.0mil + y1 = 80.0mil + } + ha:line.2 { + y2 = 27.94mil + thickness = 10.75mil + x1 = 23.0mil + x2 = 35.0mil + y1 = 27.94mil + } + ha:line.3 { + y2 = 27.94mil + thickness = 10.75mil + x1 = 0.0 + x2 = 12.0mil + y1 = 27.94mil + } + ha:line.4 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 6.0mil + x2 = 18.0mil + y1 = 28.0mil + } + } + height = 2.032001mm + } + ha:&7d { + width = 0.279402mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 9.0mil + thickness = 10.75mil + x1 = 0.127001mm + x2 = 0.127001mm + y1 = 30.0mil + } + ha:line.1 { + y2 = 63.0mil + thickness = 10.75mil + x1 = 0.127001mm + x2 = 0.127001mm + y1 = 42.0mil + } + ha:simplearc.2 { + thickness = 10.75mil + adelta = 90.000000 + astart = -90.000000 + x = 0.279401mm + y = 42.0mil + r = 6.0mil + } + ha:simplearc.3 { + thickness = 10.75mil + adelta = 90.000000 + astart = 90.000000 + x = 0.001um + y = 63.0mil + r = 5.0mil + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = -90.000000 + astart = 90.000000 + x = 0.279401mm + y = 30.0mil + r = 6.0mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = -90.000000 + astart = -90.000000 + x = 0.001um + y = 9.0mil + r = 5.0mil + } + } + height = 1.727201mm + } + ha:| { + width = 0.001um + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 3.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 31.0mil + } + ha:line.1 { + y2 = 71.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 43.0mil + } + } + height = 1.803401mm + } + ha:&7b { + width = 0.279402mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 30.0mil + thickness = 10.75mil + x1 = 0.152401mm + x2 = 0.152401mm + y1 = 9.0mil + } + ha:line.1 { + y2 = 63.0mil + thickness = 10.75mil + x1 = 0.152401mm + x2 = 0.152401mm + y1 = 42.0mil + } + ha:simplearc.2 { + thickness = 10.75mil + adelta = -90.000000 + astart = 270.000000 + x = 0.001um + y = 42.0mil + r = 6.0mil + } + ha:simplearc.3 { + thickness = 10.75mil + adelta = -90.000000 + astart = 90.000000 + x = 0.279401mm + y = 63.0mil + r = 5.0mil + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = 90.000000 + astart = 90.000000 + x = 0.001um + y = 30.0mil + r = 6.0mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = 90.000000 + astart = 270.000000 + x = 0.279401mm + y = 9.0mil + r = 5.0mil + } + } + height = 1.727201mm + } + ha:&20 { + width = 0.0 + delta = 0.9874mm + li:objects { + } + height = 0.0 + } + ha:&23 { + width = 0.889001mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 45.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 35.0mil + y1 = 45.0mil + } + ha:line.1 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 35.0mil + y1 = 28.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 26.0mil + x2 = 26.0mil + y1 = 11.0mil + } + ha:line.3 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 9.0mil + x2 = 9.0mil + y1 = 11.0mil + } + } + height = 1.574801mm + } + ha:&26 { + width = 0.862077mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 1.039876mm + thickness = 10.75mil + x1 = 24.94mil + x2 = 0.862076mm + y1 = 1.039876mm + } + ha:line.1 { + y2 = 1.573276mm + thickness = 10.75mil + x1 = 0.715817mm + x2 = 0.862076mm + y1 = 1.573276mm + } + ha:line.2 { + y2 = 1.039876mm + thickness = 10.75mil + x1 = 0.316401mm + x2 = 30.94mil + y1 = 1.565466mm + } + ha:line.3 { + y2 = 1.266107mm + thickness = 10.75mil + x1 = 0.469006mm + x2 = 0.014123mm + y1 = 0.597619mm + } + ha:line.4 { + y2 = 0.579653mm + thickness = 10.75mil + x1 = 0.716776mm + x2 = 0.09087mm + y1 = 62.0mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = 238.570434 + astart = 147.994617 + x = 0.284976mm + y = 19.0mil + r = 0.217017mm + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = 130.556045 + astart = 340.000000 + x = 0.234176mm + y = 53.0mil + r = 0.234176mm + } + } + height = 1.580377mm + } + ha:! { + width = 0.001um + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 59.0mil + } + ha:line.1 { + y2 = 45.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 11.0mil + } + } + height = 1.574801mm + } + ha:" { + width = 0.457201mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 0.0 + thickness = 10.75mil + x1 = 15.0mil + x2 = 18.0mil + y1 = 11.0mil + } + ha:line.1 { + y2 = 0.0 + thickness = 10.75mil + x1 = 0.0 + x2 = 3.0mil + y1 = 11.0mil + } + } + height = 0.279401mm + } + ha:$ { + width = 0.584201mm + delta = 0.345337mm + li:objects { + ha:line.0 { + y2 = 21.94mil + thickness = 10.75mil + x1 = 23.0mil + x2 = 23.0mil + y1 = 16.94mil + } + ha:line.1 { + y2 = 1.446276mm + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 1.293876mm + } + ha:line.2 { + y2 = 41.0mil + thickness = 10.75mil + x1 = 0.104793mm + x2 = 0.478556mm + y1 = 0.826602mm + } + ha:line.3 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.300756mm + x2 = 0.300756mm + y1 = 11.0mil + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = 156.595310 + astart = 83.659808 + x = 0.376956mm + y = 48.0mil + r = 0.204781mm + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = 168.035280 + astart = 250.000000 + x = 0.218531mm + y = 0.644334mm + r = 0.214844mm + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = -18.434949 + astart = 270.000000 + x = 0.275356mm + y = 55.0mil + r = 38.0mil + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = -19.653824 + astart = 90.000000 + x = 0.326156mm + y = 18.0mil + r = 38.0mil + } + } + height = 1.574801mm + } + ha:% { + width = 1.193801mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 46.0mil + x2 = 0.0 + y1 = 11.0mil + } + ha:simplearc.1 { + thickness = 10.75mil + adelta = 360.000000 + astart = 0.000000 + x = 9.0mil + y = 20.0mil + r = 9.0mil + } + ha:simplearc.2 { + thickness = 10.75mil + adelta = 360.000000 + astart = 0.000000 + x = 38.0mil + y = 53.0mil + r = 9.0mil + } + } + height = 1.574801mm + } + ha:' { + width = 0.076201mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 0.0 + thickness = 10.75mil + x1 = 0.0 + x2 = 3.0mil + y1 = 11.0mil + } + } + height = 0.279401mm + } + ha:( { + width = 0.134159mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 47.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 26.0mil + } + ha:simplearc.1 { + thickness = 10.75mil + adelta = -27.979474 + astart = 0.000000 + x = 1.147787mm + y = 26.0mil + r = 1.147787mm + } + ha:simplearc.2 { + thickness = 10.75mil + adelta = 27.979474 + astart = 0.000000 + x = 1.147787mm + y = 47.0mil + r = 1.147787mm + } + } + height = 1.732291mm + } + ha:) { + width = 0.13416mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 47.0mil + thickness = 10.75mil + x1 = 0.134159mm + x2 = 0.134159mm + y1 = 26.0mil + } + ha:simplearc.1 { + thickness = 10.75mil + adelta = 27.979474 + astart = 180.000000 + x = -1.013628mm + y = 26.0mil + r = 1.147787mm + } + ha:simplearc.2 { + thickness = 10.75mil + adelta = -27.979474 + astart = 180.000000 + x = -1.013628mm + y = 47.0mil + r = 1.147787mm + } + } + height = 1.732291mm + } + ha:* { + width = 0.558801mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 51.0mil + thickness = 10.75mil + x1 = 19.0mil + x2 = 3.0mil + y1 = 34.0mil + } + ha:line.1 { + y2 = 43.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 22.0mil + y1 = 43.0mil + } + ha:line.2 { + y2 = 51.0mil + thickness = 10.75mil + x1 = 3.0mil + x2 = 19.0mil + y1 = 34.0mil + } + } + height = 1.295401mm + } + ha:+ { + width = 0.558801mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 54.0mil + thickness = 10.75mil + x1 = 11.0mil + x2 = 11.0mil + y1 = 32.0mil + } + ha:line.1 { + y2 = 43.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 22.0mil + y1 = 43.0mil + } + } + height = 1.371601mm + } + ha:, { + width = 0.076201mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 65.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 3.0mil + y1 = 76.0mil + } + } + height = 1.930401mm + } + ha:- { + width = 0.558801mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 42.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 22.0mil + y1 = 42.0mil + } + } + height = 1.066801mm + } + ha:. { + width = 0.005081mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 60.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.2mil + y1 = 1.60782mm + } + } + height = 1.607821mm + } + ha:0 { + width = 0.609601mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 37.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 36.0mil + } + ha:line.1 { + y2 = 37.0mil + thickness = 10.75mil + x1 = 24.0mil + x2 = 24.0mil + y1 = 36.0mil + } + ha:line.2 { + y2 = 1.55837mm + thickness = 10.75mil + x1 = 0.177914mm + x2 = 0.224756mm + y1 = 1.506218mm + } + ha:line.3 { + y2 = 0.347982mm + thickness = 10.75mil + x1 = 0.384844mm + x2 = 0.431686mm + y1 = 0.29583mm + } + ha:line.4 { + y2 = 1.506218mm + thickness = 10.75mil + x1 = 0.384844mm + x2 = 0.431686mm + y1 = 1.55837mm + } + ha:line.5 { + y2 = 0.347982mm + thickness = 10.75mil + x1 = 0.224756mm + x2 = 0.177914mm + y1 = 0.29583mm + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = -46.397181 + astart = 293.198591 + x = 12.0mil + y = 19.0mil + r = 8.0mil + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = -34.875328 + astart = 0.000000 + x = 39.0mil + y = 36.0mil + r = 39.0mil + } + ha:simplearc.8 { + thickness = 10.75mil + adelta = -46.397181 + astart = 113.198591 + x = 12.0mil + y = 54.0mil + r = 8.0mil + } + ha:simplearc.9 { + thickness = 10.75mil + adelta = -34.875328 + astart = 180.000000 + x = -15.0mil + y = 37.0mil + r = 39.0mil + } + ha:simplearc.10 { + thickness = 10.75mil + adelta = 34.875328 + astart = 0.000000 + x = 39.0mil + y = 37.0mil + r = 39.0mil + } + ha:simplearc.11 { + thickness = 10.75mil + adelta = 34.875328 + astart = 180.000000 + x = -15.0mil + y = 36.0mil + r = 39.0mil + } + } + height = 1.574801mm + } + ha:1 { + width = 0.406401mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 1.573276mm + thickness = 10.75mil + x1 = 0.0 + x2 = 16.0mil + y1 = 1.573276mm + } + ha:line.1 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 8.0mil + x2 = 8.0mil + y1 = 11.0mil + } + ha:line.2 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 8.0mil + y1 = 18.94mil + } + } + height = 1.574801mm + } + ha:2 { + width = 0.59396mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 22.94mil + x2 = 22.94mil + y1 = 1.420876mm + } + ha:line.1 { + y2 = 0.741018mm + thickness = 10.75mil + x1 = 0.009759mm + x2 = 0.550523mm + y1 = 62.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.009759mm + x2 = 22.94mil + y1 = 62.0mil + } + ha:simplearc.3 { + thickness = 10.75mil + adelta = -192.528808 + astart = 341.565051 + x = 0.289159mm + y = 23.0mil + r = 12.0mil + } + } + height = 1.574801mm + } + ha:3 { + width = 0.584201mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 11.0mil + y1 = 62.0mil + } + ha:line.1 { + y2 = 50.0mil + thickness = 10.75mil + x1 = 23.0mil + x2 = 23.0mil + y1 = 45.0mil + } + ha:line.2 { + y2 = 34.0mil + thickness = 10.75mil + x1 = 5.0mil + x2 = 13.0mil + y1 = 34.0mil + } + ha:line.3 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 13.0mil + y1 = 11.0mil + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = -90.000000 + astart = -90.000000 + x = 13.0mil + y = 21.0mil + r = 10.0mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = -90.000000 + astart = 180.000000 + x = 10.0mil + y = 21.0mil + r = 13.0mil + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = 90.000000 + astart = 180.000000 + x = 12.0mil + y = 45.0mil + r = 11.0mil + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = 90.000000 + astart = 90.000000 + x = 11.0mil + y = 50.0mil + r = 12.0mil + } + } + height = 1.574801mm + } + ha:4 { + width = 0.711201mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 1.573276mm + thickness = 10.75mil + x1 = 13.0mil + x2 = 25.0mil + y1 = 1.573276mm + } + ha:line.1 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 19.0mil + x2 = 19.0mil + y1 = 39.0mil + } + ha:line.2 { + y2 = 51.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 28.0mil + y1 = 51.0mil + } + ha:line.3 { + y2 = 51.0mil + thickness = 10.75mil + x1 = 11.0mil + x2 = 0.0 + y1 = 11.0mil + } + } + height = 1.574801mm + } + ha:5 { + width = 0.584201mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 46.0mil + thickness = 10.75mil + x1 = 23.0mil + x2 = 23.0mil + y1 = 50.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 11.0mil + x2 = 0.0 + y1 = 62.0mil + } + ha:line.2 { + y2 = 34.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 11.0mil + y1 = 34.0mil + } + ha:line.3 { + y2 = 34.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 11.0mil + } + ha:line.4 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 23.0mil + x2 = 0.0 + y1 = 11.0mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = -90.000000 + astart = -90.000000 + x = 11.0mil + y = 46.0mil + r = 12.0mil + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = 90.000000 + astart = 90.000000 + x = 11.0mil + y = 50.0mil + r = 12.0mil + } + } + height = 1.574801mm + } + ha:6 { + width = 0.584201mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 10.0mil + x2 = 13.0mil + y1 = 62.0mil + } + ha:line.1 { + y2 = 44.0mil + thickness = 10.75mil + x1 = 23.0mil + x2 = 23.0mil + y1 = 52.0mil + } + ha:line.2 { + y2 = 52.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 30.0mil + } + ha:line.3 { + y2 = 34.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 13.0mil + y1 = 34.0mil + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = -90.000000 + astart = -90.000000 + x = 13.0mil + y = 44.0mil + r = 10.0mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = -90.000000 + astart = 90.000000 + x = 10.0mil + y = 52.0mil + r = 10.0mil + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = 90.000000 + astart = 90.000000 + x = 13.0mil + y = 52.0mil + r = 10.0mil + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = -83.659808 + astart = 0.000000 + x = 19.0mil + y = 30.0mil + r = 19.0mil + } + } + height = 1.574801mm + } + ha:7 { + width = 0.584201mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 23.0mil + x2 = 12.0mil + y1 = 11.0mil + } + ha:line.1 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 23.0mil + y1 = 11.0mil + } + ha:line.2 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 17.0mil + } + } + height = 1.574801mm + } + ha:8 { + width = 0.609601mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 10.0mil + x2 = 14.0mil + y1 = 62.0mil + } + ha:line.1 { + y2 = 34.0mil + thickness = 10.75mil + x1 = 10.0mil + x2 = 14.0mil + y1 = 34.0mil + } + ha:line.2 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 10.0mil + x2 = 14.0mil + y1 = 11.0mil + } + ha:line.3 { + y2 = 52.0mil + thickness = 10.75mil + x1 = 24.0mil + x2 = 24.0mil + y1 = 44.0mil + } + ha:line.4 { + y2 = 25.0mil + thickness = 10.75mil + x1 = 23.0mil + x2 = 23.0mil + y1 = 20.0mil + } + ha:line.5 { + y2 = 52.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 44.0mil + } + ha:line.6 { + y2 = 25.0mil + thickness = 10.75mil + x1 = 1.0mil + x2 = 1.0mil + y1 = 20.0mil + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = -90.000000 + astart = 90.000000 + x = 10.0mil + y = 25.0mil + r = 9.0mil + } + ha:simplearc.8 { + thickness = 10.75mil + adelta = 90.000000 + astart = -90.000000 + x = 10.0mil + y = 44.0mil + r = 10.0mil + } + ha:simplearc.9 { + thickness = 10.75mil + adelta = -90.000000 + astart = 90.000000 + x = 10.0mil + y = 52.0mil + r = 10.0mil + } + ha:simplearc.10 { + thickness = 10.75mil + adelta = 90.000000 + astart = -90.000000 + x = 10.0mil + y = 20.0mil + r = 9.0mil + } + ha:simplearc.11 { + thickness = 10.75mil + adelta = 90.000000 + astart = 90.000000 + x = 14.0mil + y = 25.0mil + r = 9.0mil + } + ha:simplearc.12 { + thickness = 10.75mil + adelta = -90.000000 + astart = 270.000000 + x = 14.0mil + y = 44.0mil + r = 10.0mil + } + ha:simplearc.13 { + thickness = 10.75mil + adelta = 90.000000 + astart = 90.000000 + x = 14.0mil + y = 52.0mil + r = 10.0mil + } + ha:simplearc.14 { + thickness = 10.75mil + adelta = -90.000000 + astart = 270.000000 + x = 14.0mil + y = 20.0mil + r = 9.0mil + } + } + height = 1.574801mm + } + ha:9 { + width = 0.584201mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 10.0mil + x2 = 13.0mil + y1 = 11.0mil + } + ha:line.1 { + y2 = 29.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 21.0mil + } + ha:line.2 { + y2 = 43.0mil + thickness = 10.75mil + x1 = 23.0mil + x2 = 23.0mil + y1 = 21.0mil + } + ha:line.3 { + y2 = 39.0mil + thickness = 10.75mil + x1 = 10.0mil + x2 = 23.0mil + y1 = 39.0mil + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = -90.000000 + astart = 90.000000 + x = 10.0mil + y = 29.0mil + r = 10.0mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = -90.000000 + astart = 270.000000 + x = 13.0mil + y = 21.0mil + r = 10.0mil + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = 90.000000 + astart = 270.000000 + x = 10.0mil + y = 21.0mil + r = 10.0mil + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = -83.659808 + astart = 180.000000 + x = 4.0mil + y = 43.0mil + r = 19.0mil + } + } + height = 1.571849mm + } + ha:< { + width = 0.558801mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 50.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 22.0mil + y1 = 42.0mil + } + ha:line.1 { + y2 = 34.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 22.0mil + y1 = 42.0mil + } + } + height = 1.270001mm + } + ha:> { + width = 0.558801mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 50.0mil + thickness = 10.75mil + x1 = 22.0mil + x2 = 0.0 + y1 = 42.0mil + } + ha:line.1 { + y2 = 34.0mil + thickness = 10.75mil + x1 = 22.0mil + x2 = 0.0 + y1 = 42.0mil + } + } + height = 1.270001mm + } + ha:? { + width = 0.583743mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 20.0mil + thickness = 10.75mil + x1 = 0.583742mm + x2 = 0.583742mm + y1 = 17.0mil + } + ha:line.1 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 12.9819685mil + x2 = 0.405942mm + y1 = 11.0mil + } + ha:line.2 { + y2 = 0.71041mm + thickness = 10.75mil + x1 = 0.384171mm + x2 = 0.48144mm + y1 = 0.791634mm + } + ha:line.3 { + y2 = 38.0mil + thickness = 10.75mil + x1 = 0.304342mm + x2 = 0.304342mm + y1 = 45.0mil + } + ha:line.4 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.304342mm + x2 = 0.304342mm + y1 = 60.0mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = -49.398705 + astart = 0.000000 + x = 0.532942mm + y = 38.0mil + r = 9.0mil + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = 25.641006 + astart = -90.000000 + x = 12.9819685mil + y = 41.0mil + r = 30.0mil + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = -48.366461 + astart = 180.000000 + x = 0.278942mm + y = 19.0mil + r = 12.0mil + } + ha:simplearc.8 { + thickness = 10.75mil + adelta = 90.000000 + astart = 180.000000 + x = 0.405942mm + y = 18.0mil + r = 7.0mil + } + } + height = 1.574801mm + } + ha:@ { + width = 1.143001mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 54.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 19.0mil + } + ha:line.1 { + y2 = 2.0mil + thickness = 10.75mil + x1 = 17.0mil + x2 = 28.0mil + y1 = 2.0mil + } + ha:line.2 { + y2 = 19.0mil + thickness = 10.75mil + x1 = 45.0mil + x2 = 45.0mil + y1 = 47.0mil + } + ha:line.3 { + y2 = 47.0mil + thickness = 10.75mil + x1 = 31.0mil + x2 = 31.0mil + y1 = 19.0mil + } + ha:line.4 { + y2 = 19.0mil + thickness = 10.75mil + x1 = 21.0mil + x2 = 31.0mil + y1 = 19.0mil + } + ha:line.5 { + y2 = 26.0mil + thickness = 10.75mil + x1 = 14.0mil + x2 = 14.0mil + y1 = 47.0mil + } + ha:line.6 { + y2 = 54.0mil + thickness = 10.75mil + x1 = 20.0mil + x2 = 24.0mil + y1 = 54.0mil + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = -90.000000 + astart = 0.000000 + x = 21.0mil + y = 26.0mil + r = 7.0mil + } + ha:simplearc.8 { + thickness = 10.75mil + adelta = 90.000000 + astart = -0.000000 + x = 21.0mil + y = 47.0mil + r = 7.0mil + } + ha:simplearc.9 { + thickness = 10.75mil + adelta = -90.000000 + astart = 180.000000 + x = 24.0mil + y = 47.0mil + r = 7.0mil + } + ha:simplearc.10 { + thickness = 10.75mil + adelta = 180.000000 + astart = 0.000000 + x = 38.0mil + y = 47.0mil + r = 7.0mil + } + ha:simplearc.11 { + thickness = 10.75mil + adelta = 90.000000 + astart = 180.000000 + x = 28.0mil + y = 19.0mil + r = 17.0mil + } + ha:simplearc.12 { + thickness = 10.75mil + adelta = -90.000000 + astart = 0.000000 + x = 17.0mil + y = 19.0mil + r = 17.0mil + } + ha:simplearc.13 { + thickness = 10.75mil + adelta = 96.709837 + astart = -0.000000 + x = 17.0mil + y = 54.0mil + r = 17.0mil + } + } + height = 1.803401mm + } + ha:A { + width = 1.117601mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 0.277876mm + thickness = 10.75mil + x1 = 22.0mil + x2 = 13.0mil + y1 = 0.277876mm + } + ha:line.1 { + y2 = 1.573276mm + thickness = 10.75mil + x1 = 12.0mil + x2 = 0.0 + y1 = 1.573276mm + } + ha:line.2 { + y2 = 1.573276mm + thickness = 10.75mil + x1 = 44.0mil + x2 = 32.0mil + y1 = 1.573276mm + } + ha:line.3 { + y2 = 48.0mil + thickness = 10.75mil + x1 = 0.245533mm + x2 = 0.872066mm + y1 = 48.0mil + } + ha:line.4 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 39.0mil + x2 = 22.0mil + y1 = 62.0mil + } + ha:line.5 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 5.0mil + x2 = 22.0mil + y1 = 62.0mil + } + } + height = 1.574801mm + } + ha:B { + width = 0.863601mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 6.0mil + x2 = 6.0mil + y1 = 1.573276mm + } + ha:line.1 { + y2 = 1.573276mm + thickness = 10.75mil + x1 = 0.06mil + x2 = 0.0 + y1 = 62.0mil + } + ha:line.2 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.06mil + x2 = 21.0mil + y1 = 11.0mil + } + ha:line.3 { + y2 = 34.0mil + thickness = 10.75mil + x1 = 20.0mil + x2 = 6.0mil + y1 = 34.0mil + } + ha:line.4 { + y2 = 51.0mil + thickness = 10.75mil + x1 = 34.0mil + x2 = 34.0mil + y1 = 47.0mil + } + ha:line.5 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 22.0mil + x2 = 0.06mil + y1 = 62.0mil + } + ha:line.6 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.06mil + y1 = 0.277876mm + } + ha:line.7 { + y2 = 1.573276mm + thickness = 10.75mil + x1 = 5.94mil + x2 = 6.0mil + y1 = 62.0mil + } + ha:simplearc.8 { + thickness = 10.75mil + adelta = -90.000000 + astart = -90.000000 + x = 21.0mil + y = 22.0mil + r = 11.0mil + } + ha:simplearc.9 { + thickness = 10.75mil + adelta = -90.000000 + astart = 180.000000 + x = 22.0mil + y = 50.0mil + r = 12.0mil + } + ha:simplearc.10 { + thickness = 10.75mil + adelta = -90.000000 + astart = 180.000000 + x = 20.0mil + y = 22.0mil + r = 12.0mil + } + ha:simplearc.11 { + thickness = 10.75mil + adelta = -90.000000 + astart = -90.000000 + x = 20.0mil + y = 48.0mil + r = 14.0mil + } + } + height = 1.574801mm + } + ha:C { + width = 0.709677mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 27.94mil + x2 = 27.94mil + y1 = 16.94mil + } + ha:line.1 { + y2 = 52.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 21.0mil + } + ha:line.2 { + y2 = 1.573276mm + thickness = 10.75mil + x1 = 10.0mil + x2 = 27.94mil + y1 = 62.0mil + } + ha:line.3 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 10.0mil + x2 = 27.94mil + y1 = 11.0mil + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = -90.000000 + astart = 0.000000 + x = 10.0mil + y = 21.0mil + r = 10.0mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = 90.000000 + astart = -0.000000 + x = 10.0mil + y = 52.0mil + r = 10.0mil + } + } + height = 1.574801mm + } + ha:D { + width = 0.863601mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.06mil + x2 = 24.0mil + y1 = 62.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 6.0mil + x2 = 6.0mil + y1 = 11.06mil + } + ha:line.2 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.06mil + x2 = 24.0mil + y1 = 11.0mil + } + ha:line.3 { + y2 = 11.06mil + thickness = 10.75mil + x1 = 5.94mil + x2 = 6.0mil + y1 = 11.0mil + } + ha:line.4 { + y2 = 52.0mil + thickness = 10.75mil + x1 = 34.0mil + x2 = 34.0mil + y1 = 21.0mil + } + ha:line.5 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.06mil + y1 = 1.573276mm + } + ha:line.6 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.06mil + y1 = 0.277876mm + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = 90.000000 + astart = 180.000000 + x = 24.0mil + y = 21.0mil + r = 10.0mil + } + ha:simplearc.8 { + thickness = 10.75mil + adelta = -90.000000 + astart = 180.000000 + x = 24.0mil + y = 52.0mil + r = 10.0mil + } + } + height = 1.574801mm + } + ha:E { + width = 0.787401mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 0.862076mm + thickness = 10.75mil + x1 = 25.0mil + x2 = 6.0mil + y1 = 0.862076mm + } + ha:line.1 { + y2 = 0.303276mm + thickness = 10.75mil + x1 = 0.763524mm + x2 = 31.0mil + y1 = 11.0mil + } + ha:line.2 { + y2 = 1.420876mm + thickness = 10.75mil + x1 = 30.94mil + x2 = 31.0mil + y1 = 56.0mil + } + ha:line.3 { + y2 = 56.0mil + thickness = 10.75mil + x1 = 30.94mil + x2 = 30.94mil + y1 = 62.0mil + } + ha:line.4 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 6.0mil + x2 = 6.0mil + y1 = 1.573276mm + } + ha:line.5 { + y2 = 1.573276mm + thickness = 10.75mil + x1 = 0.06mil + x2 = 0.0 + y1 = 62.0mil + } + ha:line.6 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 31.0mil + x2 = 31.0mil + y1 = 16.94mil + } + ha:line.7 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.06mil + x2 = 0.763524mm + y1 = 11.0mil + } + ha:line.8 { + y2 = 1.573276mm + thickness = 10.75mil + x1 = 0.153924mm + x2 = 6.0mil + y1 = 62.0mil + } + ha:line.9 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.06mil + y1 = 0.277876mm + } + ha:line.10 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 30.94mil + x2 = 0.06mil + y1 = 62.0mil + } + ha:line.11 { + y2 = 0.938276mm + thickness = 10.75mil + x1 = 25.0mil + x2 = 25.0mil + y1 = 30.94mil + } + } + height = 1.574801mm + } + ha:F { + width = 0.787401mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 0.862076mm + thickness = 10.75mil + x1 = 25.0mil + x2 = 6.0mil + y1 = 0.862076mm + } + ha:line.1 { + y2 = 16.94mil + thickness = 10.75mil + x1 = 30.94mil + x2 = 31.0mil + y1 = 0.428752mm + } + ha:line.2 { + y2 = 0.428752mm + thickness = 10.75mil + x1 = 30.94mil + x2 = 30.94mil + y1 = 11.0mil + } + ha:line.3 { + y2 = 0.277876mm + thickness = 10.75mil + x1 = 30.94mil + x2 = 31.0mil + y1 = 11.0mil + } + ha:line.4 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.06mil + x2 = 30.94mil + y1 = 11.0mil + } + ha:line.5 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.06mil + y1 = 0.277876mm + } + ha:line.6 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 6.0mil + x2 = 6.0mil + y1 = 62.0mil + } + ha:line.7 { + y2 = 61.88mil + thickness = 10.75mil + x1 = 12.0mil + x2 = 0.0 + y1 = 1.573276mm + } + ha:line.8 { + y2 = 0.938276mm + thickness = 10.75mil + x1 = 25.0mil + x2 = 25.0mil + y1 = 30.94mil + } + } + height = 1.574801mm + } + ha:G { + width = 0.862077mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 0.862076mm + thickness = 10.75mil + x1 = 33.88mil + x2 = 0.862076mm + y1 = 34.0mil + } + ha:line.1 { + y2 = 34.0mil + thickness = 10.75mil + x1 = 22.0mil + x2 = 33.88mil + y1 = 34.0mil + } + ha:line.2 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 27.94mil + x2 = 27.94mil + y1 = 16.94mil + } + ha:line.3 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 28.0mil + x2 = 28.0mil + y1 = 34.0mil + } + ha:line.4 { + y2 = 34.0mil + thickness = 10.75mil + x1 = 21.94mil + x2 = 22.0mil + y1 = 0.862076mm + } + ha:line.5 { + y2 = 52.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 21.0mil + } + ha:line.6 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 10.0mil + x2 = 28.0mil + y1 = 62.0mil + } + ha:line.7 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 10.0mil + x2 = 28.0mil + y1 = 11.0mil + } + ha:simplearc.8 { + thickness = 10.75mil + adelta = -90.000000 + astart = 0.000000 + x = 10.0mil + y = 21.0mil + r = 10.0mil + } + ha:simplearc.9 { + thickness = 10.75mil + adelta = 90.000000 + astart = 0.000000 + x = 10.0mil + y = 52.0mil + r = 10.0mil + } + } + height = 1.574801mm + } + ha:H { + width = 1.041401mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 0.277876mm + thickness = 10.75mil + x1 = 29.0mil + x2 = 41.0mil + y1 = 0.277876mm + } + ha:line.1 { + y2 = 61.88mil + thickness = 10.75mil + x1 = 29.0mil + x2 = 41.0mil + y1 = 61.88mil + } + ha:line.2 { + y2 = 61.88mil + thickness = 10.75mil + x1 = 0.0 + x2 = 12.0mil + y1 = 61.88mil + } + ha:line.3 { + y2 = 0.277876mm + thickness = 10.75mil + x1 = 0.0 + x2 = 12.0mil + y1 = 0.277876mm + } + ha:line.4 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 35.0mil + x2 = 35.0mil + y1 = 62.0mil + } + ha:line.5 { + y2 = 34.0mil + thickness = 10.75mil + x1 = 34.0mil + x2 = 6.0mil + y1 = 34.0mil + } + ha:line.6 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 6.0mil + x2 = 6.0mil + y1 = 62.0mil + } + } + height = 1.574801mm + } + ha:I { + width = 0.609601mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 1.573276mm + thickness = 10.75mil + x1 = 0.0 + x2 = 23.0mil + y1 = 1.573276mm + } + ha:line.1 { + y2 = 0.277876mm + thickness = 10.75mil + x1 = 0.0 + x2 = 24.0mil + y1 = 0.277876mm + } + ha:line.2 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 12.0mil + x2 = 12.0mil + y1 = 62.0mil + } + } + height = 1.574801mm + } + ha:J { + width = 0.941325mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 0.277876mm + thickness = 10.75mil + x1 = 0.103124mm + x2 = 37.06mil + y1 = 0.277876mm + } + ha:line.1 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.534924mm + x2 = 0.534924mm + y1 = 1.243076mm + } + ha:line.2 { + y2 = 1.573276mm + thickness = 10.75mil + x1 = 0.179324mm + x2 = 0.06mil + y1 = 1.573276mm + } + ha:line.3 { + y2 = 56.0mil + thickness = 10.75mil + x1 = 0.06mil + x2 = 0.0 + y1 = 1.573276mm + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = 90.000000 + astart = 90.000000 + x = 8.06mil + y = 1.243076mm + r = 13.0mil + } + } + height = 1.573277mm + } + ha:K { + width = 0.990601mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 1.573276mm + thickness = 10.75mil + x1 = 0.888145mm + x2 = 39.0mil + y1 = 1.573276mm + } + ha:line.1 { + y2 = 10.88mil + thickness = 10.75mil + x1 = 27.0mil + x2 = 39.0mil + y1 = 10.88mil + } + ha:line.2 { + y2 = 1.573276mm + thickness = 10.75mil + x1 = 0.0 + x2 = 12.0mil + y1 = 1.573276mm + } + ha:line.3 { + y2 = 0.277876mm + thickness = 10.75mil + x1 = 0.0 + x2 = 12.0mil + y1 = 0.277876mm + } + ha:line.4 { + y2 = 0.764963mm + thickness = 10.75mil + x1 = 35.0mil + x2 = 0.434763mm + y1 = 62.0mil + } + ha:line.5 { + y2 = 42.0mil + thickness = 10.75mil + x1 = 35.0mil + x2 = 6.0mil + y1 = 11.0mil + } + ha:line.6 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 6.0mil + x2 = 6.0mil + y1 = 62.0mil + } + } + height = 1.574801mm + } + ha:L { + width = 0.787401mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 31.0mil + x2 = 31.0mil + y1 = 1.420876mm + } + ha:line.1 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.06mil + x2 = 31.0mil + y1 = 62.0mil + } + ha:line.2 { + y2 = 0.277876mm + thickness = 10.75mil + x1 = 0.0 + x2 = 12.0mil + y1 = 0.277876mm + } + ha:line.3 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.06mil + y1 = 1.573276mm + } + ha:line.4 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 6.0mil + x2 = 6.0mil + y1 = 62.0mil + } + } + height = 1.574801mm + } + ha:M { + width = 1.168401mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 0.277876mm + thickness = 10.75mil + x1 = 1.166876mm + x2 = 46.0mil + y1 = 11.0mil + } + ha:line.1 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 40.0mil + x2 = 1.166876mm + y1 = 11.0mil + } + ha:line.2 { + y2 = 0.278439mm + thickness = 10.75mil + x1 = 0.151273mm + x2 = 0.151836mm + y1 = 0.277876mm + } + ha:line.3 { + y2 = 0.277876mm + thickness = 10.75mil + x1 = 0.0 + x2 = 0.151273mm + y1 = 0.277876mm + } + ha:line.4 { + y2 = 61.88mil + thickness = 10.75mil + x1 = 34.0mil + x2 = 46.0mil + y1 = 61.88mil + } + ha:line.5 { + y2 = 1.573276mm + thickness = 10.75mil + x1 = 0.0 + x2 = 12.0mil + y1 = 1.573276mm + } + ha:line.6 { + y2 = 40.0mil + thickness = 10.75mil + x1 = 40.0mil + x2 = 23.0mil + y1 = 11.0mil + } + ha:line.7 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 40.0mil + x2 = 40.0mil + y1 = 11.0mil + } + ha:line.8 { + y2 = 40.0mil + thickness = 10.75mil + x1 = 6.0mil + x2 = 23.0mil + y1 = 11.0mil + } + ha:line.9 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 6.0mil + x2 = 6.0mil + y1 = 62.0mil + } + } + height = 1.574801mm + } + ha:&2f { + width = 0.558801mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 22.0mil + x2 = 0.0 + y1 = 11.0mil + } + } + height = 1.574801mm + } + ha:&3a { + width = 0.001um + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 54.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 56.0mil + } + ha:line.1 { + y2 = 31.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 33.0mil + } + } + height = 1.422401mm + } + ha:&3b { + width = 0.076201mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 33.0mil + thickness = 10.75mil + x1 = 3.0mil + x2 = 3.0mil + y1 = 35.0mil + } + ha:line.1 { + y2 = 56.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 3.0mil + y1 = 67.0mil + } + } + height = 1.701801mm + } + ha:&3d { + width = 0.584201mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 51.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 23.0mil + y1 = 51.0mil + } + ha:line.1 { + y2 = 34.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 23.0mil + y1 = 34.0mil + } + } + height = 1.295401mm + } + ha:O { + width = 0.812801mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 23.0mil + thickness = 10.75mil + x1 = 32.0mil + x2 = 32.0mil + y1 = 50.0mil + } + ha:line.1 { + y2 = 50.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 23.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 12.0mil + x2 = 20.0mil + y1 = 62.0mil + } + ha:line.3 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 12.0mil + x2 = 20.0mil + y1 = 11.0mil + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = -90.000000 + astart = 0.000000 + x = 12.0mil + y = 23.0mil + r = 12.0mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = 90.000000 + astart = -0.000000 + x = 12.0mil + y = 50.0mil + r = 12.0mil + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = -90.000000 + astart = 180.000000 + x = 20.0mil + y = 50.0mil + r = 12.0mil + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = 90.000000 + astart = -180.000000 + x = 20.0mil + y = 23.0mil + r = 12.0mil + } + } + height = 1.574801mm + } + ha:P { + width = 0.863601mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 0.277876mm + thickness = 10.75mil + x1 = 0.06mil + x2 = 0.0 + y1 = 11.0mil + } + ha:line.1 { + y2 = 27.0mil + thickness = 10.75mil + x1 = 34.0mil + x2 = 34.0mil + y1 = 23.0mil + } + ha:line.2 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 22.0mil + x2 = 0.06mil + y1 = 11.0mil + } + ha:line.3 { + y2 = 39.0mil + thickness = 10.75mil + x1 = 22.0mil + x2 = 6.0mil + y1 = 39.0mil + } + ha:line.4 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 6.0mil + x2 = 6.0mil + y1 = 62.0mil + } + ha:line.5 { + y2 = 61.88mil + thickness = 10.75mil + x1 = 12.0mil + x2 = 0.0 + y1 = 1.573276mm + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = -90.000000 + astart = 180.000000 + x = 22.0mil + y = 27.0mil + r = 12.0mil + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = 90.000000 + astart = -180.000000 + x = 22.0mil + y = 23.0mil + r = 12.0mil + } + } + height = 1.574801mm + } + ha:N { + width = 1.041401mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 61.88mil + thickness = 10.75mil + x1 = 0.0 + x2 = 12.0mil + y1 = 61.88mil + } + ha:line.1 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 35.06mil + x2 = 35.0mil + y1 = 0.277876mm + } + ha:line.2 { + y2 = 0.277876mm + thickness = 10.75mil + x1 = 41.0mil + x2 = 35.06mil + y1 = 0.277876mm + } + ha:line.3 { + y2 = 0.277876mm + thickness = 10.75mil + x1 = 0.002009mm + x2 = 0.0 + y1 = 0.275867mm + } + ha:line.4 { + y2 = 0.275867mm + thickness = 10.75mil + x1 = 0.150391mm + x2 = 0.002009mm + y1 = 0.275867mm + } + ha:line.5 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 6.0mil + x2 = 35.0mil + y1 = 11.0mil + } + ha:line.6 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 35.0mil + x2 = 35.0mil + y1 = 62.0mil + } + ha:line.7 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 6.0mil + x2 = 6.0mil + y1 = 62.0mil + } + } + height = 1.574801mm + } + ha:R { + width = 1.016001mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 1.573276mm + thickness = 10.75mil + x1 = 39.945mil + x2 = 40.0mil + y1 = 1.571879mm + } + ha:line.1 { + y2 = 1.571879mm + thickness = 10.75mil + x1 = 33.945mil + x2 = 39.945mil + y1 = 1.571879mm + } + ha:line.2 { + y2 = 1.573276mm + thickness = 10.75mil + x1 = 0.0 + x2 = 12.0mil + y1 = 1.573276mm + } + ha:line.3 { + y2 = 0.277876mm + thickness = 10.75mil + x1 = 0.06mil + x2 = 0.0 + y1 = 11.0mil + } + ha:line.4 { + y2 = 39.0mil + thickness = 10.75mil + x1 = 34.0mil + x2 = 23.0mil + y1 = 62.0mil + } + ha:line.5 { + y2 = 27.0mil + thickness = 10.75mil + x1 = 34.0mil + x2 = 34.0mil + y1 = 23.0mil + } + ha:line.6 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 22.0mil + x2 = 0.06mil + y1 = 11.0mil + } + ha:line.7 { + y2 = 39.0mil + thickness = 10.75mil + x1 = 22.0mil + x2 = 6.0mil + y1 = 39.0mil + } + ha:line.8 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 6.0mil + x2 = 6.0mil + y1 = 62.0mil + } + ha:simplearc.9 { + thickness = 10.75mil + adelta = -90.000000 + astart = 180.000000 + x = 22.0mil + y = 27.0mil + r = 12.0mil + } + ha:simplearc.10 { + thickness = 10.75mil + adelta = 90.000000 + astart = -180.000000 + x = 22.0mil + y = 23.0mil + r = 12.0mil + } + } + height = 1.574801mm + } + ha:S { + width = 0.738125mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 1.573276mm + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 1.370076mm + } + ha:line.1 { + y2 = 18.94mil + thickness = 10.75mil + x1 = 29.0mil + x2 = 29.0mil + y1 = 0.277876mm + } + ha:line.2 { + y2 = 52.0mil + thickness = 10.75mil + x1 = 0.738124mm + x2 = 0.738124mm + y1 = 54.0mil + } + ha:line.3 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 11.06mil + x2 = 15.06mil + y1 = 11.0mil + } + ha:line.4 { + y2 = 0.845249mm + thickness = 10.75mil + x1 = 0.5852mm + x2 = 0.202161mm + y1 = 1.042223mm + } + ha:line.5 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 15.06mil + x2 = 0.534924mm + y1 = 62.0mil + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = -41.185925 + astart = 90.000000 + x = 15.06mil + y = 40.0mil + r = 22.0mil + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = -30.068583 + astart = 270.000000 + x = 15.06mil + y = 33.0mil + r = 22.0mil + } + ha:simplearc.8 { + thickness = 10.75mil + adelta = -90.000000 + astart = 0.000000 + x = 11.06mil + y = 22.0mil + r = 11.0mil + } + ha:simplearc.9 { + thickness = 10.75mil + adelta = 70.016893 + astart = 0.000000 + x = 12.06mil + y = 22.0mil + r = 12.0mil + } + ha:simplearc.10 { + thickness = 10.75mil + adelta = 90.000000 + astart = 90.000000 + x = 0.534924mm + y = 54.0mil + r = 8.0mil + } + ha:simplearc.11 { + thickness = 10.75mil + adelta = 57.528808 + astart = 180.000000 + x = 0.407924mm + y = 52.0mil + r = 13.0mil + } + } + height = 1.574801mm + } + ha:Q { + width = 0.965201mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 26.0mil + x2 = 38.0mil + y1 = 51.0mil + } + ha:line.1 { + y2 = 23.0mil + thickness = 10.75mil + x1 = 32.0mil + x2 = 32.0mil + y1 = 50.0mil + } + ha:line.2 { + y2 = 50.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 23.0mil + } + ha:line.3 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 12.0mil + x2 = 20.0mil + y1 = 62.0mil + } + ha:line.4 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 12.0mil + x2 = 20.0mil + y1 = 11.0mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = -90.000000 + astart = 0.000000 + x = 12.0mil + y = 23.0mil + r = 12.0mil + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = 90.000000 + astart = -0.000000 + x = 12.0mil + y = 50.0mil + r = 12.0mil + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = -90.000000 + astart = 180.000000 + x = 20.0mil + y = 50.0mil + r = 12.0mil + } + ha:simplearc.8 { + thickness = 10.75mil + adelta = 90.000000 + astart = -180.000000 + x = 20.0mil + y = 23.0mil + r = 12.0mil + } + } + height = 1.574801mm + } + ha:U { + width = 1.041401mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 0.277876mm + thickness = 10.75mil + x1 = 29.0mil + x2 = 41.0mil + y1 = 0.277876mm + } + ha:line.1 { + y2 = 0.277876mm + thickness = 10.75mil + x1 = 0.0 + x2 = 12.0mil + y1 = 0.277876mm + } + ha:line.2 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 35.06mil + x2 = 35.06mil + y1 = 49.0mil + } + ha:line.3 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.153924mm + x2 = 0.153924mm + y1 = 49.0mil + } + ha:line.4 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.458724mm + x2 = 0.560324mm + y1 = 62.0mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = 90.000000 + astart = 0.000000 + x = 0.484124mm + y = 49.0mil + r = 13.0mil + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = -90.000000 + astart = 180.000000 + x = 0.560324mm + y = 49.0mil + r = 13.0mil + } + } + height = 1.574801mm + } + ha:V { + width = 1.168401mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 10.88mil + thickness = 10.75mil + x1 = 46.0mil + x2 = 34.0mil + y1 = 10.88mil + } + ha:line.1 { + y2 = 10.88mil + thickness = 10.75mil + x1 = 12.0mil + x2 = 0.0 + y1 = 10.88mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 41.0mil + x2 = 23.0mil + y1 = 11.0mil + } + ha:line.3 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 5.0mil + x2 = 23.0mil + y1 = 11.0mil + } + } + height = 1.574801mm + } + ha:T { + width = 0.838201mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 0.277876mm + thickness = 10.75mil + x1 = 0.836676mm + x2 = 33.0mil + y1 = 11.0mil + } + ha:line.1 { + y2 = 16.94mil + thickness = 10.75mil + x1 = 33.0mil + x2 = 33.0mil + y1 = 11.0mil + } + ha:line.2 { + y2 = 16.94mil + thickness = 10.75mil + x1 = 0.06mil + x2 = 0.0 + y1 = 0.428752mm + } + ha:line.3 { + y2 = 0.428752mm + thickness = 10.75mil + x1 = 0.06mil + x2 = 0.06mil + y1 = 11.0mil + } + ha:line.4 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.836676mm + y1 = 11.0mil + } + ha:line.5 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 17.0mil + x2 = 17.0mil + y1 = 62.0mil + } + ha:line.6 { + y2 = 1.573276mm + thickness = 10.75mil + x1 = 24.0mil + x2 = 10.0mil + y1 = 1.573276mm + } + } + height = 1.574801mm + } + ha:X { + width = 1.092201mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 61.88mil + thickness = 10.75mil + x1 = 43.0mil + x2 = 31.0mil + y1 = 61.88mil + } + ha:line.1 { + y2 = 10.88mil + thickness = 10.75mil + x1 = 43.0mil + x2 = 31.0mil + y1 = 10.88mil + } + ha:line.2 { + y2 = 61.88mil + thickness = 10.75mil + x1 = 12.0mil + x2 = 0.0 + y1 = 61.88mil + } + ha:line.3 { + y2 = 10.88mil + thickness = 10.75mil + x1 = 12.0mil + x2 = 0.0 + y1 = 10.88mil + } + ha:line.4 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 39.0mil + x2 = 4.0mil + y1 = 11.0mil + } + ha:line.5 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 4.0mil + x2 = 39.0mil + y1 = 11.0mil + } + } + height = 1.574801mm + } + ha:Y { + width = 1.066801mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 1.573276mm + thickness = 10.75mil + x1 = 28.0mil + x2 = 14.0mil + y1 = 1.573276mm + } + ha:line.1 { + y2 = 10.82mil + thickness = 10.75mil + x1 = 12.0mil + x2 = 0.0 + y1 = 10.82mil + } + ha:line.2 { + y2 = 10.82mil + thickness = 10.75mil + x1 = 42.0mil + x2 = 30.0mil + y1 = 10.82mil + } + ha:line.3 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 21.0mil + x2 = 21.0mil + y1 = 35.0mil + } + ha:line.4 { + y2 = 35.0mil + thickness = 10.75mil + x1 = 38.0mil + x2 = 21.0mil + y1 = 11.0mil + } + ha:line.5 { + y2 = 35.0mil + thickness = 10.75mil + x1 = 4.0mil + x2 = 21.0mil + y1 = 11.0mil + } + } + height = 1.574801mm + } + ha:W { + width = 1.371601mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 10.88mil + thickness = 10.75mil + x1 = 54.0mil + x2 = 42.0mil + y1 = 10.88mil + } + ha:line.1 { + y2 = 10.88mil + thickness = 10.75mil + x1 = 12.0mil + x2 = 0.0 + y1 = 10.88mil + } + ha:line.2 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 38.0mil + x2 = 27.0mil + y1 = 62.0mil + } + ha:line.3 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 49.0mil + x2 = 38.0mil + y1 = 11.0mil + } + ha:line.4 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 16.0mil + x2 = 27.0mil + y1 = 62.0mil + } + ha:line.5 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 5.0mil + x2 = 16.0mil + y1 = 11.0mil + } + } + height = 1.574801mm + } + ha:[ { + width = 0.152401mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 5.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 6.0mil + y1 = 5.0mil + } + ha:line.1 { + y2 = 68.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 6.0mil + y1 = 68.0mil + } + ha:line.2 { + y2 = 68.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 5.0mil + } + } + height = 1.727201mm + } + ha:^ { + width = 0.406401mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 0.0 + thickness = 10.75mil + x1 = 16.0mil + x2 = 8.0mil + y1 = 9.0mil + } + ha:line.1 { + y2 = 0.0 + thickness = 10.75mil + x1 = 0.0 + x2 = 8.0mil + y1 = 9.0mil + } + } + height = 0.228601mm + } + ha:Z { + width = 0.787401mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 1.420876mm + thickness = 10.75mil + x1 = 31.0mil + x2 = 31.0mil + y1 = 62.0mil + } + ha:line.1 { + y2 = 16.94mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.0 + y1 = 11.0mil + } + ha:line.2 { + y2 = 0.277876mm + thickness = 10.75mil + x1 = 0.0 + x2 = 31.0mil + y1 = 62.0mil + } + ha:line.3 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 31.0mil + y1 = 62.0mil + } + ha:line.4 { + y2 = 0.277876mm + thickness = 10.75mil + x1 = 0.0 + x2 = 31.0mil + y1 = 11.0mil + } + } + height = 1.574801mm + } + ha:` { + width = 0.279401mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 10.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 11.0mil + y1 = 2.0mil + } + } + height = 0.254001mm + } + ha:_ { + width = 0.609601mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 68.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 24.0mil + y1 = 68.0mil + } + } + height = 1.727201mm + } + } + cell_width = 1.371601mm + cell_height = 2.032001mm + } +} Index: tags/1.0.5/font/aussiefont-serif-bold-oblique =================================================================== --- tags/1.0.5/font/aussiefont-serif-bold-oblique (nonexistent) +++ tags/1.0.5/font/aussiefont-serif-bold-oblique (revision 10414) @@ -0,0 +1,4807 @@ +li:pcb-rnd-font-v1 { + ha:geda_pcb { + id = 0 + ha:symbols { + ha:&09 { + width = 0.685801mm + delta = 0.103633mm + li:objects { + ha:line.0 { + y2 = 36.0mil + thickness = 3.0mil + x1 = 0.0 + x2 = 27.0mil + y1 = 36.0mil + } + ha:line.1 { + y2 = 30.0mil + thickness = 3.0mil + x1 = 27.0mil + x2 = 22.0mil + y1 = 36.0mil + } + ha:line.2 { + y2 = 42.0mil + thickness = 3.0mil + x1 = 27.0mil + x2 = 22.0mil + y1 = 36.0mil + } + ha:line.3 { + y2 = 42.0mil + thickness = 3.0mil + x1 = 0.0 + x2 = 5.0mil + y1 = 36.0mil + } + ha:line.4 { + y2 = 30.0mil + thickness = 3.0mil + x1 = 0.0 + x2 = 5.0mil + y1 = 36.0mil + } + } + height = 1.066801mm + } + ha:&0A { + width = 0.889001mm + delta = 10.0mil + li:objects { + ha:line.0 { + y2 = 10.0mil + thickness = 3.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 40.0mil + } + ha:line.1 { + y2 = 40.0mil + thickness = 3.0mil + x1 = 0.0 + x2 = 15.0mil + y1 = 40.0mil + } + ha:line.2 { + y2 = 45.0mil + thickness = 3.0mil + x1 = 20.0mil + x2 = 20.0mil + y1 = 75.0mil + } + ha:line.3 { + y2 = 45.0mil + thickness = 3.0mil + x1 = 20.0mil + x2 = 35.0mil + y1 = 45.0mil + } + ha:line.4 { + y2 = 60.0mil + thickness = 3.0mil + x1 = 20.0mil + x2 = 30.0mil + y1 = 60.0mil + } + } + height = 1.905001mm + } + ha:&0D { + width = 0.889001mm + delta = 0.253999mm + li:objects { + ha:line.0 { + y2 = 15.0mil + thickness = 3.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 35.0mil + } + ha:line.1 { + y2 = 10.0mil + thickness = 3.0mil + x1 = 5.0mil + x2 = 10.0mil + y1 = 10.0mil + } + ha:line.2 { + y2 = 40.0mil + thickness = 3.0mil + x1 = 5.0mil + x2 = 10.0mil + y1 = 40.0mil + } + ha:line.3 { + y2 = 45.0mil + thickness = 3.0mil + x1 = 20.0mil + x2 = 20.0mil + y1 = 75.0mil + } + ha:line.4 { + y2 = 45.0mil + thickness = 3.0mil + x1 = 20.0mil + x2 = 30.0mil + y1 = 45.0mil + } + ha:line.5 { + y2 = 60.0mil + thickness = 3.0mil + x1 = 20.0mil + x2 = 30.0mil + y1 = 60.0mil + } + ha:line.6 { + y2 = 55.0mil + thickness = 3.0mil + x1 = 35.0mil + x2 = 35.0mil + y1 = 50.0mil + } + ha:line.7 { + y2 = 75.0mil + thickness = 3.0mil + x1 = 30.0mil + x2 = 35.0mil + y1 = 60.0mil + } + ha:simplearc.8 { + thickness = 3.0mil + adelta = -90.000000 + astart = -90.000000 + x = 10.0mil + y = 15.0mil + r = 5.0mil + } + ha:simplearc.9 { + thickness = 3.0mil + adelta = 90.000000 + astart = 270.000000 + x = 5.0mil + y = 15.0mil + r = 5.0mil + } + ha:simplearc.10 { + thickness = 3.0mil + adelta = 90.000000 + astart = 90.000000 + x = 10.0mil + y = 35.0mil + r = 5.0mil + } + ha:simplearc.11 { + thickness = 3.0mil + adelta = -90.000000 + astart = 90.000000 + x = 5.0mil + y = 35.0mil + r = 5.0mil + } + ha:simplearc.12 { + thickness = 3.0mil + adelta = 90.000000 + astart = 90.000000 + x = 30.0mil + y = 55.0mil + r = 5.0mil + } + ha:simplearc.13 { + thickness = 3.0mil + adelta = -90.000000 + astart = -90.000000 + x = 30.0mil + y = 50.0mil + r = 5.0mil + } + } + height = 1.905001mm + } ha:] { + width = 0.406401mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 1.727237mm + thickness = 10.75mil + x1 = 0.0 + x2 = 0.16637mm + y1 = 1.727237mm + } + ha:line.1 { + y2 = 0.127037mm + thickness = 10.75mil + x1 = 10.0mil + x2 = 16.0mil + y1 = 0.127037mm + } + ha:line.2 { + y2 = 1.727237mm + thickness = 10.75mil + x1 = 16.0mil + x2 = 0.16637mm + y1 = 0.127037mm + } + } + height = 1.727238mm + } + ha:&5c { + width = 0.364491mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 1.574837mm + thickness = 10.75mil + x1 = 0.0 + x2 = 0.36449mm + y1 = 0.279437mm + } + } + height = 1.574838mm + } + ha:b { + width = 0.885005mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 0.254037mm + thickness = 10.75mil + x1 = 0.19812mm + x2 = 0.350292mm + y1 = 0.252513mm + } + ha:line.1 { + y2 = 1.574837mm + thickness = 10.75mil + x1 = 0.350292mm + x2 = 0.152172mm + y1 = 0.254037mm + } + ha:line.2 { + y2 = 1.573276mm + thickness = 10.75mil + x1 = 0.0 + x2 = 0.611192mm + y1 = 1.573313mm + } + ha:line.3 { + y2 = 1.420876mm + thickness = 10.75mil + x1 = 0.884098mm + x2 = 0.796968mm + y1 = 0.861877mm + } + ha:line.4 { + y2 = 27.94mil + thickness = 10.75mil + x1 = 0.290796mm + x2 = 0.748504mm + y1 = 27.94mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = 78.560593 + astart = 90.000000 + x = 0.611192mm + y = 54.46mil + r = 7.48mil + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = -96.605083 + astart = -90.000000 + x = 0.748504mm + y = 0.846176mm + r = 0.1365mm + } + } + height = 1.574838mm + } + ha:c { + width = 0.625448mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 0.862113mm + thickness = 10.75mil + x1 = 0.625447mm + x2 = 0.602587mm + y1 = 0.709713mm + } + ha:line.1 { + y2 = 0.709713mm + thickness = 10.75mil + x1 = 0.271143mm + x2 = 0.625447mm + y1 = 0.711237mm + } + ha:line.2 { + y2 = 1.573313mm + thickness = 10.75mil + x1 = 0.141603mm + x2 = 0.495907mm + y1 = 1.574837mm + } + ha:line.3 { + y2 = 1.573276mm + thickness = 10.75mil + x1 = 0.134939mm + x2 = 0.431103mm + y1 = 1.573276mm + } + ha:line.4 { + y2 = 55.74mil + thickness = 10.75mil + x1 = 0.08824mm + x2 = 0.00188mm + y1 = 0.862076mm + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = 78.560593 + astart = 270.000000 + x = 0.273812mm + y = 35.42mil + r = 7.48mil + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = -96.605083 + astart = 90.000000 + x = 0.1365mm + y = 1.436776mm + r = 0.1365mm + } + } + height = 1.574838mm + } + ha:a { + width = 0.744506mm + delta = 0.391108mm + li:objects { + ha:line.0 { + y2 = 1.574837mm + thickness = 10.75mil + x1 = 0.696271mm + x2 = 0.593401mm + y1 = 0.889037mm + } + ha:line.1 { + y2 = 1.573313mm + thickness = 10.75mil + x1 = 0.298701mm + x2 = 0.744505mm + y1 = 1.573276mm + } + ha:line.2 { + y2 = 0.711237mm + thickness = 10.75mil + x1 = 0.240341mm + x2 = 0.545141mm + y1 = 0.711237mm + } + ha:line.3 { + y2 = 1.116076mm + thickness = 10.75mil + x1 = 0.277365mm + x2 = 0.654301mm + y1 = 1.116076mm + } + ha:line.4 { + y2 = 1.573276mm + thickness = 10.75mil + x1 = 0.16911mm + x2 = 0.581954mm + y1 = 1.573276mm + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = 90.000000 + astart = 180.000000 + x = 0.518471mm + y = 0.889037mm + r = 7.0mil + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = 90.000000 + astart = 0.000000 + x = 6.7mil + y = 55.24mil + r = 6.7mil + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = -90.000000 + astart = 0.000000 + x = 11.3mil + y = 55.24mil + r = 11.3mil + } + } + height = 1.574838mm + } + ha:e { + width = 0.657861mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 1.573276mm + thickness = 10.75mil + x1 = 0.160198mm + x2 = 0.566598mm + y1 = 1.573276mm + } + ha:line.1 { + y2 = 1.141476mm + thickness = 10.75mil + x1 = 1.59mil + x2 = 0.633745mm + y1 = 1.141476mm + } + ha:line.2 { + y2 = 0.989076mm + thickness = 10.75mil + x1 = 0.0 + x2 = 0.064618mm + y1 = 1.395476mm + } + ha:line.3 { + y2 = 27.94mil + thickness = 10.75mil + x1 = 15.5mil + x2 = 15.9mil + y1 = 27.94mil + } + ha:line.4 { + y2 = 0.98946mm + thickness = 10.75mil + x1 = 0.633688mm + x2 = 0.656548mm + y1 = 1.14186mm + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = -80.753887 + astart = 350.753887 + x = 15.5mil + y = 1.042416mm + r = 0.33274mm + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = -95.826342 + astart = -90.000000 + x = 15.9mil + y = 0.963676mm + r = 10.0mil + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = -96.270309 + astart = 90.000000 + x = 0.160198mm + y = 1.413078mm + r = 0.160198mm + } + } + height = 1.573277mm + } + ha:f { + width = 0.645087mm + delta = 0.475386mm + li:objects { + ha:line.0 { + y2 = 1.573313mm + thickness = 10.75mil + x1 = 0.0 + x2 = 17.0mil + y1 = 1.573313mm + } + ha:line.1 { + y2 = 1.546897mm + thickness = 10.75mil + x1 = 0.325968mm + x2 = 0.157252mm + y1 = 0.425778mm + } + ha:line.2 { + y2 = 0.711237mm + thickness = 10.75mil + x1 = 0.129312mm + x2 = 0.561112mm + y1 = 0.711237mm + } + ha:line.3 { + y2 = 0.277965mm + thickness = 10.75mil + x1 = 0.509236mm + x2 = 0.645086mm + y1 = 0.277876mm + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = 78.560593 + astart = 270.000000 + x = 0.512574mm + y = 0.467957mm + r = 7.48mil + } + } + height = 1.573314mm + } + ha:d { + width = 0.808669mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 0.252513mm + thickness = 10.75mil + x1 = 0.808668mm + x2 = 0.654744mm + y1 = 0.252513mm + } + ha:line.1 { + y2 = 1.573313mm + thickness = 10.75mil + x1 = 0.137312mm + x2 = 0.761424mm + y1 = 1.573276mm + } + ha:line.2 { + y2 = 1.574837mm + thickness = 10.75mil + x1 = 0.80844mm + x2 = 0.61032mm + y1 = 0.254037mm + } + ha:line.3 { + y2 = 1.420876mm + thickness = 10.75mil + x1 = 0.088849mm + x2 = 0.0 + y1 = 0.862076mm + } + ha:line.4 { + y2 = 27.94mil + thickness = 10.75mil + x1 = 0.274625mm + x2 = 0.732333mm + y1 = 27.94mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = 78.560593 + astart = 270.000000 + x = 0.276185mm + y = 35.42mil + r = 7.48mil + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = -96.605083 + astart = 90.000000 + x = 0.138873mm + y = 1.436776mm + r = 0.1365mm + } + } + height = 1.574838mm + } + ha:h { + width = 0.965201mm + delta = 0.381354mm + li:objects { + ha:line.0 { + y2 = 1.573313mm + thickness = 10.75mil + x1 = 26.0mil + x2 = 38.0mil + y1 = 1.573313mm + } + ha:line.1 { + y2 = 1.573313mm + thickness = 10.75mil + x1 = 0.0 + x2 = 12.0mil + y1 = 1.573313mm + } + ha:line.2 { + y2 = 0.252513mm + thickness = 10.75mil + x1 = 0.19812mm + x2 = 13.8mil + y1 = 0.252513mm + } + ha:line.3 { + y2 = 1.574837mm + thickness = 10.75mil + x1 = 0.350292mm + x2 = 0.152172mm + y1 = 0.254037mm + } + ha:line.4 { + y2 = 0.711237mm + thickness = 10.75mil + x1 = 0.330632mm + x2 = 0.78834mm + y1 = 0.711237mm + } + ha:line.5 { + y2 = 1.574837mm + thickness = 10.75mil + x1 = 0.925653mm + x2 = 0.812572mm + y1 = 0.863637mm + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = -96.605083 + astart = 270.000000 + x = 0.79022mm + y = 0.847737mm + r = 0.1365mm + } + } + height = 1.574838mm + } + ha:i { + width = 0.609601mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 1.573313mm + thickness = 10.75mil + x1 = 0.0 + x2 = 24.0mil + y1 = 1.573313mm + } + ha:line.1 { + y2 = 0.709713mm + thickness = 10.75mil + x1 = 0.20574mm + x2 = 17.1mil + y1 = 0.709713mm + } + ha:line.2 { + y2 = 1.574837mm + thickness = 10.75mil + x1 = 0.434112mm + x2 = 0.304572mm + y1 = 0.711237mm + } + ha:line.3 { + y2 = 0.355637mm + thickness = 10.75mil + x1 = 0.498882mm + x2 = 0.487452mm + y1 = 0.279437mm + } + } + height = 1.574838mm + } + ha:g { + width = 0.889305mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 1.573276mm + thickness = 10.75mil + x1 = 0.151248mm + x2 = 0.59336mm + y1 = 1.573276mm + } + ha:line.1 { + y2 = 0.709713mm + thickness = 10.75mil + x1 = 0.28856mm + x2 = 0.889304mm + y1 = 27.94mil + } + ha:line.2 { + y2 = 0.711237mm + thickness = 10.75mil + x1 = 0.56675mm + x2 = 0.7382mm + y1 = 1.854237mm + } + ha:line.3 { + y2 = 0.862076mm + thickness = 10.75mil + x1 = 0.013935mm + x2 = 0.102785mm + y1 = 1.420876mm + } + ha:line.4 { + y2 = 2.032037mm + thickness = 10.75mil + x1 = 0.36228mm + x2 = 0.0 + y1 = 2.032037mm + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = 78.560593 + astart = 270.000000 + x = 0.28856mm + y = 35.42mil + r = 7.48mil + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = -96.605083 + astart = 90.000000 + x = 0.151248mm + y = 1.436776mm + r = 0.1365mm + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = 78.715635 + astart = 90.000000 + x = 0.350012mm + y = 1.810549mm + r = 8.72mil + } + } + height = 2.032038mm + } + ha:k { + width = 0.993141mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 0.709713mm + thickness = 10.75mil + x1 = 27.1mil + x2 = 39.1mil + y1 = 0.709713mm + } + ha:line.1 { + y2 = 1.573313mm + thickness = 10.75mil + x1 = 22.0mil + x2 = 34.0mil + y1 = 1.573313mm + } + ha:line.2 { + y2 = 1.573313mm + thickness = 10.75mil + x1 = 0.0 + x2 = 6.0mil + y1 = 1.573313mm + } + ha:line.3 { + y2 = 0.277913mm + thickness = 10.75mil + x1 = 7.65mil + x2 = 13.65mil + y1 = 0.277913mm + } + ha:line.4 { + y2 = 0.967715mm + thickness = 10.75mil + x1 = 0.736372mm + x2 = 0.499718mm + y1 = 1.574837mm + } + ha:line.5 { + y2 = 1.168437mm + thickness = 10.75mil + x1 = 0.865912mm + x2 = 0.213132mm + y1 = 0.711237mm + } + ha:line.6 { + y2 = 1.574837mm + thickness = 10.75mil + x1 = 0.346482mm + x2 = 0.152172mm + y1 = 0.279437mm + } + } + height = 1.574838mm + } + ha:l { + width = 0.609601mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 1.573313mm + thickness = 10.75mil + x1 = 0.0 + x2 = 24.0mil + y1 = 1.573313mm + } + ha:line.1 { + y2 = 1.573313mm + thickness = 10.75mil + x1 = 0.500406mm + x2 = 12.0mil + y1 = 0.279437mm + } + ha:line.2 { + y2 = 0.277913mm + thickness = 10.75mil + x1 = 7.65mil + x2 = 19.71mil + y1 = 0.277913mm + } + } + height = 1.573314mm + } + ha:j { + width = 0.5372mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 2.03063mm + thickness = 10.75mil + x1 = 0.0 + x2 = 0.069804mm + y1 = 80.0mil + } + ha:line.1 { + y2 = 1.827784mm + thickness = 10.75mil + x1 = 0.472429mm + x2 = 0.304789mm + y1 = 27.96mil + } + ha:line.2 { + y2 = 13.96mil + thickness = 10.75mil + x1 = 0.537199mm + x2 = 0.525769mm + y1 = 10.96mil + } + ha:line.3 { + y2 = 27.96mil + thickness = 10.75mil + x1 = 4.5mil + x2 = 0.472429mm + y1 = 0.710147mm + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = -59.376512 + astart = 160.839827 + x = 0.012075mm + y = 1.726078mm + r = 0.30988mm + } + } + height = 2.032001mm + } + ha:n { + width = 0.889001mm + delta = 0.399007mm + li:objects { + ha:line.0 { + y2 = 1.573313mm + thickness = 10.75mil + x1 = 29.0mil + x2 = 35.0mil + y1 = 1.573313mm + } + ha:line.1 { + y2 = 1.573313mm + thickness = 10.75mil + x1 = 0.0 + x2 = 12.0mil + y1 = 1.573313mm + } + ha:line.2 { + y2 = 1.574837mm + thickness = 10.75mil + x1 = 0.281872mm + x2 = 0.152172mm + y1 = 0.71017mm + } + ha:line.3 { + y2 = 1.574837mm + thickness = 10.75mil + x1 = 0.831622mm + x2 = 0.736372mm + y1 = 0.939837mm + } + ha:line.4 { + y2 = 0.709669mm + thickness = 10.75mil + x1 = 0.12954mm + x2 = 0.646389mm + y1 = 0.709713mm + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = -96.309371 + astart = -90.000000 + x = 0.627279mm + y = 0.917244mm + r = 0.205588mm + } + } + height = 1.574838mm + } + ha:o { + width = 0.665796mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 39.0mil + thickness = 10.75mil + x1 = 0.527um + x2 = 0.047351mm + y1 = 1.315513mm + } + ha:line.1 { + y2 = 1.30302mm + thickness = 10.75mil + x1 = 0.665269mm + x2 = 0.618445mm + y1 = 0.975567mm + } + ha:simplearc.2 { + thickness = 10.75mil + adelta = 1.505021 + astart = 2.060728 + x = 1.718468mm + y = 1.25476mm + r = 67.7mil + } + ha:simplearc.3 { + thickness = 10.75mil + adelta = -79.646680 + astart = 90.000000 + x = 0.265588mm + y = 51.7mil + r = 0.26924mm + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = 77.035491 + astart = 90.000000 + x = 0.265588mm + y = 48.0mil + r = 14.3mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = 1.505021 + astart = 182.060728 + x = -1.052672mm + y = 1.03886mm + r = 67.7mil + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = -79.646680 + astart = -90.000000 + x = 0.400208mm + y = 38.6mil + r = 0.26924mm + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = 77.035491 + astart = -90.000000 + x = 0.400208mm + y = 1.07442mm + r = 14.3mil + } + } + height = 1.582421mm + } + ha:m { + width = 1.270229mm + delta = 0.400038mm + li:objects { + ha:line.0 { + y2 = 1.573313mm + thickness = 10.75mil + x1 = 1.117828mm + x2 = 1.270228mm + y1 = 1.573313mm + } + ha:line.1 { + y2 = 1.573313mm + thickness = 10.75mil + x1 = 0.635228mm + x2 = 0.787628mm + y1 = 1.573313mm + } + ha:line.2 { + y2 = 1.574837mm + thickness = 10.75mil + x1 = 30.1mil + x2 = 25.0mil + y1 = 0.711237mm + } + ha:line.3 { + y2 = 1.574837mm + thickness = 10.75mil + x1 = 0.0 + x2 = 12.0mil + y1 = 1.574837mm + } + ha:line.4 { + y2 = 1.574837mm + thickness = 10.75mil + x1 = 0.281829mm + x2 = 6.0mil + y1 = 0.710007mm + } + ha:line.5 { + y2 = 1.574837mm + thickness = 10.75mil + x1 = 47.75mil + x2 = 44.0mil + y1 = 0.939837mm + } + ha:line.6 { + y2 = 27.94mil + thickness = 10.75mil + x1 = 0.129768mm + x2 = 1.007476mm + y1 = 0.709713mm + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = -96.309371 + astart = -90.000000 + x = 1.007476mm + y = 0.915264mm + r = 0.205588mm + } + } + height = 1.574838mm + } + ha:q { + width = 0.89061mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 2.030513mm + thickness = 10.75mil + x1 = 0.387689mm + x2 = 0.692489mm + y1 = 2.030513mm + } + ha:line.1 { + y2 = 0.711237mm + thickness = 10.75mil + x1 = 0.541385mm + x2 = 0.739505mm + y1 = 2.032037mm + } + ha:line.2 { + y2 = 1.436116mm + thickness = 10.75mil + x1 = 0.088406mm + x2 = 0.0 + y1 = 0.861987mm + } + ha:line.3 { + y2 = 1.573276mm + thickness = 10.75mil + x1 = 0.137465mm + x2 = 0.594665mm + y1 = 1.573276mm + } + ha:line.4 { + y2 = 27.94mil + thickness = 10.75mil + x1 = 0.890609mm + x2 = 10.8119685mil + y1 = 0.709713mm + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = -96.605083 + astart = -270.000000 + x = 0.137312mm + y = 1.436776mm + r = 0.1365mm + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = 78.560593 + astart = -90.000000 + x = 10.8119685mil + y = 35.42mil + r = 7.48mil + } + } + height = 2.032038mm + } + ha:r { + width = 0.698925mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 1.573313mm + thickness = 10.75mil + x1 = 0.0 + x2 = 18.0mil + y1 = 1.573313mm + } + ha:line.1 { + y2 = 0.711237mm + thickness = 10.75mil + x1 = 0.138396mm + x2 = 0.561112mm + y1 = 27.94mil + } + ha:line.2 { + y2 = 0.711237mm + thickness = 10.75mil + x1 = 0.152172mm + x2 = 0.281712mm + y1 = 1.574837mm + } + ha:line.3 { + y2 = 27.94mil + thickness = 10.75mil + x1 = 0.265396mm + x2 = 0.56156mm + y1 = 27.94mil + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = -96.605083 + astart = 270.000000 + x = 0.562424mm + y = 0.846176mm + r = 0.1365mm + } + } + height = 1.574838mm + } + ha:p { + width = 0.955566mm + delta = 0.343686mm + li:objects { + ha:line.0 { + y2 = 2.032037mm + thickness = 10.75mil + x1 = 0.351816mm + x2 = 0.153696mm + y1 = 0.711237mm + } + ha:line.1 { + y2 = 33.34mil + thickness = 10.75mil + x1 = 0.867159mm + x2 = 0.955565mm + y1 = 1.420965mm + } + ha:line.2 { + y2 = 27.94mil + thickness = 10.75mil + x1 = 0.8181mm + x2 = 0.1577mm + y1 = 27.94mil + } + ha:line.3 { + y2 = 1.573276mm + thickness = 10.75mil + x1 = 0.230852mm + x2 = 0.680941mm + y1 = 1.573276mm + } + ha:line.4 { + y2 = 2.030513mm + thickness = 10.75mil + x1 = 0.0 + x2 = 12.0mil + y1 = 2.030513mm + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = -96.605083 + astart = 270.000000 + x = 0.818253mm + y = 0.846176mm + r = 0.1365mm + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = 78.560593 + astart = 90.000000 + x = 0.680941mm + y = 54.46mil + r = 7.48mil + } + } + height = 2.032038mm + } + ha:t { + width = 0.431801mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 0.711237mm + thickness = 10.75mil + x1 = 0.0 + x2 = 17.0mil + y1 = 0.711237mm + } + ha:line.1 { + y2 = 1.344713mm + thickness = 10.75mil + x1 = 8.55mil + x2 = 0.057378mm + y1 = 0.279437mm + } + ha:line.2 { + y2 = 1.573276mm + thickness = 10.75mil + x1 = 0.285944mm + x2 = 0.339284mm + y1 = 1.573313mm + } + ha:simplearc.3 { + thickness = 10.75mil + adelta = -89.991381 + astart = 89.991381 + x = 0.285978mm + y = 1.344713mm + r = 9.0mil + } + } + height = 1.573314mm + } + ha:u { + width = 0.759461mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 0.708183mm + thickness = 10.75mil + x1 = 23.0mil + x2 = 0.738359mm + y1 = 0.709713mm + } + ha:line.1 { + y2 = 0.709713mm + thickness = 10.75mil + x1 = 0.0 + x2 = 0.153924mm + y1 = 0.709713mm + } + ha:line.2 { + y2 = 0.711237mm + thickness = 10.75mil + x1 = 0.60706mm + x2 = 0.737896mm + y1 = 1.573313mm + } + ha:line.3 { + y2 = 1.573313mm + thickness = 10.75mil + x1 = 0.201956mm + x2 = 0.75946mm + y1 = 1.574837mm + } + ha:line.4 { + y2 = 1.573276mm + thickness = 10.75mil + x1 = 0.182414mm + x2 = 0.638776mm + y1 = 1.573276mm + } + ha:line.5 { + y2 = 56.24mil + thickness = 10.75mil + x1 = 0.152366mm + x2 = 0.046956mm + y1 = 0.712216mm + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = -96.605083 + astart = 90.000000 + x = 0.182414mm + y = 1.436776mm + r = 0.1365mm + } + } + height = 1.574838mm + } + ha:s { + width = 0.739141mm + delta = 0.372068mm + li:objects { + ha:line.0 { + y2 = 0.862113mm + thickness = 10.75mil + x1 = 29.1mil + x2 = 0.71628mm + y1 = 0.709713mm + } + ha:line.1 { + y2 = 1.420913mm + thickness = 10.75mil + x1 = 0.0 + x2 = 0.9mil + y1 = 1.573313mm + } + ha:line.2 { + y2 = 1.147159mm + thickness = 10.75mil + x1 = 0.275556mm + x2 = 0.483836mm + y1 = 1.124299mm + } + ha:simplearc.3 { + thickness = 10.75mil + adelta = 90.000000 + astart = 180.000000 + x = 0.486376mm + y = 1.332579mm + r = 0.18542mm + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = -16.619264 + astart = 90.000000 + x = 0.430496mm + y = 0.179419mm + r = 1.39446mm + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = -90.000000 + astart = 180.000000 + x = 0.430496mm + y = 1.332579mm + r = 0.240697mm + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = -16.619264 + astart = -90.000000 + x = 0.311116mm + y = 2.112359mm + r = 1.39446mm + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = -90.000000 + astart = 0.000000 + x = 0.311116mm + y = 0.938879mm + r = 0.22098mm + } + ha:simplearc.8 { + thickness = 10.75mil + adelta = 90.000000 + astart = 0.000000 + x = 0.275556mm + y = 0.938879mm + r = 0.18542mm + } + } + height = 1.57388mm + } + ha:w { + width = 1.219201mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 0.709713mm + thickness = 10.75mil + x1 = 36.0mil + x2 = 48.0mil + y1 = 0.709713mm + } + ha:line.1 { + y2 = 0.709713mm + thickness = 10.75mil + x1 = 0.0 + x2 = 12.0mil + y1 = 0.709713mm + } + ha:line.2 { + y2 = 1.016037mm + thickness = 10.75mil + x1 = 0.708432mm + x2 = 0.563652mm + y1 = 1.574837mm + } + ha:line.3 { + y2 = 1.574837mm + thickness = 10.75mil + x1 = 1.066572mm + x2 = 0.708432mm + y1 = 0.711237mm + } + ha:line.4 { + y2 = 1.016037mm + thickness = 10.75mil + x1 = 0.251232mm + x2 = 0.563652mm + y1 = 1.574837mm + } + ha:line.5 { + y2 = 1.574837mm + thickness = 10.75mil + x1 = 0.152172mm + x2 = 0.251232mm + y1 = 0.711237mm + } + } + height = 1.574838mm + } + ha:x { + width = 0.993141mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 1.573313mm + thickness = 10.75mil + x1 = 22.0mil + x2 = 34.0mil + y1 = 1.573313mm + } + ha:line.1 { + y2 = 1.573313mm + thickness = 10.75mil + x1 = 0.0 + x2 = 12.0mil + y1 = 1.573313mm + } + ha:line.2 { + y2 = 0.709713mm + thickness = 10.75mil + x1 = 27.1mil + x2 = 39.1mil + y1 = 0.709713mm + } + ha:line.3 { + y2 = 0.709713mm + thickness = 10.75mil + x1 = 0.12954mm + x2 = 17.1mil + y1 = 0.709713mm + } + ha:line.4 { + y2 = 0.711237mm + thickness = 10.75mil + x1 = 0.152172mm + x2 = 0.840512mm + y1 = 1.574837mm + } + ha:line.5 { + y2 = 1.574837mm + thickness = 10.75mil + x1 = 0.281712mm + x2 = 0.710972mm + y1 = 0.711237mm + } + } + height = 1.574838mm + } + ha:v { + width = 0.863601mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 0.709713mm + thickness = 10.75mil + x1 = 22.0mil + x2 = 34.0mil + y1 = 0.709713mm + } + ha:line.1 { + y2 = 0.709713mm + thickness = 10.75mil + x1 = 0.0 + x2 = 12.0mil + y1 = 0.709713mm + } + ha:line.2 { + y2 = 1.574837mm + thickness = 10.75mil + x1 = 0.710972mm + x2 = 0.302032mm + y1 = 0.711237mm + } + ha:line.3 { + y2 = 1.574837mm + thickness = 10.75mil + x1 = 0.152172mm + x2 = 0.302032mm + y1 = 0.711237mm + } + } + height = 1.574838mm + } + ha:z { + width = 0.739369mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 1.420913mm + thickness = 10.75mil + x1 = 0.609828mm + x2 = 0.632688mm + y1 = 1.573313mm + } + ha:line.1 { + y2 = 0.862113mm + thickness = 10.75mil + x1 = 0.12954mm + x2 = 0.106908mm + y1 = 0.711237mm + } + ha:line.2 { + y2 = 1.573313mm + thickness = 10.75mil + x1 = 0.0 + x2 = 0.609828mm + y1 = 1.574837mm + } + ha:line.3 { + y2 = 1.574837mm + thickness = 10.75mil + x1 = 0.739368mm + x2 = 0.0 + y1 = 0.709713mm + } + ha:line.4 { + y2 = 0.709713mm + thickness = 10.75mil + x1 = 0.12954mm + x2 = 0.739368mm + y1 = 0.711237mm + } + } + height = 1.574838mm + } + ha:~ { + width = 0.623277mm + delta = 0.342875mm + li:objects { + ha:simplearc.0 { + thickness = 10.75mil + adelta = 51.095862 + astart = 90.000000 + x = 0.471077mm + y = 0.763433mm + r = 7.7mil + } + ha:simplearc.1 { + thickness = 10.75mil + adelta = -48.632951 + astart = 90.000000 + x = 0.471077mm + y = 0.740573mm + r = 0.21844mm + } + ha:simplearc.2 { + thickness = 10.75mil + adelta = 51.095862 + astart = -90.000000 + x = 0.1522mm + y = 1.014476mm + r = 7.7mil + } + ha:simplearc.3 { + thickness = 10.75mil + adelta = -48.632951 + astart = -90.000000 + x = 0.1522mm + y = 40.84mil + r = 0.21844mm + } + } + height = 0.959014mm + } + ha:y { + width = 1.010921mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 2.030513mm + thickness = 10.75mil + x1 = 0.0 + x2 = 18.0mil + y1 = 2.030513mm + } + ha:line.1 { + y2 = 0.711237mm + thickness = 10.75mil + x1 = 0.228372mm + x2 = 0.858292mm + y1 = 2.032037mm + } + ha:line.2 { + y2 = 0.709713mm + thickness = 10.75mil + x1 = 27.8mil + x2 = 1.01092mm + y1 = 0.709713mm + } + ha:line.3 { + y2 = 0.709713mm + thickness = 10.75mil + x1 = 0.12192mm + x2 = 16.8mil + y1 = 0.709713mm + } + ha:line.4 { + y2 = 1.574837mm + thickness = 10.75mil + x1 = 0.274092mm + x2 = 0.449352mm + y1 = 0.711237mm + } + } + height = 2.032038mm + } + ha:&7d { + width = 0.425665mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 0.254817mm + thickness = 10.75mil + x1 = 0.285812mm + x2 = 0.366516mm + y1 = 29.94mil + } + ha:line.1 { + y2 = 1.028581mm + thickness = 10.75mil + x1 = 0.160158mm + x2 = 0.247703mm + y1 = 61.74mil + } + ha:simplearc.2 { + thickness = 10.75mil + adelta = -90.000000 + astart = 90.000000 + x = 0.425664mm + y = 0.770636mm + r = 5.5mil + } + ha:simplearc.3 { + thickness = 10.75mil + adelta = 67.203479 + astart = 270.000000 + x = 0.425664mm + y = 1.103376mm + r = 0.19304mm + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = 70.509921 + astart = 98.050671 + x = -0.026608mm + y = 1.533144mm + r = 7.48mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = -85.868748 + astart = 259.263665 + x = 0.232624mm + y = 0.234036mm + r = 0.1365mm + } + } + height = 1.721264mm + } + ha:| { + width = 0.259081mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 0.076237mm + thickness = 10.75mil + x1 = 6.0mil + x2 = 0.25908mm + y1 = 0.787437mm + } + ha:line.1 { + y2 = 1.803437mm + thickness = 10.75mil + x1 = 4.2mil + x2 = 0.0 + y1 = 1.092237mm + } + } + height = 1.803438mm + } + ha:&7b { + width = 0.425664mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 1.568395mm + thickness = 10.75mil + x1 = 0.139852mm + x2 = 0.059148mm + y1 = 41.84mil + } + ha:line.1 { + y2 = 0.794631mm + thickness = 10.75mil + x1 = 0.265506mm + x2 = 0.177961mm + y1 = 0.255016mm + } + ha:simplearc.2 { + thickness = 10.75mil + adelta = -90.000000 + astart = -90.000000 + x = 0.0 + y = 1.052576mm + r = 5.5mil + } + ha:simplearc.3 { + thickness = 10.75mil + adelta = 67.203479 + astart = 90.000000 + x = 0.0 + y = 0.719836mm + r = 0.19304mm + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = 70.509921 + astart = 278.050671 + x = 0.452272mm + y = 0.290068mm + r = 7.48mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = -85.868748 + astart = 79.263665 + x = 0.19304mm + y = 1.589176mm + r = 0.1365mm + } + } + height = 1.723287mm + } + ha:&20 { + width = 0.0 + delta = 0.9874mm + li:objects { + } + height = 0.0 + } + ha:&23 { + width = 1.010997mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.379628mm + x2 = 0.17366mm + y1 = 11.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.837336mm + x2 = 0.631368mm + y1 = 11.0mil + } + ha:line.2 { + y2 = 28.0mil + thickness = 10.75mil + x1 = 0.068656mm + x2 = 1.010996mm + y1 = 28.0mil + } + ha:line.3 { + y2 = 45.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 37.1mil + y1 = 45.0mil + } + } + height = 1.574801mm + } + ha:&26 { + width = 0.95112mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 1.266107mm + thickness = 10.75mil + x1 = 0.613237mm + x2 = 0.029851mm + y1 = 0.592539mm + } + ha:line.1 { + y2 = 0.58928mm + thickness = 10.75mil + x1 = 0.725581mm + x2 = 8.9mil + y1 = 62.0mil + } + ha:line.2 { + y2 = 1.039876mm + thickness = 10.75mil + x1 = 0.26015mm + x2 = 34.88mil + y1 = 1.564839mm + } + ha:line.3 { + y2 = 11.4mil + thickness = 10.75mil + x1 = 18.8mil + x2 = 16.1mil + y1 = 0.289578mm + } + ha:line.4 { + y2 = 1.039876mm + thickness = 10.75mil + x1 = 0.722519mm + x2 = 0.951119mm + y1 = 1.039876mm + } + ha:line.5 { + y2 = 1.573276mm + thickness = 10.75mil + x1 = 0.72485mm + x2 = 0.871109mm + y1 = 1.573276mm + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = -114.341090 + astart = 24.341090 + x = 16.6mil + y = 19.8mil + r = 8.4mil + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = -132.075532 + astart = 270.806929 + x = 0.48006mm + y = 18.5mil + r = 0.18034mm + } + ha:simplearc.8 { + thickness = 10.75mil + adelta = -30.398728 + astart = 0.000000 + x = 0.22098mm + y = 54.2mil + r = 0.22098mm + } + ha:simplearc.9 { + thickness = 10.75mil + adelta = -108.245855 + astart = 108.245855 + x = 0.19812mm + y = 54.2mil + r = 0.19812mm + } + } + height = 1.574801mm + } + ha:! { + width = 0.20597mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 45.0mil + thickness = 10.75mil + x1 = 0.205969mm + x2 = 0.068656mm + y1 = 11.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.012116mm + x2 = 0.0 + y1 = 59.0mil + } + } + height = 1.574801mm + } + ha:" { + width = 0.529058mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 0.0 + thickness = 10.75mil + x1 = 0.0 + x2 = 0.125197mm + y1 = 11.0mil + } + ha:line.1 { + y2 = 0.0 + thickness = 10.75mil + x1 = 15.9mil + x2 = 0.529057mm + y1 = 11.0mil + } + } + height = 0.279401mm + } + ha:$ { + width = 0.784861mm + delta = 0.353341mm + li:objects { + ha:line.0 { + y2 = 39.74mil + thickness = 10.75mil + x1 = 0.259172mm + x2 = 0.550281mm + y1 = 0.852937mm + } + ha:line.1 { + y2 = 1.573276mm + thickness = 10.75mil + x1 = 0.508371mm + x2 = 0.302402mm + y1 = 0.277876mm + } + ha:line.2 { + y2 = 21.5mil + thickness = 10.75mil + x1 = 0.78486mm + x2 = 0.76581mm + y1 = 16.5mil + } + ha:line.3 { + y2 = 57.0mil + thickness = 10.75mil + x1 = 0.9mil + x2 = 0.0 + y1 = 51.0mil + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = -13.889035 + astart = 270.825530 + x = 0.376529mm + y = 2.190496mm + r = 1.76022mm + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = 63.145579 + astart = 0.000000 + x = 0.361289mm + y = 25.64mil + r = 8.9mil + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = -90.000000 + astart = 0.000000 + x = 0.351129mm + y = 0.648716mm + r = 8.5mil + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = -13.889035 + astart = 90.825530 + x = 0.412089mm + y = -0.339344mm + r = 1.76022mm + } + ha:simplearc.8 { + thickness = 10.75mil + adelta = 57.355360 + astart = 180.000000 + x = 0.427329mm + y = 47.24mil + r = 8.9mil + } + ha:simplearc.9 { + thickness = 10.75mil + adelta = -90.000000 + astart = 180.000000 + x = 0.437489mm + y = 47.34mil + r = 8.5mil + } + } + height = 1.573277mm + } + ha:% { + width = 1.444474mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 1.444473mm + x2 = 0.0 + y1 = 11.0mil + } + ha:simplearc.1 { + thickness = 10.75mil + adelta = 92.779167 + astart = 267.220833 + x = 42.7mil + y = 1.39192mm + r = 10.4mil + } + ha:simplearc.2 { + thickness = 10.75mil + adelta = 94.398705 + astart = 180.000000 + x = 44.2mil + y = 51.6mil + r = 7.2mil + } + ha:simplearc.3 { + thickness = 10.75mil + adelta = 92.779167 + astart = 87.220833 + x = 41.0mil + y = 51.7mil + r = 10.4mil + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = 94.398705 + astart = 0.000000 + x = 39.5mil + y = 1.39446mm + r = 7.2mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = 92.779167 + astart = 267.220833 + x = 17.1mil + y = 21.5mil + r = 10.4mil + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = 94.398705 + astart = 180.000000 + x = 18.6mil + y = 18.3mil + r = 7.2mil + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = 92.779167 + astart = 87.220833 + x = 15.4mil + y = 0.46736mm + r = 10.4mil + } + ha:simplearc.8 { + thickness = 10.75mil + adelta = 94.398705 + astart = 0.000000 + x = 13.9mil + y = 21.6mil + r = 7.2mil + } + } + height = 1.577341mm + } + ha:' { + width = 0.125198mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 0.0 + thickness = 10.75mil + x1 = 0.0 + x2 = 0.125197mm + y1 = 11.0mil + } + } + height = 0.279401mm + } + ha:( { + width = 0.336347mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 1.2787mm + thickness = 10.75mil + x1 = 0.101022mm + x2 = 0.00636mm + y1 = 0.655586mm + } + ha:simplearc.1 { + thickness = 10.75mil + adelta = -32.083745 + astart = 352.278174 + x = 45.2mil + y = 0.79756mm + r = 41.6mil + } + ha:simplearc.2 { + thickness = 10.75mil + adelta = 31.611030 + astart = 352.937397 + x = 33.0mil + y = 1.38176mm + r = 33.0mil + } + } + height = 1.730001mm + } + ha:) { + width = 0.336348mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 0.574696mm + thickness = 10.75mil + x1 = 0.235325mm + x2 = 0.329987mm + y1 = 1.19781mm + } + ha:simplearc.1 { + thickness = 10.75mil + adelta = -32.083745 + astart = 172.278174 + x = -0.811733mm + y = 1.055836mm + r = 41.6mil + } + ha:simplearc.2 { + thickness = 10.75mil + adelta = 31.611030 + astart = 172.937397 + x = -0.501853mm + y = 0.471636mm + r = 33.0mil + } + } + height = 1.732281mm + } + ha:* { + width = 0.592329mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 51.0mil + thickness = 10.75mil + x1 = 0.117119mm + x2 = 0.479247mm + y1 = 34.0mil + } + ha:line.1 { + y2 = 43.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 23.32mil + y1 = 43.0mil + } + ha:line.2 { + y2 = 51.0mil + thickness = 10.75mil + x1 = 0.547903mm + x2 = 0.048463mm + y1 = 34.0mil + } + } + height = 1.295401mm + } + ha:+ { + width = 0.592329mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 43.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 23.32mil + y1 = 43.0mil + } + ha:line.1 { + y2 = 54.0mil + thickness = 10.75mil + x1 = 0.340589mm + x2 = 0.251739mm + y1 = 32.0mil + } + } + height = 1.371601mm + } + ha:, { + width = 0.125198mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 65.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.125197mm + y1 = 76.0mil + } + } + height = 1.930401mm + } + ha:- { + width = 0.592329mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 42.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 23.32mil + y1 = 42.0mil + } + } + height = 1.066801mm + } + ha:. { + width = 0.018713mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 60.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.018712mm + y1 = 1.60782mm + } + } + height = 1.607821mm + } + ha:0 { + width = 0.670561mm + delta = 0.342875mm + li:objects { + ha:simplearc.0 { + thickness = 10.75mil + adelta = -59.264512 + astart = 90.000000 + x = 8.5mil + y = 1.45542mm + r = 0.11684mm + } + ha:simplearc.1 { + thickness = 10.75mil + adelta = 43.667780 + astart = 90.000000 + x = 8.5mil + y = 1.34112mm + r = 0.23114mm + } + ha:simplearc.2 { + thickness = 10.75mil + adelta = -43.549373 + astart = 180.000000 + x = -0.39624mm + y = 0.77216mm + r = 42.0mil + } + ha:simplearc.3 { + thickness = 10.75mil + adelta = 30.353941 + astart = 180.000000 + x = -0.20574mm + y = 0.77216mm + r = 34.5mil + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = -59.264512 + astart = -90.000000 + x = 0.45466mm + y = 0.39624mm + r = 0.11684mm + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = 43.667780 + astart = -90.000000 + x = 0.45466mm + y = 20.1mil + r = 0.23114mm + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = -43.549373 + astart = 0.000000 + x = 42.0mil + y = 42.5mil + r = 42.0mil + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = 30.353941 + astart = 0.000000 + x = 34.5mil + y = 42.5mil + r = 34.5mil + } + } + height = 1.572261mm + } + ha:1 { + width = 0.408942mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.408941mm + x2 = 0.202972mm + y1 = 11.0mil + } + ha:line.1 { + y2 = 1.573276mm + thickness = 10.75mil + x1 = 0.0 + x2 = 16.0mil + y1 = 1.573276mm + } + ha:line.2 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.175489mm + x2 = 0.408941mm + y1 = 18.94mil + } + } + height = 1.574801mm + } + ha:2 { + width = 0.780023mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 23.32mil + y1 = 62.0mil + } + ha:line.1 { + y2 = 0.721548mm + thickness = 10.75mil + x1 = 0.0 + x2 = 0.717149mm + y1 = 62.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.615416mm + x2 = 23.32mil + y1 = 1.420876mm + } + ha:simplearc.3 { + thickness = 10.75mil + adelta = 59.379667 + astart = -90.000000 + x = 0.522471mm + y = 0.700881mm + r = 0.420871mm + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = -37.733329 + astart = 180.000000 + x = 0.479383mm + y = 0.537561mm + r = 0.300639mm + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = -90.000000 + astart = -90.000000 + x = 0.522471mm + y = 0.537561mm + r = 0.257551mm + } + } + height = 1.574801mm + } + ha:3 { + width = 0.787401mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.205969mm + x2 = 0.555981mm + y1 = 11.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 11.66mil + y1 = 62.0mil + } + ha:line.2 { + y2 = 34.0mil + thickness = 10.75mil + x1 = 0.47682mm + x2 = 0.436169mm + y1 = 0.866301mm + } + ha:line.3 { + y2 = 34.0mil + thickness = 10.75mil + x1 = 0.247701mm + x2 = 0.463093mm + y1 = 34.0mil + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = 56.309932 + astart = 90.000000 + x = 15.8mil + y = 19.0mil + r = 15.0mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = -41.427263 + astart = 180.000000 + x = 0.510819mm + y = 0.510819mm + r = 0.276581mm + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = -90.000000 + astart = -90.000000 + x = 0.555981mm + y = 0.510819mm + r = 0.231419mm + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = 67.453710 + astart = 90.000000 + x = 11.66mil + y = 1.203249mm + r = 0.371551mm + } + ha:simplearc.8 { + thickness = 10.75mil + adelta = -17.603639 + astart = 180.000000 + x = -0.196911mm + y = 1.074185mm + r = 0.881615mm + } + ha:simplearc.9 { + thickness = 10.75mil + adelta = -90.000000 + astart = -90.000000 + x = 0.47682mm + y = 1.074185mm + r = 0.207884mm + } + } + height = 1.574801mm + } + ha:4 { + width = 0.753873mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 51.0mil + thickness = 10.75mil + x1 = 0.457708mm + x2 = 0.0 + y1 = 11.0mil + } + ha:line.1 { + y2 = 51.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.753872mm + y1 = 51.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.560019mm + x2 = 0.467131mm + y1 = 39.0mil + } + ha:line.3 { + y2 = 1.573276mm + thickness = 10.75mil + x1 = 0.314959mm + x2 = 0.619759mm + y1 = 1.573276mm + } + } + height = 1.574801mm + } + ha:5 { + width = 0.825222mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.825221mm + x2 = 0.205969mm + y1 = 11.0mil + } + ha:line.1 { + y2 = 34.0mil + thickness = 10.75mil + x1 = 0.205969mm + x2 = 0.113081mm + y1 = 11.0mil + } + ha:line.2 { + y2 = 34.0mil + thickness = 10.75mil + x1 = 0.113081mm + x2 = 0.409245mm + y1 = 34.0mil + } + ha:line.3 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.380498mm + x2 = 0.0 + y1 = 1.573394mm + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = -70.344464 + astart = 180.000000 + x = 0.225755mm + y = 1.140155mm + r = 0.460045mm + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = -90.000000 + astart = -90.000000 + x = 0.409245mm + y = 1.140155mm + r = 0.276555mm + } + } + height = 1.574801mm + } + ha:6 { + width = 0.651562mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 34.0mil + thickness = 10.75mil + x1 = 0.072695mm + x2 = 0.422707mm + y1 = 34.0mil + } + ha:line.1 { + y2 = 52.0mil + thickness = 10.75mil + x1 = 4.0mil + x2 = 0.0 + y1 = 27.0mil + } + ha:line.2 { + y2 = 1.092454mm + thickness = 10.75mil + x1 = 0.614373mm + x2 = 0.651561mm + y1 = 1.319923mm + } + ha:line.3 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.228854mm + x2 = 0.309626mm + y1 = 62.0mil + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = -68.630916 + astart = 342.245445 + x = 0.656895mm + y = 34.0mil + r = 23.0mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = -96.270387 + astart = 90.000000 + x = 0.228854mm + y = 52.99mil + r = 0.228854mm + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = 79.815149 + astart = 90.000000 + x = 0.309626mm + y = 49.81mil + r = 0.309626mm + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = -90.000000 + astart = -90.000000 + x = 0.422707mm + y = 1.092454mm + r = 0.228854mm + } + } + height = 1.574801mm + } + ha:7 { + width = 0.643485mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.024232mm + y1 = 17.0mil + } + ha:line.1 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.024232mm + x2 = 0.643484mm + y1 = 11.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.643484mm + x2 = 5.565mil + y1 = 11.0mil + } + } + height = 1.574801mm + } + ha:8 { + width = 0.751841mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 53.0mil + thickness = 10.75mil + x1 = 2.0mil + x2 = 0.0 + y1 = 42.0mil + } + ha:line.1 { + y2 = 34.0mil + thickness = 10.75mil + x1 = 0.341935mm + x2 = 0.449631mm + y1 = 34.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.228854mm + x2 = 13.25mil + y1 = 62.0mil + } + ha:line.3 { + y2 = 11.0mil + thickness = 10.75mil + x1 = 0.434823mm + x2 = 0.542519mm + y1 = 11.0mil + } + ha:line.4 { + y2 = 0.687656mm + thickness = 10.75mil + x1 = 29.6mil + x2 = 0.714565mm + y1 = 20.0mil + } + ha:line.5 { + y2 = 25.0mil + thickness = 10.75mil + x1 = 0.173241mm + x2 = 0.135966mm + y1 = 0.455344mm + } + ha:line.6 { + y2 = 1.372325mm + thickness = 10.75mil + x1 = 27.0mil + x2 = 0.636795mm + y1 = 1.092454mm + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = 67.850877 + astart = 90.000000 + x = 0.452983mm + y = 0.581177mm + r = 0.282423mm + } + ha:simplearc.8 { + thickness = 10.75mil + adelta = 85.179363 + astart = 180.000000 + x = 20.6mil + y = 20.0mil + r = 9.0mil + } + ha:simplearc.9 { + thickness = 10.75mil + adelta = 67.850877 + astart = -90.000000 + x = 0.434823mm + y = 0.561823mm + r = 0.282423mm + } + ha:simplearc.10 { + thickness = 10.75mil + adelta = 90.000000 + astart = 0.000000 + x = 0.364566mm + y = 25.0mil + r = 9.0mil + } + ha:simplearc.11 { + thickness = 10.75mil + adelta = -90.000000 + astart = 270.000000 + x = 0.456946mm + y = 1.092454mm + r = 0.228854mm + } + ha:simplearc.12 { + thickness = 10.75mil + adelta = 67.988717 + astart = 270.000000 + x = 0.351045mm + y = 46.77854331mil + r = 12.75mil + } + ha:simplearc.13 { + thickness = 10.75mil + adelta = 67.988717 + astart = 90.000000 + x = 13.25mil + y = 49.25mil + r = 12.75mil + } + ha:simplearc.14 { + thickness = 10.75mil + adelta = -90.000000 + astart = 90.000000 + x = 0.228854mm + y = 52.99mil + r = 0.228854mm + } + } + height = 1.574801mm + } + ha:9 { + width = 0.651562mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 0.990238mm + thickness = 10.75mil + x1 = 0.228854mm + x2 = 0.578866mm + y1 = 0.990238mm + } + ha:line.1 { + y2 = 0.533038mm + thickness = 10.75mil + x1 = 0.549961mm + x2 = 0.651561mm + y1 = 1.168038mm + } + ha:line.2 { + y2 = 0.761384mm + thickness = 10.75mil + x1 = 0.037188mm + x2 = 0.0 + y1 = 0.533915mm + } + ha:line.3 { + y2 = 0.279038mm + thickness = 10.75mil + x1 = 0.341935mm + x2 = 0.422707mm + y1 = 0.279038mm + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = -68.630916 + astart = 162.245445 + x = -0.21mil + y = 0.990238mm + r = 23.0mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = -96.270387 + astart = 270.000000 + x = 0.422707mm + y = 0.507892mm + r = 0.228854mm + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = 79.815149 + astart = 270.000000 + x = 0.341935mm + y = 0.588664mm + r = 0.309626mm + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = -90.000000 + astart = 90.000000 + x = 0.228854mm + y = 0.761384mm + r = 0.228854mm + } + } + height = 1.573276mm + } + ha:< { + width = 0.624638mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 34.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.624637mm + y1 = 42.0mil + } + ha:line.1 { + y2 = 50.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.560019mm + y1 = 42.0mil + } + } + height = 1.270001mm + } + ha:> { + width = 0.624638mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 34.0mil + thickness = 10.75mil + x1 = 0.624637mm + x2 = 0.064618mm + y1 = 42.0mil + } + ha:line.1 { + y2 = 50.0mil + thickness = 10.75mil + x1 = 0.624637mm + x2 = 0.0 + y1 = 42.0mil + } + } + height = 1.270001mm + } + ha:? { + width = 0.605773mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.140432mm + x2 = 0.132355mm + y1 = 60.0mil + } + ha:line.1 { + y2 = 38.6mil + thickness = 10.75mil + x1 = 0.201011mm + x2 = 0.227312mm + y1 = 1.14046mm + } + ha:line.2 { + y2 = 0.567117mm + thickness = 10.75mil + x1 = 0.531535mm + x2 = 0.576337mm + y1 = 0.636503mm + } + ha:line.3 { + y2 = 27.8mil + thickness = 10.75mil + x1 = 0.372092mm + x2 = 0.458452mm + y1 = 30.3mil + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = 17.272585 + astart = -90.000000 + x = 0.417812mm + y = 66.4mil + r = 1.40716mm + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = -20.872164 + astart = 145.218995 + x = 0.325574mm + y = 0.493457mm + r = 0.250763mm + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = -33.690068 + astart = 180.000000 + x = 0.430512mm + y = 18.5mil + r = 6.9mil + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = -41.552840 + astart = 345.768542 + x = 0.577832mm + y = 42.1mil + r = 14.3mil + } + ha:simplearc.8 { + thickness = 10.75mil + adelta = -90.000000 + astart = -90.000000 + x = 0.417812mm + y = 0.46736mm + r = 7.4mil + } + } + height = 1.574801mm + } + ha:@ { + width = 1.37171mm + delta = 0.343415mm + li:objects { + ha:line.0 { + y2 = 25.94mil + thickness = 10.75mil + x1 = 0.413824mm + x2 = 0.498635mm + y1 = 1.192276mm + } + ha:line.1 { + y2 = 18.94mil + thickness = 10.75mil + x1 = 0.715373mm + x2 = 0.984613mm + y1 = 18.94mil + } + ha:line.2 { + y2 = 1.192276mm + thickness = 10.75mil + x1 = 0.984613mm + x2 = 0.871532mm + y1 = 18.94mil + } + ha:line.3 { + y2 = 1.94mil + thickness = 10.75mil + x1 = 0.676333mm + x2 = 0.972497mm + y1 = 1.94mil + } + ha:line.4 { + y2 = 55.74mil + thickness = 10.75mil + x1 = 0.149969mm + x2 = 0.003538mm + y1 = 18.94mil + } + ha:line.5 { + y2 = 0.427736mm + thickness = 10.75mil + x1 = 1.248468mm + x2 = 1.371709mm + y1 = 1.192276mm + } + ha:line.6 { + y2 = 70.84mil + thickness = 10.75mil + x1 = 0.25654mm + x2 = 0.44958mm + y1 = 1.776476mm + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = -90.000000 + astart = 90.000000 + x = 41.0mil + y = 47.14mil + r = 0.17272mm + } + ha:simplearc.8 { + thickness = 10.75mil + adelta = 80.073754 + astart = 90.000000 + x = 41.0mil + y = 45.74mil + r = 0.20828mm + } + ha:simplearc.9 { + thickness = 10.75mil + adelta = 70.448005 + astart = 90.000000 + x = 23.5mil + y = 1.077976mm + r = 0.29464mm + } + ha:simplearc.10 { + thickness = 10.75mil + adelta = -90.000000 + astart = 90.000000 + x = 23.5mil + y = 46.84mil + r = 7.2mil + } + ha:simplearc.11 { + thickness = 10.75mil + adelta = 87.153067 + astart = 351.448170 + x = 0.32004mm + y = 57.64mil + r = 0.32004mm + } + ha:simplearc.12 { + thickness = 10.75mil + adelta = 78.876123 + astart = -90.000000 + x = 0.715373mm + y = 0.701149mm + r = 0.220073mm + } + ha:simplearc.13 { + thickness = 10.75mil + adelta = 78.736107 + astart = -90.000000 + x = 0.676333mm + y = 0.585909mm + r = 0.536633mm + } + ha:simplearc.14 { + thickness = 10.75mil + adelta = -87.335143 + astart = -90.000000 + x = 0.972497mm + y = 0.448379mm + r = 0.399103mm + } + } + height = 1.799337mm + } + ha:A { + width = 1.117601mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 0.277913mm + thickness = 10.75mil + x1 = 0.75311mm + x2 = 0.52451mm + y1 = 0.277913mm + } + ha:line.1 { + y2 = 1.573313mm + thickness = 10.75mil + x1 = 12.0mil + x2 = 0.0 + y1 = 1.573313mm + } + ha:line.2 { + y2 = 1.573313mm + thickness = 10.75mil + x1 = 44.0mil + x2 = 32.0mil + y1 = 1.573313mm + } + ha:line.3 { + y2 = 1.219237mm + thickness = 10.75mil + x1 = 0.298645mm + x2 = 0.925178mm + y1 = 1.219237mm + } + ha:line.4 { + y2 = 0.279437mm + thickness = 10.75mil + x1 = 0.990372mm + x2 = 0.752882mm + y1 = 1.574837mm + } + ha:line.5 { + y2 = 0.279437mm + thickness = 10.75mil + x1 = 0.126772mm + x2 = 0.752882mm + y1 = 1.574837mm + } + } + height = 1.574838mm + } + ha:B { + width = 1.002414mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 0.279437mm + thickness = 10.75mil + x1 = 0.151104mm + x2 = 0.345186mm + y1 = 1.573313mm + } + ha:line.1 { + y2 = 1.573313mm + thickness = 10.75mil + x1 = 0.149352mm + x2 = 0.151104mm + y1 = 1.574837mm + } + ha:line.2 { + y2 = 0.279437mm + thickness = 10.75mil + x1 = 7.65mil + x2 = 0.749046mm + y1 = 0.279437mm + } + ha:line.3 { + y2 = 1.574837mm + thickness = 10.75mil + x1 = 0.0 + x2 = 0.570001mm + y1 = 1.574837mm + } + ha:line.4 { + y2 = 0.862076mm + thickness = 10.75mil + x1 = 0.7467mm + x2 = 0.2641mm + y1 = 0.862076mm + } + ha:line.5 { + y2 = 1.259877mm + thickness = 10.75mil + x1 = 0.946537mm + x2 = 0.936777mm + y1 = 1.206958mm + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = -78.618860 + astart = -90.000000 + x = 0.749046mm + y = 0.535748mm + r = 0.256311mm + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = 87.345804 + astart = 90.000000 + x = 0.626897mm + y = 0.485177mm + r = 14.8mil + } + ha:simplearc.8 { + thickness = 10.75mil + adelta = 80.528338 + astart = 90.000000 + x = 0.561289mm + y = 1.194269mm + r = 0.380568mm + } + ha:simplearc.9 { + thickness = 10.75mil + adelta = -103.760785 + astart = -90.000000 + x = 0.675157mm + y = 1.140497mm + r = 11.0mil + } + } + height = 1.574838mm + } + ha:C { + width = 0.89304mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 0.279437mm + thickness = 10.75mil + x1 = 0.870407mm + x2 = 0.893039mm + y1 = 0.430313mm + } + ha:line.1 { + y2 = 1.573313mm + thickness = 10.75mil + x1 = 0.243053mm + x2 = 0.698957mm + y1 = 1.574837mm + } + ha:line.2 { + y2 = 0.279437mm + thickness = 10.75mil + x1 = 0.437363mm + x2 = 0.893039mm + y1 = 0.279437mm + } + ha:line.3 { + y2 = 1.574837mm + thickness = 10.75mil + x1 = 0.231394mm + x2 = 22.89mil + y1 = 1.574837mm + } + ha:line.4 { + y2 = 1.343697mm + thickness = 10.75mil + x1 = 0.127737mm + x2 = 0.0 + y1 = 0.533437mm + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = -90.000000 + astart = 90.000000 + x = 0.231394mm + y = 1.343443mm + r = 0.231394mm + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = 78.336927 + astart = -90.000000 + x = 0.437363mm + y = 0.59488mm + r = 0.315443mm + } + } + height = 1.574838mm + } + ha:D { + width = 1.06101mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 1.574837mm + thickness = 10.75mil + x1 = 0.346253mm + x2 = 0.152172mm + y1 = 0.280961mm + } + ha:line.1 { + y2 = 0.280961mm + thickness = 10.75mil + x1 = 0.344958mm + x2 = 0.346253mm + y1 = 0.279437mm + } + ha:line.2 { + y2 = 1.574837mm + thickness = 10.75mil + x1 = 0.0 + x2 = 0.623621mm + y1 = 1.573313mm + } + ha:line.3 { + y2 = 0.279437mm + thickness = 10.75mil + x1 = 7.65mil + x2 = 0.195606mm + y1 = 0.277913mm + } + ha:line.4 { + y2 = 0.279437mm + thickness = 10.75mil + x1 = 0.195606mm + x2 = 0.82959mm + y1 = 0.279437mm + } + ha:line.5 { + y2 = 1.325917mm + thickness = 10.75mil + x1 = 1.060984mm + x2 = 0.933247mm + y1 = 0.510577mm + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = -90.000000 + astart = 270.000000 + x = 0.829615mm + y = 0.513371mm + r = 0.231394mm + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = 78.336927 + astart = 90.000000 + x = 0.623646mm + y = 1.261934mm + r = 0.315443mm + } + } + height = 1.577378mm + } + ha:E { + width = 0.981483mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 0.862113mm + thickness = 10.75mil + x1 = 0.74168mm + x2 = 0.25908mm + y1 = 0.862113mm + } + ha:line.1 { + y2 = 0.303313mm + thickness = 10.75mil + x1 = 0.957606mm + x2 = 38.5mil + y1 = 0.279437mm + } + ha:line.2 { + y2 = 1.420913mm + thickness = 10.75mil + x1 = 0.808508mm + x2 = 0.81026mm + y1 = 1.422437mm + } + ha:line.3 { + y2 = 1.422437mm + thickness = 10.75mil + x1 = 0.785648mm + x2 = 0.808508mm + y1 = 1.574837mm + } + ha:line.4 { + y2 = 0.279437mm + thickness = 10.75mil + x1 = 6.0mil + x2 = 0.346482mm + y1 = 1.573313mm + } + ha:line.5 { + y2 = 1.573313mm + thickness = 10.75mil + x1 = 0.001296mm + x2 = 0.0 + y1 = 1.574837mm + } + ha:line.6 { + y2 = 0.279437mm + thickness = 10.75mil + x1 = 37.75mil + x2 = 0.981482mm + y1 = 0.430313mm + } + ha:line.7 { + y2 = 0.279437mm + thickness = 10.75mil + x1 = 0.195606mm + x2 = 0.957606mm + y1 = 0.279437mm + } + ha:line.8 { + y2 = 1.573313mm + thickness = 10.75mil + x1 = 0.153696mm + x2 = 6.0mil + y1 = 1.574837mm + } + ha:line.9 { + y2 = 0.279437mm + thickness = 10.75mil + x1 = 7.65mil + x2 = 0.195606mm + y1 = 0.277913mm + } + ha:line.10 { + y2 = 1.574837mm + thickness = 10.75mil + x1 = 0.785648mm + x2 = 0.001296mm + y1 = 1.574837mm + } + ha:line.11 { + y2 = 0.938313mm + thickness = 10.75mil + x1 = 0.75311mm + x2 = 28.75mil + y1 = 0.785913mm + } + } + height = 1.574838mm + } + ha:F { + width = 0.981482mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 0.862113mm + thickness = 10.75mil + x1 = 0.741451mm + x2 = 0.258851mm + y1 = 0.862113mm + } + ha:line.1 { + y2 = 0.430313mm + thickness = 10.75mil + x1 = 0.957326mm + x2 = 0.958621mm + y1 = 0.428789mm + } + ha:line.2 { + y2 = 0.428789mm + thickness = 10.75mil + x1 = 0.979729mm + x2 = 0.957326mm + y1 = 0.279437mm + } + ha:line.3 { + y2 = 0.277913mm + thickness = 10.75mil + x1 = 0.979729mm + x2 = 0.981481mm + y1 = 0.279437mm + } + ha:line.4 { + y2 = 0.279437mm + thickness = 10.75mil + x1 = 0.195377mm + x2 = 0.979729mm + y1 = 0.279437mm + } + ha:line.5 { + y2 = 0.279437mm + thickness = 10.75mil + x1 = 0.194081mm + x2 = 0.195377mm + y1 = 0.277913mm + } + ha:line.6 { + y2 = 0.279437mm + thickness = 10.75mil + x1 = 0.151943mm + x2 = 0.346253mm + y1 = 1.574837mm + } + ha:line.7 { + y2 = 1.571789mm + thickness = 10.75mil + x1 = 0.304571mm + x2 = 0.0 + y1 = 1.573313mm + } + ha:line.8 { + y2 = 0.938313mm + thickness = 10.75mil + x1 = 0.752881mm + x2 = 0.730021mm + y1 = 0.785913mm + } + } + height = 1.574838mm + } + ha:G { + width = 0.964728mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 0.279437mm + thickness = 10.75mil + x1 = 0.904249mm + x2 = 0.926881mm + y1 = 0.430313mm + } + ha:line.1 { + y2 = 0.277876mm + thickness = 10.75mil + x1 = 0.437363mm + x2 = 0.921995mm + y1 = 0.277876mm + } + ha:line.2 { + y2 = 1.573276mm + thickness = 10.75mil + x1 = 0.231394mm + x2 = 28.19mil + y1 = 1.573276mm + } + ha:line.3 { + y2 = 1.341882mm + thickness = 10.75mil + x1 = 0.127737mm + x2 = 0.0 + y1 = 20.94mil + } + ha:line.4 { + y2 = 1.573276mm + thickness = 10.75mil + x1 = 0.829107mm + x2 = 28.19mil + y1 = 0.862076mm + } + ha:line.5 { + y2 = 0.863637mm + thickness = 10.75mil + x1 = 0.662975mm + x2 = 0.964727mm + y1 = 0.863637mm + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = -90.000000 + astart = 90.000000 + x = 0.231394mm + y = 1.341882mm + r = 0.231394mm + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = 78.336927 + astart = 270.000000 + x = 0.437363mm + y = 0.593319mm + r = 0.315443mm + } + } + height = 1.573277mm + } + ha:H { + width = 1.235482mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 0.277913mm + thickness = 10.75mil + x1 = 0.930681mm + x2 = 1.235481mm + y1 = 0.277913mm + } + ha:line.1 { + y2 = 1.571789mm + thickness = 10.75mil + x1 = 29.0mil + x2 = 41.0mil + y1 = 1.571789mm + } + ha:line.2 { + y2 = 1.571789mm + thickness = 10.75mil + x1 = 0.0 + x2 = 12.0mil + y1 = 1.571789mm + } + ha:line.3 { + y2 = 0.277913mm + thickness = 10.75mil + x1 = 0.194081mm + x2 = 0.498881mm + y1 = 0.277913mm + } + ha:line.4 { + y2 = 0.279437mm + thickness = 10.75mil + x1 = 0.888543mm + x2 = 1.082853mm + y1 = 1.574837mm + } + ha:line.5 { + y2 = 0.863637mm + thickness = 10.75mil + x1 = 0.969823mm + x2 = 0.258623mm + y1 = 0.863637mm + } + ha:line.6 { + y2 = 0.279437mm + thickness = 10.75mil + x1 = 0.151943mm + x2 = 0.346253mm + y1 = 1.574837mm + } + } + height = 1.574838mm + } + ha:I { + width = 0.803911mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 1.573313mm + thickness = 10.75mil + x1 = 0.0 + x2 = 23.0mil + y1 = 1.573313mm + } + ha:line.1 { + y2 = 0.277913mm + thickness = 10.75mil + x1 = 7.65mil + x2 = 0.80391mm + y1 = 0.277913mm + } + ha:line.2 { + y2 = 0.279437mm + thickness = 10.75mil + x1 = 0.304572mm + x2 = 0.498882mm + y1 = 1.574837mm + } + } + height = 1.574838mm + } + ha:J { + width = 1.134111mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 0.277913mm + thickness = 10.75mil + x1 = 11.65mil + x2 = 1.13411mm + y1 = 0.277913mm + } + ha:line.1 { + y2 = 1.422437mm + thickness = 10.75mil + x1 = 0.0 + x2 = 0.021108mm + y1 = 1.573313mm + } + ha:line.2 { + y2 = 0.277876mm + thickness = 10.75mil + x1 = 0.555489mm + x2 = 0.721072mm + y1 = 1.319276mm + } + ha:line.3 { + y2 = 1.573276mm + thickness = 10.75mil + x1 = 0.245863mm + x2 = 0.005um + y1 = 1.573276mm + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = 78.708251 + astart = 90.000000 + x = 0.245863mm + y = 49.52mil + r = 0.315468mm + } + } + height = 1.573314mm + } + ha:K { + width = 1.18514mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 1.573313mm + thickness = 10.75mil + x1 = 0.888145mm + x2 = 39.0mil + y1 = 1.573313mm + } + ha:line.1 { + y2 = 0.276389mm + thickness = 10.75mil + x1 = 0.880339mm + x2 = 1.185139mm + y1 = 0.276389mm + } + ha:line.2 { + y2 = 1.573313mm + thickness = 10.75mil + x1 = 0.0 + x2 = 12.0mil + y1 = 1.573313mm + } + ha:line.3 { + y2 = 0.277913mm + thickness = 10.75mil + x1 = 7.65mil + x2 = 0.49911mm + y1 = 0.277913mm + } + ha:line.4 { + y2 = 0.765mm + thickness = 10.75mil + x1 = 0.888772mm + x2 = 0.55601mm + y1 = 1.574837mm + } + ha:line.5 { + y2 = 1.066837mm + thickness = 10.75mil + x1 = 1.083082mm + x2 = 0.228372mm + y1 = 0.279437mm + } + ha:line.6 { + y2 = 0.279437mm + thickness = 10.75mil + x1 = 0.152172mm + x2 = 0.346482mm + y1 = 1.574837mm + } + } + height = 1.574838mm + } + ha:L { + width = 0.810261mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 1.574837mm + thickness = 10.75mil + x1 = 0.81026mm + x2 = 0.787172mm + y1 = 1.420913mm + } + ha:line.1 { + y2 = 1.574837mm + thickness = 10.75mil + x1 = 0.001296mm + x2 = 0.787172mm + y1 = 1.574837mm + } + ha:line.2 { + y2 = 0.277913mm + thickness = 10.75mil + x1 = 7.65mil + x2 = 0.49911mm + y1 = 0.277913mm + } + ha:line.3 { + y2 = 1.574837mm + thickness = 10.75mil + x1 = 0.0 + x2 = 0.001296mm + y1 = 1.573313mm + } + ha:line.4 { + y2 = 0.279437mm + thickness = 10.75mil + x1 = 0.152172mm + x2 = 0.346482mm + y1 = 1.574837mm + } + } + height = 1.574838mm + } + ha:M { + width = 1.362711mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 0.277913mm + thickness = 10.75mil + x1 = 1.360958mm + x2 = 1.36271mm + y1 = 0.279437mm + } + ha:line.1 { + y2 = 0.279437mm + thickness = 10.75mil + x1 = 1.210082mm + x2 = 1.360958mm + y1 = 0.279437mm + } + ha:line.2 { + y2 = 0.278476mm + thickness = 10.75mil + x1 = 0.345583mm + x2 = 0.346062mm + y1 = 0.277913mm + } + ha:line.3 { + y2 = 0.277913mm + thickness = 10.75mil + x1 = 7.65mil + x2 = 0.345583mm + y1 = 0.277913mm + } + ha:line.4 { + y2 = 1.571789mm + thickness = 10.75mil + x1 = 0.863829mm + x2 = 1.168629mm + y1 = 1.571789mm + } + ha:line.5 { + y2 = 1.573313mm + thickness = 10.75mil + x1 = 0.0 + x2 = 12.0mil + y1 = 1.573313mm + } + ha:line.6 { + y2 = 1.016037mm + thickness = 10.75mil + x1 = 1.210082mm + x2 = 0.667792mm + y1 = 0.279437mm + } + ha:line.7 { + y2 = 1.574837mm + thickness = 10.75mil + x1 = 1.210082mm + x2 = 1.015772mm + y1 = 0.279437mm + } + ha:line.8 { + y2 = 1.016037mm + thickness = 10.75mil + x1 = 0.346482mm + x2 = 0.667792mm + y1 = 0.279437mm + } + ha:line.9 { + y2 = 0.279437mm + thickness = 10.75mil + x1 = 0.152172mm + x2 = 0.346482mm + y1 = 1.574837mm + } + } + height = 1.574838mm + } + ha:&2f { + width = 0.798298mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 10.75mil + x1 = 0.798297mm + x2 = 0.0 + y1 = 11.0mil + } + } + height = 1.574801mm + } + ha:&3a { + width = 0.100966mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 31.0mil + thickness = 10.75mil + x1 = 0.092888mm + x2 = 3.975mil + y1 = 33.0mil + } + ha:line.1 { + y2 = 54.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.008077mm + y1 = 56.0mil + } + } + height = 1.422401mm + } + ha:&3b { + width = 0.218085mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 56.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.125197mm + y1 = 67.0mil + } + ha:line.1 { + y2 = 33.0mil + thickness = 10.75mil + x1 = 0.210007mm + x2 = 0.218084mm + y1 = 35.0mil + } + } + height = 1.701801mm + } + ha:&3d { + width = 0.687909mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 34.0mil + thickness = 10.75mil + x1 = 0.068656mm + x2 = 0.687908mm + y1 = 34.0mil + } + ha:line.1 { + y2 = 51.0mil + thickness = 10.75mil + x1 = 0.0 + x2 = 0.619252mm + y1 = 51.0mil + } + } + height = 1.295401mm + } + ha:O { + width = 0.894081mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 0.277876mm + thickness = 10.75mil + x1 = 0.483133mm + x2 = 0.617753mm + y1 = 0.277876mm + } + ha:line.1 { + y2 = 1.573276mm + thickness = 10.75mil + x1 = 0.276327mm + x2 = 0.410947mm + y1 = 1.573276mm + } + ha:line.2 { + y2 = 1.296416mm + thickness = 10.75mil + x1 = 0.114331mm + x2 = 0.0 + y1 = 0.563417mm + } + ha:line.3 { + y2 = 0.552196mm + thickness = 10.75mil + x1 = 0.779749mm + x2 = 35.2mil + y1 = 1.287735mm + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = 75.196020 + astart = 90.000000 + x = 16.1mil + y = 46.84mil + r = 0.38354mm + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = -90.000000 + astart = 90.000000 + x = 10.8mil + y = 51.14mil + r = 10.8mil + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = 75.196020 + astart = -90.000000 + x = 19.1mil + y = 0.661416mm + r = 0.38354mm + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = -90.000000 + astart = -90.000000 + x = 0.61976mm + y = 0.552196mm + r = 10.8mil + } + } + height = 1.573277mm + } + ha:P { + width = 1.057225mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 0.277913mm + thickness = 10.75mil + x1 = 0.195377mm + x2 = 0.194081mm + y1 = 0.279437mm + } + ha:line.1 { + y2 = 0.990637mm + thickness = 10.75mil + x1 = 26.14mil + x2 = 0.239573mm + y1 = 0.990637mm + } + ha:line.2 { + y2 = 0.279437mm + thickness = 10.75mil + x1 = 0.151943mm + x2 = 0.346253mm + y1 = 1.574837mm + } + ha:line.3 { + y2 = 1.571789mm + thickness = 10.75mil + x1 = 0.304571mm + x2 = 0.0 + y1 = 1.573313mm + } + ha:line.4 { + y2 = 0.279437mm + thickness = 10.75mil + x1 = 0.195377mm + x2 = 0.777037mm + y1 = 0.279437mm + } + ha:line.5 { + y2 = 0.675677mm + thickness = 10.75mil + x1 = 1.049204mm + x2 = 1.039444mm + y1 = 0.622758mm + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = 80.528338 + astart = 90.000000 + x = 26.14mil + y = 0.610069mm + r = 0.380568mm + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = -103.760785 + astart = -90.000000 + x = 0.777824mm + y = 0.556297mm + r = 11.0mil + } + } + height = 1.574838mm + } + ha:N { + width = 1.235482mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 1.571789mm + thickness = 10.75mil + x1 = 0.0 + x2 = 12.0mil + y1 = 1.571789mm + } + ha:line.1 { + y2 = 0.279437mm + thickness = 10.75mil + x1 = 1.084605mm + x2 = 1.082853mm + y1 = 0.277913mm + } + ha:line.2 { + y2 = 0.277913mm + thickness = 10.75mil + x1 = 1.235481mm + x2 = 1.084605mm + y1 = 0.277913mm + } + ha:line.3 { + y2 = 0.277913mm + thickness = 10.75mil + x1 = 0.196392mm + x2 = 0.194081mm + y1 = 0.275904mm + } + ha:line.4 { + y2 = 0.275904mm + thickness = 10.75mil + x1 = 0.344774mm + x2 = 0.196392mm + y1 = 0.275904mm + } + ha:line.5 { + y2 = 1.574837mm + thickness = 10.75mil + x1 = 0.346253mm + x2 = 0.888543mm + y1 = 0.279437mm + } + ha:line.6 { + y2 = 0.279437mm + thickness = 10.75mil + x1 = 0.888543mm + x2 = 1.082853mm + y1 = 1.574837mm + } + ha:line.7 { + y2 = 0.279437mm + thickness = 10.75mil + x1 = 0.151943mm + x2 = 0.346253mm + y1 = 1.574837mm + } + } + height = 1.574838mm + } + ha:R { + width = 1.03053mm + delta = 0.342875mm + li:objects { + ha:line.0 { + y2 = 1.573313mm + thickness = 10.75mil + x1 = 1.014813mm + x2 = 40.0mil + y1 = 1.571916mm + } + ha:line.1 { + y2 = 1.571916mm + thickness = 10.75mil + x1 = 0.862413mm + x2 = 1.014813mm + y1 = 1.571916mm + } + ha:line.2 { + y2 = 1.573313mm + thickness = 10.75mil + x1 = 0.0 + x2 = 12.0mil + y1 = 1.573313mm + } + ha:line.3 { + y2 = 0.277913mm + thickness = 10.75mil + x1 = 0.195606mm + x2 = 7.65mil + y1 = 0.279437mm + } + ha:line.4 { + y2 = 0.990637mm + thickness = 10.75mil + x1 = 0.863372mm + x2 = 0.671602mm + y1 = 1.574837mm + } + ha:line.5 { + y2 = 0.279437mm + thickness = 10.75mil + x1 = 0.752882mm + x2 = 0.195606mm + y1 = 0.279437mm + } + ha:line.6 { + y2 = 0.990637mm + thickness = 10.75mil + x1 = 0.646202mm + x2 = 0.239802mm + y1 = 0.990637mm + } + ha:line.7 { + y2 = 0.279437mm + thickness = 10.75mil + x1 = 0.152172mm + x2 = 0.346482mm + y1 = 1.574837mm + } + ha:line.8 { + y2 = 0.681736mm + thickness = 10.75mil + x1 = 1.022316mm + x2 = 1.012156mm + y1 = 24.64mil + } + ha:simplearc.9 { + thickness = 10.75mil + adelta = 80.528338 + astart = 90.000000 + x = 0.637261mm + y = 0.610069mm + r = 0.380568mm + } + ha:simplearc.10 { + thickness = 10.75mil + adelta = -103.760785 + astart = -90.000000 + x = 0.751129mm + y = 0.558837mm + r = 11.0mil + } + } + height = 1.574838mm + } + ha:S { + width = 0.930911mm + delta = 0.367967mm + li:objects { + ha:line.0 { + y2 = 1.041437mm + thickness = 10.75mil + x1 = 0.296734mm + x2 = 0.707122mm + y1 = 0.819174mm + } + ha:line.1 { + y2 = 18.94mil + thickness = 10.75mil + x1 = 0.93091mm + x2 = 35.45mil + y1 = 0.277876mm + } + ha:line.2 { + y2 = 1.573276mm + thickness = 10.75mil + x1 = 0.03048mm + x2 = 0.0 + y1 = 1.370076mm + } + ha:simplearc.3 { + thickness = 10.75mil + adelta = -47.997193 + astart = 180.000000 + x = 0.491023mm + y = 1.264875mm + r = 0.345522mm + } + ha:simplearc.4 { + thickness = 10.75mil + adelta = -58.233191 + astart = 111.607450 + x = 0.458202mm + y = 0.876337mm + r = 27.5mil + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = 63.432338 + astart = 178.228530 + x = 0.592822mm + y = 1.257337mm + r = 0.24384mm + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = -27.159796 + astart = -90.000000 + x = 0.605522mm + y = 0.937297mm + r = 0.65786mm + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = 69.520750 + astart = 262.470073 + x = 0.552182mm + y = 0.680757mm + r = 15.9mil + } + ha:simplearc.8 { + thickness = 10.75mil + adelta = 86.104823 + astart = 335.556045 + x = 0.412482mm + y = 0.604557mm + r = 0.24384mm + } + } + height = 1.574838mm + } + ha:Q { + width = 0.896418mm + delta = 0.345211mm + li:objects { + ha:line.0 { + y2 = 1.574837mm + thickness = 10.75mil + x1 = 0.617753mm + x2 = 0.896417mm + y1 = 1.295437mm + } + ha:line.1 { + y2 = 0.279437mm + thickness = 10.75mil + x1 = 0.483133mm + x2 = 0.617753mm + y1 = 0.279437mm + } + ha:line.2 { + y2 = 1.574837mm + thickness = 10.75mil + x1 = 0.276327mm + x2 = 0.410947mm + y1 = 1.574837mm + } + ha:line.3 { + y2 = 1.297977mm + thickness = 10.75mil + x1 = 0.114331mm + x2 = 0.0 + y1 = 0.564978mm + } + ha:line.4 { + y2 = 0.553757mm + thickness = 10.75mil + x1 = 0.779749mm + x2 = 35.2mil + y1 = 1.289296mm + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = 75.196020 + astart = 90.000000 + x = 16.1mil + y = 1.191297mm + r = 0.38354mm + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = -90.000000 + astart = 90.000000 + x = 10.8mil + y = 1.300517mm + r = 10.8mil + } + ha:simplearc.7 { + thickness = 10.75mil + adelta = 75.196020 + astart = -90.000000 + x = 19.1mil + y = 0.662977mm + r = 0.38354mm + } + ha:simplearc.8 { + thickness = 10.75mil + adelta = -90.000000 + astart = -90.000000 + x = 0.61976mm + y = 0.553757mm + r = 10.8mil + } + } + height = 1.574838mm + } + ha:U { + width = 1.092201mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 0.277913mm + thickness = 10.75mil + x1 = 31.0mil + x2 = 43.0mil + y1 = 0.277913mm + } + ha:line.1 { + y2 = 0.277913mm + thickness = 10.75mil + x1 = 0.0 + x2 = 12.0mil + y1 = 0.277913mm + } + ha:line.2 { + y2 = 0.277876mm + thickness = 10.75mil + x1 = 0.019219mm + x2 = 0.172686mm + y1 = 1.243076mm + } + ha:line.3 { + y2 = 0.277876mm + thickness = 10.75mil + x1 = 0.799142mm + x2 = 0.953482mm + y1 = 1.245574mm + } + ha:line.4 { + y2 = 52.64mil + thickness = 10.75mil + x1 = 0.019219mm + x2 = 0.016679mm + y1 = 1.243076mm + } + ha:simplearc.5 { + thickness = 10.75mil + adelta = 67.796888 + astart = 359.432734 + x = 0.237659mm + y = 52.14mil + r = 0.22098mm + } + ha:simplearc.6 { + thickness = 10.75mil + adelta = 93.961205 + astart = 68.198591 + x = 0.349419mm + y = 43.34mil + r = 18.6mil + } + } + height = 1.573277mm + } + ha:V { + width = 1.168401mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 0.276389mm + thickness = 10.75mil + x1 = 46.0mil + x2 = 34.0mil + y1 = 0.276389mm + } + ha:line.1 { + y2 = 0.276389mm + thickness = 10.75mil + x1 = 12.0mil + x2 = 0.0 + y1 = 0.276389mm + } + ha:line.2 { + y2 = 1.574837mm + thickness = 10.75mil + x1 = 1.040943mm + x2 = 0.389433mm + y1 = 0.279437mm + } + ha:line.3 { + y2 = 1.574837mm + thickness = 10.75mil + x1 = 0.126543mm + x2 = 0.389433mm + y1 = 0.279437mm + } + } + height = 1.574838mm + } + ha:T { + width = 0.861061mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 0.277913mm + thickness = 10.75mil + x1 = 0.859308mm + x2 = 0.86106mm + y1 = 0.279437mm + } + ha:line.1 { + y2 = 0.430313mm + thickness = 10.75mil + x1 = 0.860832mm + x2 = 33.0mil + y1 = 0.279437mm + } + ha:line.2 { + y2 = 0.430313mm + thickness = 10.75mil + x1 = 0.001753mm + x2 = 0.0 + y1 = 0.428789mm + } + ha:line.3 { + y2 = 0.428789mm + thickness = 10.75mil + x1 = 0.024156mm + x2 = 0.001753mm + y1 = 0.279437mm + } + ha:line.4 { + y2 = 0.279437mm + thickness = 10.75mil + x1 = 0.022632mm + x2 = 0.859308mm + y1 = 0.279437mm + } + ha:line.5 { + y2 = 0.279437mm + thickness = 10.75mil + x1 = 0.260122mm + x2 = 0.454432mm + y1 = 1.574837mm + } + ha:line.6 { + y2 = 1.573313mm + thickness = 10.75mil + x1 = 17.25mil + x2 = 3.25mil + y1 = 1.573313mm + } + } + height = 1.574838mm + } + ha:X { + width = 1.286511mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 1.571789mm + thickness = 10.75mil + x1 = 43.0mil + x2 = 31.0mil + y1 = 1.571789mm + } + ha:line.1 { + y2 = 0.276389mm + thickness = 10.75mil + x1 = 1.28651mm + x2 = 0.98171mm + y1 = 0.276389mm + } + ha:line.2 { + y2 = 1.571789mm + thickness = 10.75mil + x1 = 12.0mil + x2 = 0.0 + y1 = 1.571789mm + } + ha:line.3 { + y2 = 0.276389mm + thickness = 10.75mil + x1 = 0.49911mm + x2 = 7.65mil + y1 = 0.276389mm + } + ha:line.4 { + y2 = 1.574837mm + thickness = 10.75mil + x1 = 1.184453mm + x2 = 0.101143mm + y1 = 0.279437mm + } + ha:line.5 { + y2 = 1.574837mm + thickness = 10.75mil + x1 = 0.295453mm + x2 = 0.990143mm + y1 = 0.279437mm + } + } + height = 1.574838mm + } + ha:Y { + width = 1.066801mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 1.573313mm + thickness = 10.75mil + x1 = 0.516432mm + x2 = 0.160832mm + y1 = 1.573313mm + } + ha:line.1 { + y2 = 0.274865mm + thickness = 10.75mil + x1 = 12.0mil + x2 = 0.0 + y1 = 0.274865mm + } + ha:line.2 { + y2 = 0.274865mm + thickness = 10.75mil + x1 = 42.0mil + x2 = 30.0mil + y1 = 0.274865mm + } + ha:line.3 { + y2 = 1.574837mm + thickness = 10.75mil + x1 = 0.441274mm + x2 = 0.338404mm + y1 = 0.889037mm + } + ha:line.4 { + y2 = 0.889037mm + thickness = 10.75mil + x1 = 0.964514mm + x2 = 0.441274mm + y1 = 0.279437mm + } + ha:line.5 { + y2 = 0.889037mm + thickness = 10.75mil + x1 = 0.100914mm + x2 = 0.441274mm + y1 = 0.279437mm + } + } + height = 1.574838mm + } + ha:W { + width = 1.371601mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 0.276389mm + thickness = 10.75mil + x1 = 54.0mil + x2 = 42.0mil + y1 = 0.276389mm + } + ha:line.1 { + y2 = 0.276389mm + thickness = 10.75mil + x1 = 12.0mil + x2 = 0.0 + y1 = 0.276389mm + } + ha:line.2 { + y2 = 0.711237mm + thickness = 10.75mil + x1 = 0.770433mm + x2 = 0.620573mm + y1 = 1.574837mm + } + ha:line.3 { + y2 = 1.574837mm + thickness = 10.75mil + x1 = 1.244143mm + x2 = 0.770433mm + y1 = 0.279437mm + } + ha:line.4 { + y2 = 0.711237mm + thickness = 10.75mil + x1 = 0.211633mm + x2 = 0.620573mm + y1 = 1.574837mm + } + ha:line.5 { + y2 = 1.574837mm + thickness = 10.75mil + x1 = 0.126543mm + x2 = 0.211633mm + y1 = 0.279437mm + } + } + height = 1.574838mm + } + ha:[ { + width = 0.392431mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 1.727237mm + thickness = 10.75mil + x1 = 0.0 + x2 = 0.12954mm + y1 = 1.727237mm + } + ha:line.1 { + y2 = 0.127037mm + thickness = 10.75mil + x1 = 0.24003mm + x2 = 0.39243mm + y1 = 0.127037mm + } + ha:line.2 { + y2 = 1.727237mm + thickness = 10.75mil + x1 = 0.24003mm + x2 = 0.0 + y1 = 0.127037mm + } + } + height = 1.727238mm + } + ha:^ { + width = 0.406401mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 0.037um + thickness = 10.75mil + x1 = 16.0mil + x2 = 0.23749mm + y1 = 0.228637mm + } + ha:line.1 { + y2 = 0.037um + thickness = 10.75mil + x1 = 0.0 + x2 = 0.23749mm + y1 = 0.228637mm + } + } + height = 0.228638mm + } + ha:Z { + width = 0.981939mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 1.420913mm + thickness = 10.75mil + x1 = 31.0mil + x2 = 0.810488mm + y1 = 1.574837mm + } + ha:line.1 { + y2 = 0.430313mm + thickness = 10.75mil + x1 = 7.65mil + x2 = 0.171678mm + y1 = 0.279437mm + } + ha:line.2 { + y2 = 0.277913mm + thickness = 10.75mil + x1 = 0.0 + x2 = 0.981938mm + y1 = 1.574837mm + } + ha:line.3 { + y2 = 1.574837mm + thickness = 10.75mil + x1 = 0.0 + x2 = 31.0mil + y1 = 1.574837mm + } + ha:line.4 { + y2 = 0.277913mm + thickness = 10.75mil + x1 = 7.65mil + x2 = 0.981938mm + y1 = 0.279437mm + } + } + height = 1.574838mm + } + ha:` { + width = 0.248921mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 0.254037mm + thickness = 10.75mil + x1 = 0.0 + x2 = 9.8mil + y1 = 0.050837mm + } + } + height = 0.254038mm + } + ha:_ { + width = 0.609601mm + delta = 0.4794mm + li:objects { + ha:line.0 { + y2 = 1.727237mm + thickness = 10.75mil + x1 = 0.0 + x2 = 24.0mil + y1 = 1.727237mm + } + } + height = 1.727238mm + } + } + cell_width = 1.444474mm + cell_height = 2.032038mm + } +} Index: tags/1.0.5/font/aussiefont-serif-oblique =================================================================== --- tags/1.0.5/font/aussiefont-serif-oblique (nonexistent) +++ tags/1.0.5/font/aussiefont-serif-oblique (revision 10414) @@ -0,0 +1,4807 @@ +li:pcb-rnd-font-v1 { + ha:geda_pcb { + id = 0 + ha:symbols { + ha:&09 { + width = 0.685801mm + delta = 0.103633mm + li:objects { + ha:line.0 { + y2 = 36.0mil + thickness = 3.0mil + x1 = 0.0 + x2 = 27.0mil + y1 = 36.0mil + } + ha:line.1 { + y2 = 30.0mil + thickness = 3.0mil + x1 = 27.0mil + x2 = 22.0mil + y1 = 36.0mil + } + ha:line.2 { + y2 = 42.0mil + thickness = 3.0mil + x1 = 27.0mil + x2 = 22.0mil + y1 = 36.0mil + } + ha:line.3 { + y2 = 42.0mil + thickness = 3.0mil + x1 = 0.0 + x2 = 5.0mil + y1 = 36.0mil + } + ha:line.4 { + y2 = 30.0mil + thickness = 3.0mil + x1 = 0.0 + x2 = 5.0mil + y1 = 36.0mil + } + } + height = 1.066801mm + } + ha:&0A { + width = 0.889001mm + delta = 10.0mil + li:objects { + ha:line.0 { + y2 = 10.0mil + thickness = 3.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 40.0mil + } + ha:line.1 { + y2 = 40.0mil + thickness = 3.0mil + x1 = 0.0 + x2 = 15.0mil + y1 = 40.0mil + } + ha:line.2 { + y2 = 45.0mil + thickness = 3.0mil + x1 = 20.0mil + x2 = 20.0mil + y1 = 75.0mil + } + ha:line.3 { + y2 = 45.0mil + thickness = 3.0mil + x1 = 20.0mil + x2 = 35.0mil + y1 = 45.0mil + } + ha:line.4 { + y2 = 60.0mil + thickness = 3.0mil + x1 = 20.0mil + x2 = 30.0mil + y1 = 60.0mil + } + } + height = 1.905001mm + } + ha:&0D { + width = 0.889001mm + delta = 0.253999mm + li:objects { + ha:line.0 { + y2 = 15.0mil + thickness = 3.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 35.0mil + } + ha:line.1 { + y2 = 10.0mil + thickness = 3.0mil + x1 = 5.0mil + x2 = 10.0mil + y1 = 10.0mil + } + ha:line.2 { + y2 = 40.0mil + thickness = 3.0mil + x1 = 5.0mil + x2 = 10.0mil + y1 = 40.0mil + } + ha:line.3 { + y2 = 45.0mil + thickness = 3.0mil + x1 = 20.0mil + x2 = 20.0mil + y1 = 75.0mil + } + ha:line.4 { + y2 = 45.0mil + thickness = 3.0mil + x1 = 20.0mil + x2 = 30.0mil + y1 = 45.0mil + } + ha:line.5 { + y2 = 60.0mil + thickness = 3.0mil + x1 = 20.0mil + x2 = 30.0mil + y1 = 60.0mil + } + ha:line.6 { + y2 = 55.0mil + thickness = 3.0mil + x1 = 35.0mil + x2 = 35.0mil + y1 = 50.0mil + } + ha:line.7 { + y2 = 75.0mil + thickness = 3.0mil + x1 = 30.0mil + x2 = 35.0mil + y1 = 60.0mil + } + ha:simplearc.8 { + thickness = 3.0mil + adelta = -90.000000 + astart = -90.000000 + x = 10.0mil + y = 15.0mil + r = 5.0mil + } + ha:simplearc.9 { + thickness = 3.0mil + adelta = 90.000000 + astart = 270.000000 + x = 5.0mil + y = 15.0mil + r = 5.0mil + } + ha:simplearc.10 { + thickness = 3.0mil + adelta = 90.000000 + astart = 90.000000 + x = 10.0mil + y = 35.0mil + r = 5.0mil + } + ha:simplearc.11 { + thickness = 3.0mil + adelta = -90.000000 + astart = 90.000000 + x = 5.0mil + y = 35.0mil + r = 5.0mil + } + ha:simplearc.12 { + thickness = 3.0mil + adelta = 90.000000 + astart = 90.000000 + x = 30.0mil + y = 55.0mil + r = 5.0mil + } + ha:simplearc.13 { + thickness = 3.0mil + adelta = -90.000000 + astart = -90.000000 + x = 30.0mil + y = 50.0mil + r = 5.0mil + } + } + height = 1.905001mm + } ha:] { + width = 0.406401mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 1.727237mm + thickness = 8.0mil + x1 = 0.0 + x2 = 0.16637mm + y1 = 1.727237mm + } + ha:line.1 { + y2 = 0.127037mm + thickness = 8.0mil + x1 = 10.0mil + x2 = 16.0mil + y1 = 0.127037mm + } + ha:line.2 { + y2 = 1.727237mm + thickness = 8.0mil + x1 = 16.0mil + x2 = 0.16637mm + y1 = 0.127037mm + } + } + height = 1.727238mm + } + ha:&5c { + width = 0.364491mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 1.574837mm + thickness = 8.0mil + x1 = 0.0 + x2 = 0.36449mm + y1 = 0.279437mm + } + } + height = 1.574838mm + } + ha:b { + width = 0.885005mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 0.254037mm + thickness = 8.0mil + x1 = 0.19812mm + x2 = 0.350292mm + y1 = 0.252513mm + } + ha:line.1 { + y2 = 1.574837mm + thickness = 8.0mil + x1 = 0.350292mm + x2 = 0.152172mm + y1 = 0.254037mm + } + ha:line.2 { + y2 = 1.573276mm + thickness = 8.0mil + x1 = 0.0 + x2 = 0.611192mm + y1 = 1.573313mm + } + ha:line.3 { + y2 = 1.420876mm + thickness = 8.0mil + x1 = 0.884098mm + x2 = 0.796968mm + y1 = 0.861877mm + } + ha:line.4 { + y2 = 27.94mil + thickness = 8.0mil + x1 = 0.290796mm + x2 = 0.748504mm + y1 = 27.94mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = 78.560593 + astart = 90.000000 + x = 0.611192mm + y = 54.46mil + r = 7.48mil + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = -96.605083 + astart = -90.000000 + x = 0.748504mm + y = 0.846176mm + r = 0.1365mm + } + } + height = 1.574838mm + } + ha:c { + width = 0.625448mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 0.862113mm + thickness = 8.0mil + x1 = 0.625447mm + x2 = 0.602587mm + y1 = 0.709713mm + } + ha:line.1 { + y2 = 0.709713mm + thickness = 8.0mil + x1 = 0.271143mm + x2 = 0.625447mm + y1 = 0.711237mm + } + ha:line.2 { + y2 = 1.573313mm + thickness = 8.0mil + x1 = 0.141603mm + x2 = 0.495907mm + y1 = 1.574837mm + } + ha:line.3 { + y2 = 1.573276mm + thickness = 8.0mil + x1 = 0.134939mm + x2 = 0.431103mm + y1 = 1.573276mm + } + ha:line.4 { + y2 = 55.74mil + thickness = 8.0mil + x1 = 0.08824mm + x2 = 0.00188mm + y1 = 0.862076mm + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = 78.560593 + astart = 270.000000 + x = 0.273812mm + y = 35.42mil + r = 7.48mil + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = -96.605083 + astart = 90.000000 + x = 0.1365mm + y = 1.436776mm + r = 0.1365mm + } + } + height = 1.574838mm + } + ha:a { + width = 0.744506mm + delta = 0.226033mm + li:objects { + ha:line.0 { + y2 = 1.574837mm + thickness = 8.0mil + x1 = 0.696271mm + x2 = 0.593401mm + y1 = 0.889037mm + } + ha:line.1 { + y2 = 1.573313mm + thickness = 8.0mil + x1 = 0.298701mm + x2 = 0.744505mm + y1 = 1.573276mm + } + ha:line.2 { + y2 = 0.711237mm + thickness = 8.0mil + x1 = 0.240341mm + x2 = 0.545141mm + y1 = 0.711237mm + } + ha:line.3 { + y2 = 1.116076mm + thickness = 8.0mil + x1 = 0.277365mm + x2 = 0.654301mm + y1 = 1.116076mm + } + ha:line.4 { + y2 = 1.573276mm + thickness = 8.0mil + x1 = 0.16911mm + x2 = 0.581954mm + y1 = 1.573276mm + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = 90.000000 + astart = 180.000000 + x = 0.518471mm + y = 0.889037mm + r = 7.0mil + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = 90.000000 + astart = 0.000000 + x = 6.7mil + y = 55.24mil + r = 6.7mil + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = -90.000000 + astart = 0.000000 + x = 11.3mil + y = 55.24mil + r = 11.3mil + } + } + height = 1.574838mm + } + ha:e { + width = 0.657861mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 1.573276mm + thickness = 8.0mil + x1 = 0.160198mm + x2 = 0.566598mm + y1 = 1.573276mm + } + ha:line.1 { + y2 = 1.141476mm + thickness = 8.0mil + x1 = 1.59mil + x2 = 0.633745mm + y1 = 1.141476mm + } + ha:line.2 { + y2 = 0.989076mm + thickness = 8.0mil + x1 = 0.0 + x2 = 0.064618mm + y1 = 1.395476mm + } + ha:line.3 { + y2 = 27.94mil + thickness = 8.0mil + x1 = 15.5mil + x2 = 15.9mil + y1 = 27.94mil + } + ha:line.4 { + y2 = 0.98946mm + thickness = 8.0mil + x1 = 0.633688mm + x2 = 0.656548mm + y1 = 1.14186mm + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = -80.753887 + astart = 350.753887 + x = 15.5mil + y = 1.042416mm + r = 0.33274mm + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = -95.826342 + astart = -90.000000 + x = 15.9mil + y = 0.963676mm + r = 10.0mil + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = -96.270309 + astart = 90.000000 + x = 0.160198mm + y = 1.413078mm + r = 0.160198mm + } + } + height = 1.573277mm + } + ha:f { + width = 0.645087mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 1.573313mm + thickness = 8.0mil + x1 = 0.0 + x2 = 17.0mil + y1 = 1.573313mm + } + ha:line.1 { + y2 = 1.546897mm + thickness = 8.0mil + x1 = 0.325968mm + x2 = 0.157252mm + y1 = 0.425778mm + } + ha:line.2 { + y2 = 0.711237mm + thickness = 8.0mil + x1 = 0.129312mm + x2 = 0.561112mm + y1 = 0.711237mm + } + ha:line.3 { + y2 = 0.277965mm + thickness = 8.0mil + x1 = 0.509236mm + x2 = 0.645086mm + y1 = 0.277876mm + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = 78.560593 + astart = 270.000000 + x = 0.512574mm + y = 0.467957mm + r = 7.48mil + } + } + height = 1.573314mm + } + ha:d { + width = 0.808669mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 0.252513mm + thickness = 8.0mil + x1 = 0.808668mm + x2 = 0.654744mm + y1 = 0.252513mm + } + ha:line.1 { + y2 = 1.573313mm + thickness = 8.0mil + x1 = 0.137312mm + x2 = 0.761424mm + y1 = 1.573276mm + } + ha:line.2 { + y2 = 1.574837mm + thickness = 8.0mil + x1 = 0.80844mm + x2 = 0.61032mm + y1 = 0.254037mm + } + ha:line.3 { + y2 = 1.420876mm + thickness = 8.0mil + x1 = 0.088849mm + x2 = 0.0 + y1 = 0.862076mm + } + ha:line.4 { + y2 = 27.94mil + thickness = 8.0mil + x1 = 0.274625mm + x2 = 0.732333mm + y1 = 27.94mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = 78.560593 + astart = 270.000000 + x = 0.276185mm + y = 35.42mil + r = 7.48mil + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = -96.605083 + astart = 90.000000 + x = 0.138873mm + y = 1.436776mm + r = 0.1365mm + } + } + height = 1.574838mm + } + ha:h { + width = 0.965201mm + delta = 0.216279mm + li:objects { + ha:line.0 { + y2 = 1.573313mm + thickness = 8.0mil + x1 = 26.0mil + x2 = 38.0mil + y1 = 1.573313mm + } + ha:line.1 { + y2 = 1.573313mm + thickness = 8.0mil + x1 = 0.0 + x2 = 12.0mil + y1 = 1.573313mm + } + ha:line.2 { + y2 = 0.252513mm + thickness = 8.0mil + x1 = 0.19812mm + x2 = 13.8mil + y1 = 0.252513mm + } + ha:line.3 { + y2 = 1.574837mm + thickness = 8.0mil + x1 = 0.350292mm + x2 = 0.152172mm + y1 = 0.254037mm + } + ha:line.4 { + y2 = 0.711237mm + thickness = 8.0mil + x1 = 0.330632mm + x2 = 0.78834mm + y1 = 0.711237mm + } + ha:line.5 { + y2 = 1.574837mm + thickness = 8.0mil + x1 = 0.925653mm + x2 = 0.812572mm + y1 = 0.863637mm + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = -96.605083 + astart = 270.000000 + x = 0.79022mm + y = 0.847737mm + r = 0.1365mm + } + } + height = 1.574838mm + } + ha:i { + width = 0.609601mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 1.573313mm + thickness = 8.0mil + x1 = 0.0 + x2 = 24.0mil + y1 = 1.573313mm + } + ha:line.1 { + y2 = 0.709713mm + thickness = 8.0mil + x1 = 0.20574mm + x2 = 17.1mil + y1 = 0.709713mm + } + ha:line.2 { + y2 = 1.574837mm + thickness = 8.0mil + x1 = 0.434112mm + x2 = 0.304572mm + y1 = 0.711237mm + } + ha:line.3 { + y2 = 0.355637mm + thickness = 8.0mil + x1 = 0.498882mm + x2 = 0.487452mm + y1 = 0.279437mm + } + } + height = 1.574838mm + } + ha:g { + width = 0.889305mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 1.573276mm + thickness = 8.0mil + x1 = 0.151248mm + x2 = 0.59336mm + y1 = 1.573276mm + } + ha:line.1 { + y2 = 0.709713mm + thickness = 8.0mil + x1 = 0.28856mm + x2 = 0.889304mm + y1 = 27.94mil + } + ha:line.2 { + y2 = 0.711237mm + thickness = 8.0mil + x1 = 0.56675mm + x2 = 0.7382mm + y1 = 1.854237mm + } + ha:line.3 { + y2 = 0.862076mm + thickness = 8.0mil + x1 = 0.013935mm + x2 = 0.102785mm + y1 = 1.420876mm + } + ha:line.4 { + y2 = 2.032037mm + thickness = 8.0mil + x1 = 0.36228mm + x2 = 0.0 + y1 = 2.032037mm + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = 78.560593 + astart = 270.000000 + x = 0.28856mm + y = 35.42mil + r = 7.48mil + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = -96.605083 + astart = 90.000000 + x = 0.151248mm + y = 1.436776mm + r = 0.1365mm + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = 78.715635 + astart = 90.000000 + x = 0.350012mm + y = 1.810549mm + r = 8.72mil + } + } + height = 2.032038mm + } + ha:k { + width = 0.993141mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 0.709713mm + thickness = 8.0mil + x1 = 27.1mil + x2 = 39.1mil + y1 = 0.709713mm + } + ha:line.1 { + y2 = 1.573313mm + thickness = 8.0mil + x1 = 22.0mil + x2 = 34.0mil + y1 = 1.573313mm + } + ha:line.2 { + y2 = 1.573313mm + thickness = 8.0mil + x1 = 0.0 + x2 = 6.0mil + y1 = 1.573313mm + } + ha:line.3 { + y2 = 0.277913mm + thickness = 8.0mil + x1 = 7.65mil + x2 = 13.65mil + y1 = 0.277913mm + } + ha:line.4 { + y2 = 0.967715mm + thickness = 8.0mil + x1 = 0.736372mm + x2 = 0.499718mm + y1 = 1.574837mm + } + ha:line.5 { + y2 = 1.168437mm + thickness = 8.0mil + x1 = 0.865912mm + x2 = 0.213132mm + y1 = 0.711237mm + } + ha:line.6 { + y2 = 1.574837mm + thickness = 8.0mil + x1 = 0.346482mm + x2 = 0.152172mm + y1 = 0.279437mm + } + } + height = 1.574838mm + } + ha:l { + width = 0.609601mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 1.573313mm + thickness = 8.0mil + x1 = 0.0 + x2 = 24.0mil + y1 = 1.573313mm + } + ha:line.1 { + y2 = 1.573313mm + thickness = 8.0mil + x1 = 0.500406mm + x2 = 12.0mil + y1 = 0.279437mm + } + ha:line.2 { + y2 = 0.277913mm + thickness = 8.0mil + x1 = 7.65mil + x2 = 19.71mil + y1 = 0.277913mm + } + } + height = 1.573314mm + } + ha:j { + width = 0.5372mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 2.03063mm + thickness = 8.0mil + x1 = 0.0 + x2 = 0.069804mm + y1 = 80.0mil + } + ha:line.1 { + y2 = 1.827784mm + thickness = 8.0mil + x1 = 0.472429mm + x2 = 0.304789mm + y1 = 27.96mil + } + ha:line.2 { + y2 = 13.96mil + thickness = 8.0mil + x1 = 0.537199mm + x2 = 0.525769mm + y1 = 10.96mil + } + ha:line.3 { + y2 = 27.96mil + thickness = 8.0mil + x1 = 4.5mil + x2 = 0.472429mm + y1 = 0.710147mm + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = -59.376512 + astart = 160.839827 + x = 0.012075mm + y = 1.726078mm + r = 0.30988mm + } + } + height = 2.032001mm + } + ha:n { + width = 0.889001mm + delta = 0.233932mm + li:objects { + ha:line.0 { + y2 = 1.573313mm + thickness = 8.0mil + x1 = 29.0mil + x2 = 35.0mil + y1 = 1.573313mm + } + ha:line.1 { + y2 = 1.573313mm + thickness = 8.0mil + x1 = 0.0 + x2 = 12.0mil + y1 = 1.573313mm + } + ha:line.2 { + y2 = 1.574837mm + thickness = 8.0mil + x1 = 0.281872mm + x2 = 0.152172mm + y1 = 0.71017mm + } + ha:line.3 { + y2 = 1.574837mm + thickness = 8.0mil + x1 = 0.831622mm + x2 = 0.736372mm + y1 = 0.939837mm + } + ha:line.4 { + y2 = 0.709669mm + thickness = 8.0mil + x1 = 0.12954mm + x2 = 0.646389mm + y1 = 0.709713mm + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = -96.309371 + astart = -90.000000 + x = 0.627279mm + y = 0.917244mm + r = 0.205588mm + } + } + height = 1.574838mm + } + ha:o { + width = 0.665796mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 39.0mil + thickness = 8.0mil + x1 = 0.527um + x2 = 0.047351mm + y1 = 1.315513mm + } + ha:line.1 { + y2 = 1.30302mm + thickness = 8.0mil + x1 = 0.665269mm + x2 = 0.618445mm + y1 = 0.975567mm + } + ha:simplearc.2 { + thickness = 8.0mil + adelta = 1.505021 + astart = 2.060728 + x = 1.718468mm + y = 1.25476mm + r = 67.7mil + } + ha:simplearc.3 { + thickness = 8.0mil + adelta = -79.646680 + astart = 90.000000 + x = 0.265588mm + y = 51.7mil + r = 0.26924mm + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = 77.035491 + astart = 90.000000 + x = 0.265588mm + y = 48.0mil + r = 14.3mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = 1.505021 + astart = 182.060728 + x = -1.052672mm + y = 1.03886mm + r = 67.7mil + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = -79.646680 + astart = -90.000000 + x = 0.400208mm + y = 38.6mil + r = 0.26924mm + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = 77.035491 + astart = -90.000000 + x = 0.400208mm + y = 1.07442mm + r = 14.3mil + } + } + height = 1.582421mm + } + ha:m { + width = 1.270229mm + delta = 0.234963mm + li:objects { + ha:line.0 { + y2 = 1.573313mm + thickness = 8.0mil + x1 = 1.117828mm + x2 = 1.270228mm + y1 = 1.573313mm + } + ha:line.1 { + y2 = 1.573313mm + thickness = 8.0mil + x1 = 0.635228mm + x2 = 0.787628mm + y1 = 1.573313mm + } + ha:line.2 { + y2 = 1.574837mm + thickness = 8.0mil + x1 = 30.1mil + x2 = 25.0mil + y1 = 0.711237mm + } + ha:line.3 { + y2 = 1.574837mm + thickness = 8.0mil + x1 = 0.0 + x2 = 12.0mil + y1 = 1.574837mm + } + ha:line.4 { + y2 = 1.574837mm + thickness = 8.0mil + x1 = 0.281829mm + x2 = 6.0mil + y1 = 0.710007mm + } + ha:line.5 { + y2 = 1.574837mm + thickness = 8.0mil + x1 = 47.75mil + x2 = 44.0mil + y1 = 0.939837mm + } + ha:line.6 { + y2 = 27.94mil + thickness = 8.0mil + x1 = 0.129768mm + x2 = 1.007476mm + y1 = 0.709713mm + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = -96.309371 + astart = -90.000000 + x = 1.007476mm + y = 0.915264mm + r = 0.205588mm + } + } + height = 1.574838mm + } + ha:q { + width = 0.89061mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 2.030513mm + thickness = 8.0mil + x1 = 0.387689mm + x2 = 0.692489mm + y1 = 2.030513mm + } + ha:line.1 { + y2 = 0.711237mm + thickness = 8.0mil + x1 = 0.541385mm + x2 = 0.739505mm + y1 = 2.032037mm + } + ha:line.2 { + y2 = 1.436116mm + thickness = 8.0mil + x1 = 0.088406mm + x2 = 0.0 + y1 = 0.861987mm + } + ha:line.3 { + y2 = 1.573276mm + thickness = 8.0mil + x1 = 0.137465mm + x2 = 0.594665mm + y1 = 1.573276mm + } + ha:line.4 { + y2 = 27.94mil + thickness = 8.0mil + x1 = 0.890609mm + x2 = 10.8119685mil + y1 = 0.709713mm + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = -96.605083 + astart = -270.000000 + x = 0.137312mm + y = 1.436776mm + r = 0.1365mm + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = 78.560593 + astart = -90.000000 + x = 10.8119685mil + y = 35.42mil + r = 7.48mil + } + } + height = 2.032038mm + } + ha:r { + width = 0.698925mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 1.573313mm + thickness = 8.0mil + x1 = 0.0 + x2 = 18.0mil + y1 = 1.573313mm + } + ha:line.1 { + y2 = 0.711237mm + thickness = 8.0mil + x1 = 0.138396mm + x2 = 0.561112mm + y1 = 27.94mil + } + ha:line.2 { + y2 = 0.711237mm + thickness = 8.0mil + x1 = 0.152172mm + x2 = 0.281712mm + y1 = 1.574837mm + } + ha:line.3 { + y2 = 27.94mil + thickness = 8.0mil + x1 = 0.265396mm + x2 = 0.56156mm + y1 = 27.94mil + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = -96.605083 + astart = 270.000000 + x = 0.562424mm + y = 0.846176mm + r = 0.1365mm + } + } + height = 1.574838mm + } + ha:p { + width = 0.955566mm + delta = 0.178611mm + li:objects { + ha:line.0 { + y2 = 2.032037mm + thickness = 8.0mil + x1 = 0.351816mm + x2 = 0.153696mm + y1 = 0.711237mm + } + ha:line.1 { + y2 = 33.34mil + thickness = 8.0mil + x1 = 0.867159mm + x2 = 0.955565mm + y1 = 1.420965mm + } + ha:line.2 { + y2 = 27.94mil + thickness = 8.0mil + x1 = 0.8181mm + x2 = 0.1577mm + y1 = 27.94mil + } + ha:line.3 { + y2 = 1.573276mm + thickness = 8.0mil + x1 = 0.230852mm + x2 = 0.680941mm + y1 = 1.573276mm + } + ha:line.4 { + y2 = 2.030513mm + thickness = 8.0mil + x1 = 0.0 + x2 = 12.0mil + y1 = 2.030513mm + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = -96.605083 + astart = 270.000000 + x = 0.818253mm + y = 0.846176mm + r = 0.1365mm + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = 78.560593 + astart = 90.000000 + x = 0.680941mm + y = 54.46mil + r = 7.48mil + } + } + height = 2.032038mm + } + ha:t { + width = 0.431801mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 0.711237mm + thickness = 8.0mil + x1 = 0.0 + x2 = 17.0mil + y1 = 0.711237mm + } + ha:line.1 { + y2 = 1.344713mm + thickness = 8.0mil + x1 = 8.55mil + x2 = 0.057378mm + y1 = 0.279437mm + } + ha:line.2 { + y2 = 1.573276mm + thickness = 8.0mil + x1 = 0.285944mm + x2 = 0.339284mm + y1 = 1.573313mm + } + ha:simplearc.3 { + thickness = 8.0mil + adelta = -89.991381 + astart = 89.991381 + x = 0.285978mm + y = 1.344713mm + r = 9.0mil + } + } + height = 1.573314mm + } + ha:u { + width = 0.759461mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 0.708183mm + thickness = 8.0mil + x1 = 23.0mil + x2 = 0.738359mm + y1 = 0.709713mm + } + ha:line.1 { + y2 = 0.709713mm + thickness = 8.0mil + x1 = 0.0 + x2 = 0.153924mm + y1 = 0.709713mm + } + ha:line.2 { + y2 = 0.711237mm + thickness = 8.0mil + x1 = 0.60706mm + x2 = 0.737896mm + y1 = 1.573313mm + } + ha:line.3 { + y2 = 1.573313mm + thickness = 8.0mil + x1 = 0.201956mm + x2 = 0.75946mm + y1 = 1.574837mm + } + ha:line.4 { + y2 = 1.573276mm + thickness = 8.0mil + x1 = 0.182414mm + x2 = 0.638776mm + y1 = 1.573276mm + } + ha:line.5 { + y2 = 56.24mil + thickness = 8.0mil + x1 = 0.152366mm + x2 = 0.046956mm + y1 = 0.712216mm + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = -96.605083 + astart = 90.000000 + x = 0.182414mm + y = 1.436776mm + r = 0.1365mm + } + } + height = 1.574838mm + } + ha:s { + width = 0.739141mm + delta = 0.206993mm + li:objects { + ha:line.0 { + y2 = 0.862113mm + thickness = 8.0mil + x1 = 29.1mil + x2 = 0.71628mm + y1 = 0.709713mm + } + ha:line.1 { + y2 = 1.420913mm + thickness = 8.0mil + x1 = 0.0 + x2 = 0.9mil + y1 = 1.573313mm + } + ha:line.2 { + y2 = 1.147159mm + thickness = 8.0mil + x1 = 0.275556mm + x2 = 0.483836mm + y1 = 1.124299mm + } + ha:simplearc.3 { + thickness = 8.0mil + adelta = 90.000000 + astart = 180.000000 + x = 0.486376mm + y = 1.332579mm + r = 0.18542mm + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = -16.619264 + astart = 90.000000 + x = 0.430496mm + y = 0.179419mm + r = 1.39446mm + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = -90.000000 + astart = 180.000000 + x = 0.430496mm + y = 1.332579mm + r = 0.240697mm + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = -16.619264 + astart = -90.000000 + x = 0.311116mm + y = 2.112359mm + r = 1.39446mm + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = -90.000000 + astart = 0.000000 + x = 0.311116mm + y = 0.938879mm + r = 0.22098mm + } + ha:simplearc.8 { + thickness = 8.0mil + adelta = 90.000000 + astart = 0.000000 + x = 0.275556mm + y = 0.938879mm + r = 0.18542mm + } + } + height = 1.57388mm + } + ha:w { + width = 1.219201mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 0.709713mm + thickness = 8.0mil + x1 = 36.0mil + x2 = 48.0mil + y1 = 0.709713mm + } + ha:line.1 { + y2 = 0.709713mm + thickness = 8.0mil + x1 = 0.0 + x2 = 12.0mil + y1 = 0.709713mm + } + ha:line.2 { + y2 = 1.016037mm + thickness = 8.0mil + x1 = 0.708432mm + x2 = 0.563652mm + y1 = 1.574837mm + } + ha:line.3 { + y2 = 1.574837mm + thickness = 8.0mil + x1 = 1.066572mm + x2 = 0.708432mm + y1 = 0.711237mm + } + ha:line.4 { + y2 = 1.016037mm + thickness = 8.0mil + x1 = 0.251232mm + x2 = 0.563652mm + y1 = 1.574837mm + } + ha:line.5 { + y2 = 1.574837mm + thickness = 8.0mil + x1 = 0.152172mm + x2 = 0.251232mm + y1 = 0.711237mm + } + } + height = 1.574838mm + } + ha:x { + width = 0.993141mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 1.573313mm + thickness = 8.0mil + x1 = 22.0mil + x2 = 34.0mil + y1 = 1.573313mm + } + ha:line.1 { + y2 = 1.573313mm + thickness = 8.0mil + x1 = 0.0 + x2 = 12.0mil + y1 = 1.573313mm + } + ha:line.2 { + y2 = 0.709713mm + thickness = 8.0mil + x1 = 27.1mil + x2 = 39.1mil + y1 = 0.709713mm + } + ha:line.3 { + y2 = 0.709713mm + thickness = 8.0mil + x1 = 0.12954mm + x2 = 17.1mil + y1 = 0.709713mm + } + ha:line.4 { + y2 = 0.711237mm + thickness = 8.0mil + x1 = 0.152172mm + x2 = 0.840512mm + y1 = 1.574837mm + } + ha:line.5 { + y2 = 1.574837mm + thickness = 8.0mil + x1 = 0.281712mm + x2 = 0.710972mm + y1 = 0.711237mm + } + } + height = 1.574838mm + } + ha:v { + width = 0.863601mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 0.709713mm + thickness = 8.0mil + x1 = 22.0mil + x2 = 34.0mil + y1 = 0.709713mm + } + ha:line.1 { + y2 = 0.709713mm + thickness = 8.0mil + x1 = 0.0 + x2 = 12.0mil + y1 = 0.709713mm + } + ha:line.2 { + y2 = 1.574837mm + thickness = 8.0mil + x1 = 0.710972mm + x2 = 0.302032mm + y1 = 0.711237mm + } + ha:line.3 { + y2 = 1.574837mm + thickness = 8.0mil + x1 = 0.152172mm + x2 = 0.302032mm + y1 = 0.711237mm + } + } + height = 1.574838mm + } + ha:z { + width = 0.739369mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 1.420913mm + thickness = 8.0mil + x1 = 0.609828mm + x2 = 0.632688mm + y1 = 1.573313mm + } + ha:line.1 { + y2 = 0.862113mm + thickness = 8.0mil + x1 = 0.12954mm + x2 = 0.106908mm + y1 = 0.711237mm + } + ha:line.2 { + y2 = 1.573313mm + thickness = 8.0mil + x1 = 0.0 + x2 = 0.609828mm + y1 = 1.574837mm + } + ha:line.3 { + y2 = 1.574837mm + thickness = 8.0mil + x1 = 0.739368mm + x2 = 0.0 + y1 = 0.709713mm + } + ha:line.4 { + y2 = 0.709713mm + thickness = 8.0mil + x1 = 0.12954mm + x2 = 0.739368mm + y1 = 0.711237mm + } + } + height = 1.574838mm + } + ha:~ { + width = 0.623277mm + delta = 7.0mil + li:objects { + ha:simplearc.0 { + thickness = 8.0mil + adelta = 51.095862 + astart = 90.000000 + x = 0.471077mm + y = 0.763433mm + r = 7.7mil + } + ha:simplearc.1 { + thickness = 8.0mil + adelta = -48.632951 + astart = 90.000000 + x = 0.471077mm + y = 0.740573mm + r = 0.21844mm + } + ha:simplearc.2 { + thickness = 8.0mil + adelta = 51.095862 + astart = -90.000000 + x = 0.1522mm + y = 1.014476mm + r = 7.7mil + } + ha:simplearc.3 { + thickness = 8.0mil + adelta = -48.632951 + astart = -90.000000 + x = 0.1522mm + y = 40.84mil + r = 0.21844mm + } + } + height = 0.959014mm + } + ha:y { + width = 1.010921mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 2.030513mm + thickness = 8.0mil + x1 = 0.0 + x2 = 18.0mil + y1 = 2.030513mm + } + ha:line.1 { + y2 = 0.711237mm + thickness = 8.0mil + x1 = 0.228372mm + x2 = 0.858292mm + y1 = 2.032037mm + } + ha:line.2 { + y2 = 0.709713mm + thickness = 8.0mil + x1 = 27.8mil + x2 = 1.01092mm + y1 = 0.709713mm + } + ha:line.3 { + y2 = 0.709713mm + thickness = 8.0mil + x1 = 0.12192mm + x2 = 16.8mil + y1 = 0.709713mm + } + ha:line.4 { + y2 = 1.574837mm + thickness = 8.0mil + x1 = 0.274092mm + x2 = 0.449352mm + y1 = 0.711237mm + } + } + height = 2.032038mm + } + ha:&7d { + width = 0.425665mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 0.254817mm + thickness = 8.0mil + x1 = 0.285812mm + x2 = 0.366516mm + y1 = 29.94mil + } + ha:line.1 { + y2 = 1.028581mm + thickness = 8.0mil + x1 = 0.160158mm + x2 = 0.247703mm + y1 = 61.74mil + } + ha:simplearc.2 { + thickness = 8.0mil + adelta = -90.000000 + astart = 90.000000 + x = 0.425664mm + y = 0.770636mm + r = 5.5mil + } + ha:simplearc.3 { + thickness = 8.0mil + adelta = 67.203479 + astart = 270.000000 + x = 0.425664mm + y = 1.103376mm + r = 0.19304mm + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = 70.509921 + astart = 98.050671 + x = -0.026608mm + y = 1.533144mm + r = 7.48mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = -85.868748 + astart = 259.263665 + x = 0.232624mm + y = 0.234036mm + r = 0.1365mm + } + } + height = 1.721264mm + } + ha:| { + width = 0.259081mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 0.076237mm + thickness = 8.0mil + x1 = 6.0mil + x2 = 0.25908mm + y1 = 0.787437mm + } + ha:line.1 { + y2 = 1.803437mm + thickness = 8.0mil + x1 = 4.2mil + x2 = 0.0 + y1 = 1.092237mm + } + } + height = 1.803438mm + } + ha:&7b { + width = 0.425664mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 1.568395mm + thickness = 8.0mil + x1 = 0.139852mm + x2 = 0.059148mm + y1 = 41.84mil + } + ha:line.1 { + y2 = 0.794631mm + thickness = 8.0mil + x1 = 0.265506mm + x2 = 0.177961mm + y1 = 0.255016mm + } + ha:simplearc.2 { + thickness = 8.0mil + adelta = -90.000000 + astart = -90.000000 + x = 0.0 + y = 1.052576mm + r = 5.5mil + } + ha:simplearc.3 { + thickness = 8.0mil + adelta = 67.203479 + astart = 90.000000 + x = 0.0 + y = 0.719836mm + r = 0.19304mm + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = 70.509921 + astart = 278.050671 + x = 0.452272mm + y = 0.290068mm + r = 7.48mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = -85.868748 + astart = 79.263665 + x = 0.19304mm + y = 1.589176mm + r = 0.1365mm + } + } + height = 1.723287mm + } + ha:&20 { + width = 0.0 + delta = 31.0mil + li:objects { + } + height = 0.0 + } + ha:&23 { + width = 1.010997mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.379628mm + x2 = 0.17366mm + y1 = 11.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.837336mm + x2 = 0.631368mm + y1 = 11.0mil + } + ha:line.2 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 0.068656mm + x2 = 1.010996mm + y1 = 28.0mil + } + ha:line.3 { + y2 = 45.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 37.1mil + y1 = 45.0mil + } + } + height = 1.574801mm + } + ha:&26 { + width = 0.95112mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 1.266107mm + thickness = 8.0mil + x1 = 0.613237mm + x2 = 0.029851mm + y1 = 0.592539mm + } + ha:line.1 { + y2 = 0.58928mm + thickness = 8.0mil + x1 = 0.725581mm + x2 = 8.9mil + y1 = 62.0mil + } + ha:line.2 { + y2 = 1.039876mm + thickness = 8.0mil + x1 = 0.26015mm + x2 = 34.88mil + y1 = 1.564839mm + } + ha:line.3 { + y2 = 11.4mil + thickness = 8.0mil + x1 = 18.8mil + x2 = 16.1mil + y1 = 0.289578mm + } + ha:line.4 { + y2 = 1.039876mm + thickness = 8.0mil + x1 = 0.722519mm + x2 = 0.951119mm + y1 = 1.039876mm + } + ha:line.5 { + y2 = 1.573276mm + thickness = 8.0mil + x1 = 0.72485mm + x2 = 0.871109mm + y1 = 1.573276mm + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = -114.341090 + astart = 24.341090 + x = 16.6mil + y = 19.8mil + r = 8.4mil + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = -132.075532 + astart = 270.806929 + x = 0.48006mm + y = 18.5mil + r = 0.18034mm + } + ha:simplearc.8 { + thickness = 8.0mil + adelta = -30.398728 + astart = 0.000000 + x = 0.22098mm + y = 54.2mil + r = 0.22098mm + } + ha:simplearc.9 { + thickness = 8.0mil + adelta = -108.245855 + astart = 108.245855 + x = 0.19812mm + y = 54.2mil + r = 0.19812mm + } + } + height = 1.574801mm + } + ha:! { + width = 0.20597mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 45.0mil + thickness = 8.0mil + x1 = 0.205969mm + x2 = 0.068656mm + y1 = 11.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.012116mm + x2 = 0.0 + y1 = 59.0mil + } + } + height = 1.574801mm + } + ha:" { + width = 0.529058mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 0.0 + thickness = 8.0mil + x1 = 0.0 + x2 = 0.125197mm + y1 = 11.0mil + } + ha:line.1 { + y2 = 0.0 + thickness = 8.0mil + x1 = 15.9mil + x2 = 0.529057mm + y1 = 11.0mil + } + } + height = 0.279401mm + } + ha:$ { + width = 0.784861mm + delta = 0.188266mm + li:objects { + ha:line.0 { + y2 = 39.74mil + thickness = 8.0mil + x1 = 0.259172mm + x2 = 0.550281mm + y1 = 0.852937mm + } + ha:line.1 { + y2 = 1.573276mm + thickness = 8.0mil + x1 = 0.508371mm + x2 = 0.302402mm + y1 = 0.277876mm + } + ha:line.2 { + y2 = 21.5mil + thickness = 8.0mil + x1 = 0.78486mm + x2 = 0.76581mm + y1 = 16.5mil + } + ha:line.3 { + y2 = 57.0mil + thickness = 8.0mil + x1 = 0.9mil + x2 = 0.0 + y1 = 51.0mil + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = -13.889035 + astart = 270.825530 + x = 0.376529mm + y = 2.190496mm + r = 1.76022mm + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = 63.145579 + astart = 0.000000 + x = 0.361289mm + y = 25.64mil + r = 8.9mil + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = -90.000000 + astart = 0.000000 + x = 0.351129mm + y = 0.648716mm + r = 8.5mil + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = -13.889035 + astart = 90.825530 + x = 0.412089mm + y = -0.339344mm + r = 1.76022mm + } + ha:simplearc.8 { + thickness = 8.0mil + adelta = 57.355360 + astart = 180.000000 + x = 0.427329mm + y = 47.24mil + r = 8.9mil + } + ha:simplearc.9 { + thickness = 8.0mil + adelta = -90.000000 + astart = 180.000000 + x = 0.437489mm + y = 47.34mil + r = 8.5mil + } + } + height = 1.573277mm + } + ha:% { + width = 1.444474mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 1.444473mm + x2 = 0.0 + y1 = 11.0mil + } + ha:simplearc.1 { + thickness = 8.0mil + adelta = 92.779167 + astart = 267.220833 + x = 42.7mil + y = 1.39192mm + r = 10.4mil + } + ha:simplearc.2 { + thickness = 8.0mil + adelta = 94.398705 + astart = 180.000000 + x = 44.2mil + y = 51.6mil + r = 7.2mil + } + ha:simplearc.3 { + thickness = 8.0mil + adelta = 92.779167 + astart = 87.220833 + x = 41.0mil + y = 51.7mil + r = 10.4mil + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = 94.398705 + astart = 0.000000 + x = 39.5mil + y = 1.39446mm + r = 7.2mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = 92.779167 + astart = 267.220833 + x = 17.1mil + y = 21.5mil + r = 10.4mil + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = 94.398705 + astart = 180.000000 + x = 18.6mil + y = 18.3mil + r = 7.2mil + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = 92.779167 + astart = 87.220833 + x = 15.4mil + y = 0.46736mm + r = 10.4mil + } + ha:simplearc.8 { + thickness = 8.0mil + adelta = 94.398705 + astart = 0.000000 + x = 13.9mil + y = 21.6mil + r = 7.2mil + } + } + height = 1.577341mm + } + ha:' { + width = 0.125198mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 0.0 + thickness = 8.0mil + x1 = 0.0 + x2 = 0.125197mm + y1 = 11.0mil + } + } + height = 0.279401mm + } + ha:( { + width = 0.336347mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 1.2787mm + thickness = 8.0mil + x1 = 0.101022mm + x2 = 0.00636mm + y1 = 0.655586mm + } + ha:simplearc.1 { + thickness = 8.0mil + adelta = -32.083745 + astart = 352.278174 + x = 45.2mil + y = 0.79756mm + r = 41.6mil + } + ha:simplearc.2 { + thickness = 8.0mil + adelta = 31.611030 + astart = 352.937397 + x = 33.0mil + y = 1.38176mm + r = 33.0mil + } + } + height = 1.730001mm + } + ha:) { + width = 0.336348mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 0.574696mm + thickness = 8.0mil + x1 = 0.235325mm + x2 = 0.329987mm + y1 = 1.19781mm + } + ha:simplearc.1 { + thickness = 8.0mil + adelta = -32.083745 + astart = 172.278174 + x = -0.811733mm + y = 1.055836mm + r = 41.6mil + } + ha:simplearc.2 { + thickness = 8.0mil + adelta = 31.611030 + astart = 172.937397 + x = -0.501853mm + y = 0.471636mm + r = 33.0mil + } + } + height = 1.732281mm + } + ha:* { + width = 0.592329mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 51.0mil + thickness = 8.0mil + x1 = 0.117119mm + x2 = 0.479247mm + y1 = 34.0mil + } + ha:line.1 { + y2 = 43.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 23.32mil + y1 = 43.0mil + } + ha:line.2 { + y2 = 51.0mil + thickness = 8.0mil + x1 = 0.547903mm + x2 = 0.048463mm + y1 = 34.0mil + } + } + height = 1.295401mm + } + ha:+ { + width = 0.592329mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 43.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 23.32mil + y1 = 43.0mil + } + ha:line.1 { + y2 = 54.0mil + thickness = 8.0mil + x1 = 0.340589mm + x2 = 0.251739mm + y1 = 32.0mil + } + } + height = 1.371601mm + } + ha:, { + width = 0.125198mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 65.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.125197mm + y1 = 76.0mil + } + } + height = 1.930401mm + } + ha:- { + width = 0.592329mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 42.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 23.32mil + y1 = 42.0mil + } + } + height = 1.066801mm + } + ha:. { + width = 0.018713mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 60.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.018712mm + y1 = 1.60782mm + } + } + height = 1.607821mm + } + ha:0 { + width = 0.670561mm + delta = 7.0mil + li:objects { + ha:simplearc.0 { + thickness = 8.0mil + adelta = -59.264512 + astart = 90.000000 + x = 8.5mil + y = 1.45542mm + r = 0.11684mm + } + ha:simplearc.1 { + thickness = 8.0mil + adelta = 43.667780 + astart = 90.000000 + x = 8.5mil + y = 1.34112mm + r = 0.23114mm + } + ha:simplearc.2 { + thickness = 8.0mil + adelta = -43.549373 + astart = 180.000000 + x = -0.39624mm + y = 0.77216mm + r = 42.0mil + } + ha:simplearc.3 { + thickness = 8.0mil + adelta = 30.353941 + astart = 180.000000 + x = -0.20574mm + y = 0.77216mm + r = 34.5mil + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = -59.264512 + astart = -90.000000 + x = 0.45466mm + y = 0.39624mm + r = 0.11684mm + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = 43.667780 + astart = -90.000000 + x = 0.45466mm + y = 20.1mil + r = 0.23114mm + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = -43.549373 + astart = 0.000000 + x = 42.0mil + y = 42.5mil + r = 42.0mil + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = 30.353941 + astart = 0.000000 + x = 34.5mil + y = 42.5mil + r = 34.5mil + } + } + height = 1.572261mm + } + ha:1 { + width = 0.408942mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.408941mm + x2 = 0.202972mm + y1 = 11.0mil + } + ha:line.1 { + y2 = 1.573276mm + thickness = 8.0mil + x1 = 0.0 + x2 = 16.0mil + y1 = 1.573276mm + } + ha:line.2 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.175489mm + x2 = 0.408941mm + y1 = 18.94mil + } + } + height = 1.574801mm + } + ha:2 { + width = 0.780023mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 23.32mil + y1 = 62.0mil + } + ha:line.1 { + y2 = 0.721548mm + thickness = 8.0mil + x1 = 0.0 + x2 = 0.717149mm + y1 = 62.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.615416mm + x2 = 23.32mil + y1 = 1.420876mm + } + ha:simplearc.3 { + thickness = 8.0mil + adelta = 59.379667 + astart = -90.000000 + x = 0.522471mm + y = 0.700881mm + r = 0.420871mm + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = -37.733329 + astart = 180.000000 + x = 0.479383mm + y = 0.537561mm + r = 0.300639mm + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = -90.000000 + astart = -90.000000 + x = 0.522471mm + y = 0.537561mm + r = 0.257551mm + } + } + height = 1.574801mm + } + ha:3 { + width = 0.787401mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.205969mm + x2 = 0.555981mm + y1 = 11.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 11.66mil + y1 = 62.0mil + } + ha:line.2 { + y2 = 34.0mil + thickness = 8.0mil + x1 = 0.47682mm + x2 = 0.436169mm + y1 = 0.866301mm + } + ha:line.3 { + y2 = 34.0mil + thickness = 8.0mil + x1 = 0.247701mm + x2 = 0.463093mm + y1 = 34.0mil + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = 56.309932 + astart = 90.000000 + x = 15.8mil + y = 19.0mil + r = 15.0mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = -41.427263 + astart = 180.000000 + x = 0.510819mm + y = 0.510819mm + r = 0.276581mm + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = -90.000000 + astart = -90.000000 + x = 0.555981mm + y = 0.510819mm + r = 0.231419mm + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = 67.453710 + astart = 90.000000 + x = 11.66mil + y = 1.203249mm + r = 0.371551mm + } + ha:simplearc.8 { + thickness = 8.0mil + adelta = -17.603639 + astart = 180.000000 + x = -0.196911mm + y = 1.074185mm + r = 0.881615mm + } + ha:simplearc.9 { + thickness = 8.0mil + adelta = -90.000000 + astart = -90.000000 + x = 0.47682mm + y = 1.074185mm + r = 0.207884mm + } + } + height = 1.574801mm + } + ha:4 { + width = 0.753873mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 51.0mil + thickness = 8.0mil + x1 = 0.457708mm + x2 = 0.0 + y1 = 11.0mil + } + ha:line.1 { + y2 = 51.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.753872mm + y1 = 51.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.560019mm + x2 = 0.467131mm + y1 = 39.0mil + } + ha:line.3 { + y2 = 1.573276mm + thickness = 8.0mil + x1 = 0.314959mm + x2 = 0.619759mm + y1 = 1.573276mm + } + } + height = 1.574801mm + } + ha:5 { + width = 0.825222mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.825221mm + x2 = 0.205969mm + y1 = 11.0mil + } + ha:line.1 { + y2 = 34.0mil + thickness = 8.0mil + x1 = 0.205969mm + x2 = 0.113081mm + y1 = 11.0mil + } + ha:line.2 { + y2 = 34.0mil + thickness = 8.0mil + x1 = 0.113081mm + x2 = 0.409245mm + y1 = 34.0mil + } + ha:line.3 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.380498mm + x2 = 0.0 + y1 = 1.573394mm + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = -70.344464 + astart = 180.000000 + x = 0.225755mm + y = 1.140155mm + r = 0.460045mm + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = -90.000000 + astart = -90.000000 + x = 0.409245mm + y = 1.140155mm + r = 0.276555mm + } + } + height = 1.574801mm + } + ha:6 { + width = 0.651562mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 34.0mil + thickness = 8.0mil + x1 = 0.072695mm + x2 = 0.422707mm + y1 = 34.0mil + } + ha:line.1 { + y2 = 52.0mil + thickness = 8.0mil + x1 = 4.0mil + x2 = 0.0 + y1 = 27.0mil + } + ha:line.2 { + y2 = 1.092454mm + thickness = 8.0mil + x1 = 0.614373mm + x2 = 0.651561mm + y1 = 1.319923mm + } + ha:line.3 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.228854mm + x2 = 0.309626mm + y1 = 62.0mil + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = -68.630916 + astart = 342.245445 + x = 0.656895mm + y = 34.0mil + r = 23.0mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = -96.270387 + astart = 90.000000 + x = 0.228854mm + y = 52.99mil + r = 0.228854mm + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = 79.815149 + astart = 90.000000 + x = 0.309626mm + y = 49.81mil + r = 0.309626mm + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = -90.000000 + astart = -90.000000 + x = 0.422707mm + y = 1.092454mm + r = 0.228854mm + } + } + height = 1.574801mm + } + ha:7 { + width = 0.643485mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.024232mm + y1 = 17.0mil + } + ha:line.1 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.024232mm + x2 = 0.643484mm + y1 = 11.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.643484mm + x2 = 5.565mil + y1 = 11.0mil + } + } + height = 1.574801mm + } + ha:8 { + width = 0.751841mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 53.0mil + thickness = 8.0mil + x1 = 2.0mil + x2 = 0.0 + y1 = 42.0mil + } + ha:line.1 { + y2 = 34.0mil + thickness = 8.0mil + x1 = 0.341935mm + x2 = 0.449631mm + y1 = 34.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.228854mm + x2 = 13.25mil + y1 = 62.0mil + } + ha:line.3 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.434823mm + x2 = 0.542519mm + y1 = 11.0mil + } + ha:line.4 { + y2 = 0.687656mm + thickness = 8.0mil + x1 = 29.6mil + x2 = 0.714565mm + y1 = 20.0mil + } + ha:line.5 { + y2 = 25.0mil + thickness = 8.0mil + x1 = 0.173241mm + x2 = 0.135966mm + y1 = 0.455344mm + } + ha:line.6 { + y2 = 1.372325mm + thickness = 8.0mil + x1 = 27.0mil + x2 = 0.636795mm + y1 = 1.092454mm + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = 67.850877 + astart = 90.000000 + x = 0.452983mm + y = 0.581177mm + r = 0.282423mm + } + ha:simplearc.8 { + thickness = 8.0mil + adelta = 85.179363 + astart = 180.000000 + x = 20.6mil + y = 20.0mil + r = 9.0mil + } + ha:simplearc.9 { + thickness = 8.0mil + adelta = 67.850877 + astart = -90.000000 + x = 0.434823mm + y = 0.561823mm + r = 0.282423mm + } + ha:simplearc.10 { + thickness = 8.0mil + adelta = 90.000000 + astart = 0.000000 + x = 0.364566mm + y = 25.0mil + r = 9.0mil + } + ha:simplearc.11 { + thickness = 8.0mil + adelta = -90.000000 + astart = 270.000000 + x = 0.456946mm + y = 1.092454mm + r = 0.228854mm + } + ha:simplearc.12 { + thickness = 8.0mil + adelta = 67.988717 + astart = 270.000000 + x = 0.351045mm + y = 46.77854331mil + r = 12.75mil + } + ha:simplearc.13 { + thickness = 8.0mil + adelta = 67.988717 + astart = 90.000000 + x = 13.25mil + y = 49.25mil + r = 12.75mil + } + ha:simplearc.14 { + thickness = 8.0mil + adelta = -90.000000 + astart = 90.000000 + x = 0.228854mm + y = 52.99mil + r = 0.228854mm + } + } + height = 1.574801mm + } + ha:9 { + width = 0.651562mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 0.990238mm + thickness = 8.0mil + x1 = 0.228854mm + x2 = 0.578866mm + y1 = 0.990238mm + } + ha:line.1 { + y2 = 0.533038mm + thickness = 8.0mil + x1 = 0.549961mm + x2 = 0.651561mm + y1 = 1.168038mm + } + ha:line.2 { + y2 = 0.761384mm + thickness = 8.0mil + x1 = 0.037188mm + x2 = 0.0 + y1 = 0.533915mm + } + ha:line.3 { + y2 = 0.279038mm + thickness = 8.0mil + x1 = 0.341935mm + x2 = 0.422707mm + y1 = 0.279038mm + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = -68.630916 + astart = 162.245445 + x = -0.21mil + y = 0.990238mm + r = 23.0mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = -96.270387 + astart = 270.000000 + x = 0.422707mm + y = 0.507892mm + r = 0.228854mm + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = 79.815149 + astart = 270.000000 + x = 0.341935mm + y = 0.588664mm + r = 0.309626mm + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = -90.000000 + astart = 90.000000 + x = 0.228854mm + y = 0.761384mm + r = 0.228854mm + } + } + height = 1.573276mm + } + ha:< { + width = 0.624638mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 34.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.624637mm + y1 = 42.0mil + } + ha:line.1 { + y2 = 50.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.560019mm + y1 = 42.0mil + } + } + height = 1.270001mm + } + ha:> { + width = 0.624638mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 34.0mil + thickness = 8.0mil + x1 = 0.624637mm + x2 = 0.064618mm + y1 = 42.0mil + } + ha:line.1 { + y2 = 50.0mil + thickness = 8.0mil + x1 = 0.624637mm + x2 = 0.0 + y1 = 42.0mil + } + } + height = 1.270001mm + } + ha:? { + width = 0.605773mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.140432mm + x2 = 0.132355mm + y1 = 60.0mil + } + ha:line.1 { + y2 = 38.6mil + thickness = 8.0mil + x1 = 0.201011mm + x2 = 0.227312mm + y1 = 1.14046mm + } + ha:line.2 { + y2 = 0.567117mm + thickness = 8.0mil + x1 = 0.531535mm + x2 = 0.576337mm + y1 = 0.636503mm + } + ha:line.3 { + y2 = 27.8mil + thickness = 8.0mil + x1 = 0.372092mm + x2 = 0.458452mm + y1 = 30.3mil + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = 17.272585 + astart = -90.000000 + x = 0.417812mm + y = 66.4mil + r = 1.40716mm + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = -20.872164 + astart = 145.218995 + x = 0.325574mm + y = 0.493457mm + r = 0.250763mm + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = -33.690068 + astart = 180.000000 + x = 0.430512mm + y = 18.5mil + r = 6.9mil + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = -41.552840 + astart = 345.768542 + x = 0.577832mm + y = 42.1mil + r = 14.3mil + } + ha:simplearc.8 { + thickness = 8.0mil + adelta = -90.000000 + astart = -90.000000 + x = 0.417812mm + y = 0.46736mm + r = 7.4mil + } + } + height = 1.574801mm + } + ha:@ { + width = 1.37171mm + delta = 0.17834mm + li:objects { + ha:line.0 { + y2 = 25.94mil + thickness = 8.0mil + x1 = 0.413824mm + x2 = 0.498635mm + y1 = 1.192276mm + } + ha:line.1 { + y2 = 18.94mil + thickness = 8.0mil + x1 = 0.715373mm + x2 = 0.984613mm + y1 = 18.94mil + } + ha:line.2 { + y2 = 1.192276mm + thickness = 8.0mil + x1 = 0.984613mm + x2 = 0.871532mm + y1 = 18.94mil + } + ha:line.3 { + y2 = 1.94mil + thickness = 8.0mil + x1 = 0.676333mm + x2 = 0.972497mm + y1 = 1.94mil + } + ha:line.4 { + y2 = 55.74mil + thickness = 8.0mil + x1 = 0.149969mm + x2 = 0.003538mm + y1 = 18.94mil + } + ha:line.5 { + y2 = 0.427736mm + thickness = 8.0mil + x1 = 1.248468mm + x2 = 1.371709mm + y1 = 1.192276mm + } + ha:line.6 { + y2 = 70.84mil + thickness = 8.0mil + x1 = 0.25654mm + x2 = 0.44958mm + y1 = 1.776476mm + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = -90.000000 + astart = 90.000000 + x = 41.0mil + y = 47.14mil + r = 0.17272mm + } + ha:simplearc.8 { + thickness = 8.0mil + adelta = 80.073754 + astart = 90.000000 + x = 41.0mil + y = 45.74mil + r = 0.20828mm + } + ha:simplearc.9 { + thickness = 8.0mil + adelta = 70.448005 + astart = 90.000000 + x = 23.5mil + y = 1.077976mm + r = 0.29464mm + } + ha:simplearc.10 { + thickness = 8.0mil + adelta = -90.000000 + astart = 90.000000 + x = 23.5mil + y = 46.84mil + r = 7.2mil + } + ha:simplearc.11 { + thickness = 8.0mil + adelta = 87.153067 + astart = 351.448170 + x = 0.32004mm + y = 57.64mil + r = 0.32004mm + } + ha:simplearc.12 { + thickness = 8.0mil + adelta = 78.876123 + astart = -90.000000 + x = 0.715373mm + y = 0.701149mm + r = 0.220073mm + } + ha:simplearc.13 { + thickness = 8.0mil + adelta = 78.736107 + astart = -90.000000 + x = 0.676333mm + y = 0.585909mm + r = 0.536633mm + } + ha:simplearc.14 { + thickness = 8.0mil + adelta = -87.335143 + astart = -90.000000 + x = 0.972497mm + y = 0.448379mm + r = 0.399103mm + } + } + height = 1.799337mm + } + ha:A { + width = 1.117601mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 0.277913mm + thickness = 8.0mil + x1 = 0.75311mm + x2 = 0.52451mm + y1 = 0.277913mm + } + ha:line.1 { + y2 = 1.573313mm + thickness = 8.0mil + x1 = 12.0mil + x2 = 0.0 + y1 = 1.573313mm + } + ha:line.2 { + y2 = 1.573313mm + thickness = 8.0mil + x1 = 44.0mil + x2 = 32.0mil + y1 = 1.573313mm + } + ha:line.3 { + y2 = 1.219237mm + thickness = 8.0mil + x1 = 0.298645mm + x2 = 0.925178mm + y1 = 1.219237mm + } + ha:line.4 { + y2 = 0.279437mm + thickness = 8.0mil + x1 = 0.990372mm + x2 = 0.752882mm + y1 = 1.574837mm + } + ha:line.5 { + y2 = 0.279437mm + thickness = 8.0mil + x1 = 0.126772mm + x2 = 0.752882mm + y1 = 1.574837mm + } + } + height = 1.574838mm + } + ha:B { + width = 1.002414mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 0.279437mm + thickness = 8.0mil + x1 = 0.151104mm + x2 = 0.345186mm + y1 = 1.573313mm + } + ha:line.1 { + y2 = 1.573313mm + thickness = 8.0mil + x1 = 0.149352mm + x2 = 0.151104mm + y1 = 1.574837mm + } + ha:line.2 { + y2 = 0.279437mm + thickness = 8.0mil + x1 = 7.65mil + x2 = 0.749046mm + y1 = 0.279437mm + } + ha:line.3 { + y2 = 1.574837mm + thickness = 8.0mil + x1 = 0.0 + x2 = 0.570001mm + y1 = 1.574837mm + } + ha:line.4 { + y2 = 0.862076mm + thickness = 8.0mil + x1 = 0.7467mm + x2 = 0.2641mm + y1 = 0.862076mm + } + ha:line.5 { + y2 = 1.259877mm + thickness = 8.0mil + x1 = 0.946537mm + x2 = 0.936777mm + y1 = 1.206958mm + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = -78.618860 + astart = -90.000000 + x = 0.749046mm + y = 0.535748mm + r = 0.256311mm + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = 87.345804 + astart = 90.000000 + x = 0.626897mm + y = 0.485177mm + r = 14.8mil + } + ha:simplearc.8 { + thickness = 8.0mil + adelta = 80.528338 + astart = 90.000000 + x = 0.561289mm + y = 1.194269mm + r = 0.380568mm + } + ha:simplearc.9 { + thickness = 8.0mil + adelta = -103.760785 + astart = -90.000000 + x = 0.675157mm + y = 1.140497mm + r = 11.0mil + } + } + height = 1.574838mm + } + ha:C { + width = 0.89304mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 0.279437mm + thickness = 8.0mil + x1 = 0.870407mm + x2 = 0.893039mm + y1 = 0.430313mm + } + ha:line.1 { + y2 = 1.573313mm + thickness = 8.0mil + x1 = 0.243053mm + x2 = 0.698957mm + y1 = 1.574837mm + } + ha:line.2 { + y2 = 0.279437mm + thickness = 8.0mil + x1 = 0.437363mm + x2 = 0.893039mm + y1 = 0.279437mm + } + ha:line.3 { + y2 = 1.574837mm + thickness = 8.0mil + x1 = 0.231394mm + x2 = 22.89mil + y1 = 1.574837mm + } + ha:line.4 { + y2 = 1.343697mm + thickness = 8.0mil + x1 = 0.127737mm + x2 = 0.0 + y1 = 0.533437mm + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = -90.000000 + astart = 90.000000 + x = 0.231394mm + y = 1.343443mm + r = 0.231394mm + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = 78.336927 + astart = -90.000000 + x = 0.437363mm + y = 0.59488mm + r = 0.315443mm + } + } + height = 1.574838mm + } + ha:D { + width = 1.06101mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 1.574837mm + thickness = 8.0mil + x1 = 0.346253mm + x2 = 0.152172mm + y1 = 0.280961mm + } + ha:line.1 { + y2 = 0.280961mm + thickness = 8.0mil + x1 = 0.344958mm + x2 = 0.346253mm + y1 = 0.279437mm + } + ha:line.2 { + y2 = 1.574837mm + thickness = 8.0mil + x1 = 0.0 + x2 = 0.623621mm + y1 = 1.573313mm + } + ha:line.3 { + y2 = 0.279437mm + thickness = 8.0mil + x1 = 7.65mil + x2 = 0.195606mm + y1 = 0.277913mm + } + ha:line.4 { + y2 = 0.279437mm + thickness = 8.0mil + x1 = 0.195606mm + x2 = 0.82959mm + y1 = 0.279437mm + } + ha:line.5 { + y2 = 1.325917mm + thickness = 8.0mil + x1 = 1.060984mm + x2 = 0.933247mm + y1 = 0.510577mm + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = -90.000000 + astart = 270.000000 + x = 0.829615mm + y = 0.513371mm + r = 0.231394mm + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = 78.336927 + astart = 90.000000 + x = 0.623646mm + y = 1.261934mm + r = 0.315443mm + } + } + height = 1.577378mm + } + ha:E { + width = 0.981483mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 0.862113mm + thickness = 8.0mil + x1 = 0.74168mm + x2 = 0.25908mm + y1 = 0.862113mm + } + ha:line.1 { + y2 = 0.303313mm + thickness = 8.0mil + x1 = 0.957606mm + x2 = 38.5mil + y1 = 0.279437mm + } + ha:line.2 { + y2 = 1.420913mm + thickness = 8.0mil + x1 = 0.808508mm + x2 = 0.81026mm + y1 = 1.422437mm + } + ha:line.3 { + y2 = 1.422437mm + thickness = 8.0mil + x1 = 0.785648mm + x2 = 0.808508mm + y1 = 1.574837mm + } + ha:line.4 { + y2 = 0.279437mm + thickness = 8.0mil + x1 = 6.0mil + x2 = 0.346482mm + y1 = 1.573313mm + } + ha:line.5 { + y2 = 1.573313mm + thickness = 8.0mil + x1 = 0.001296mm + x2 = 0.0 + y1 = 1.574837mm + } + ha:line.6 { + y2 = 0.279437mm + thickness = 8.0mil + x1 = 37.75mil + x2 = 0.981482mm + y1 = 0.430313mm + } + ha:line.7 { + y2 = 0.279437mm + thickness = 8.0mil + x1 = 0.195606mm + x2 = 0.957606mm + y1 = 0.279437mm + } + ha:line.8 { + y2 = 1.573313mm + thickness = 8.0mil + x1 = 0.153696mm + x2 = 6.0mil + y1 = 1.574837mm + } + ha:line.9 { + y2 = 0.279437mm + thickness = 8.0mil + x1 = 7.65mil + x2 = 0.195606mm + y1 = 0.277913mm + } + ha:line.10 { + y2 = 1.574837mm + thickness = 8.0mil + x1 = 0.785648mm + x2 = 0.001296mm + y1 = 1.574837mm + } + ha:line.11 { + y2 = 0.938313mm + thickness = 8.0mil + x1 = 0.75311mm + x2 = 28.75mil + y1 = 0.785913mm + } + } + height = 1.574838mm + } + ha:F { + width = 0.981482mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 0.862113mm + thickness = 8.0mil + x1 = 0.741451mm + x2 = 0.258851mm + y1 = 0.862113mm + } + ha:line.1 { + y2 = 0.430313mm + thickness = 8.0mil + x1 = 0.957326mm + x2 = 0.958621mm + y1 = 0.428789mm + } + ha:line.2 { + y2 = 0.428789mm + thickness = 8.0mil + x1 = 0.979729mm + x2 = 0.957326mm + y1 = 0.279437mm + } + ha:line.3 { + y2 = 0.277913mm + thickness = 8.0mil + x1 = 0.979729mm + x2 = 0.981481mm + y1 = 0.279437mm + } + ha:line.4 { + y2 = 0.279437mm + thickness = 8.0mil + x1 = 0.195377mm + x2 = 0.979729mm + y1 = 0.279437mm + } + ha:line.5 { + y2 = 0.279437mm + thickness = 8.0mil + x1 = 0.194081mm + x2 = 0.195377mm + y1 = 0.277913mm + } + ha:line.6 { + y2 = 0.279437mm + thickness = 8.0mil + x1 = 0.151943mm + x2 = 0.346253mm + y1 = 1.574837mm + } + ha:line.7 { + y2 = 1.571789mm + thickness = 8.0mil + x1 = 0.304571mm + x2 = 0.0 + y1 = 1.573313mm + } + ha:line.8 { + y2 = 0.938313mm + thickness = 8.0mil + x1 = 0.752881mm + x2 = 0.730021mm + y1 = 0.785913mm + } + } + height = 1.574838mm + } + ha:G { + width = 0.964728mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 0.279437mm + thickness = 8.0mil + x1 = 0.904249mm + x2 = 0.926881mm + y1 = 0.430313mm + } + ha:line.1 { + y2 = 0.277876mm + thickness = 8.0mil + x1 = 0.437363mm + x2 = 0.921995mm + y1 = 0.277876mm + } + ha:line.2 { + y2 = 1.573276mm + thickness = 8.0mil + x1 = 0.231394mm + x2 = 28.19mil + y1 = 1.573276mm + } + ha:line.3 { + y2 = 1.341882mm + thickness = 8.0mil + x1 = 0.127737mm + x2 = 0.0 + y1 = 20.94mil + } + ha:line.4 { + y2 = 1.573276mm + thickness = 8.0mil + x1 = 0.829107mm + x2 = 28.19mil + y1 = 0.862076mm + } + ha:line.5 { + y2 = 0.863637mm + thickness = 8.0mil + x1 = 0.662975mm + x2 = 0.964727mm + y1 = 0.863637mm + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = -90.000000 + astart = 90.000000 + x = 0.231394mm + y = 1.341882mm + r = 0.231394mm + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = 78.336927 + astart = 270.000000 + x = 0.437363mm + y = 0.593319mm + r = 0.315443mm + } + } + height = 1.573277mm + } + ha:H { + width = 1.235482mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 0.277913mm + thickness = 8.0mil + x1 = 0.930681mm + x2 = 1.235481mm + y1 = 0.277913mm + } + ha:line.1 { + y2 = 1.571789mm + thickness = 8.0mil + x1 = 29.0mil + x2 = 41.0mil + y1 = 1.571789mm + } + ha:line.2 { + y2 = 1.571789mm + thickness = 8.0mil + x1 = 0.0 + x2 = 12.0mil + y1 = 1.571789mm + } + ha:line.3 { + y2 = 0.277913mm + thickness = 8.0mil + x1 = 0.194081mm + x2 = 0.498881mm + y1 = 0.277913mm + } + ha:line.4 { + y2 = 0.279437mm + thickness = 8.0mil + x1 = 0.888543mm + x2 = 1.082853mm + y1 = 1.574837mm + } + ha:line.5 { + y2 = 0.863637mm + thickness = 8.0mil + x1 = 0.969823mm + x2 = 0.258623mm + y1 = 0.863637mm + } + ha:line.6 { + y2 = 0.279437mm + thickness = 8.0mil + x1 = 0.151943mm + x2 = 0.346253mm + y1 = 1.574837mm + } + } + height = 1.574838mm + } + ha:I { + width = 0.803911mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 1.573313mm + thickness = 8.0mil + x1 = 0.0 + x2 = 23.0mil + y1 = 1.573313mm + } + ha:line.1 { + y2 = 0.277913mm + thickness = 8.0mil + x1 = 7.65mil + x2 = 0.80391mm + y1 = 0.277913mm + } + ha:line.2 { + y2 = 0.279437mm + thickness = 8.0mil + x1 = 0.304572mm + x2 = 0.498882mm + y1 = 1.574837mm + } + } + height = 1.574838mm + } + ha:J { + width = 1.134111mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 0.277913mm + thickness = 8.0mil + x1 = 11.65mil + x2 = 1.13411mm + y1 = 0.277913mm + } + ha:line.1 { + y2 = 1.422437mm + thickness = 8.0mil + x1 = 0.0 + x2 = 0.021108mm + y1 = 1.573313mm + } + ha:line.2 { + y2 = 0.277876mm + thickness = 8.0mil + x1 = 0.555489mm + x2 = 0.721072mm + y1 = 1.319276mm + } + ha:line.3 { + y2 = 1.573276mm + thickness = 8.0mil + x1 = 0.245863mm + x2 = 0.005um + y1 = 1.573276mm + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = 78.708251 + astart = 90.000000 + x = 0.245863mm + y = 49.52mil + r = 0.315468mm + } + } + height = 1.573314mm + } + ha:K { + width = 1.18514mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 1.573313mm + thickness = 8.0mil + x1 = 0.888145mm + x2 = 39.0mil + y1 = 1.573313mm + } + ha:line.1 { + y2 = 0.276389mm + thickness = 8.0mil + x1 = 0.880339mm + x2 = 1.185139mm + y1 = 0.276389mm + } + ha:line.2 { + y2 = 1.573313mm + thickness = 8.0mil + x1 = 0.0 + x2 = 12.0mil + y1 = 1.573313mm + } + ha:line.3 { + y2 = 0.277913mm + thickness = 8.0mil + x1 = 7.65mil + x2 = 0.49911mm + y1 = 0.277913mm + } + ha:line.4 { + y2 = 0.765mm + thickness = 8.0mil + x1 = 0.888772mm + x2 = 0.55601mm + y1 = 1.574837mm + } + ha:line.5 { + y2 = 1.066837mm + thickness = 8.0mil + x1 = 1.083082mm + x2 = 0.228372mm + y1 = 0.279437mm + } + ha:line.6 { + y2 = 0.279437mm + thickness = 8.0mil + x1 = 0.152172mm + x2 = 0.346482mm + y1 = 1.574837mm + } + } + height = 1.574838mm + } + ha:L { + width = 0.810261mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 1.574837mm + thickness = 8.0mil + x1 = 0.81026mm + x2 = 0.787172mm + y1 = 1.420913mm + } + ha:line.1 { + y2 = 1.574837mm + thickness = 8.0mil + x1 = 0.001296mm + x2 = 0.787172mm + y1 = 1.574837mm + } + ha:line.2 { + y2 = 0.277913mm + thickness = 8.0mil + x1 = 7.65mil + x2 = 0.49911mm + y1 = 0.277913mm + } + ha:line.3 { + y2 = 1.574837mm + thickness = 8.0mil + x1 = 0.0 + x2 = 0.001296mm + y1 = 1.573313mm + } + ha:line.4 { + y2 = 0.279437mm + thickness = 8.0mil + x1 = 0.152172mm + x2 = 0.346482mm + y1 = 1.574837mm + } + } + height = 1.574838mm + } + ha:M { + width = 1.362711mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 0.277913mm + thickness = 8.0mil + x1 = 1.360958mm + x2 = 1.36271mm + y1 = 0.279437mm + } + ha:line.1 { + y2 = 0.279437mm + thickness = 8.0mil + x1 = 1.210082mm + x2 = 1.360958mm + y1 = 0.279437mm + } + ha:line.2 { + y2 = 0.278476mm + thickness = 8.0mil + x1 = 0.345583mm + x2 = 0.346062mm + y1 = 0.277913mm + } + ha:line.3 { + y2 = 0.277913mm + thickness = 8.0mil + x1 = 7.65mil + x2 = 0.345583mm + y1 = 0.277913mm + } + ha:line.4 { + y2 = 1.571789mm + thickness = 8.0mil + x1 = 0.863829mm + x2 = 1.168629mm + y1 = 1.571789mm + } + ha:line.5 { + y2 = 1.573313mm + thickness = 8.0mil + x1 = 0.0 + x2 = 12.0mil + y1 = 1.573313mm + } + ha:line.6 { + y2 = 1.016037mm + thickness = 8.0mil + x1 = 1.210082mm + x2 = 0.667792mm + y1 = 0.279437mm + } + ha:line.7 { + y2 = 1.574837mm + thickness = 8.0mil + x1 = 1.210082mm + x2 = 1.015772mm + y1 = 0.279437mm + } + ha:line.8 { + y2 = 1.016037mm + thickness = 8.0mil + x1 = 0.346482mm + x2 = 0.667792mm + y1 = 0.279437mm + } + ha:line.9 { + y2 = 0.279437mm + thickness = 8.0mil + x1 = 0.152172mm + x2 = 0.346482mm + y1 = 1.574837mm + } + } + height = 1.574838mm + } + ha:&2f { + width = 0.798298mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.798297mm + x2 = 0.0 + y1 = 11.0mil + } + } + height = 1.574801mm + } + ha:&3a { + width = 0.100966mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 31.0mil + thickness = 8.0mil + x1 = 0.092888mm + x2 = 3.975mil + y1 = 33.0mil + } + ha:line.1 { + y2 = 54.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.008077mm + y1 = 56.0mil + } + } + height = 1.422401mm + } + ha:&3b { + width = 0.218085mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 56.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.125197mm + y1 = 67.0mil + } + ha:line.1 { + y2 = 33.0mil + thickness = 8.0mil + x1 = 0.210007mm + x2 = 0.218084mm + y1 = 35.0mil + } + } + height = 1.701801mm + } + ha:&3d { + width = 0.687909mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 34.0mil + thickness = 8.0mil + x1 = 0.068656mm + x2 = 0.687908mm + y1 = 34.0mil + } + ha:line.1 { + y2 = 51.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.619252mm + y1 = 51.0mil + } + } + height = 1.295401mm + } + ha:O { + width = 0.894081mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 0.277876mm + thickness = 8.0mil + x1 = 0.483133mm + x2 = 0.617753mm + y1 = 0.277876mm + } + ha:line.1 { + y2 = 1.573276mm + thickness = 8.0mil + x1 = 0.276327mm + x2 = 0.410947mm + y1 = 1.573276mm + } + ha:line.2 { + y2 = 1.296416mm + thickness = 8.0mil + x1 = 0.114331mm + x2 = 0.0 + y1 = 0.563417mm + } + ha:line.3 { + y2 = 0.552196mm + thickness = 8.0mil + x1 = 0.779749mm + x2 = 35.2mil + y1 = 1.287735mm + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = 75.196020 + astart = 90.000000 + x = 16.1mil + y = 46.84mil + r = 0.38354mm + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = -90.000000 + astart = 90.000000 + x = 10.8mil + y = 51.14mil + r = 10.8mil + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = 75.196020 + astart = -90.000000 + x = 19.1mil + y = 0.661416mm + r = 0.38354mm + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = -90.000000 + astart = -90.000000 + x = 0.61976mm + y = 0.552196mm + r = 10.8mil + } + } + height = 1.573277mm + } + ha:P { + width = 1.057225mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 0.277913mm + thickness = 8.0mil + x1 = 0.195377mm + x2 = 0.194081mm + y1 = 0.279437mm + } + ha:line.1 { + y2 = 0.990637mm + thickness = 8.0mil + x1 = 26.14mil + x2 = 0.239573mm + y1 = 0.990637mm + } + ha:line.2 { + y2 = 0.279437mm + thickness = 8.0mil + x1 = 0.151943mm + x2 = 0.346253mm + y1 = 1.574837mm + } + ha:line.3 { + y2 = 1.571789mm + thickness = 8.0mil + x1 = 0.304571mm + x2 = 0.0 + y1 = 1.573313mm + } + ha:line.4 { + y2 = 0.279437mm + thickness = 8.0mil + x1 = 0.195377mm + x2 = 0.777037mm + y1 = 0.279437mm + } + ha:line.5 { + y2 = 0.675677mm + thickness = 8.0mil + x1 = 1.049204mm + x2 = 1.039444mm + y1 = 0.622758mm + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = 80.528338 + astart = 90.000000 + x = 26.14mil + y = 0.610069mm + r = 0.380568mm + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = -103.760785 + astart = -90.000000 + x = 0.777824mm + y = 0.556297mm + r = 11.0mil + } + } + height = 1.574838mm + } + ha:N { + width = 1.235482mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 1.571789mm + thickness = 8.0mil + x1 = 0.0 + x2 = 12.0mil + y1 = 1.571789mm + } + ha:line.1 { + y2 = 0.279437mm + thickness = 8.0mil + x1 = 1.084605mm + x2 = 1.082853mm + y1 = 0.277913mm + } + ha:line.2 { + y2 = 0.277913mm + thickness = 8.0mil + x1 = 1.235481mm + x2 = 1.084605mm + y1 = 0.277913mm + } + ha:line.3 { + y2 = 0.277913mm + thickness = 8.0mil + x1 = 0.196392mm + x2 = 0.194081mm + y1 = 0.275904mm + } + ha:line.4 { + y2 = 0.275904mm + thickness = 8.0mil + x1 = 0.344774mm + x2 = 0.196392mm + y1 = 0.275904mm + } + ha:line.5 { + y2 = 1.574837mm + thickness = 8.0mil + x1 = 0.346253mm + x2 = 0.888543mm + y1 = 0.279437mm + } + ha:line.6 { + y2 = 0.279437mm + thickness = 8.0mil + x1 = 0.888543mm + x2 = 1.082853mm + y1 = 1.574837mm + } + ha:line.7 { + y2 = 0.279437mm + thickness = 8.0mil + x1 = 0.151943mm + x2 = 0.346253mm + y1 = 1.574837mm + } + } + height = 1.574838mm + } + ha:R { + width = 1.03053mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 1.573313mm + thickness = 8.0mil + x1 = 1.014813mm + x2 = 40.0mil + y1 = 1.571916mm + } + ha:line.1 { + y2 = 1.571916mm + thickness = 8.0mil + x1 = 0.862413mm + x2 = 1.014813mm + y1 = 1.571916mm + } + ha:line.2 { + y2 = 1.573313mm + thickness = 8.0mil + x1 = 0.0 + x2 = 12.0mil + y1 = 1.573313mm + } + ha:line.3 { + y2 = 0.277913mm + thickness = 8.0mil + x1 = 0.195606mm + x2 = 7.65mil + y1 = 0.279437mm + } + ha:line.4 { + y2 = 0.990637mm + thickness = 8.0mil + x1 = 0.863372mm + x2 = 0.671602mm + y1 = 1.574837mm + } + ha:line.5 { + y2 = 0.279437mm + thickness = 8.0mil + x1 = 0.752882mm + x2 = 0.195606mm + y1 = 0.279437mm + } + ha:line.6 { + y2 = 0.990637mm + thickness = 8.0mil + x1 = 0.646202mm + x2 = 0.239802mm + y1 = 0.990637mm + } + ha:line.7 { + y2 = 0.279437mm + thickness = 8.0mil + x1 = 0.152172mm + x2 = 0.346482mm + y1 = 1.574837mm + } + ha:line.8 { + y2 = 0.681736mm + thickness = 8.0mil + x1 = 1.022316mm + x2 = 1.012156mm + y1 = 24.64mil + } + ha:simplearc.9 { + thickness = 8.0mil + adelta = 80.528338 + astart = 90.000000 + x = 0.637261mm + y = 0.610069mm + r = 0.380568mm + } + ha:simplearc.10 { + thickness = 8.0mil + adelta = -103.760785 + astart = -90.000000 + x = 0.751129mm + y = 0.558837mm + r = 11.0mil + } + } + height = 1.574838mm + } + ha:S { + width = 0.930911mm + delta = 0.202892mm + li:objects { + ha:line.0 { + y2 = 1.041437mm + thickness = 8.0mil + x1 = 0.296734mm + x2 = 0.707122mm + y1 = 0.819174mm + } + ha:line.1 { + y2 = 18.94mil + thickness = 8.0mil + x1 = 0.93091mm + x2 = 35.45mil + y1 = 0.277876mm + } + ha:line.2 { + y2 = 1.573276mm + thickness = 8.0mil + x1 = 0.03048mm + x2 = 0.0 + y1 = 1.370076mm + } + ha:simplearc.3 { + thickness = 8.0mil + adelta = -47.997193 + astart = 180.000000 + x = 0.491023mm + y = 1.264875mm + r = 0.345522mm + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = -58.233191 + astart = 111.607450 + x = 0.458202mm + y = 0.876337mm + r = 27.5mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = 63.432338 + astart = 178.228530 + x = 0.592822mm + y = 1.257337mm + r = 0.24384mm + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = -27.159796 + astart = -90.000000 + x = 0.605522mm + y = 0.937297mm + r = 0.65786mm + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = 69.520750 + astart = 262.470073 + x = 0.552182mm + y = 0.680757mm + r = 15.9mil + } + ha:simplearc.8 { + thickness = 8.0mil + adelta = 86.104823 + astart = 335.556045 + x = 0.412482mm + y = 0.604557mm + r = 0.24384mm + } + } + height = 1.574838mm + } + ha:Q { + width = 0.896418mm + delta = 0.180136mm + li:objects { + ha:line.0 { + y2 = 1.574837mm + thickness = 8.0mil + x1 = 0.617753mm + x2 = 0.896417mm + y1 = 1.295437mm + } + ha:line.1 { + y2 = 0.279437mm + thickness = 8.0mil + x1 = 0.483133mm + x2 = 0.617753mm + y1 = 0.279437mm + } + ha:line.2 { + y2 = 1.574837mm + thickness = 8.0mil + x1 = 0.276327mm + x2 = 0.410947mm + y1 = 1.574837mm + } + ha:line.3 { + y2 = 1.297977mm + thickness = 8.0mil + x1 = 0.114331mm + x2 = 0.0 + y1 = 0.564978mm + } + ha:line.4 { + y2 = 0.553757mm + thickness = 8.0mil + x1 = 0.779749mm + x2 = 35.2mil + y1 = 1.289296mm + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = 75.196020 + astart = 90.000000 + x = 16.1mil + y = 1.191297mm + r = 0.38354mm + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = -90.000000 + astart = 90.000000 + x = 10.8mil + y = 1.300517mm + r = 10.8mil + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = 75.196020 + astart = -90.000000 + x = 19.1mil + y = 0.662977mm + r = 0.38354mm + } + ha:simplearc.8 { + thickness = 8.0mil + adelta = -90.000000 + astart = -90.000000 + x = 0.61976mm + y = 0.553757mm + r = 10.8mil + } + } + height = 1.574838mm + } + ha:U { + width = 1.092201mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 0.277913mm + thickness = 8.0mil + x1 = 31.0mil + x2 = 43.0mil + y1 = 0.277913mm + } + ha:line.1 { + y2 = 0.277913mm + thickness = 8.0mil + x1 = 0.0 + x2 = 12.0mil + y1 = 0.277913mm + } + ha:line.2 { + y2 = 0.277876mm + thickness = 8.0mil + x1 = 0.019219mm + x2 = 0.172686mm + y1 = 1.243076mm + } + ha:line.3 { + y2 = 0.277876mm + thickness = 8.0mil + x1 = 0.799142mm + x2 = 0.953482mm + y1 = 1.245574mm + } + ha:line.4 { + y2 = 52.64mil + thickness = 8.0mil + x1 = 0.019219mm + x2 = 0.016679mm + y1 = 1.243076mm + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = 67.796888 + astart = 359.432734 + x = 0.237659mm + y = 52.14mil + r = 0.22098mm + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = 93.961205 + astart = 68.198591 + x = 0.349419mm + y = 43.34mil + r = 18.6mil + } + } + height = 1.573277mm + } + ha:V { + width = 1.168401mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 0.276389mm + thickness = 8.0mil + x1 = 46.0mil + x2 = 34.0mil + y1 = 0.276389mm + } + ha:line.1 { + y2 = 0.276389mm + thickness = 8.0mil + x1 = 12.0mil + x2 = 0.0 + y1 = 0.276389mm + } + ha:line.2 { + y2 = 1.574837mm + thickness = 8.0mil + x1 = 1.040943mm + x2 = 0.389433mm + y1 = 0.279437mm + } + ha:line.3 { + y2 = 1.574837mm + thickness = 8.0mil + x1 = 0.126543mm + x2 = 0.389433mm + y1 = 0.279437mm + } + } + height = 1.574838mm + } + ha:T { + width = 0.861061mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 0.277913mm + thickness = 8.0mil + x1 = 0.859308mm + x2 = 0.86106mm + y1 = 0.279437mm + } + ha:line.1 { + y2 = 0.430313mm + thickness = 8.0mil + x1 = 0.860832mm + x2 = 33.0mil + y1 = 0.279437mm + } + ha:line.2 { + y2 = 0.430313mm + thickness = 8.0mil + x1 = 0.001753mm + x2 = 0.0 + y1 = 0.428789mm + } + ha:line.3 { + y2 = 0.428789mm + thickness = 8.0mil + x1 = 0.024156mm + x2 = 0.001753mm + y1 = 0.279437mm + } + ha:line.4 { + y2 = 0.279437mm + thickness = 8.0mil + x1 = 0.022632mm + x2 = 0.859308mm + y1 = 0.279437mm + } + ha:line.5 { + y2 = 0.279437mm + thickness = 8.0mil + x1 = 0.260122mm + x2 = 0.454432mm + y1 = 1.574837mm + } + ha:line.6 { + y2 = 1.573313mm + thickness = 8.0mil + x1 = 17.25mil + x2 = 3.25mil + y1 = 1.573313mm + } + } + height = 1.574838mm + } + ha:X { + width = 1.286511mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 1.571789mm + thickness = 8.0mil + x1 = 43.0mil + x2 = 31.0mil + y1 = 1.571789mm + } + ha:line.1 { + y2 = 0.276389mm + thickness = 8.0mil + x1 = 1.28651mm + x2 = 0.98171mm + y1 = 0.276389mm + } + ha:line.2 { + y2 = 1.571789mm + thickness = 8.0mil + x1 = 12.0mil + x2 = 0.0 + y1 = 1.571789mm + } + ha:line.3 { + y2 = 0.276389mm + thickness = 8.0mil + x1 = 0.49911mm + x2 = 7.65mil + y1 = 0.276389mm + } + ha:line.4 { + y2 = 1.574837mm + thickness = 8.0mil + x1 = 1.184453mm + x2 = 0.101143mm + y1 = 0.279437mm + } + ha:line.5 { + y2 = 1.574837mm + thickness = 8.0mil + x1 = 0.295453mm + x2 = 0.990143mm + y1 = 0.279437mm + } + } + height = 1.574838mm + } + ha:Y { + width = 1.066801mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 1.573313mm + thickness = 8.0mil + x1 = 0.516432mm + x2 = 0.160832mm + y1 = 1.573313mm + } + ha:line.1 { + y2 = 0.274865mm + thickness = 8.0mil + x1 = 12.0mil + x2 = 0.0 + y1 = 0.274865mm + } + ha:line.2 { + y2 = 0.274865mm + thickness = 8.0mil + x1 = 42.0mil + x2 = 30.0mil + y1 = 0.274865mm + } + ha:line.3 { + y2 = 1.574837mm + thickness = 8.0mil + x1 = 0.441274mm + x2 = 0.338404mm + y1 = 0.889037mm + } + ha:line.4 { + y2 = 0.889037mm + thickness = 8.0mil + x1 = 0.964514mm + x2 = 0.441274mm + y1 = 0.279437mm + } + ha:line.5 { + y2 = 0.889037mm + thickness = 8.0mil + x1 = 0.100914mm + x2 = 0.441274mm + y1 = 0.279437mm + } + } + height = 1.574838mm + } + ha:W { + width = 1.371601mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 0.276389mm + thickness = 8.0mil + x1 = 54.0mil + x2 = 42.0mil + y1 = 0.276389mm + } + ha:line.1 { + y2 = 0.276389mm + thickness = 8.0mil + x1 = 12.0mil + x2 = 0.0 + y1 = 0.276389mm + } + ha:line.2 { + y2 = 0.711237mm + thickness = 8.0mil + x1 = 0.770433mm + x2 = 0.620573mm + y1 = 1.574837mm + } + ha:line.3 { + y2 = 1.574837mm + thickness = 8.0mil + x1 = 1.244143mm + x2 = 0.770433mm + y1 = 0.279437mm + } + ha:line.4 { + y2 = 0.711237mm + thickness = 8.0mil + x1 = 0.211633mm + x2 = 0.620573mm + y1 = 1.574837mm + } + ha:line.5 { + y2 = 1.574837mm + thickness = 8.0mil + x1 = 0.126543mm + x2 = 0.211633mm + y1 = 0.279437mm + } + } + height = 1.574838mm + } + ha:[ { + width = 0.392431mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 1.727237mm + thickness = 8.0mil + x1 = 0.0 + x2 = 0.12954mm + y1 = 1.727237mm + } + ha:line.1 { + y2 = 0.127037mm + thickness = 8.0mil + x1 = 0.24003mm + x2 = 0.39243mm + y1 = 0.127037mm + } + ha:line.2 { + y2 = 1.727237mm + thickness = 8.0mil + x1 = 0.24003mm + x2 = 0.0 + y1 = 0.127037mm + } + } + height = 1.727238mm + } + ha:^ { + width = 0.406401mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 0.037um + thickness = 8.0mil + x1 = 16.0mil + x2 = 0.23749mm + y1 = 0.228637mm + } + ha:line.1 { + y2 = 0.037um + thickness = 8.0mil + x1 = 0.0 + x2 = 0.23749mm + y1 = 0.228637mm + } + } + height = 0.228638mm + } + ha:Z { + width = 0.981939mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 1.420913mm + thickness = 8.0mil + x1 = 31.0mil + x2 = 0.810488mm + y1 = 1.574837mm + } + ha:line.1 { + y2 = 0.430313mm + thickness = 8.0mil + x1 = 7.65mil + x2 = 0.171678mm + y1 = 0.279437mm + } + ha:line.2 { + y2 = 0.277913mm + thickness = 8.0mil + x1 = 0.0 + x2 = 0.981938mm + y1 = 1.574837mm + } + ha:line.3 { + y2 = 1.574837mm + thickness = 8.0mil + x1 = 0.0 + x2 = 31.0mil + y1 = 1.574837mm + } + ha:line.4 { + y2 = 0.277913mm + thickness = 8.0mil + x1 = 7.65mil + x2 = 0.981938mm + y1 = 0.279437mm + } + } + height = 1.574838mm + } + ha:` { + width = 0.248921mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 0.254037mm + thickness = 8.0mil + x1 = 0.0 + x2 = 9.8mil + y1 = 0.050837mm + } + } + height = 0.254038mm + } + ha:_ { + width = 0.609601mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 1.727237mm + thickness = 8.0mil + x1 = 0.0 + x2 = 24.0mil + y1 = 1.727237mm + } + } + height = 1.727238mm + } + } + cell_width = 1.444474mm + cell_height = 2.032038mm + } +} Index: tags/1.0.5/font/aussiefont-serif-regular =================================================================== --- tags/1.0.5/font/aussiefont-serif-regular (nonexistent) +++ tags/1.0.5/font/aussiefont-serif-regular (revision 10414) @@ -0,0 +1,4692 @@ +li:pcb-rnd-font-v1 { + ha:geda_pcb { + id = 0 + ha:symbols { + ha:&09 { + width = 0.685801mm + delta = 0.103633mm + li:objects { + ha:line.0 { + y2 = 36.0mil + thickness = 3.0mil + x1 = 0.0 + x2 = 27.0mil + y1 = 36.0mil + } + ha:line.1 { + y2 = 30.0mil + thickness = 3.0mil + x1 = 27.0mil + x2 = 22.0mil + y1 = 36.0mil + } + ha:line.2 { + y2 = 42.0mil + thickness = 3.0mil + x1 = 27.0mil + x2 = 22.0mil + y1 = 36.0mil + } + ha:line.3 { + y2 = 42.0mil + thickness = 3.0mil + x1 = 0.0 + x2 = 5.0mil + y1 = 36.0mil + } + ha:line.4 { + y2 = 30.0mil + thickness = 3.0mil + x1 = 0.0 + x2 = 5.0mil + y1 = 36.0mil + } + } + height = 1.066801mm + } + ha:&0A { + width = 0.889001mm + delta = 10.0mil + li:objects { + ha:line.0 { + y2 = 10.0mil + thickness = 3.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 40.0mil + } + ha:line.1 { + y2 = 40.0mil + thickness = 3.0mil + x1 = 0.0 + x2 = 15.0mil + y1 = 40.0mil + } + ha:line.2 { + y2 = 45.0mil + thickness = 3.0mil + x1 = 20.0mil + x2 = 20.0mil + y1 = 75.0mil + } + ha:line.3 { + y2 = 45.0mil + thickness = 3.0mil + x1 = 20.0mil + x2 = 35.0mil + y1 = 45.0mil + } + ha:line.4 { + y2 = 60.0mil + thickness = 3.0mil + x1 = 20.0mil + x2 = 30.0mil + y1 = 60.0mil + } + } + height = 1.905001mm + } + ha:&0D { + width = 0.889001mm + delta = 0.253999mm + li:objects { + ha:line.0 { + y2 = 15.0mil + thickness = 3.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 35.0mil + } + ha:line.1 { + y2 = 10.0mil + thickness = 3.0mil + x1 = 5.0mil + x2 = 10.0mil + y1 = 10.0mil + } + ha:line.2 { + y2 = 40.0mil + thickness = 3.0mil + x1 = 5.0mil + x2 = 10.0mil + y1 = 40.0mil + } + ha:line.3 { + y2 = 45.0mil + thickness = 3.0mil + x1 = 20.0mil + x2 = 20.0mil + y1 = 75.0mil + } + ha:line.4 { + y2 = 45.0mil + thickness = 3.0mil + x1 = 20.0mil + x2 = 30.0mil + y1 = 45.0mil + } + ha:line.5 { + y2 = 60.0mil + thickness = 3.0mil + x1 = 20.0mil + x2 = 30.0mil + y1 = 60.0mil + } + ha:line.6 { + y2 = 55.0mil + thickness = 3.0mil + x1 = 35.0mil + x2 = 35.0mil + y1 = 50.0mil + } + ha:line.7 { + y2 = 75.0mil + thickness = 3.0mil + x1 = 30.0mil + x2 = 35.0mil + y1 = 60.0mil + } + ha:simplearc.8 { + thickness = 3.0mil + adelta = -90.000000 + astart = -90.000000 + x = 10.0mil + y = 15.0mil + r = 5.0mil + } + ha:simplearc.9 { + thickness = 3.0mil + adelta = 90.000000 + astart = 270.000000 + x = 5.0mil + y = 15.0mil + r = 5.0mil + } + ha:simplearc.10 { + thickness = 3.0mil + adelta = 90.000000 + astart = 90.000000 + x = 10.0mil + y = 35.0mil + r = 5.0mil + } + ha:simplearc.11 { + thickness = 3.0mil + adelta = -90.000000 + astart = 90.000000 + x = 5.0mil + y = 35.0mil + r = 5.0mil + } + ha:simplearc.12 { + thickness = 3.0mil + adelta = 90.000000 + astart = 90.000000 + x = 30.0mil + y = 55.0mil + r = 5.0mil + } + ha:simplearc.13 { + thickness = 3.0mil + adelta = -90.000000 + astart = -90.000000 + x = 30.0mil + y = 50.0mil + r = 5.0mil + } + } + height = 1.905001mm + } ha:] { + width = 0.152401mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 5.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 6.0mil + y1 = 5.0mil + } + ha:line.1 { + y2 = 68.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 6.0mil + y1 = 68.0mil + } + ha:line.2 { + y2 = 68.0mil + thickness = 8.0mil + x1 = 6.0mil + x2 = 6.0mil + y1 = 5.0mil + } + } + height = 1.727201mm + } + ha:&5c { + width = 0.558801mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 22.0mil + y1 = 11.0mil + } + } + height = 1.574801mm + } + ha:b { + width = 0.736601mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 10.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 6.0mil + y1 = 0.252476mm + } + ha:line.1 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 6.0mil + x2 = 23.0mil + y1 = 28.0mil + } + ha:line.2 { + y2 = 56.0mil + thickness = 8.0mil + x1 = 29.0mil + x2 = 29.0mil + y1 = 34.0mil + } + ha:line.3 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 23.0mil + y1 = 1.573276mm + } + ha:line.4 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 6.0mil + x2 = 6.0mil + y1 = 10.0mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = 90.000000 + astart = 90.000000 + x = 23.0mil + y = 56.0mil + r = 6.0mil + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = 90.000000 + astart = 180.000000 + x = 23.0mil + y = 34.0mil + r = 6.0mil + } + } + height = 1.574801mm + } + ha:c { + width = 0.506477mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 0.862076mm + thickness = 8.0mil + x1 = 19.94mil + x2 = 19.94mil + y1 = 27.94mil + } + ha:line.1 { + y2 = 27.94mil + thickness = 8.0mil + x1 = 6.0mil + x2 = 19.94mil + y1 = 28.0mil + } + ha:line.2 { + y2 = 56.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 34.0mil + } + ha:line.3 { + y2 = 1.573276mm + thickness = 8.0mil + x1 = 6.0mil + x2 = 19.94mil + y1 = 62.0mil + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = -90.000000 + astart = 90.000000 + x = 6.0mil + y = 56.0mil + r = 6.0mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = -90.000000 + astart = 0.000000 + x = 6.0mil + y = 34.0mil + r = 6.0mil + } + } + height = 1.574801mm + } + ha:a { + width = 0.735077mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 23.0mil + x2 = 23.0mil + y1 = 35.0mil + } + ha:line.1 { + y2 = 44.0mil + thickness = 8.0mil + x1 = 9.0mil + x2 = 23.0mil + y1 = 44.0mil + } + ha:line.2 { + y2 = 1.573276mm + thickness = 8.0mil + x1 = 9.0mil + x2 = 28.94mil + y1 = 62.0mil + } + ha:line.3 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 4.0mil + x2 = 16.0mil + y1 = 28.0mil + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = 90.000000 + astart = 180.000000 + x = 16.0mil + y = 35.0mil + r = 7.0mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = -180.000000 + astart = 90.000000 + x = 9.0mil + y = 53.0mil + r = 9.0mil + } + } + height = 1.574801mm + } + ha:e { + width = 0.558801mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 7.0mil + x2 = 22.0mil + y1 = 62.0mil + } + ha:line.1 { + y2 = 39.0mil + thickness = 8.0mil + x1 = 22.0mil + x2 = 22.0mil + y1 = 45.0mil + } + ha:line.2 { + y2 = 45.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 22.0mil + y1 = 45.0mil + } + ha:line.3 { + y2 = 39.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 55.0mil + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = 90.000000 + astart = 0.000000 + x = 7.0mil + y = 55.0mil + r = 7.0mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = -180.000000 + astart = 0.000000 + x = 11.0mil + y = 39.0mil + r = 11.0mil + } + } + height = 1.574801mm + } + ha:f { + width = 0.431801mm + delta = 0.279399mm + li:objects { + ha:line.0 { + y2 = 1.573276mm + thickness = 8.0mil + x1 = 0.0 + x2 = 17.0mil + y1 = 1.573276mm + } + ha:line.1 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 6.0mil + x2 = 6.0mil + y1 = 18.0mil + } + ha:line.2 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 17.0mil + y1 = 28.0mil + } + ha:line.3 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 13.0mil + x2 = 17.0mil + y1 = 11.0mil + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = -90.000000 + astart = 0.000000 + x = 13.0mil + y = 18.0mil + r = 7.0mil + } + } + height = 1.574801mm + } + ha:d { + width = 0.735077mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 0.252476mm + thickness = 8.0mil + x1 = 23.0mil + x2 = 16.94mil + y1 = 0.252476mm + } + ha:line.1 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 6.0mil + x2 = 23.0mil + y1 = 28.0mil + } + ha:line.2 { + y2 = 56.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 34.0mil + } + ha:line.3 { + y2 = 1.573276mm + thickness = 8.0mil + x1 = 6.0mil + x2 = 28.94mil + y1 = 62.0mil + } + ha:line.4 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 23.0mil + x2 = 23.0mil + y1 = 10.0mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = -90.000000 + astart = 90.000000 + x = 6.0mil + y = 56.0mil + r = 6.0mil + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = -90.000000 + astart = 0.000000 + x = 6.0mil + y = 34.0mil + r = 6.0mil + } + } + height = 1.574801mm + } + ha:h { + width = 0.965201mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 1.573276mm + thickness = 8.0mil + x1 = 26.0mil + x2 = 38.0mil + y1 = 1.573276mm + } + ha:line.1 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 6.0mil + x2 = 26.0mil + y1 = 27.94mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 32.0mil + x2 = 32.0mil + y1 = 34.0mil + } + ha:line.3 { + y2 = 1.573276mm + thickness = 8.0mil + x1 = 0.0 + x2 = 12.0mil + y1 = 1.573276mm + } + ha:line.4 { + y2 = 0.252476mm + thickness = 8.0mil + x1 = 0.0 + x2 = 6.0mil + y1 = 0.252476mm + } + ha:line.5 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 6.0mil + x2 = 6.0mil + y1 = 10.0mil + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = 90.000000 + astart = 180.000000 + x = 26.0mil + y = 34.0mil + r = 6.0mil + } + } + height = 1.574801mm + } + ha:i { + width = 0.609601mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 1.573276mm + thickness = 8.0mil + x1 = 0.0 + x2 = 24.0mil + y1 = 1.573276mm + } + ha:line.1 { + y2 = 27.94mil + thickness = 8.0mil + x1 = 3.0mil + x2 = 12.0mil + y1 = 27.94mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 12.0mil + x2 = 12.0mil + y1 = 28.0mil + } + ha:line.3 { + y2 = 14.0mil + thickness = 8.0mil + x1 = 12.0mil + x2 = 12.0mil + y1 = 11.0mil + } + } + height = 1.574801mm + } + ha:g { + width = 0.735077mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 80.0mil + thickness = 8.0mil + x1 = 3.0mil + x2 = 16.0mil + y1 = 80.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 6.0mil + x2 = 23.0mil + y1 = 62.0mil + } + ha:line.2 { + y2 = 34.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 56.0mil + } + ha:line.3 { + y2 = 27.94mil + thickness = 8.0mil + x1 = 6.0mil + x2 = 28.94mil + y1 = 28.0mil + } + ha:line.4 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 23.0mil + x2 = 23.0mil + y1 = 73.0mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = 90.000000 + astart = -90.000000 + x = 6.0mil + y = 34.0mil + r = 6.0mil + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = 90.000000 + astart = -0.000000 + x = 6.0mil + y = 56.0mil + r = 6.0mil + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = 90.000000 + astart = 90.000000 + x = 16.0mil + y = 73.0mil + r = 7.0mil + } + } + height = 2.032001mm + } + ha:k { + width = 0.863601mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 27.94mil + thickness = 8.0mil + x1 = 22.0mil + x2 = 34.0mil + y1 = 27.94mil + } + ha:line.1 { + y2 = 1.573276mm + thickness = 8.0mil + x1 = 22.0mil + x2 = 34.0mil + y1 = 1.573276mm + } + ha:line.2 { + y2 = 1.573276mm + thickness = 8.0mil + x1 = 0.0 + x2 = 6.0mil + y1 = 1.573276mm + } + ha:line.3 { + y2 = 0.277876mm + thickness = 8.0mil + x1 = 0.0 + x2 = 6.0mil + y1 = 0.277876mm + } + ha:line.4 { + y2 = 0.967678mm + thickness = 8.0mil + x1 = 29.0mil + x2 = 0.408878mm + y1 = 62.0mil + } + ha:line.5 { + y2 = 46.0mil + thickness = 8.0mil + x1 = 29.0mil + x2 = 6.0mil + y1 = 28.0mil + } + ha:line.6 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 6.0mil + x2 = 6.0mil + y1 = 11.0mil + } + } + height = 1.574801mm + } + ha:l { + width = 0.609601mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 1.573276mm + thickness = 8.0mil + x1 = 0.0 + x2 = 24.0mil + y1 = 1.573276mm + } + ha:line.1 { + y2 = 1.573276mm + thickness = 8.0mil + x1 = 12.06mil + x2 = 12.0mil + y1 = 11.0mil + } + ha:line.2 { + y2 = 0.277876mm + thickness = 8.0mil + x1 = 0.0 + x2 = 12.06mil + y1 = 0.277876mm + } + } + height = 1.573277mm + } + ha:j { + width = 0.357125mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 80.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.153924mm + y1 = 2.030476mm + } + ha:line.1 { + y2 = 0.708152mm + thickness = 8.0mil + x1 = 0.0 + x2 = 14.06mil + y1 = 27.94mil + } + ha:line.2 { + y2 = 72.0mil + thickness = 8.0mil + x1 = 14.06mil + x2 = 14.06mil + y1 = 28.0mil + } + ha:line.3 { + y2 = 14.0mil + thickness = 8.0mil + x1 = 14.06mil + x2 = 14.06mil + y1 = 11.0mil + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = -90.000000 + astart = 180.000000 + x = 0.153924mm + y = 72.0mil + r = 8.0mil + } + } + height = 2.032001mm + } + ha:n { + width = 0.889001mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 1.573276mm + thickness = 8.0mil + x1 = 29.0mil + x2 = 35.0mil + y1 = 1.573276mm + } + ha:line.1 { + y2 = 1.573276mm + thickness = 8.0mil + x1 = 0.0 + x2 = 12.0mil + y1 = 1.573276mm + } + ha:line.2 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 6.0mil + x2 = 6.0mil + y1 = 0.710133mm + } + ha:line.3 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 29.0mil + x2 = 29.0mil + y1 = 37.0mil + } + ha:line.4 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 20.0mil + y1 = 27.94mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = -90.000000 + astart = -90.000000 + x = 20.0mil + y = 37.0mil + r = 9.0mil + } + } + height = 1.574801mm + } + ha:o { + width = 0.630009mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 1.573276mm + thickness = 8.0mil + x1 = 0.264204mm + x2 = 0.365804mm + y1 = 1.573276mm + } + ha:line.1 { + y2 = 27.94mil + thickness = 8.0mil + x1 = 0.264204mm + x2 = 0.365804mm + y1 = 27.94mil + } + ha:line.2 { + y2 = 0.99928mm + thickness = 8.0mil + x1 = 0.630008mm + x2 = 0.630008mm + y1 = 1.283672mm + } + ha:line.3 { + y2 = 1.283672mm + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 0.99928mm + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = -90.000000 + astart = 0.000000 + x = 0.289604mm + y = 0.99928mm + r = 0.289604mm + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = 90.000000 + astart = 180.000000 + x = 0.340404mm + y = 0.99928mm + r = 0.289604mm + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = 90.000000 + astart = -0.000000 + x = 0.289604mm + y = 1.283672mm + r = 0.289604mm + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = -90.000000 + astart = -180.000000 + x = 0.340404mm + y = 1.283672mm + r = 0.289604mm + } + } + height = 1.573277mm + } + ha:m { + width = 1.270001mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 1.573276mm + thickness = 8.0mil + x1 = 44.0mil + x2 = 50.0mil + y1 = 1.573276mm + } + ha:line.1 { + y2 = 1.573276mm + thickness = 8.0mil + x1 = 25.0mil + x2 = 31.0mil + y1 = 1.573276mm + } + ha:line.2 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 44.0mil + x2 = 44.0mil + y1 = 37.0mil + } + ha:line.3 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 25.0mil + x2 = 25.0mil + y1 = 28.0mil + } + ha:line.4 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 12.0mil + y1 = 62.0mil + } + ha:line.5 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.152105mm + x2 = 6.0mil + y1 = 0.70997mm + } + ha:line.6 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 35.0mil + y1 = 27.94mil + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = -90.000000 + astart = -90.000000 + x = 35.0mil + y = 37.0mil + r = 9.0mil + } + } + height = 1.574801mm + } + ha:q { + width = 0.735077mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 2.030476mm + thickness = 8.0mil + x1 = 16.94mil + x2 = 28.94mil + y1 = 2.030476mm + } + ha:line.1 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 6.0mil + x2 = 23.0mil + y1 = 62.0mil + } + ha:line.2 { + y2 = 56.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 34.0mil + } + ha:line.3 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 28.94mil + x2 = 6.0mil + y1 = 27.94mil + } + ha:line.4 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 23.0mil + x2 = 23.0mil + y1 = 80.0mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = 90.000000 + astart = -90.000000 + x = 6.0mil + y = 34.0mil + r = 6.0mil + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = 90.000000 + astart = 0.000000 + x = 6.0mil + y = 56.0mil + r = 6.0mil + } + } + height = 2.032001mm + } + ha:r { + width = 0.584201mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 1.573276mm + thickness = 8.0mil + x1 = 0.0 + x2 = 18.0mil + y1 = 1.573276mm + } + ha:line.1 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 17.0mil + y1 = 28.0mil + } + ha:line.2 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 6.0mil + x2 = 6.0mil + y1 = 62.0mil + } + ha:simplearc.3 { + thickness = 8.0mil + adelta = 90.000000 + astart = 180.000000 + x = 17.0mil + y = 34.0mil + r = 6.0mil + } + } + height = 1.574801mm + } + ha:p { + width = 0.736601mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 2.030476mm + thickness = 8.0mil + x1 = 0.0 + x2 = 12.0mil + y1 = 2.030476mm + } + ha:line.1 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 6.0mil + x2 = 23.0mil + y1 = 62.0mil + } + ha:line.2 { + y2 = 56.0mil + thickness = 8.0mil + x1 = 29.0mil + x2 = 29.0mil + y1 = 34.0mil + } + ha:line.3 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 23.0mil + y1 = 27.94mil + } + ha:line.4 { + y2 = 80.0mil + thickness = 8.0mil + x1 = 6.0mil + x2 = 6.0mil + y1 = 28.0mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = -90.000000 + astart = 270.000000 + x = 23.0mil + y = 34.0mil + r = 6.0mil + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = -90.000000 + astart = 180.000000 + x = 23.0mil + y = 56.0mil + r = 6.0mil + } + } + height = 2.032001mm + } + ha:t { + width = 0.45329mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 17.0mil + y1 = 28.0mil + } + ha:line.1 { + y2 = 1.344676mm + thickness = 8.0mil + x1 = 6.0mil + x2 = 6.0mil + y1 = 11.0mil + } + ha:simplearc.2 { + thickness = 8.0mil + adelta = -108.434949 + astart = 108.434949 + x = 15.0mil + y = 1.344676mm + r = 9.0mil + } + } + height = 1.573277mm + } + ha:u { + width = 0.889001mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 0.708146mm + thickness = 8.0mil + x1 = 23.0mil + x2 = 0.738129mm + y1 = 27.94mil + } + ha:line.1 { + y2 = 27.94mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.153924mm + y1 = 27.94mil + } + ha:line.2 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 29.0mil + x2 = 0.738124mm + y1 = 1.573276mm + } + ha:line.3 { + y2 = 1.573276mm + thickness = 8.0mil + x1 = 13.06mil + x2 = 35.0mil + y1 = 62.0mil + } + ha:line.4 { + y2 = 55.0mil + thickness = 8.0mil + x1 = 0.153924mm + x2 = 0.153924mm + y1 = 28.0mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = 90.000000 + astart = 0.000000 + x = 13.06mil + y = 55.0mil + r = 7.0mil + } + } + height = 1.574801mm + } + ha:s { + width = 0.620118mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 0.862076mm + thickness = 8.0mil + x1 = 24.0mil + x2 = 24.0mil + y1 = 27.94mil + } + ha:line.1 { + y2 = 1.420876mm + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 1.573276mm + } + ha:line.2 { + y2 = 1.141047mm + thickness = 8.0mil + x1 = 0.206305mm + x2 = 0.412721mm + y1 = 1.119181mm + } + ha:simplearc.3 { + thickness = 8.0mil + adelta = -180.000000 + astart = 90.000000 + x = 0.206305mm + y = 36.0mil + r = 0.204781mm + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = -17.605835 + astart = 268.781125 + x = 0.180905mm + y = 75.0mil + r = 47.0mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = -186.525031 + astart = 269.133210 + x = 0.409505mm + y = 1.353612mm + r = 0.210612mm + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = -17.031080 + astart = 90.000000 + x = 0.382409mm + y = 0.368674mm + r = 47.0mil + } + } + height = 1.573277mm + } + ha:w { + width = 1.219201mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 27.94mil + thickness = 8.0mil + x1 = 36.0mil + x2 = 48.0mil + y1 = 27.94mil + } + ha:line.1 { + y2 = 27.94mil + thickness = 8.0mil + x1 = 0.0 + x2 = 12.0mil + y1 = 27.94mil + } + ha:line.2 { + y2 = 40.0mil + thickness = 8.0mil + x1 = 33.0mil + x2 = 24.0mil + y1 = 62.0mil + } + ha:line.3 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 42.0mil + x2 = 33.0mil + y1 = 28.0mil + } + ha:line.4 { + y2 = 40.0mil + thickness = 8.0mil + x1 = 15.0mil + x2 = 24.0mil + y1 = 62.0mil + } + ha:line.5 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 6.0mil + x2 = 15.0mil + y1 = 28.0mil + } + } + height = 1.574801mm + } + ha:x { + width = 0.863601mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 1.573276mm + thickness = 8.0mil + x1 = 22.0mil + x2 = 34.0mil + y1 = 1.573276mm + } + ha:line.1 { + y2 = 1.573276mm + thickness = 8.0mil + x1 = 0.0 + x2 = 12.0mil + y1 = 1.573276mm + } + ha:line.2 { + y2 = 27.94mil + thickness = 8.0mil + x1 = 22.0mil + x2 = 34.0mil + y1 = 27.94mil + } + ha:line.3 { + y2 = 27.94mil + thickness = 8.0mil + x1 = 0.0 + x2 = 12.0mil + y1 = 27.94mil + } + ha:line.4 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 6.0mil + x2 = 28.0mil + y1 = 62.0mil + } + ha:line.5 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 6.0mil + x2 = 28.0mil + y1 = 28.0mil + } + } + height = 1.574801mm + } + ha:v { + width = 0.863601mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 27.94mil + thickness = 8.0mil + x1 = 22.0mil + x2 = 34.0mil + y1 = 27.94mil + } + ha:line.1 { + y2 = 27.94mil + thickness = 8.0mil + x1 = 0.0 + x2 = 12.0mil + y1 = 27.94mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 28.0mil + x2 = 17.0mil + y1 = 28.0mil + } + ha:line.3 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 6.0mil + x2 = 17.0mil + y1 = 28.0mil + } + } + height = 1.574801mm + } + ha:z { + width = 0.609601mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 1.420876mm + thickness = 8.0mil + x1 = 24.0mil + x2 = 24.0mil + y1 = 1.573276mm + } + ha:line.1 { + y2 = 0.862076mm + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 28.0mil + } + ha:line.2 { + y2 = 1.573276mm + thickness = 8.0mil + x1 = 0.0 + x2 = 24.0mil + y1 = 62.0mil + } + ha:line.3 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 24.0mil + x2 = 0.0 + y1 = 27.94mil + } + ha:line.4 { + y2 = 27.94mil + thickness = 8.0mil + x1 = 0.0 + x2 = 24.0mil + y1 = 28.0mil + } + } + height = 1.574801mm + } + ha:~ { + width = 0.589861mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 0.922452mm + thickness = 8.0mil + x1 = 0.264009mm + x2 = 0.325852mm + y1 = 0.863007mm + } + ha:simplearc.1 { + thickness = 8.0mil + adelta = -19.075098 + astart = 312.273689 + x = 0.273375mm + y = 47.0mil + r = 16.0mil + } + ha:simplearc.2 { + thickness = 8.0mil + adelta = -19.075098 + astart = 132.273689 + x = 0.316486mm + y = 0.591659mm + r = 16.0mil + } + ha:simplearc.3 { + thickness = 8.0mil + adelta = -31.668558 + astart = -90.000000 + x = 0.113286mm + y = 1.107348mm + r = 0.287089mm + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = -31.668558 + astart = 90.000000 + x = 0.476575mm + y = 0.678111mm + r = 0.287089mm + } + } + height = 0.965201mm + } + ha:y { + width = 0.889001mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 2.030476mm + thickness = 8.0mil + x1 = 3.0mil + x2 = 21.0mil + y1 = 2.030476mm + } + ha:line.1 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 12.0mil + x2 = 29.0mil + y1 = 80.0mil + } + ha:line.2 { + y2 = 27.94mil + thickness = 8.0mil + x1 = 23.0mil + x2 = 35.0mil + y1 = 27.94mil + } + ha:line.3 { + y2 = 27.94mil + thickness = 8.0mil + x1 = 0.0 + x2 = 12.0mil + y1 = 27.94mil + } + ha:line.4 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 6.0mil + x2 = 18.0mil + y1 = 28.0mil + } + } + height = 2.032001mm + } + ha:&7d { + width = 0.279402mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 9.0mil + thickness = 8.0mil + x1 = 0.127001mm + x2 = 0.127001mm + y1 = 30.0mil + } + ha:line.1 { + y2 = 63.0mil + thickness = 8.0mil + x1 = 0.127001mm + x2 = 0.127001mm + y1 = 42.0mil + } + ha:simplearc.2 { + thickness = 8.0mil + adelta = 90.000000 + astart = -90.000000 + x = 0.279401mm + y = 42.0mil + r = 6.0mil + } + ha:simplearc.3 { + thickness = 8.0mil + adelta = 90.000000 + astart = 90.000000 + x = 0.001um + y = 63.0mil + r = 5.0mil + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = -90.000000 + astart = 90.000000 + x = 0.279401mm + y = 30.0mil + r = 6.0mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = -90.000000 + astart = -90.000000 + x = 0.001um + y = 9.0mil + r = 5.0mil + } + } + height = 1.727201mm + } + ha:| { + width = 0.001um + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 3.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 31.0mil + } + ha:line.1 { + y2 = 71.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 43.0mil + } + } + height = 1.803401mm + } + ha:&7b { + width = 0.279402mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 30.0mil + thickness = 8.0mil + x1 = 0.152401mm + x2 = 0.152401mm + y1 = 9.0mil + } + ha:line.1 { + y2 = 63.0mil + thickness = 8.0mil + x1 = 0.152401mm + x2 = 0.152401mm + y1 = 42.0mil + } + ha:simplearc.2 { + thickness = 8.0mil + adelta = -90.000000 + astart = 270.000000 + x = 0.001um + y = 42.0mil + r = 6.0mil + } + ha:simplearc.3 { + thickness = 8.0mil + adelta = -90.000000 + astart = 90.000000 + x = 0.279401mm + y = 63.0mil + r = 5.0mil + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = 90.000000 + astart = 90.000000 + x = 0.001um + y = 30.0mil + r = 6.0mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = 90.000000 + astart = 270.000000 + x = 0.279401mm + y = 9.0mil + r = 5.0mil + } + } + height = 1.727201mm + } + ha:&20 { + width = 0.0 + delta = 31.0mil + li:objects { + } + height = 0.0 + } + ha:&23 { + width = 0.889001mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 45.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 35.0mil + y1 = 45.0mil + } + ha:line.1 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 35.0mil + y1 = 28.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 26.0mil + x2 = 26.0mil + y1 = 11.0mil + } + ha:line.3 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 9.0mil + x2 = 9.0mil + y1 = 11.0mil + } + } + height = 1.574801mm + } + ha:&26 { + width = 0.862077mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 1.039876mm + thickness = 8.0mil + x1 = 24.94mil + x2 = 0.862076mm + y1 = 1.039876mm + } + ha:line.1 { + y2 = 1.573276mm + thickness = 8.0mil + x1 = 0.715817mm + x2 = 0.862076mm + y1 = 1.573276mm + } + ha:line.2 { + y2 = 1.039876mm + thickness = 8.0mil + x1 = 0.316401mm + x2 = 30.94mil + y1 = 1.565466mm + } + ha:line.3 { + y2 = 1.266107mm + thickness = 8.0mil + x1 = 0.469006mm + x2 = 0.014123mm + y1 = 0.597619mm + } + ha:line.4 { + y2 = 0.579653mm + thickness = 8.0mil + x1 = 0.716776mm + x2 = 0.09087mm + y1 = 62.0mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = 238.570434 + astart = 147.994617 + x = 0.284976mm + y = 19.0mil + r = 0.217017mm + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = 130.556045 + astart = 340.000000 + x = 0.234176mm + y = 53.0mil + r = 0.234176mm + } + } + height = 1.580377mm + } + ha:! { + width = 0.001um + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 59.0mil + } + ha:line.1 { + y2 = 45.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 11.0mil + } + } + height = 1.574801mm + } + ha:" { + width = 0.457201mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 0.0 + thickness = 8.0mil + x1 = 15.0mil + x2 = 18.0mil + y1 = 11.0mil + } + ha:line.1 { + y2 = 0.0 + thickness = 8.0mil + x1 = 0.0 + x2 = 3.0mil + y1 = 11.0mil + } + } + height = 0.279401mm + } + ha:$ { + width = 0.584201mm + delta = 0.180262mm + li:objects { + ha:line.0 { + y2 = 21.94mil + thickness = 8.0mil + x1 = 23.0mil + x2 = 23.0mil + y1 = 16.94mil + } + ha:line.1 { + y2 = 1.446276mm + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 1.293876mm + } + ha:line.2 { + y2 = 41.0mil + thickness = 8.0mil + x1 = 0.104793mm + x2 = 0.478556mm + y1 = 0.826602mm + } + ha:line.3 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.300756mm + x2 = 0.300756mm + y1 = 11.0mil + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = 156.595310 + astart = 83.659808 + x = 0.376956mm + y = 48.0mil + r = 0.204781mm + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = 168.035280 + astart = 250.000000 + x = 0.218531mm + y = 0.644334mm + r = 0.214844mm + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = -18.434949 + astart = 270.000000 + x = 0.275356mm + y = 55.0mil + r = 38.0mil + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = -19.653824 + astart = 90.000000 + x = 0.326156mm + y = 18.0mil + r = 38.0mil + } + } + height = 1.574801mm + } + ha:% { + width = 1.193801mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 46.0mil + x2 = 0.0 + y1 = 11.0mil + } + ha:simplearc.1 { + thickness = 8.0mil + adelta = 360.000000 + astart = 0.000000 + x = 9.0mil + y = 20.0mil + r = 9.0mil + } + ha:simplearc.2 { + thickness = 8.0mil + adelta = 360.000000 + astart = 0.000000 + x = 38.0mil + y = 53.0mil + r = 9.0mil + } + } + height = 1.574801mm + } + ha:' { + width = 0.076201mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 0.0 + thickness = 8.0mil + x1 = 0.0 + x2 = 3.0mil + y1 = 11.0mil + } + } + height = 0.279401mm + } + ha:( { + width = 0.134159mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 47.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 26.0mil + } + ha:simplearc.1 { + thickness = 8.0mil + adelta = -27.979474 + astart = 0.000000 + x = 1.147787mm + y = 26.0mil + r = 1.147787mm + } + ha:simplearc.2 { + thickness = 8.0mil + adelta = 27.979474 + astart = 0.000000 + x = 1.147787mm + y = 47.0mil + r = 1.147787mm + } + } + height = 1.732291mm + } + ha:) { + width = 0.13416mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 47.0mil + thickness = 8.0mil + x1 = 0.134159mm + x2 = 0.134159mm + y1 = 26.0mil + } + ha:simplearc.1 { + thickness = 8.0mil + adelta = 27.979474 + astart = 180.000000 + x = -1.013628mm + y = 26.0mil + r = 1.147787mm + } + ha:simplearc.2 { + thickness = 8.0mil + adelta = -27.979474 + astart = 180.000000 + x = -1.013628mm + y = 47.0mil + r = 1.147787mm + } + } + height = 1.732291mm + } + ha:* { + width = 0.558801mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 51.0mil + thickness = 8.0mil + x1 = 19.0mil + x2 = 3.0mil + y1 = 34.0mil + } + ha:line.1 { + y2 = 43.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 22.0mil + y1 = 43.0mil + } + ha:line.2 { + y2 = 51.0mil + thickness = 8.0mil + x1 = 3.0mil + x2 = 19.0mil + y1 = 34.0mil + } + } + height = 1.295401mm + } + ha:+ { + width = 0.558801mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 54.0mil + thickness = 8.0mil + x1 = 11.0mil + x2 = 11.0mil + y1 = 32.0mil + } + ha:line.1 { + y2 = 43.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 22.0mil + y1 = 43.0mil + } + } + height = 1.371601mm + } + ha:, { + width = 0.076201mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 65.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 3.0mil + y1 = 76.0mil + } + } + height = 1.930401mm + } + ha:- { + width = 0.558801mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 42.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 22.0mil + y1 = 42.0mil + } + } + height = 1.066801mm + } + ha:. { + width = 0.005081mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 60.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.2mil + y1 = 1.60782mm + } + } + height = 1.607821mm + } + ha:0 { + width = 0.609601mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 37.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 36.0mil + } + ha:line.1 { + y2 = 37.0mil + thickness = 8.0mil + x1 = 24.0mil + x2 = 24.0mil + y1 = 36.0mil + } + ha:line.2 { + y2 = 1.55837mm + thickness = 8.0mil + x1 = 0.177914mm + x2 = 0.224756mm + y1 = 1.506218mm + } + ha:line.3 { + y2 = 0.347982mm + thickness = 8.0mil + x1 = 0.384844mm + x2 = 0.431686mm + y1 = 0.29583mm + } + ha:line.4 { + y2 = 1.506218mm + thickness = 8.0mil + x1 = 0.384844mm + x2 = 0.431686mm + y1 = 1.55837mm + } + ha:line.5 { + y2 = 0.347982mm + thickness = 8.0mil + x1 = 0.224756mm + x2 = 0.177914mm + y1 = 0.29583mm + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = -46.397181 + astart = 293.198591 + x = 12.0mil + y = 19.0mil + r = 8.0mil + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = -34.875328 + astart = 0.000000 + x = 39.0mil + y = 36.0mil + r = 39.0mil + } + ha:simplearc.8 { + thickness = 8.0mil + adelta = -46.397181 + astart = 113.198591 + x = 12.0mil + y = 54.0mil + r = 8.0mil + } + ha:simplearc.9 { + thickness = 8.0mil + adelta = -34.875328 + astart = 180.000000 + x = -15.0mil + y = 37.0mil + r = 39.0mil + } + ha:simplearc.10 { + thickness = 8.0mil + adelta = 34.875328 + astart = 0.000000 + x = 39.0mil + y = 37.0mil + r = 39.0mil + } + ha:simplearc.11 { + thickness = 8.0mil + adelta = 34.875328 + astart = 180.000000 + x = -15.0mil + y = 36.0mil + r = 39.0mil + } + } + height = 1.574801mm + } + ha:1 { + width = 0.406401mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 1.573276mm + thickness = 8.0mil + x1 = 0.0 + x2 = 16.0mil + y1 = 1.573276mm + } + ha:line.1 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 8.0mil + x2 = 8.0mil + y1 = 11.0mil + } + ha:line.2 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 8.0mil + y1 = 18.94mil + } + } + height = 1.574801mm + } + ha:2 { + width = 0.59396mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 22.94mil + x2 = 22.94mil + y1 = 1.420876mm + } + ha:line.1 { + y2 = 0.741018mm + thickness = 8.0mil + x1 = 0.009759mm + x2 = 0.550523mm + y1 = 62.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.009759mm + x2 = 22.94mil + y1 = 62.0mil + } + ha:simplearc.3 { + thickness = 8.0mil + adelta = -192.528808 + astart = 341.565051 + x = 0.289159mm + y = 23.0mil + r = 12.0mil + } + } + height = 1.574801mm + } + ha:3 { + width = 0.584201mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 11.0mil + y1 = 62.0mil + } + ha:line.1 { + y2 = 50.0mil + thickness = 8.0mil + x1 = 23.0mil + x2 = 23.0mil + y1 = 45.0mil + } + ha:line.2 { + y2 = 34.0mil + thickness = 8.0mil + x1 = 5.0mil + x2 = 13.0mil + y1 = 34.0mil + } + ha:line.3 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 13.0mil + y1 = 11.0mil + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = -90.000000 + astart = -90.000000 + x = 13.0mil + y = 21.0mil + r = 10.0mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = -90.000000 + astart = 180.000000 + x = 10.0mil + y = 21.0mil + r = 13.0mil + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = 90.000000 + astart = 180.000000 + x = 12.0mil + y = 45.0mil + r = 11.0mil + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = 90.000000 + astart = 90.000000 + x = 11.0mil + y = 50.0mil + r = 12.0mil + } + } + height = 1.574801mm + } + ha:4 { + width = 0.711201mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 1.573276mm + thickness = 8.0mil + x1 = 13.0mil + x2 = 25.0mil + y1 = 1.573276mm + } + ha:line.1 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 19.0mil + x2 = 19.0mil + y1 = 39.0mil + } + ha:line.2 { + y2 = 51.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 28.0mil + y1 = 51.0mil + } + ha:line.3 { + y2 = 51.0mil + thickness = 8.0mil + x1 = 11.0mil + x2 = 0.0 + y1 = 11.0mil + } + } + height = 1.574801mm + } + ha:5 { + width = 0.584201mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 46.0mil + thickness = 8.0mil + x1 = 23.0mil + x2 = 23.0mil + y1 = 50.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 11.0mil + x2 = 0.0 + y1 = 62.0mil + } + ha:line.2 { + y2 = 34.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 11.0mil + y1 = 34.0mil + } + ha:line.3 { + y2 = 34.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 11.0mil + } + ha:line.4 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 23.0mil + x2 = 0.0 + y1 = 11.0mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = -90.000000 + astart = -90.000000 + x = 11.0mil + y = 46.0mil + r = 12.0mil + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = 90.000000 + astart = 90.000000 + x = 11.0mil + y = 50.0mil + r = 12.0mil + } + } + height = 1.574801mm + } + ha:6 { + width = 0.584201mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 10.0mil + x2 = 13.0mil + y1 = 62.0mil + } + ha:line.1 { + y2 = 44.0mil + thickness = 8.0mil + x1 = 23.0mil + x2 = 23.0mil + y1 = 52.0mil + } + ha:line.2 { + y2 = 52.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 30.0mil + } + ha:line.3 { + y2 = 34.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 13.0mil + y1 = 34.0mil + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = -90.000000 + astart = -90.000000 + x = 13.0mil + y = 44.0mil + r = 10.0mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = -90.000000 + astart = 90.000000 + x = 10.0mil + y = 52.0mil + r = 10.0mil + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = 90.000000 + astart = 90.000000 + x = 13.0mil + y = 52.0mil + r = 10.0mil + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = -83.659808 + astart = 0.000000 + x = 19.0mil + y = 30.0mil + r = 19.0mil + } + } + height = 1.574801mm + } + ha:7 { + width = 0.584201mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 23.0mil + x2 = 12.0mil + y1 = 11.0mil + } + ha:line.1 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 23.0mil + y1 = 11.0mil + } + ha:line.2 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 17.0mil + } + } + height = 1.574801mm + } + ha:8 { + width = 0.609601mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 10.0mil + x2 = 14.0mil + y1 = 62.0mil + } + ha:line.1 { + y2 = 34.0mil + thickness = 8.0mil + x1 = 10.0mil + x2 = 14.0mil + y1 = 34.0mil + } + ha:line.2 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 10.0mil + x2 = 14.0mil + y1 = 11.0mil + } + ha:line.3 { + y2 = 52.0mil + thickness = 8.0mil + x1 = 24.0mil + x2 = 24.0mil + y1 = 44.0mil + } + ha:line.4 { + y2 = 25.0mil + thickness = 8.0mil + x1 = 23.0mil + x2 = 23.0mil + y1 = 20.0mil + } + ha:line.5 { + y2 = 52.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 44.0mil + } + ha:line.6 { + y2 = 25.0mil + thickness = 8.0mil + x1 = 1.0mil + x2 = 1.0mil + y1 = 20.0mil + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = -90.000000 + astart = 90.000000 + x = 10.0mil + y = 25.0mil + r = 9.0mil + } + ha:simplearc.8 { + thickness = 8.0mil + adelta = 90.000000 + astart = -90.000000 + x = 10.0mil + y = 44.0mil + r = 10.0mil + } + ha:simplearc.9 { + thickness = 8.0mil + adelta = -90.000000 + astart = 90.000000 + x = 10.0mil + y = 52.0mil + r = 10.0mil + } + ha:simplearc.10 { + thickness = 8.0mil + adelta = 90.000000 + astart = -90.000000 + x = 10.0mil + y = 20.0mil + r = 9.0mil + } + ha:simplearc.11 { + thickness = 8.0mil + adelta = 90.000000 + astart = 90.000000 + x = 14.0mil + y = 25.0mil + r = 9.0mil + } + ha:simplearc.12 { + thickness = 8.0mil + adelta = -90.000000 + astart = 270.000000 + x = 14.0mil + y = 44.0mil + r = 10.0mil + } + ha:simplearc.13 { + thickness = 8.0mil + adelta = 90.000000 + astart = 90.000000 + x = 14.0mil + y = 52.0mil + r = 10.0mil + } + ha:simplearc.14 { + thickness = 8.0mil + adelta = -90.000000 + astart = 270.000000 + x = 14.0mil + y = 20.0mil + r = 9.0mil + } + } + height = 1.574801mm + } + ha:9 { + width = 0.584201mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 10.0mil + x2 = 13.0mil + y1 = 11.0mil + } + ha:line.1 { + y2 = 29.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 21.0mil + } + ha:line.2 { + y2 = 43.0mil + thickness = 8.0mil + x1 = 23.0mil + x2 = 23.0mil + y1 = 21.0mil + } + ha:line.3 { + y2 = 39.0mil + thickness = 8.0mil + x1 = 10.0mil + x2 = 23.0mil + y1 = 39.0mil + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = -90.000000 + astart = 90.000000 + x = 10.0mil + y = 29.0mil + r = 10.0mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = -90.000000 + astart = 270.000000 + x = 13.0mil + y = 21.0mil + r = 10.0mil + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = 90.000000 + astart = 270.000000 + x = 10.0mil + y = 21.0mil + r = 10.0mil + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = -83.659808 + astart = 180.000000 + x = 4.0mil + y = 43.0mil + r = 19.0mil + } + } + height = 1.571849mm + } + ha:< { + width = 0.558801mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 50.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 22.0mil + y1 = 42.0mil + } + ha:line.1 { + y2 = 34.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 22.0mil + y1 = 42.0mil + } + } + height = 1.270001mm + } + ha:> { + width = 0.558801mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 50.0mil + thickness = 8.0mil + x1 = 22.0mil + x2 = 0.0 + y1 = 42.0mil + } + ha:line.1 { + y2 = 34.0mil + thickness = 8.0mil + x1 = 22.0mil + x2 = 0.0 + y1 = 42.0mil + } + } + height = 1.270001mm + } + ha:? { + width = 0.583743mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 20.0mil + thickness = 8.0mil + x1 = 0.583742mm + x2 = 0.583742mm + y1 = 17.0mil + } + ha:line.1 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 12.9819685mil + x2 = 0.405942mm + y1 = 11.0mil + } + ha:line.2 { + y2 = 0.71041mm + thickness = 8.0mil + x1 = 0.384171mm + x2 = 0.48144mm + y1 = 0.791634mm + } + ha:line.3 { + y2 = 38.0mil + thickness = 8.0mil + x1 = 0.304342mm + x2 = 0.304342mm + y1 = 45.0mil + } + ha:line.4 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.304342mm + x2 = 0.304342mm + y1 = 60.0mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = -49.398705 + astart = 0.000000 + x = 0.532942mm + y = 38.0mil + r = 9.0mil + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = 25.641006 + astart = -90.000000 + x = 12.9819685mil + y = 41.0mil + r = 30.0mil + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = -48.366461 + astart = 180.000000 + x = 0.278942mm + y = 19.0mil + r = 12.0mil + } + ha:simplearc.8 { + thickness = 8.0mil + adelta = 90.000000 + astart = 180.000000 + x = 0.405942mm + y = 18.0mil + r = 7.0mil + } + } + height = 1.574801mm + } + ha:@ { + width = 1.143001mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 54.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 19.0mil + } + ha:line.1 { + y2 = 2.0mil + thickness = 8.0mil + x1 = 17.0mil + x2 = 28.0mil + y1 = 2.0mil + } + ha:line.2 { + y2 = 19.0mil + thickness = 8.0mil + x1 = 45.0mil + x2 = 45.0mil + y1 = 47.0mil + } + ha:line.3 { + y2 = 47.0mil + thickness = 8.0mil + x1 = 31.0mil + x2 = 31.0mil + y1 = 19.0mil + } + ha:line.4 { + y2 = 19.0mil + thickness = 8.0mil + x1 = 21.0mil + x2 = 31.0mil + y1 = 19.0mil + } + ha:line.5 { + y2 = 26.0mil + thickness = 8.0mil + x1 = 14.0mil + x2 = 14.0mil + y1 = 47.0mil + } + ha:line.6 { + y2 = 54.0mil + thickness = 8.0mil + x1 = 20.0mil + x2 = 24.0mil + y1 = 54.0mil + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = -90.000000 + astart = 0.000000 + x = 21.0mil + y = 26.0mil + r = 7.0mil + } + ha:simplearc.8 { + thickness = 8.0mil + adelta = 90.000000 + astart = -0.000000 + x = 21.0mil + y = 47.0mil + r = 7.0mil + } + ha:simplearc.9 { + thickness = 8.0mil + adelta = -90.000000 + astart = 180.000000 + x = 24.0mil + y = 47.0mil + r = 7.0mil + } + ha:simplearc.10 { + thickness = 8.0mil + adelta = 180.000000 + astart = 0.000000 + x = 38.0mil + y = 47.0mil + r = 7.0mil + } + ha:simplearc.11 { + thickness = 8.0mil + adelta = 90.000000 + astart = 180.000000 + x = 28.0mil + y = 19.0mil + r = 17.0mil + } + ha:simplearc.12 { + thickness = 8.0mil + adelta = -90.000000 + astart = 0.000000 + x = 17.0mil + y = 19.0mil + r = 17.0mil + } + ha:simplearc.13 { + thickness = 8.0mil + adelta = 96.709837 + astart = -0.000000 + x = 17.0mil + y = 54.0mil + r = 17.0mil + } + } + height = 1.803401mm + } + ha:A { + width = 1.117601mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 0.277876mm + thickness = 8.0mil + x1 = 22.0mil + x2 = 13.0mil + y1 = 0.277876mm + } + ha:line.1 { + y2 = 1.573276mm + thickness = 8.0mil + x1 = 12.0mil + x2 = 0.0 + y1 = 1.573276mm + } + ha:line.2 { + y2 = 1.573276mm + thickness = 8.0mil + x1 = 44.0mil + x2 = 32.0mil + y1 = 1.573276mm + } + ha:line.3 { + y2 = 48.0mil + thickness = 8.0mil + x1 = 0.245533mm + x2 = 0.872066mm + y1 = 48.0mil + } + ha:line.4 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 39.0mil + x2 = 22.0mil + y1 = 62.0mil + } + ha:line.5 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 5.0mil + x2 = 22.0mil + y1 = 62.0mil + } + } + height = 1.574801mm + } + ha:B { + width = 0.863601mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 6.0mil + x2 = 6.0mil + y1 = 1.573276mm + } + ha:line.1 { + y2 = 1.573276mm + thickness = 8.0mil + x1 = 0.06mil + x2 = 0.0 + y1 = 62.0mil + } + ha:line.2 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.06mil + x2 = 21.0mil + y1 = 11.0mil + } + ha:line.3 { + y2 = 34.0mil + thickness = 8.0mil + x1 = 20.0mil + x2 = 6.0mil + y1 = 34.0mil + } + ha:line.4 { + y2 = 51.0mil + thickness = 8.0mil + x1 = 34.0mil + x2 = 34.0mil + y1 = 47.0mil + } + ha:line.5 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 22.0mil + x2 = 0.06mil + y1 = 62.0mil + } + ha:line.6 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.06mil + y1 = 0.277876mm + } + ha:line.7 { + y2 = 1.573276mm + thickness = 8.0mil + x1 = 5.94mil + x2 = 6.0mil + y1 = 62.0mil + } + ha:simplearc.8 { + thickness = 8.0mil + adelta = -90.000000 + astart = -90.000000 + x = 21.0mil + y = 22.0mil + r = 11.0mil + } + ha:simplearc.9 { + thickness = 8.0mil + adelta = -90.000000 + astart = 180.000000 + x = 22.0mil + y = 50.0mil + r = 12.0mil + } + ha:simplearc.10 { + thickness = 8.0mil + adelta = -90.000000 + astart = 180.000000 + x = 20.0mil + y = 22.0mil + r = 12.0mil + } + ha:simplearc.11 { + thickness = 8.0mil + adelta = -90.000000 + astart = -90.000000 + x = 20.0mil + y = 48.0mil + r = 14.0mil + } + } + height = 1.574801mm + } + ha:C { + width = 0.709677mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 27.94mil + x2 = 27.94mil + y1 = 16.94mil + } + ha:line.1 { + y2 = 52.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 21.0mil + } + ha:line.2 { + y2 = 1.573276mm + thickness = 8.0mil + x1 = 10.0mil + x2 = 27.94mil + y1 = 62.0mil + } + ha:line.3 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 10.0mil + x2 = 27.94mil + y1 = 11.0mil + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = -90.000000 + astart = 0.000000 + x = 10.0mil + y = 21.0mil + r = 10.0mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = 90.000000 + astart = -0.000000 + x = 10.0mil + y = 52.0mil + r = 10.0mil + } + } + height = 1.574801mm + } + ha:D { + width = 0.863601mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.06mil + x2 = 24.0mil + y1 = 62.0mil + } + ha:line.1 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 6.0mil + x2 = 6.0mil + y1 = 11.06mil + } + ha:line.2 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.06mil + x2 = 24.0mil + y1 = 11.0mil + } + ha:line.3 { + y2 = 11.06mil + thickness = 8.0mil + x1 = 5.94mil + x2 = 6.0mil + y1 = 11.0mil + } + ha:line.4 { + y2 = 52.0mil + thickness = 8.0mil + x1 = 34.0mil + x2 = 34.0mil + y1 = 21.0mil + } + ha:line.5 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.06mil + y1 = 1.573276mm + } + ha:line.6 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.06mil + y1 = 0.277876mm + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = 90.000000 + astart = 180.000000 + x = 24.0mil + y = 21.0mil + r = 10.0mil + } + ha:simplearc.8 { + thickness = 8.0mil + adelta = -90.000000 + astart = 180.000000 + x = 24.0mil + y = 52.0mil + r = 10.0mil + } + } + height = 1.574801mm + } + ha:E { + width = 0.787401mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 0.862076mm + thickness = 8.0mil + x1 = 25.0mil + x2 = 6.0mil + y1 = 0.862076mm + } + ha:line.1 { + y2 = 0.303276mm + thickness = 8.0mil + x1 = 0.763524mm + x2 = 31.0mil + y1 = 11.0mil + } + ha:line.2 { + y2 = 1.420876mm + thickness = 8.0mil + x1 = 30.94mil + x2 = 31.0mil + y1 = 56.0mil + } + ha:line.3 { + y2 = 56.0mil + thickness = 8.0mil + x1 = 30.94mil + x2 = 30.94mil + y1 = 62.0mil + } + ha:line.4 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 6.0mil + x2 = 6.0mil + y1 = 1.573276mm + } + ha:line.5 { + y2 = 1.573276mm + thickness = 8.0mil + x1 = 0.06mil + x2 = 0.0 + y1 = 62.0mil + } + ha:line.6 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 31.0mil + x2 = 31.0mil + y1 = 16.94mil + } + ha:line.7 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.06mil + x2 = 0.763524mm + y1 = 11.0mil + } + ha:line.8 { + y2 = 1.573276mm + thickness = 8.0mil + x1 = 0.153924mm + x2 = 6.0mil + y1 = 62.0mil + } + ha:line.9 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.06mil + y1 = 0.277876mm + } + ha:line.10 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 30.94mil + x2 = 0.06mil + y1 = 62.0mil + } + ha:line.11 { + y2 = 0.938276mm + thickness = 8.0mil + x1 = 25.0mil + x2 = 25.0mil + y1 = 30.94mil + } + } + height = 1.574801mm + } + ha:F { + width = 0.787401mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 0.862076mm + thickness = 8.0mil + x1 = 25.0mil + x2 = 6.0mil + y1 = 0.862076mm + } + ha:line.1 { + y2 = 16.94mil + thickness = 8.0mil + x1 = 30.94mil + x2 = 31.0mil + y1 = 0.428752mm + } + ha:line.2 { + y2 = 0.428752mm + thickness = 8.0mil + x1 = 30.94mil + x2 = 30.94mil + y1 = 11.0mil + } + ha:line.3 { + y2 = 0.277876mm + thickness = 8.0mil + x1 = 30.94mil + x2 = 31.0mil + y1 = 11.0mil + } + ha:line.4 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.06mil + x2 = 30.94mil + y1 = 11.0mil + } + ha:line.5 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.06mil + y1 = 0.277876mm + } + ha:line.6 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 6.0mil + x2 = 6.0mil + y1 = 62.0mil + } + ha:line.7 { + y2 = 61.88mil + thickness = 8.0mil + x1 = 12.0mil + x2 = 0.0 + y1 = 1.573276mm + } + ha:line.8 { + y2 = 0.938276mm + thickness = 8.0mil + x1 = 25.0mil + x2 = 25.0mil + y1 = 30.94mil + } + } + height = 1.574801mm + } + ha:G { + width = 0.862077mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 0.862076mm + thickness = 8.0mil + x1 = 33.88mil + x2 = 0.862076mm + y1 = 34.0mil + } + ha:line.1 { + y2 = 34.0mil + thickness = 8.0mil + x1 = 22.0mil + x2 = 33.88mil + y1 = 34.0mil + } + ha:line.2 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 27.94mil + x2 = 27.94mil + y1 = 16.94mil + } + ha:line.3 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 28.0mil + x2 = 28.0mil + y1 = 34.0mil + } + ha:line.4 { + y2 = 34.0mil + thickness = 8.0mil + x1 = 21.94mil + x2 = 22.0mil + y1 = 0.862076mm + } + ha:line.5 { + y2 = 52.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 21.0mil + } + ha:line.6 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 10.0mil + x2 = 28.0mil + y1 = 62.0mil + } + ha:line.7 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 10.0mil + x2 = 28.0mil + y1 = 11.0mil + } + ha:simplearc.8 { + thickness = 8.0mil + adelta = -90.000000 + astart = 0.000000 + x = 10.0mil + y = 21.0mil + r = 10.0mil + } + ha:simplearc.9 { + thickness = 8.0mil + adelta = 90.000000 + astart = 0.000000 + x = 10.0mil + y = 52.0mil + r = 10.0mil + } + } + height = 1.574801mm + } + ha:H { + width = 1.041401mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 0.277876mm + thickness = 8.0mil + x1 = 29.0mil + x2 = 41.0mil + y1 = 0.277876mm + } + ha:line.1 { + y2 = 61.88mil + thickness = 8.0mil + x1 = 29.0mil + x2 = 41.0mil + y1 = 61.88mil + } + ha:line.2 { + y2 = 61.88mil + thickness = 8.0mil + x1 = 0.0 + x2 = 12.0mil + y1 = 61.88mil + } + ha:line.3 { + y2 = 0.277876mm + thickness = 8.0mil + x1 = 0.0 + x2 = 12.0mil + y1 = 0.277876mm + } + ha:line.4 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 35.0mil + x2 = 35.0mil + y1 = 62.0mil + } + ha:line.5 { + y2 = 34.0mil + thickness = 8.0mil + x1 = 34.0mil + x2 = 6.0mil + y1 = 34.0mil + } + ha:line.6 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 6.0mil + x2 = 6.0mil + y1 = 62.0mil + } + } + height = 1.574801mm + } + ha:I { + width = 0.609601mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 1.573276mm + thickness = 8.0mil + x1 = 0.0 + x2 = 23.0mil + y1 = 1.573276mm + } + ha:line.1 { + y2 = 0.277876mm + thickness = 8.0mil + x1 = 0.0 + x2 = 24.0mil + y1 = 0.277876mm + } + ha:line.2 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 12.0mil + x2 = 12.0mil + y1 = 62.0mil + } + } + height = 1.574801mm + } + ha:J { + width = 0.941325mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 0.277876mm + thickness = 8.0mil + x1 = 0.103124mm + x2 = 37.06mil + y1 = 0.277876mm + } + ha:line.1 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.534924mm + x2 = 0.534924mm + y1 = 1.243076mm + } + ha:line.2 { + y2 = 1.573276mm + thickness = 8.0mil + x1 = 0.179324mm + x2 = 0.06mil + y1 = 1.573276mm + } + ha:line.3 { + y2 = 56.0mil + thickness = 8.0mil + x1 = 0.06mil + x2 = 0.0 + y1 = 1.573276mm + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = 90.000000 + astart = 90.000000 + x = 8.06mil + y = 1.243076mm + r = 13.0mil + } + } + height = 1.573277mm + } + ha:K { + width = 0.990601mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 1.573276mm + thickness = 8.0mil + x1 = 0.888145mm + x2 = 39.0mil + y1 = 1.573276mm + } + ha:line.1 { + y2 = 10.88mil + thickness = 8.0mil + x1 = 27.0mil + x2 = 39.0mil + y1 = 10.88mil + } + ha:line.2 { + y2 = 1.573276mm + thickness = 8.0mil + x1 = 0.0 + x2 = 12.0mil + y1 = 1.573276mm + } + ha:line.3 { + y2 = 0.277876mm + thickness = 8.0mil + x1 = 0.0 + x2 = 12.0mil + y1 = 0.277876mm + } + ha:line.4 { + y2 = 0.764963mm + thickness = 8.0mil + x1 = 35.0mil + x2 = 0.434763mm + y1 = 62.0mil + } + ha:line.5 { + y2 = 42.0mil + thickness = 8.0mil + x1 = 35.0mil + x2 = 6.0mil + y1 = 11.0mil + } + ha:line.6 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 6.0mil + x2 = 6.0mil + y1 = 62.0mil + } + } + height = 1.574801mm + } + ha:L { + width = 0.787401mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 31.0mil + x2 = 31.0mil + y1 = 1.420876mm + } + ha:line.1 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.06mil + x2 = 31.0mil + y1 = 62.0mil + } + ha:line.2 { + y2 = 0.277876mm + thickness = 8.0mil + x1 = 0.0 + x2 = 12.0mil + y1 = 0.277876mm + } + ha:line.3 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.06mil + y1 = 1.573276mm + } + ha:line.4 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 6.0mil + x2 = 6.0mil + y1 = 62.0mil + } + } + height = 1.574801mm + } + ha:M { + width = 1.168401mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 0.277876mm + thickness = 8.0mil + x1 = 1.166876mm + x2 = 46.0mil + y1 = 11.0mil + } + ha:line.1 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 40.0mil + x2 = 1.166876mm + y1 = 11.0mil + } + ha:line.2 { + y2 = 0.278439mm + thickness = 8.0mil + x1 = 0.151273mm + x2 = 0.151836mm + y1 = 0.277876mm + } + ha:line.3 { + y2 = 0.277876mm + thickness = 8.0mil + x1 = 0.0 + x2 = 0.151273mm + y1 = 0.277876mm + } + ha:line.4 { + y2 = 61.88mil + thickness = 8.0mil + x1 = 34.0mil + x2 = 46.0mil + y1 = 61.88mil + } + ha:line.5 { + y2 = 1.573276mm + thickness = 8.0mil + x1 = 0.0 + x2 = 12.0mil + y1 = 1.573276mm + } + ha:line.6 { + y2 = 40.0mil + thickness = 8.0mil + x1 = 40.0mil + x2 = 23.0mil + y1 = 11.0mil + } + ha:line.7 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 40.0mil + x2 = 40.0mil + y1 = 11.0mil + } + ha:line.8 { + y2 = 40.0mil + thickness = 8.0mil + x1 = 6.0mil + x2 = 23.0mil + y1 = 11.0mil + } + ha:line.9 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 6.0mil + x2 = 6.0mil + y1 = 62.0mil + } + } + height = 1.574801mm + } + ha:&2f { + width = 0.558801mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 22.0mil + x2 = 0.0 + y1 = 11.0mil + } + } + height = 1.574801mm + } + ha:&3a { + width = 0.001um + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 54.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 56.0mil + } + ha:line.1 { + y2 = 31.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 33.0mil + } + } + height = 1.422401mm + } + ha:&3b { + width = 0.076201mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 33.0mil + thickness = 8.0mil + x1 = 3.0mil + x2 = 3.0mil + y1 = 35.0mil + } + ha:line.1 { + y2 = 56.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 3.0mil + y1 = 67.0mil + } + } + height = 1.701801mm + } + ha:&3d { + width = 0.584201mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 51.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 23.0mil + y1 = 51.0mil + } + ha:line.1 { + y2 = 34.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 23.0mil + y1 = 34.0mil + } + } + height = 1.295401mm + } + ha:O { + width = 0.812801mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 23.0mil + thickness = 8.0mil + x1 = 32.0mil + x2 = 32.0mil + y1 = 50.0mil + } + ha:line.1 { + y2 = 50.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 23.0mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 12.0mil + x2 = 20.0mil + y1 = 62.0mil + } + ha:line.3 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 12.0mil + x2 = 20.0mil + y1 = 11.0mil + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = -90.000000 + astart = 0.000000 + x = 12.0mil + y = 23.0mil + r = 12.0mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = 90.000000 + astart = -0.000000 + x = 12.0mil + y = 50.0mil + r = 12.0mil + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = -90.000000 + astart = 180.000000 + x = 20.0mil + y = 50.0mil + r = 12.0mil + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = 90.000000 + astart = -180.000000 + x = 20.0mil + y = 23.0mil + r = 12.0mil + } + } + height = 1.574801mm + } + ha:P { + width = 0.863601mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 0.277876mm + thickness = 8.0mil + x1 = 0.06mil + x2 = 0.0 + y1 = 11.0mil + } + ha:line.1 { + y2 = 27.0mil + thickness = 8.0mil + x1 = 34.0mil + x2 = 34.0mil + y1 = 23.0mil + } + ha:line.2 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 22.0mil + x2 = 0.06mil + y1 = 11.0mil + } + ha:line.3 { + y2 = 39.0mil + thickness = 8.0mil + x1 = 22.0mil + x2 = 6.0mil + y1 = 39.0mil + } + ha:line.4 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 6.0mil + x2 = 6.0mil + y1 = 62.0mil + } + ha:line.5 { + y2 = 61.88mil + thickness = 8.0mil + x1 = 12.0mil + x2 = 0.0 + y1 = 1.573276mm + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = -90.000000 + astart = 180.000000 + x = 22.0mil + y = 27.0mil + r = 12.0mil + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = 90.000000 + astart = -180.000000 + x = 22.0mil + y = 23.0mil + r = 12.0mil + } + } + height = 1.574801mm + } + ha:N { + width = 1.041401mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 61.88mil + thickness = 8.0mil + x1 = 0.0 + x2 = 12.0mil + y1 = 61.88mil + } + ha:line.1 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 35.06mil + x2 = 35.0mil + y1 = 0.277876mm + } + ha:line.2 { + y2 = 0.277876mm + thickness = 8.0mil + x1 = 41.0mil + x2 = 35.06mil + y1 = 0.277876mm + } + ha:line.3 { + y2 = 0.277876mm + thickness = 8.0mil + x1 = 0.002009mm + x2 = 0.0 + y1 = 0.275867mm + } + ha:line.4 { + y2 = 0.275867mm + thickness = 8.0mil + x1 = 0.150391mm + x2 = 0.002009mm + y1 = 0.275867mm + } + ha:line.5 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 6.0mil + x2 = 35.0mil + y1 = 11.0mil + } + ha:line.6 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 35.0mil + x2 = 35.0mil + y1 = 62.0mil + } + ha:line.7 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 6.0mil + x2 = 6.0mil + y1 = 62.0mil + } + } + height = 1.574801mm + } + ha:R { + width = 1.016001mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 1.573276mm + thickness = 8.0mil + x1 = 39.945mil + x2 = 40.0mil + y1 = 1.571879mm + } + ha:line.1 { + y2 = 1.571879mm + thickness = 8.0mil + x1 = 33.945mil + x2 = 39.945mil + y1 = 1.571879mm + } + ha:line.2 { + y2 = 1.573276mm + thickness = 8.0mil + x1 = 0.0 + x2 = 12.0mil + y1 = 1.573276mm + } + ha:line.3 { + y2 = 0.277876mm + thickness = 8.0mil + x1 = 0.06mil + x2 = 0.0 + y1 = 11.0mil + } + ha:line.4 { + y2 = 39.0mil + thickness = 8.0mil + x1 = 34.0mil + x2 = 23.0mil + y1 = 62.0mil + } + ha:line.5 { + y2 = 27.0mil + thickness = 8.0mil + x1 = 34.0mil + x2 = 34.0mil + y1 = 23.0mil + } + ha:line.6 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 22.0mil + x2 = 0.06mil + y1 = 11.0mil + } + ha:line.7 { + y2 = 39.0mil + thickness = 8.0mil + x1 = 22.0mil + x2 = 6.0mil + y1 = 39.0mil + } + ha:line.8 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 6.0mil + x2 = 6.0mil + y1 = 62.0mil + } + ha:simplearc.9 { + thickness = 8.0mil + adelta = -90.000000 + astart = 180.000000 + x = 22.0mil + y = 27.0mil + r = 12.0mil + } + ha:simplearc.10 { + thickness = 8.0mil + adelta = 90.000000 + astart = -180.000000 + x = 22.0mil + y = 23.0mil + r = 12.0mil + } + } + height = 1.574801mm + } + ha:S { + width = 0.738125mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 1.573276mm + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 1.370076mm + } + ha:line.1 { + y2 = 18.94mil + thickness = 8.0mil + x1 = 29.0mil + x2 = 29.0mil + y1 = 0.277876mm + } + ha:line.2 { + y2 = 52.0mil + thickness = 8.0mil + x1 = 0.738124mm + x2 = 0.738124mm + y1 = 54.0mil + } + ha:line.3 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 11.06mil + x2 = 15.06mil + y1 = 11.0mil + } + ha:line.4 { + y2 = 0.845249mm + thickness = 8.0mil + x1 = 0.5852mm + x2 = 0.202161mm + y1 = 1.042223mm + } + ha:line.5 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 15.06mil + x2 = 0.534924mm + y1 = 62.0mil + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = -41.185925 + astart = 90.000000 + x = 15.06mil + y = 40.0mil + r = 22.0mil + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = -30.068583 + astart = 270.000000 + x = 15.06mil + y = 33.0mil + r = 22.0mil + } + ha:simplearc.8 { + thickness = 8.0mil + adelta = -90.000000 + astart = 0.000000 + x = 11.06mil + y = 22.0mil + r = 11.0mil + } + ha:simplearc.9 { + thickness = 8.0mil + adelta = 70.016893 + astart = 0.000000 + x = 12.06mil + y = 22.0mil + r = 12.0mil + } + ha:simplearc.10 { + thickness = 8.0mil + adelta = 90.000000 + astart = 90.000000 + x = 0.534924mm + y = 54.0mil + r = 8.0mil + } + ha:simplearc.11 { + thickness = 8.0mil + adelta = 57.528808 + astart = 180.000000 + x = 0.407924mm + y = 52.0mil + r = 13.0mil + } + } + height = 1.574801mm + } + ha:Q { + width = 0.965201mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 26.0mil + x2 = 38.0mil + y1 = 51.0mil + } + ha:line.1 { + y2 = 23.0mil + thickness = 8.0mil + x1 = 32.0mil + x2 = 32.0mil + y1 = 50.0mil + } + ha:line.2 { + y2 = 50.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 23.0mil + } + ha:line.3 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 12.0mil + x2 = 20.0mil + y1 = 62.0mil + } + ha:line.4 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 12.0mil + x2 = 20.0mil + y1 = 11.0mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = -90.000000 + astart = 0.000000 + x = 12.0mil + y = 23.0mil + r = 12.0mil + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = 90.000000 + astart = -0.000000 + x = 12.0mil + y = 50.0mil + r = 12.0mil + } + ha:simplearc.7 { + thickness = 8.0mil + adelta = -90.000000 + astart = 180.000000 + x = 20.0mil + y = 50.0mil + r = 12.0mil + } + ha:simplearc.8 { + thickness = 8.0mil + adelta = 90.000000 + astart = -180.000000 + x = 20.0mil + y = 23.0mil + r = 12.0mil + } + } + height = 1.574801mm + } + ha:U { + width = 1.041401mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 0.277876mm + thickness = 8.0mil + x1 = 29.0mil + x2 = 41.0mil + y1 = 0.277876mm + } + ha:line.1 { + y2 = 0.277876mm + thickness = 8.0mil + x1 = 0.0 + x2 = 12.0mil + y1 = 0.277876mm + } + ha:line.2 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 35.06mil + x2 = 35.06mil + y1 = 49.0mil + } + ha:line.3 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.153924mm + x2 = 0.153924mm + y1 = 49.0mil + } + ha:line.4 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.458724mm + x2 = 0.560324mm + y1 = 62.0mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = 90.000000 + astart = 0.000000 + x = 0.484124mm + y = 49.0mil + r = 13.0mil + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = -90.000000 + astart = 180.000000 + x = 0.560324mm + y = 49.0mil + r = 13.0mil + } + } + height = 1.574801mm + } + ha:V { + width = 1.168401mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 10.88mil + thickness = 8.0mil + x1 = 46.0mil + x2 = 34.0mil + y1 = 10.88mil + } + ha:line.1 { + y2 = 10.88mil + thickness = 8.0mil + x1 = 12.0mil + x2 = 0.0 + y1 = 10.88mil + } + ha:line.2 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 41.0mil + x2 = 23.0mil + y1 = 11.0mil + } + ha:line.3 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 5.0mil + x2 = 23.0mil + y1 = 11.0mil + } + } + height = 1.574801mm + } + ha:T { + width = 0.838201mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 0.277876mm + thickness = 8.0mil + x1 = 0.836676mm + x2 = 33.0mil + y1 = 11.0mil + } + ha:line.1 { + y2 = 16.94mil + thickness = 8.0mil + x1 = 33.0mil + x2 = 33.0mil + y1 = 11.0mil + } + ha:line.2 { + y2 = 16.94mil + thickness = 8.0mil + x1 = 0.06mil + x2 = 0.0 + y1 = 0.428752mm + } + ha:line.3 { + y2 = 0.428752mm + thickness = 8.0mil + x1 = 0.06mil + x2 = 0.06mil + y1 = 11.0mil + } + ha:line.4 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.836676mm + y1 = 11.0mil + } + ha:line.5 { + y2 = 11.0mil + thickness = 8.0mil + x1 = 17.0mil + x2 = 17.0mil + y1 = 62.0mil + } + ha:line.6 { + y2 = 1.573276mm + thickness = 8.0mil + x1 = 24.0mil + x2 = 10.0mil + y1 = 1.573276mm + } + } + height = 1.574801mm + } + ha:X { + width = 1.092201mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 61.88mil + thickness = 8.0mil + x1 = 43.0mil + x2 = 31.0mil + y1 = 61.88mil + } + ha:line.1 { + y2 = 10.88mil + thickness = 8.0mil + x1 = 43.0mil + x2 = 31.0mil + y1 = 10.88mil + } + ha:line.2 { + y2 = 61.88mil + thickness = 8.0mil + x1 = 12.0mil + x2 = 0.0 + y1 = 61.88mil + } + ha:line.3 { + y2 = 10.88mil + thickness = 8.0mil + x1 = 12.0mil + x2 = 0.0 + y1 = 10.88mil + } + ha:line.4 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 39.0mil + x2 = 4.0mil + y1 = 11.0mil + } + ha:line.5 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 4.0mil + x2 = 39.0mil + y1 = 11.0mil + } + } + height = 1.574801mm + } + ha:Y { + width = 1.066801mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 1.573276mm + thickness = 8.0mil + x1 = 28.0mil + x2 = 14.0mil + y1 = 1.573276mm + } + ha:line.1 { + y2 = 10.82mil + thickness = 8.0mil + x1 = 12.0mil + x2 = 0.0 + y1 = 10.82mil + } + ha:line.2 { + y2 = 10.82mil + thickness = 8.0mil + x1 = 42.0mil + x2 = 30.0mil + y1 = 10.82mil + } + ha:line.3 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 21.0mil + x2 = 21.0mil + y1 = 35.0mil + } + ha:line.4 { + y2 = 35.0mil + thickness = 8.0mil + x1 = 38.0mil + x2 = 21.0mil + y1 = 11.0mil + } + ha:line.5 { + y2 = 35.0mil + thickness = 8.0mil + x1 = 4.0mil + x2 = 21.0mil + y1 = 11.0mil + } + } + height = 1.574801mm + } + ha:W { + width = 1.371601mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 10.88mil + thickness = 8.0mil + x1 = 54.0mil + x2 = 42.0mil + y1 = 10.88mil + } + ha:line.1 { + y2 = 10.88mil + thickness = 8.0mil + x1 = 12.0mil + x2 = 0.0 + y1 = 10.88mil + } + ha:line.2 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 38.0mil + x2 = 27.0mil + y1 = 62.0mil + } + ha:line.3 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 49.0mil + x2 = 38.0mil + y1 = 11.0mil + } + ha:line.4 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 16.0mil + x2 = 27.0mil + y1 = 62.0mil + } + ha:line.5 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 5.0mil + x2 = 16.0mil + y1 = 11.0mil + } + } + height = 1.574801mm + } + ha:[ { + width = 0.152401mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 5.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 6.0mil + y1 = 5.0mil + } + ha:line.1 { + y2 = 68.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 6.0mil + y1 = 68.0mil + } + ha:line.2 { + y2 = 68.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 5.0mil + } + } + height = 1.727201mm + } + ha:^ { + width = 0.406401mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 0.0 + thickness = 8.0mil + x1 = 16.0mil + x2 = 8.0mil + y1 = 9.0mil + } + ha:line.1 { + y2 = 0.0 + thickness = 8.0mil + x1 = 0.0 + x2 = 8.0mil + y1 = 9.0mil + } + } + height = 0.228601mm + } + ha:Z { + width = 0.787401mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 1.420876mm + thickness = 8.0mil + x1 = 31.0mil + x2 = 31.0mil + y1 = 62.0mil + } + ha:line.1 { + y2 = 16.94mil + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 11.0mil + } + ha:line.2 { + y2 = 0.277876mm + thickness = 8.0mil + x1 = 0.0 + x2 = 31.0mil + y1 = 62.0mil + } + ha:line.3 { + y2 = 62.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 31.0mil + y1 = 62.0mil + } + ha:line.4 { + y2 = 0.277876mm + thickness = 8.0mil + x1 = 0.0 + x2 = 31.0mil + y1 = 11.0mil + } + } + height = 1.574801mm + } + ha:` { + width = 0.279401mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 10.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 11.0mil + y1 = 2.0mil + } + } + height = 0.254001mm + } + ha:_ { + width = 0.609601mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 68.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 24.0mil + y1 = 68.0mil + } + } + height = 1.727201mm + } + } + cell_width = 1.371601mm + cell_height = 2.032001mm + } +} Index: tags/1.0.5/library/Makefile =================================================================== --- tags/1.0.5/library/Makefile (nonexistent) +++ tags/1.0.5/library/Makefile (revision 10414) @@ -0,0 +1,49 @@ +# This Makefile is a plain old hand written one; all configuration settings +# are included from ../Makefile.conf which is scconfig generated + +ROOT=.. + +all: + +# NOTE: this rule is _not_ called from linstall +install_: + $(MKDIR) "$(DATADIR)/symbol" "$(DATADIR)/hlibrary" "$(DATADIR)/devmap" "$(DATADIR)/spice" + $(CPC) "`pwd`/devmap"/* "$(DATADIR)/devmap" + $(CPC) "`pwd`/spice"/* "$(DATADIR)/spice" + $(CPC) "`pwd`/symbol"/common_sym.awk "$(DATADIR)/symbol"/common_sym.awk + $(CPC) "`pwd`/symbol"/LICENSE "$(DATADIR)/symbol"/LICENSE + $(MKDIR) "$(DATADIR)/symbol/analog" + $(CPC) "`pwd`/symbol/analog"/* "$(DATADIR)/symbol/analog" + $(MKDIR) "$(DATADIR)/symbol/diode" + $(CPC) "`pwd`/symbol/diode"/* "$(DATADIR)/symbol/diode" + $(MKDIR) "$(DATADIR)/symbol/mech" + $(CPC) "`pwd`/symbol/mech"/* "$(DATADIR)/symbol/mech" + $(MKDIR) "$(DATADIR)/symbol/misc" + $(CPC) "`pwd`/symbol/misc"/* "$(DATADIR)/symbol/misc" + $(MKDIR) "$(DATADIR)/symbol/passive" + $(CPC) "`pwd`/symbol/passive"/* "$(DATADIR)/symbol/passive" + $(MKDIR) "$(DATADIR)/symbol/power" + $(CPC) "`pwd`/symbol/power"/* "$(DATADIR)/symbol/power" + $(MKDIR) "$(DATADIR)/symbol/transistor" + $(CPC) "`pwd`/symbol/transistor"/* "$(DATADIR)/symbol/transistor" + +install: + $(MAKE) install_ CPC="$(CP)" + +# hack: pcb's chdir() based approach gets fooled on symlinks because of "cd .." +# returns to the wrong dir - rather symlink the whole dir +linstall: + $(MAKE) uninstall + $(MKDIR) "$(DATADIR)" + $(LN) "`pwd`/symbol" "$(DATADIR)/symbol" + $(LN) "`pwd`/hlibrary" "$(DATADIR)/hlibrary" + $(LN) "`pwd`/devmap" "$(DATADIR)/devmap" + $(LN) "`pwd`/spice" "$(DATADIR)/spice" + +uninstall: + $(RM) "$(DATADIR)/symbol" "$(DATADIR)/devmap" "$(DATADIR)/spice" + +clean: + +include $(ROOT)/Makefile.conf + Index: tags/1.0.5/library/devmap/1n4148_minimelf.devmap =================================================================== --- tags/1.0.5/library/devmap/1n4148_minimelf.devmap (nonexistent) +++ tags/1.0.5/library/devmap/1n4148_minimelf.devmap (revision 10414) @@ -0,0 +1,10 @@ +ha:std_devmap.v1 { + ha:comp_attribs { + footprint=minimelf + device=1n4148 + li:portmap={ + {C->pcb/pinnum=1} + {A->pcb/pinnum=2} + } + } +} Index: tags/1.0.5/library/devmap/1n5817_do41.devmap =================================================================== --- tags/1.0.5/library/devmap/1n5817_do41.devmap (nonexistent) +++ tags/1.0.5/library/devmap/1n5817_do41.devmap (revision 10414) @@ -0,0 +1,10 @@ +ha:std_devmap.v1 { + ha:comp_attribs { + footprint={alf(400mil, type=normal)} + device=1n5817 + li:portmap={ + {C->pcb/pinnum=1} + {A->pcb/pinnum=2} + } + } +} Index: tags/1.0.5/library/devmap/2n3904_to92.devmap =================================================================== --- tags/1.0.5/library/devmap/2n3904_to92.devmap (nonexistent) +++ tags/1.0.5/library/devmap/2n3904_to92.devmap (revision 10414) @@ -0,0 +1,11 @@ +ha:std_devmap.v1 { + ha:comp_attribs { + footprint=TO92 + device=2n3904 + li:portmap={ + {E->pcb/pinnum=1} + {B->pcb/pinnum=2} + {C->pcb/pinnum=3} + } + } +} Index: tags/1.0.5/library/devmap/2n7002_sot23.devmap =================================================================== --- tags/1.0.5/library/devmap/2n7002_sot23.devmap (nonexistent) +++ tags/1.0.5/library/devmap/2n7002_sot23.devmap (revision 10414) @@ -0,0 +1,11 @@ +ha:std_devmap.v1 { + ha:comp_attribs { + footprint=SOT23 + device=2n7002 + li:portmap={ + {G->pcb/pinnum=1} + {S->pcb/pinnum=2} + {D->pcb/pinnum=3} + } + } +} Index: tags/1.0.5/library/devmap/bc817_sot23.devmap =================================================================== --- tags/1.0.5/library/devmap/bc817_sot23.devmap (nonexistent) +++ tags/1.0.5/library/devmap/bc817_sot23.devmap (revision 10414) @@ -0,0 +1,11 @@ +ha:std_devmap.v1 { + ha:comp_attribs { + footprint=SOT23 + device=bc817 + li:portmap={ + {B->pcb/pinnum=1} + {E->pcb/pinnum=2} + {C->pcb/pinnum=3} + } + } +} Index: tags/1.0.5/library/devmap/bc857_sot23.devmap =================================================================== --- tags/1.0.5/library/devmap/bc857_sot23.devmap (nonexistent) +++ tags/1.0.5/library/devmap/bc857_sot23.devmap (revision 10414) @@ -0,0 +1,11 @@ +ha:std_devmap.v1 { + ha:comp_attribs { + footprint=SOT23 + device=bc857 + li:portmap={ + {B->pcb/pinnum=1} + {E->pcb/pinnum=2} + {C->pcb/pinnum=3} + } + } +} Index: tags/1.0.5/library/devmap/bc857bs_sot363.devmap =================================================================== --- tags/1.0.5/library/devmap/bc857bs_sot363.devmap (nonexistent) +++ tags/1.0.5/library/devmap/bc857bs_sot363.devmap (revision 10414) @@ -0,0 +1,14 @@ +ha:std_devmap.v1 { + ha:comp_attribs { + footprint=SOT23 + device=bc857bs + li:portmap={ + {1/B->pcb/pinnum=2} + {1/E->pcb/pinnum=1} + {1/C->pcb/pinnum=6} + {2/B->pcb/pinnum=5} + {2/E->pcb/pinnum=4} + {2/C->pcb/pinnum=3} + } + } +} Index: tags/1.0.5/library/devmap/bss84_sot23.devmap =================================================================== --- tags/1.0.5/library/devmap/bss84_sot23.devmap (nonexistent) +++ tags/1.0.5/library/devmap/bss84_sot23.devmap (revision 10414) @@ -0,0 +1,11 @@ +ha:std_devmap.v1 { + ha:comp_attribs { + footprint=SOT23 + device=bss84 + li:portmap={ + {G->pcb/pinnum=1} + {S->pcb/pinnum=2} + {D->pcb/pinnum=3} + } + } +} Index: tags/1.0.5/library/devmap/bzx55c3v3_do35.devmap =================================================================== --- tags/1.0.5/library/devmap/bzx55c3v3_do35.devmap (nonexistent) +++ tags/1.0.5/library/devmap/bzx55c3v3_do35.devmap (revision 10414) @@ -0,0 +1,10 @@ +ha:std_devmap.v1 { + ha:comp_attribs { + footprint={alf(400mil, type=schottky)} + device=bzx55c3v3 + li:portmap={ + {C->pcb/pinnum=1} + {A->pcb/pinnum=2} + } + } +} Index: tags/1.0.5/library/devmap/irf510_to220.devmap =================================================================== --- tags/1.0.5/library/devmap/irf510_to220.devmap (nonexistent) +++ tags/1.0.5/library/devmap/irf510_to220.devmap (revision 10414) @@ -0,0 +1,11 @@ +ha:std_devmap.v1 { + ha:comp_attribs { + footprint=TO220 + device=irf510 + li:portmap={ + {G->pcb/pinnum=1} + {S->pcb/pinnum=3} + {D->pcb/pinnum=2} + } + } +} Index: tags/1.0.5/library/devmap/led5.devmap =================================================================== --- tags/1.0.5/library/devmap/led5.devmap (nonexistent) +++ tags/1.0.5/library/devmap/led5.devmap (revision 10414) @@ -0,0 +1,10 @@ +ha:std_devmap.v1 { + ha:comp_attribs { + footprint=LED5 + device=led5 + li:portmap={ + {C->pcb/pinnum=1} + {A->pcb/pinnum=2} + } + } +} Index: tags/1.0.5/library/devmap/lm358_so8.devmap =================================================================== --- tags/1.0.5/library/devmap/lm358_so8.devmap (nonexistent) +++ tags/1.0.5/library/devmap/lm358_so8.devmap (revision 10414) @@ -0,0 +1,18 @@ +ha:std_devmap.v1 { + ha:comp_attribs { + footprint=so(8) + device=lm358 + li:portmap={ + {1/in- -> pcb/pinnum=2} + {1/in+ -> pcb/pinnum=3} + {1/out -> pcb/pinnum=1} + {1/V+ -> pcb/pinnum=8} + {1/V- -> pcb/pinnum=4} + {2/in- -> pcb/pinnum=6} + {2/in+ -> pcb/pinnum=5} + {2/out -> pcb/pinnum=7} + {2/V+ -> pcb/pinnum=8} + {2/V- -> pcb/pinnum=4} + } + } +} Index: tags/1.0.5/library/devmap/lm393_so8.devmap =================================================================== --- tags/1.0.5/library/devmap/lm393_so8.devmap (nonexistent) +++ tags/1.0.5/library/devmap/lm393_so8.devmap (revision 10414) @@ -0,0 +1,18 @@ +ha:std_devmap.v1 { + ha:comp_attribs { + footprint=so(8) + device=lm393 + li:portmap={ + {1/in- -> pcb/pinnum=2} + {1/in+ -> pcb/pinnum=3} + {1/out -> pcb/pinnum=1} + {1/V+ -> pcb/pinnum=8} + {1/V- -> pcb/pinnum=4} + {2/in- -> pcb/pinnum=6} + {2/in+ -> pcb/pinnum=5} + {2/out -> pcb/pinnum=7} + {2/V+ -> pcb/pinnum=8} + {2/V- -> pcb/pinnum=4} + } + } +} Index: tags/1.0.5/library/devmap/pol_rcy.devmap =================================================================== --- tags/1.0.5/library/devmap/pol_rcy.devmap (nonexistent) +++ tags/1.0.5/library/devmap/pol_rcy.devmap (revision 10414) @@ -0,0 +1,8 @@ +ha:std_devmap.v1 { + ha:comp_attribs { + li:portmap={ + {P->pcb/pinnum=1} + {N->pcb/pinnum=2} + } + } +} Index: tags/1.0.5/library/spice/bc817.prm =================================================================== --- tags/1.0.5/library/spice/bc817.prm (nonexistent) +++ tags/1.0.5/library/spice/bc817.prm (revision 10414) @@ -0,0 +1,12 @@ +* (C) 2023 Tibor 'Igor2' Palinkas +* License: CC0 (no rights reserved): https://creativecommons.org/publicdomain/zero/1.0/ +* Source: based on Vishay's datasheet: https://archive.org/details/bc817_spice_vishay +* +.model BC817 npn ( ++ IS=2.43485e-13 VAF=10 BF=270 IKF=1.12487 NE=1.84302 ISE=7.17747e-12 ++ IKR=0.149889 ISC=2.42047e-12 NC=3.94859 NR=1.04566 BR=2.51332 RC=0.407107 ++ CJC=5.516e-11 FC=0.8 MJC=0.529364 VJC=0.4 CJE=5.10473e-11 MJE=0.412728 ++ VJE=0.561234 TF=7.1424e-10 ITF=0.175457 VTF=1.86025 XTF=1.09929 RB=6.50128 ++ IRB=0.1 RBM=0.1 RE=0.0814215 TR=1e-07 ++ ) + Index: tags/1.0.5/library/spice/bridge_adc_ttl.prm =================================================================== --- tags/1.0.5/library/spice/bridge_adc_ttl.prm (nonexistent) +++ tags/1.0.5/library/spice/bridge_adc_ttl.prm (revision 10414) @@ -0,0 +1,7 @@ +* (C) 2023 Tibor 'Igor2' Palinkas +* License: CC0 (no rights reserved): https://creativecommons.org/publicdomain/zero/1.0/ +* +* source: https://www.allaboutcircuits.com/textbook/digital/chpt-3/logic-signal-voltage-levels/ + +.model bridge_adc_ttl adc_bridge ++ (in_low=0.8 in_high=2.0 rise_delay=1.0e-12 fall_delay=1.0e-12) Index: tags/1.0.5/library/spice/bridge_dac_ttl.prm =================================================================== --- tags/1.0.5/library/spice/bridge_dac_ttl.prm (nonexistent) +++ tags/1.0.5/library/spice/bridge_dac_ttl.prm (revision 10414) @@ -0,0 +1,8 @@ +* (C) 2023 Tibor 'Igor2' Palinkas +* License: CC0 (no rights reserved): https://creativecommons.org/publicdomain/zero/1.0/ +* +* source: https://www.allaboutcircuits.com/textbook/digital/chpt-3/logic-signal-voltage-levels/ + +.model bridge_dac_ttl dac_bridge( ++ out_low = 0 out_high = 5 out_undef = 1.4 ++ input_load = 5.0e-12 t_rise = 50e-9 t_fall = 20e-9) Index: tags/1.0.5/library/spice/lm358.mod =================================================================== --- tags/1.0.5/library/spice/lm358.mod (nonexistent) +++ tags/1.0.5/library/spice/lm358.mod (revision 10414) @@ -0,0 +1,63 @@ +* lm358 - low power opamp model (single slot) +* +* (C) 2023 Tibor 'Igor2' Palinkas +* License: CC0 (no rights reserved): https://creativecommons.org/publicdomain/zero/1.0/ +* Source: from ST's datasheet: https://archive.org/details/st-ts321 +* (st321 is reasonably close to lm358 for simple simulation cases; see +* warnings on page 7) +* +* +** CONNECTIONS: +* 1 inverting input +* 2 non-inverting INPUT +* 3 output +* 4 positive power supply +* 5 negative power supply +.SUBCKT LM358 1 2 3 4 5 + +.MODEL MDTH D IS=1E-8 KF=3.104131E-15 CJO=10F + +* INPUT STAGE +CIP 2 5 1.000000E-12 +CIN 1 5 1.000000E-12 +EIP 10 5 2 5 1 +EIN 16 5 1 5 1 +RIP 10 11 2.600000E+01 +RIN 15 16 2.600000E+01 +RIS 11 15 2.003862E+02 +DIP 11 12 MDTH 400E-12 +DIN 15 14 MDTH 400E-12 +VOFP 12 13 DC 0 +VOFN 13 14 DC 0 +IPOL 13 5 1.000000E-05 +CPS 11 15 3.783376E-09 +DINN 17 13 MDTH 400E-12 +VIN 17 5 0.000000e+00 +DINR 15 18 MDTH 400E-12 +VIP 4 18 2.000000E+00 +FCP 4 5 VOFP 3.400000E+01 +FCN 5 4 VOFN 3.400000E+01 +FIBP 2 5 VOFN 2.000000E-03 +FIBN 5 1 VOFP 2.000000E-03 + +* AMPLIFYING STAGE +FIP 5 19 VOFP 3.600000E+02 +FIN 5 19 VOFN 3.600000E+02 +RG1 19 5 3.652997E+06 +RG2 19 4 3.652997E+06 +CC 19 5 6.000000E-09 +DOPM 19 22 MDTH 400E-12 +DONM 21 19 MDTH 400E-12 +HOPM 22 28 VOUT 7.500000E+03 +VIPM 28 4 1.500000E+02 +HONM 21 27 VOUT 7.500000E+03 +VINM 5 27 1.500000E+02 +EOUT 26 23 19 5 1 +VOUT 23 5 0 +ROUT 26 3 20 +COUT 3 5 1.000000E-12 +DOP 19 25 MDTH 400E-12 +VOP 4 25 2.242230E+00 +DON 24 19 MDTH 400E-12 +VON 24 5 7.922301E-01 +.ENDS Index: tags/1.0.5/library/src/symbol/power/ldo.bs =================================================================== --- tags/1.0.5/library/src/symbol/power/ldo.bs (nonexistent) +++ tags/1.0.5/library/src/symbol/power/ldo.bs (revision 10414) @@ -0,0 +1,27 @@ +refdes U?? +attr_invis -sym-source sch-rnd default symbol lib +attr_invis -sym-copyright (C) 2022 Tibor 'Igor2' Palinkas +attr_invis -sym-license-dist GPLv2+ +attr_invis -sym-license-use Public Domain + +pinalign bottom center +pinalign left center +pinalign right center + +shape box +begin pin in + num 1 + loc left +end pin + +begin pin gnd + num 2 + loc bottom +end pin + +begin pin out + num 3 + loc right +end pin + + Index: tags/1.0.5/library/symbol/LICENSE =================================================================== --- tags/1.0.5/library/symbol/LICENSE (nonexistent) +++ tags/1.0.5/library/symbol/LICENSE (revision 10414) @@ -0,0 +1,29 @@ +Default sch-rnd symbol licensing policy +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Symbol files normally should contain three attributes: + + - sym-copyright: free form text with the copyright holder's name + and year of the copyright + + - sym-license-dist: generic symbol file distribution license + + - sym-license-use: distribution license in the special case the symbol + is used in a schematics sheet and distributed in/with + the schematics sheet for the specific purpose of + making the schematic sheet work + +In practice this means if you use a symbol by placing it in a schematics, +and distribute the schematics with all the symbols it uses, sym-license-use +applies. However if you are distributing a library of symbols for other, +purposes, for example with the intention of providing a generic, reusable +set of symbols, sym-license-dist applies. + +If sym-license-dist or sym-license-use contains the text "Public Domain" +(with or without capital letters), the user of the file may alternatively +choose the apply the Creative Commons CC0 license (CC0 1.0 Universal) instead +for distribution or use, respectively. + +Sch-rnd symbol files having any of these three fields are assumed to +interpret them as described above unless accompanying document explicitly +states otherwise. Index: tags/1.0.5/library/symbol/analog/comparator-1.ry =================================================================== --- tags/1.0.5/library/symbol/analog/comparator-1.ry (nonexistent) +++ tags/1.0.5/library/symbol/analog/comparator-1.ry (revision 10414) @@ -0,0 +1,87 @@ +ha:cschem-group-v1 { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAAG; + li:objects { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAAB; + x=-8000; y=4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=in+ + role=terminal + } + } + ha:group.2 { + uuid=iNOQfJpO6hT/HFDFGjoAAAAC; + x=-8000; y=-4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=in- + role=terminal + } + } + ha:group.3 { + uuid=iNOQfJpO6hT/HFDFGjoAAAAD; + x=12000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=out + role=terminal + } + } + ha:line.4 { x1=-8000; y1=-8000; x2=-8000; y2=8000; stroke=sym-decor; } + ha:line.5 { x1=-8000; y1=8000; x2=8000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=8000; y1=0; x2=-8000; y2=-8000; stroke=sym-decor; } + ha:line.7 { x1=-6000; y1=5000; x2=-6000; y2=3000; stroke=sym-decor; } + ha:line.8 { x1=-7000; y1=4000; x2=-5000; y2=4000; stroke=sym-decor; } + ha:line.9 { x1=-7000; y1=-4000; x2=-5000; y2=-4000; stroke=sym-decor; } + ha:group.10 { + uuid=iNOQfJpO6hT/HFDFGjoAAAAE; + x=0; y=-4000; rot=270.000000; mirx=1; miry=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=0; y1=-1000; rot=180.000000; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=V- + role=terminal + } + } + ha:group.11 { + uuid=iNOQfJpO6hT/HFDFGjoAAAAF; + x=0; y=8000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=-4000; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=V+ + role=terminal + } + } + ha:line.12 { x1=-1000; y1=-2000; x2=0; y2=2000; stroke=sym-decor; } + ha:line.13 { x1=0; y1=2000; x2=2000; y2=2000; stroke=sym-decor; } + ha:line.14 { x1=1000; y1=2000; x2=0; y2=-2000; stroke=sym-decor; } + ha:line.15 { x1=0; y1=-2000; x2=-2000; y2=-2000; stroke=sym-decor; } + ha:text.16 { x1=-8000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + name=U?? + role=symbol + -slot=1 + -sym-source = {sch-rnd default symbol lib} + -sym-copyright = {(C) 2022 Tibor 'Igor2' Palinkas} + -sym-license-dist = {GPLv2+} + -sym-license-use = {Public Domain} + } + } +} Index: tags/1.0.5/library/symbol/analog/opamp-1.ry =================================================================== --- tags/1.0.5/library/symbol/analog/opamp-1.ry (nonexistent) +++ tags/1.0.5/library/symbol/analog/opamp-1.ry (revision 10414) @@ -0,0 +1,89 @@ +ha:cschem-group-v1 { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAAH; + x=12000; y=0; + li:objects { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAAI; + x=-20000; y=4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=in+ + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.2 { + uuid=iNOQfJpO6hT/HFDFGjoAAAAJ; + x=-20000; y=-4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=in- + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:group.3 { + uuid=iNOQfJpO6hT/HFDFGjoAAAAK; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=out + role=terminal + ha:spice/pinnum = { value=3; prio=31050; } + } + } + ha:line.4 { x1=-20000; y1=-8000; x2=-20000; y2=8000; stroke=sym-decor; } + ha:line.5 { x1=-20000; y1=8000; x2=-4000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=-4000; y1=0; x2=-20000; y2=-8000; stroke=sym-decor; } + ha:line.7 { x1=-18000; y1=5000; x2=-18000; y2=3000; stroke=sym-decor; } + ha:line.8 { x1=-19000; y1=4000; x2=-17000; y2=4000; stroke=sym-decor; } + ha:line.9 { x1=-19000; y1=-4000; x2=-17000; y2=-4000; stroke=sym-decor; } + ha:group.10 { + uuid=iNOQfJpO6hT/HFDFGjoAAAAL; + x=-12000; y=-4000; rot=270.000000; mirx=1; miry=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=0; y1=-1000; rot=180.000000; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=V- + role=terminal + ha:spice/pinnum = { value=5; prio=31050; } + } + } + ha:group.11 { + uuid=iNOQfJpO6hT/HFDFGjoAAAAM; + x=-12000; y=8000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=-4000; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=V+ + role=terminal + ha:spice/pinnum = { value=4; prio=31050; } + } + } + ha:text.12 { x1=-21000; y1=9000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + name=U?? + role=symbol + devmap=lm358_so8 + -slot=1 + -sym-source = {sch-rnd default symbol lib} + -sym-copyright = {(C) 2022 Tibor 'Igor2' Palinkas} + -sym-license-dist = {GPLv2+} + -sym-license-use = {Public Domain} + } + } +} Index: tags/1.0.5/library/symbol/common_sym.awk =================================================================== --- tags/1.0.5/library/symbol/common_sym.awk (nonexistent) +++ tags/1.0.5/library/symbol/common_sym.awk (revision 10414) @@ -0,0 +1,571 @@ +# Copyright (C) 2022 Tibor 'Igor2' Palinkas +# License: GNU LGPL 2.1 or later +# (Output generated using this script is not affected by the license of the script) + +BEGIN { + q="\"" + + DEFAULT["pin_flags"] = "__auto" + + s_default=1 + s_weak=2 + s_explicit=3 + + offs_x = 0 + offs_y = 0 + proto_next_id = 0 + pin_grid = 4000 + +# index names + i_objs = 1 + i_objid = 2 + i_indent = 3 + i_attrs = 4 + i_id = 5 + i_x = 6 + i_y = 7 + i_rot = 9 + i_mirx = 10 + i_miry = 11 + + + pi=3.141592654 + + NL = "\n" + +# redirect: output file + ofn = "/dev/stdout" + +# minuid + for(n = 32; n < 127; n++) + ORD[sprintf("%c", n)] = n + BASE64 = "ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyz0123456789+/" +} + +# call this with the first 19 characters of minuid --gen +function minuid_init(seed ,n) +{ + minuid_prefix = seed; + if (length(minuid_prefix) != 19) { + print "Error: invalid seed in minuid_init(): needs to be 19 chars long" > "/dev/stderr" + exit(1) + } + for(n = 0; n < 5; n++) + MINUID_SUFF[n] = 0 +} + + +function minuid_gen( n,s) +{ + if (minuid_prefix == "") { + print "Error: called minuid_get() without minuid_init()" > "/dev/stderr" + exit(1) + } + + for(n = 4; n >= 0; n--) { + MINUID_SUFF[n]++ + if (MINUID_SUFF[n] < 63) + break; + MINUID_SUFF[n] = 0 + } + + s = minuid_prefix + for(n = 0; n < 5; n++) + s = s substr(BASE64, (MINUID_SUFF[n] % 64 + 1), 1) + return s +} + +function maybe_print_minuid(ind) +{ + if (minuid_prefix != "") + print ind "uuid=" minuid_gen() ";" > ofn +} + +function maybe_ret_minuid(ind) +{ + if (minuid_prefix != "") + return ind "uuid=" minuid_gen() ";" NL + return "" +} + +# Throw an error and exit +function error(msg) +{ + print "Error: " msg > "/dev/stderr" + exit 1 +} + +# return a if it is not empty, else return b +function either(a, b) +{ + return a != "" ? a : b +} + +# strip leading/trailing whitespaces +function strip(s) +{ + sub("^[ \t\r\n]*", "", s) + sub("[ \t\r\n]*$", "", s) + return s +} + +function lht_str(s) +{ + if (s ~ "[^A-Za-z0-9 _%.-]") { + gsub("}", "\\}", s) + return "{" s "}" + } + return s +} + +function sym_text_(GRP, x, y, str, rot, mirx, miry, dynfloat, pen ,s) +{ + if (pen == "") pen = "sym-decor"; + + s = s GRP[i_indent] "ha:text." (++GRP[i_objid]) " {" + s = s " x1=" x "; y1=" y "; rot=" either(rot, 0) + if (mirx) s = s "; mirx=1" + if (miry) s = s "; miry=1" + s = s "; stroke=" pen ";" + if (dynfloat > 0) { + if ((pen == "term-primary") || (pen == "term-secondary") || (dynfloat ~ "nofloat")) + s = s " dyntext=1;" + else + s = s " dyntext=1; floater=1;" + } + + s = s " text=" lht_str(str) "; }" + + GRP[i_objs] = GRP[i_objs] s NL +} + +function sym_text(GRP, x, y, str, rot, mirx, miry, dynfloat, pen) +{ + sym_text(GRP, x, y, str, rot, dynfloat, pen) +} + +function sym_text_attr_(GRP, x, y, attrname, rot, mirx, miry, pen, prefix ,s) +{ + if (!(attrname ~ "^[aA].")) + attrname = "A." attrname + return sym_text_(GRP, x, y, prefix "%../" attrname "%", rot, mirx, miry, 1, pen) +} + +function sym_text_attr(GRP, x, y, attrname, rot, pen, prefix) +{ + sym_text_attr_(GRP, x, y, attrname, rot, 0, 0, pen, prefix) +} + +function sym_line_(id, x1, y1, x2, y2, pen ,s) +{ + if (pen == "") pen = "sym-decor"; + + if (id != "") + id = "." id + + s = "ha:line" id " {" + s = s " x1=" x1 "; y1=" y1 "; x2=" x2 "; y2=" y2 "; stroke=" pen "; }" + return s +} + +function sym_line(GRP, x1, y1, x2, y2, pen ,s) +{ + s = GRP[i_indent] sym_line_(++GRP[i_objid], x1, y1, x2, y2, pen) + GRP[i_objs] = GRP[i_objs] s NL +} + +function sym_arc(GRP, cx, cy, r, a_start, a_delta, pen ,s) +{ + if (pen == "") pen = "sym-decor"; + + s = s GRP[i_indent] "ha:arc." (++GRP[i_objid]) " {" + s = s " cx=" cx "; cy=" cy "; r=" r "; sang=" a_start "; dang=" a_delta "; stroke=" pen "; }" + + GRP[i_objs] = GRP[i_objs] s NL +} + +# POLY[] is an array indexed between 0 to 2*N-1 for a polygon of N +# vertices, packed as x0;y0;x1;y1;x2;y2 ... xN;yN. The usual pcb-rnd +# polygon rules apply: at least 3 vertices, no self-intersection. This +# call does not make any attempt on cheking polygon validity. +function sym_poly(GRP, POLY, pen, fill ,s,n) +{ + if (pen == "") pen = "sym-decor"; + + s = s GRP[i_indent] "ha:polygon." (++GRP[i_objid]) " {" NL + s = s GRP[i_indent] " li:outline {" NL + + for(n = 2; (n in POLY); n += 2) + s = s GRP[i_indent] " " sym_line_(id, POLY[n-2], POLY[n-1], POLY[n], POLY[n+1], pen) NL + s = s GRP[i_indent] " " sym_line_(id, POLY[n-2], POLY[n-1], POLY[0], POLY[1], pen) NL + + s = s GRP[i_indent] " }" NL + s = s GRP[i_indent] " stroke=" pen NL + if (fill != "") + s = s GRP[i_indent] " fill=" fill NL + s = s GRP[i_indent] "}" + + GRP[i_objs] = GRP[i_objs] s NL +} + +# reset a polygon so it has no vertices +function poly_reset(POLY ,n) +{ + for(n = 0; (n in POLY); n += 2) + delete POLY[n] + POLY["len"] = 0 +} + +# append x;y to the end of a polygon's vertex list +function poly_append(POLY, x, y) +{ + POLY[POLY["len"]++] = x; + POLY[POLY["len"]++] = y; +} + +function sym_rect(GRP, x1, y1, x2, y2, pen, fill ,POLY) +{ + poly_reset(POLY) + poly_append(POLY, x1, y1) + poly_append(POLY, x1, y2) + poly_append(POLY, x2, y2) + poly_append(POLY, x2, y1) + + sym_poly(GRP, POLY, pen, fill) +} + + +# start generating a subcircuit +function sym_begin(name, ax, ay) +{ + print "ha:cschem-group-v1 {" > ofn + + SYM[i_indent]=" "; + SYM[i_objid] = 0; + SYM[i_id] = 1; + + grp_attr_append(SYM, "role", "symbol") + if (name != "") { + grp_attr_append(SYM, "name", name) + sym_text_attr(SYM, int(ax), int(ay), "name", 0, "sym-primary") + } +} + +# generate subcircuit footers +function sym_end( layer,n,v,L,lt,UID) +{ + print grp_render(SYM, " ") > ofn + print "}" > ofn +} + +function grp_attr_append(GRP, key, val ,s) +{ + s = s GRP[i_indent] key "=" lht_str(val) ";" + GRP[i_attrs] = GRP[i_attrs] s NL +} + +function grp_attrarr_append(GRP, key, AA, n,v) +{ + s = s GRP[i_indent] "li:" key "= {" NL + v = AA["len"] + for(n = 0; n < v; n++) + s = s GRP[i_indent] "\t" lht_str(AA[n]) NL + s = s GRP[i_indent] "}" NL + GRP[i_attrs] = GRP[i_attrs] s +} + +function attrarr_reset(AA) +{ + AA["len"] = 0 +} + +function attrarr_append(AA, val) +{ + AA[AA["len"]++] = val +} + + +function grp_render(GRP, ind ,s) +{ + s = s ind "ha:group." GRP[i_id] " {" NL + s = s maybe_ret_minuid(ind " ") + if ((GRP[i_x] != 0) || (GRP[i_y] != 0)) + s = s ind " x=" GRP[i_x] "; y=" GRP[i_y] ";" NL + if ((GRP[i_rot] != 0) || (GRP[i_mirx] != 0) || (GRP[i_miry] != 0)) + s = s ind " rot=" GRP[i_rot] "; mirx=" GRP[i_mirx] "; miry=" GRP[i_miry] ";" NL + s = s ind " li:objects {" NL + s = s GRP[i_objs] + s = s ind " }" NL + s = s ind " ha:attrib {" NL + s = s GRP[i_attrs] + s = s ind " }" NL + s = s ind "}" + return s +} + +function slen(str) +{ + return (length(str)-1)/4 +} + +# generate a term group; orientaiton is one of: left, right, top, bottom. +# Orientation "left" means "left facing terminal": horizontal line with +# 0;0 of the terminal is on the right, anticipated connection point on the left. +# In other words, if the symbol is a box, ori means on which side the term is placed. +# If pindecor is non-empty, it can be "circle" or "intri" or "outtri" (in pin space). +# If intdecor is non-empty, it can be "intri" or "outtri" (in name2 space). +# If label2 is non-empty, print that instead of terminal name for name2 +# Normally name is the terminal name (which is also the "pin number", name2==""); +# alternatively name is the "pin number" and name2 is the terminal name. +# Then if name2 is not "" and label2 is not "", the printout will differ from term name +function sym_term(GRP, x, y, ori, name, name2, pindecor, intdecor, label2, s,TERM,rot,mirx,miry,dx,tx,TRI,dynt) +{ + TERM[i_id] = ++GRP[i_objid]; + TERM[i_indent] = GRP[i_indent] "\t\t"; + TERM[i_x] = x + TERM[i_y] = y + rot = 0 + mirx = 0 + miry = 0 + + if (ori == "left") { + mirx = 1 + } + else if (ori == "right") { +# nothing to do: default + } + else if (ori == "top") { + rot = 90 + } + else if (ori == "bottom") { + rot = -90 + mirx = 1 + } + TERM[i_rot] = rot + TERM[i_mirx] = mirx + TERM[i_miry] = miry + + grp_attr_append(TERM, "role", "terminal") + + if (pindecor == "circle") { + dx = 1000 + sym_arc(TERM, dx/2, 0, dx/2, 0, 360, "term-decor") + } + else if (pindecor == "outtri") { + dx = 1000 + poly_reset(TRI) + poly_append(TRI, dx, 0) + poly_append(TRI, 0, +dx) + poly_append(TRI, 0, -dx) + sym_poly(TERM, TRI, "term-decor", "term-decor") + } + else if (pindecor == "intri") { + dx = 1000 + poly_reset(TRI) + poly_append(TRI, 0, 0) + poly_append(TRI, dx, +dx) + poly_append(TRI, dx, -dx) + sym_poly(TERM, TRI, "term-decor", "term-decor") + } + else + dx = 0; + + if (intdecor == "intri") { + tx = 1000 + poly_reset(TRI) + poly_append(TRI, -tx, 0) + poly_append(TRI, 0, +tx) + poly_append(TRI, 0, -tx) + sym_poly(TERM, TRI, "sym-decor", "") + } + else if (intdecor == "outtri") { + tx = 1000 + poly_reset(TRI) + poly_append(TRI, 0, 0) + poly_append(TRI, -tx, +tx) + poly_append(TRI, -tx, -tx) + sym_poly(TERM, TRI, "sym-decor", "") + } + else + tx = 0; + + sym_line(TERM, dx, 0, pin_grid, 0, "term-decor") + + if (name2 != "") { + grp_attr_append(TERM, "pinnum", name) + grp_attr_append(TERM, "name", name2) + sym_text_attr(TERM, (1/4) * pin_grid, 0, "a.display/name", 0, "term-primary") + if (label2 != "") { + dynt = (label2 ~ "^[%]") + sym_text_(TERM, -tx-500, -0.5 * pin_grid, label2, 0, 1, 0, dynt, "term-secondary") + } + else + sym_text_attr_(TERM, -tx-500, -0.5 * pin_grid, "name", 0, 1, 0, "term-secondary") + } + else { + grp_attr_append(TERM, "name", name) + sym_text_attr(TERM, (1/4) * pin_grid, 0, "name", 0, "term-primary") + } + + GRP[i_objs] = GRP[i_objs] grp_render(TERM, GRP[i_indent]) NL +} + + +function set_arg_(OUT, key, value, strength) +{ + if (OUT[key, "strength"] > strength) + return + + OUT[key] = value + OUT[key, "strength"] = strength +} + +# set parameter key=value with optioal strength (s_* consts) in array OUT[] +# set only if current strength is stronger than the original value +# if key starts with a "?", use s_weak +# if key is in DEFAULT[], use DEFAULT[] instead of OUT[] +function set_arg(OUT, key, value ,strength) +{ + if (strength == "") + strength = s_explicit + if (key ~ "^[?]") { + sub("^[?]", "", key) + strength = s_weak + } + + if (key in DEFAULT) { + if (DEFAULT[key, "dim"]) + value = parse_dim_(value, 0) + set_arg_(DEFAULT, key, value, strength) + } + else + set_arg_(OUT, key, value, strength) +} + +# Process a generator argument list from arg_names. Save the result in +# array OUT. If mandatory is specified, check whether all mandatory +# parameters are specified +# Both arg_names and mandatory are comma separated list of argument names +function proc_args(OUT, arg_names, mandatory, N,A,M,v,n,key,val,pos) +{ + gsub(" ", "", arg_names) + gsub(" ", "", mandatory) + split(arg_names, N, ",") + v = split(args, A, ",") + +# fill in all named and positional arguments + pos = 1 + for(n = 1; n <= v; n++) { + A[n] = strip(A[n]) + if (A[n] == "") + continue + if (A[n] ~ "=") { +# named + key=A[n] + val=A[n] + sub("=.*", "", key) + sub("^[^=]*=", "", val) + set_arg(OUT, key, val, s_explicit) + } + else { +# positional + if (N[pos] == "") { + error("too many positional arguments at " A[n]) + } + while((N[pos] in OUT) && (N[pos, "strength"] == s_explicit)) pos++ + set_arg(OUT, N[pos], A[n], s_explicit) + pos++ + } + } + +# check whether all mandatory arguments are specified + v = split(mandatory, M, ",") + for(n = 1; n <= v; n++) { + if (!(M[n] in OUT)) { + error("missing argument " M[n] " (or positional " n ")") + exit 1 + } + } +} + +# decide whether x is true or false +# returns 1 if true +# returns 0 if false +function tobool(x) +{ + if (x == int(x)) + return (int(x) != 0) + + x = tolower(x) + return (x == "true") || (x == "yes") || (x == "on") +} + +function help_extract(SEEN, fn, dirn, OVER, IGN, WANT,tmp,key,val,i,skip) +{ + if (fn in SEEN) + return + SEEN[fn]++ + print "#@@info-gen-extract " fn > ofn + close(fn) + while((getline line < fn) > 0) { + if (line ~ "^#@@include") { + sub("^#@@include[ \t]*", "", line) + tmp = dirn "/" line + WANT[tmp]++ + } + else if (line ~ "^#@@over@ignore") { + key = line + sub("^#@@over@ignore:", "", key) + sub(" .*", "", key) + IGN[key] = 1 + } + else if (line ~ "^#@@over@") { + key = line + sub("^#@@over@", "", key) + val = "#@@" key + sub(" .*", "", key) + OVER[key] = val + } + else if (line ~ "^#@@") { + key = line + sub("^#@@", "", key) + sub(" .*", "", key) + skip = 0 + for(i in IGN) { + if (key ~ i) + skip = 1 + } + if (skip) + continue + if (key in OVER) { + print OVER[key] > ofn + OVER[key "::PRINTED"] = 1 + } + else + print line > ofn + } + } + close(fn) + for(tmp in WANT) + help_extract(SEEN, tmp, dirn, OVER, IGN) +} + +function help_print( SEEN, OVER, dirn, k) +{ + print "#@@info-generator pcb-rnd common_subc.awk" > ofn + dirn = genfull + sub("/[^/]*$", "", dirn) + help_extract(SEEN, genfull, dirn, OVER) + for(k in OVER) { + if (!(k ~ "::PRINTED$") && !((k "::PRINTED") in OVER)) + print OVER[k] > ofn + } +} + +function help_auto() +{ + if ((args ~ "^--help") || (args ~ ",[ \t]*--help")) { + help_print() + exit(0) + } +} Index: tags/1.0.5/library/symbol/diode/diode-1.ry =================================================================== --- tags/1.0.5/library/symbol/diode/diode-1.ry (nonexistent) +++ tags/1.0.5/library/symbol/diode/diode-1.ry (revision 10414) @@ -0,0 +1,51 @@ +ha:cschem-group-v1 { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAAN; + li:objects { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAAO; + x=16000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=C + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.2 { + uuid=iNOQfJpO6hT/HFDFGjoAAAAP; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=A + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:text.3 { x1=12000; y1=5000; rot=90.000000; dyntext=1; stroke=sym-secondary; text=%../a.devmap%; floater=1; } + ha:text.4 { x1=8000; y1=5000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.5 { x1=12000; y1=0; x2=10000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=4000; y1=0; x2=6000; y2=0; stroke=sym-decor; } + ha:line.7 { x1=6000; y1=4000; x2=10000; y2=0; stroke=sym-decor; } + ha:line.8 { x1=10000; y1=0; x2=6000; y2=-4000; stroke=sym-decor; } + ha:line.9 { x1=6000; y1=4000; x2=6000; y2=-4000; stroke=sym-decor; } + ha:line.10 { x1=10000; y1=4000; x2=10000; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + name=D?? + role=symbol + devmap=1n4148_minimelf + ha:spice/prefix = { value=D; prio=31050; } + -sym-source = {sch-rnd default symbol lib} + -sym-copyright = {(C) 2022 Tibor 'Igor2' Palinkas} + -sym-license-dist = {GPLv2+} + -sym-license-use = {Public Domain} + } + } +} Index: tags/1.0.5/library/symbol/diode/led-1.ry =================================================================== --- tags/1.0.5/library/symbol/diode/led-1.ry (nonexistent) +++ tags/1.0.5/library/symbol/diode/led-1.ry (revision 10414) @@ -0,0 +1,60 @@ +ha:cschem-group-v1 { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAAQ; + li:objects { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAAR; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=C + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.2 { + uuid=iNOQfJpO6hT/HFDFGjoAAAAS; + x=-16000; y=0; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=A + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:line.3 { x1=-4000; y1=0; x2=-6000; y2=0; stroke=sym-decor; } + ha:line.4 { x1=-12000; y1=0; x2=-10000; y2=0; stroke=sym-decor; } + ha:line.5 { x1=-10000; y1=4000; x2=-6000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=-6000; y1=0; x2=-10000; y2=-4000; stroke=sym-decor; } + ha:line.7 { x1=-10000; y1=4000; x2=-10000; y2=-4000; stroke=sym-decor; } + ha:line.8 { x1=-6000; y1=4000; x2=-6000; y2=-4000; stroke=sym-decor; } + ha:text.9 { x1=-4000; y1=13000; rot=90.000000; dyntext=1; stroke=sym-secondary; text=%../a.devmap%; floater=1; } + ha:text.10 { x1=-8000; y1=13000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.11 { x1=-8000; y1=8000; x2=-6000; y2=11000; stroke=sym-decor; } + ha:line.12 { x1=-6000; y1=11000; x2=-7000; y2=10000; stroke=sym-decor; } + ha:line.13 { x1=-6000; y1=11000; x2=-6517; y2=9545; stroke=sym-decor; } + ha:line.14 { x1=-10000; y1=7000; x2=-8000; y2=10000; stroke=sym-decor; } + ha:line.15 { x1=-8000; y1=10000; x2=-8000; y2=8000; stroke=sym-decor; } + ha:line.16 { x1=-8303; y1=6354; x2=-6303; y2=9354; stroke=sym-decor; } + ha:line.17 { x1=-6303; y1=9354; x2=-7303; y2=8354; stroke=sym-decor; } + ha:line.18 { x1=-6303; y1=9354; x2=-6820; y2=7899; stroke=sym-decor; } + ha:line.19 { x1=-10303; y1=5354; x2=-8303; y2=8354; stroke=sym-decor; } + ha:line.20 { x1=-8303; y1=8354; x2=-8303; y2=6354; stroke=sym-decor; } + } + ha:attrib { + devmap=led5 + name=D?? + role=symbol + ha:spice/prefix = { value=D; prio=31050; } + -sym-source = {sch-rnd default symbol lib} + -sym-copyright = {(C) 2022 Tibor 'Igor2' Palinkas} + -sym-license-dist = {GPLv2+} + -sym-license-use = {Public Domain} + } + } +} Index: tags/1.0.5/library/symbol/diode/schottky-1.ry =================================================================== --- tags/1.0.5/library/symbol/diode/schottky-1.ry (nonexistent) +++ tags/1.0.5/library/symbol/diode/schottky-1.ry (revision 10414) @@ -0,0 +1,53 @@ +ha:cschem-group-v1 { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAAT; + li:objects { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAAU; + x=16000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=C + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.2 { + uuid=iNOQfJpO6hT/HFDFGjoAAAAV; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=A + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:text.3 { x1=12000; y1=5000; rot=90.000000; dyntext=1; stroke=sym-secondary; text=%../a.devmap%; floater=1; } + ha:text.4 { x1=8000; y1=5000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.5 { x1=12000; y1=0; x2=10000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=4000; y1=0; x2=6000; y2=0; stroke=sym-decor; } + ha:line.7 { x1=6000; y1=4000; x2=10000; y2=0; stroke=sym-decor; } + ha:line.8 { x1=10000; y1=0; x2=6000; y2=-4000; stroke=sym-decor; } + ha:line.9 { x1=6000; y1=4000; x2=6000; y2=-4000; stroke=sym-decor; } + ha:arc.10 { cx=11000; cy=4000; r=1000; sang=0.000000; dang=180.000000; stroke=sym-decor; } + ha:arc.11 { cx=9000; cy=-4000; r=1000; sang=180.000000; dang=180.000000; stroke=sym-decor; } + ha:line.12 { x1=10000; y1=-4000; x2=10000; y2=4000; stroke=sym-decor; } + } + ha:attrib { + name=D?? + role=symbol + devmap=1n5817_do41 + ha:spice/prefix = { value=D; prio=31050; } + -sym-source = {sch-rnd default symbol lib} + -sym-copyright = {(C) 2022 Tibor 'Igor2' Palinkas} + -sym-license-dist = {GPLv2+} + -sym-license-use = {Public Domain} + } + } +} Index: tags/1.0.5/library/symbol/diode/zener-1.ry =================================================================== --- tags/1.0.5/library/symbol/diode/zener-1.ry (nonexistent) +++ tags/1.0.5/library/symbol/diode/zener-1.ry (revision 10414) @@ -0,0 +1,53 @@ +ha:cschem-group-v1 { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAAW; + li:objects { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAAX; + x=16000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=C + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.2 { + uuid=iNOQfJpO6hT/HFDFGjoAAAAY; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=A + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:text.3 { x1=12000; y1=5000; rot=90.000000; dyntext=1; stroke=sym-secondary; text=%../a.devmap%; floater=1; } + ha:text.4 { x1=8000; y1=5000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.5 { x1=12000; y1=0; x2=10000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=4000; y1=0; x2=6000; y2=0; stroke=sym-decor; } + ha:line.7 { x1=6000; y1=4000; x2=10000; y2=0; stroke=sym-decor; } + ha:line.8 { x1=10000; y1=0; x2=6000; y2=-4000; stroke=sym-decor; } + ha:line.9 { x1=6000; y1=4000; x2=6000; y2=-4000; stroke=sym-decor; } + ha:line.10 { x1=10000; y1=-4000; x2=10000; y2=4000; stroke=sym-decor; } + ha:line.11 { x1=10000; y1=4000; x2=8000; y2=4000; stroke=sym-decor; } + ha:line.12 { x1=10000; y1=-4000; x2=12000; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + name=D?? + role=symbol + devmap=bzx55c3v3_do35 + ha:spice/prefix = { value=D; prio=31050; } + -sym-source = {sch-rnd default symbol lib} + -sym-copyright = {(C) 2022 Tibor 'Igor2' Palinkas} + -sym-license-dist = {GPLv2+} + -sym-license-use = {Public Domain} + } + } +} Index: tags/1.0.5/library/symbol/diode/zener-2.ry =================================================================== --- tags/1.0.5/library/symbol/diode/zener-2.ry (nonexistent) +++ tags/1.0.5/library/symbol/diode/zener-2.ry (revision 10414) @@ -0,0 +1,52 @@ +ha:cschem-group-v1 { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAAZ; + li:objects { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAAa; + x=16000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=C + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.2 { + uuid=iNOQfJpO6hT/HFDFGjoAAAAb; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=A + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:text.3 { x1=12000; y1=5000; rot=90.000000; dyntext=1; stroke=sym-secondary; text=%../a.devmap%; floater=1; } + ha:text.4 { x1=8000; y1=5000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.5 { x1=12000; y1=0; x2=10000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=4000; y1=0; x2=6000; y2=0; stroke=sym-decor; } + ha:line.7 { x1=6000; y1=4000; x2=10000; y2=0; stroke=sym-decor; } + ha:line.8 { x1=10000; y1=0; x2=6000; y2=-4000; stroke=sym-decor; } + ha:line.9 { x1=6000; y1=4000; x2=6000; y2=-4000; stroke=sym-decor; } + ha:line.10 { x1=10000; y1=-4000; x2=10000; y2=4000; stroke=sym-decor; } + ha:line.11 { x1=10000; y1=4000; x2=8000; y2=4000; stroke=sym-decor; } + } + ha:attrib { + name=D?? + role=symbol + devmap=bzx55c3v3_do35 + ha:spice/prefix = { value=D; prio=31050; } + -sym-source = {sch-rnd default symbol lib} + -sym-copyright = {(C) 2022 Tibor 'Igor2' Palinkas} + -sym-license-dist = {GPLv2+} + -sym-license-use = {Public Domain} + } + } +} Index: tags/1.0.5/library/symbol/mech/connector =================================================================== --- tags/1.0.5/library/symbol/mech/connector (nonexistent) +++ tags/1.0.5/library/symbol/mech/connector (revision 10414) @@ -0,0 +1,45 @@ +#!/bin/sh + +#@@example connector(2, 3) + +#@@purpose Generate pin-array connectors (e.g. headers). + +#@@desc Generate a connectors that consits of an array of +#@@desc evenly spaced terminals and a frame. + +#@@params ny, nx, spacing, eshift, etrunc + +#@@param:ny number of pins (in vertical direction) +#@@param:nx number of columns (in horizontal direction; e.g. single row connectors have 1, headers have 2) +#@@optional:nx + +#@@param:eshift double pin spacing, shift even rows or columns by 1 spacing (optional; default: don't shift) +#@@enum:eshift:x shift columns (vertical) +#@@enum:eshift:y shift rows (horizontal) +#@@enum:eshift:none do not shift anything +#@@default:eshift none +#@@optional:eshift +#@@preview_args:eshift 2,3 + +#@@param:etrunc truncate the last pin of a shifted row or column +#@@bool:etrunc +#@@default:etrunc false +#@@optional:etrunc +#@@preview_args:etrunc 2,3,eshift=x + +#@@param:sequence pin numbering sequence +#@@enum:sequence:normal increase by y first, then by x +#@@enum:sequence:pivot increase by x first, then by y +#@@enum:sequence:zigzag "dip-style" numbering in zig-zag: number odd x rows by y ascending, even x rows by y descending +#@@preview_args:sequence 2,4 +#@@thumbsize:sequence 3 +#@@thumbnum:sequence 1 +#@@default:sequence normal +#@@optional:sequence + + + +#@@include common_sym.awk + +awk -f `dirname $0`/../common_sym.awk -f `dirname $0`/connector.awk -v "args=$*" -v gen=`basename $0` -v "genfull=$0" + Property changes on: tags/1.0.5/library/symbol/mech/connector ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/1.0.5/library/symbol/mech/connector.awk =================================================================== --- tags/1.0.5/library/symbol/mech/connector.awk (nonexistent) +++ tags/1.0.5/library/symbol/mech/connector.awk (revision 10414) @@ -0,0 +1,103 @@ +BEGIN { + help_auto() + set_arg(P, "?sequence", "normal") + set_arg(P, "?nx", "1") + + proc_args(P, "ny,nx,eshift,etrunc", "ny") + + P["nx"] = int(P["nx"]) + P["ny"] = int(P["ny"]) + + eshift=tolower(P["eshift"]) + etrunc=tobool(P["etrunc"]) + if ((eshift != "x") && (eshift != "y") && (eshift != "") && (eshift != "none")) + error("eshift must be x or y or none (got: " eshift ")"); + + if ((eshift == "x") || (eshift == "y")) + step = pin_grid*2; + else + step = pin_grid; + + if (P["nx"] > 2) { + mult=int(P["nx"]/2) + while(mult > 0) { + step = step * 2; + mult-- + } + } + + half = int(step/2); + + + sym_begin("CONN??", 0, -half) + grp_attr_append(SYM, "spice/omit", "yes") + + for(x = 0; x < P["nx"]; x++) { + if ((eshift == "x") && ((x % 2) == 1)) + yo = step/2 + else + yo = 0 + for(y = 0; y < P["ny"]; y++) { + if ((eshift == "y") && ((y % 2) == 1)) { + xo = step/2 + if ((etrunc) && (x == P["nx"]-1)) + continue + } + else { + xo = 0 + if ((etrunc) && (y == P["ny"]-1) && (yo != 0)) + continue + } + if (P["sequence"] == "normal") { + pinno++ + } + else if (P["sequence"] == "pivot") { + pinno = y * P["nx"] + x + 1 + } + else if (P["sequence"] == "zigzag") { + if (x % 2) { + pinno = (x+1) * P["ny"] - y + if ((etrunc) && (eshift == "x")) + pinno -= int(x/2)+1 + else if ((etrunc) && (eshift == "y")) + pinno += int(x/2) + } + else { + pinno = x * P["ny"] + y + 1 + if ((etrunc) && (eshift == "x")) + pinno -= x/2 + else if ((etrunc) && (eshift == "y")) + pinno += x/2-1 + } + } + + if (x < 1) + pdir="left"; + else + pdir="right"; + sym_term(SYM, x * step + xo, y * step + yo, pdir, pinno) + } + } + + xo = 0 + yo = 0 + if (!etrunc) { + if (eshift == "y") + xo = step/2 + if (eshift == "x") + yo = step/2 + } + + xs = P["nx"]-1; + if (xs == 0) + xs = 1; + sym_rect(SYM, 0, -half, xs * step + xo, P["ny"] * step + yo - half) + + for(x = 1; x < P["nx"]-1; x++) { + xx = x * step + xo + sym_line(SYM, xx, -half, xx, P["ny"] * step + yo - half) + } + + sym_end() + +} Index: tags/1.0.5/library/symbol/mech/hole.ry =================================================================== --- tags/1.0.5/library/symbol/mech/hole.ry (nonexistent) +++ tags/1.0.5/library/symbol/mech/hole.ry (revision 10414) @@ -0,0 +1,28 @@ +ha:cschem-group-v1 { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAAc; + li:objects { + ha:arc.1 { cx=-8000; cy=0; r=4000; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:group.2 { + uuid=iNOQfJpO6hT/HFDFGjoAAAAd; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=-11000; y1=-2000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + name=H?? + role=symbol + sym-source = {sch-rnd default symbol lib} + sym-copyright = {(C) 2022 Tibor 'Igor2' Palinkas} + sym-license-dist = {GPLv2+} + sym-license-use = {Public Domain} + } + } +} Index: tags/1.0.5/library/symbol/mech/switch =================================================================== --- tags/1.0.5/library/symbol/mech/switch (nonexistent) +++ tags/1.0.5/library/symbol/mech/switch (revision 10414) @@ -0,0 +1,27 @@ +#!/bin/sh + +#@@example switch(2, 3) + +#@@purpose Generate a switchs or push button + +#@@desc Generate a switchs or push button with arbitrary number of throws +#@@desc and poles. + +#@@params pole, throw, style + +#@@param:pole number of poles (mechanically coupled parallel copies of the switch section) +#@@default:pole 1 +#@@param:throw number of throws (positions or output terminals for the single input terminal, per switch section) +#@@default:throw 1 +#@@param:style graphics for the switching element between terminals +#@@enum:style:switch static switch with 2 or more states +#@@enum:style:rotary terminals arranged in rotary switch style +#@@enum:style:push push button, off by default (two-state) +#@@enum:style:invpush push button, on by default (two-state) +#@@enum:style:relay same as switch, but includes relay coil on top +#@@default:style switch + +#@@include common_sym.awk + +awk -f `dirname $0`/../common_sym.awk -f `dirname $0`/switch.awk -v "args=$*" -v gen=`basename $0` -v "genfull=$0" + Property changes on: tags/1.0.5/library/symbol/mech/switch ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/1.0.5/library/symbol/mech/switch.awk =================================================================== --- tags/1.0.5/library/symbol/mech/switch.awk (nonexistent) +++ tags/1.0.5/library/symbol/mech/switch.awk (revision 10414) @@ -0,0 +1,189 @@ +function left(y, r, need_term, y0) +{ + if (need_term) + sym_term(SYM, 0, y * pin_grid, "left", prefix "1") + + if (y0 != "") + sym_line(SYM, 0, y * pin_grid, 0, y0 * pin_grid) + + sym_line(SYM, 0, y * pin_grid, 0.3 * pin_grid, y * pin_grid) + if (P["style"] ~ "push") + sym_arc(SYM, (0.3 + r) * pin_grid, y * pin_grid, r * pin_grid, 0, 360) +} + +function right(x0, y0, prefix, r, t, left_multi, RES ,tune,nn,n,tn,i) +{ + tn = 2 + if ((t % 2) == 0) + tune = 1 + i = 0 + for(nn = -int(t/2); nn < int(t/2+0.5); nn++) { + n = nn + tune; + RES[i, "y"] = y0+n + RES[i, "x"] = x0-0.3 - r + sym_term(SYM, x0 * pin_grid, (y0+n) * pin_grid, "right", prefix tn) + sym_line(SYM, (x0-0.3) * pin_grid, (y0+n) * pin_grid, x0 * pin_grid, (y0 + n) * pin_grid) + if (r > 0) + sym_arc(SYM, (x0-0.3 - r) * pin_grid, (y0+n) * pin_grid, r * pin_grid, 0, 360) + if (left_multi) + left(y0+n, r, 0, y0) + + tn++ + i++ + } + + return n +} + +function gen_straight(y0, prefix, last ,n,t,tn,yoffs,r,nn,tune,cap,coupler,relay,left_multi) +{ + r = 0.1 + if (P["style"] == "invpush") + yoffs = -r; + else + yoffs = r; + + t = P["throw"] + + if ((P["style"] == "push") || (P["style"] == "invpush")) + left_multi = 1 + +# generate left side + left(y0, r, 1) + +# generate right side terminals + n = right(2, y0, prefix, r, t, left_multi) + +# generate switch mechanics + if (P["style"] == "switch") { + sym_line(SYM, 0.3*pin_grid, y0 * pin_grid, 1.4*pin_grid, (y0+0.8) * pin_grid) + coupler = y0+0.5 + } + else if (P["style"] == "relay") { + sym_line(SYM, 0.3*pin_grid, y0 * pin_grid, 1.4*pin_grid, (y0+0.8) * pin_grid) + coupler = y0+0.5 + relay = 1.5 + } + else if (P["style"] == "push") { + sym_line(SYM, 0.3*pin_grid, (y0+1-r) * pin_grid, 1.7*pin_grid, (y0+1-r) * pin_grid) + coupler = y0+1-r + cap = 2 + } + else if (P["style"] == "invpush") { + sym_line(SYM, 0.3*pin_grid, (y0-r) * pin_grid, 1.7*pin_grid, (y0-r) * pin_grid) + coupler = y0-r + cap = 1 + } + else + error("invalid switch style " P["style"]) + + COUPLER["top"] = y0 + n + if (cap || relay) + COUPLER["top"] += cap + relay + else + COUPLER["top"] -= 0.5 + + if (COUPLER["bottom"] == "") + COUPLER["bottom"] = coupler + +# generate cap or relay + if (last) { + if (cap) { + sym_line(SYM, 0.4*pin_grid, COUPLER["top"] * pin_grid, 1.6*pin_grid, COUPLER["top"] * pin_grid) + sym_line(SYM, 0.4*pin_grid, COUPLER["top"] * pin_grid, 0.4*pin_grid, (COUPLER["top"]-r*2) * pin_grid) + sym_line(SYM, 1.6*pin_grid, COUPLER["top"] * pin_grid, 1.6*pin_grid, (COUPLER["top"]-r*2) * pin_grid) + } + if (relay) { + sym_rect(SYM, 0*pin_grid, (COUPLER["top"]+3) * pin_grid, 2*pin_grid, COUPLER["top"] * pin_grid) + sym_line(SYM, 0*pin_grid, (COUPLER["top"]+0.5) * pin_grid, 2*pin_grid, (COUPLER["top"]+2.5) * pin_grid) + sym_term(SYM, 0, (COUPLER["top"]+1.5) * pin_grid, "left", "coil1") + sym_term(SYM, 2*pin_grid, (COUPLER["top"]+1.5) * pin_grid, "right", "coil2") + } + } + + return t+1 +} + +function gen_rotary(y0, prefix, last ,RES,n,t,da,sa,a,rx0,ry0,rx,ry,rr,r) +{ + r = 0.1 + rr = 1 + t = P["throw"] + sa = 3.141592654/4 + if ((t%2) == 1) + da = (sa*2)/(t-1) + else { + da = (sa*2)/t + sa -= da + } + +# generate left side + left(y0, r, 1) + +# generate right side terminals + right(4, y0, prefix, 0, t, 0, RES) + + rx0 = 1 + ry0 = y0 + a = -sa + for(n = 0; n < t; n++) { + rx = rx0 + cos(a) * rr + ry = ry0 + sin(a) * rr + sym_line(SYM, int(rx * pin_grid), int(ry * pin_grid), RES[n, "x"] * pin_grid, RES[n, "y"] * pin_grid) + a += da + } + + sym_line(SYM, 0.3*pin_grid, y0 * pin_grid, 1.8*pin_grid, (y0+0.3) * pin_grid) + coupler = y0+0.15 + + COUPLER["top"] = y0+0.15 + if (COUPLER["bottom"] == "") + COUPLER["bottom"] = coupler + + return t+1 +} + + +function gen_sect(y0, prefix, last) +{ + if (P["style"] == "rotary") return gen_rotary(y0, prefix, last) + return gen_straight(y0, prefix, last) +} + +BEGIN { + help_auto() + + set_arg(P, "?pole", "1") + set_arg(P, "?throw", "1") + set_arg(P, "?style", "switch") + + proc_args(P, "pole, throw, style") + + P["pole"] = int(P["pole"]) + P["throw"] = int(P["throw"]) + + if (P["pole"] > 26) + error("Too many poles; must be less than 27"); + if (P["pole"] < 1) + error("Too few poles; must be at least 1"); + if (P["throw"] < 1) + error("Too few throws; must be at least 1"); + + sym_begin("SW??", -pin_grid*2, -pin_grid) + grp_attr_append(SYM, "spice/omit", "yes") + + prefix="" + y0 = 0 + for(pole = 0; pole < P["pole"]; pole++) { + if (P["pole"] > 1) + prefix = sprintf("%c", 65+pole) + y0 += gen_sect(y0, prefix, (pole == P["pole"]-1)) + } + +# draw coupler + if (COUPLER["bottom"] != COUPLER["top"]) + sym_line(SYM, 1*pin_grid, COUPLER["bottom"] * pin_grid, 1*pin_grid, COUPLER["top"] * pin_grid) + + + sym_end() +} Index: tags/1.0.5/library/symbol/mech/testpoint.ry =================================================================== --- tags/1.0.5/library/symbol/mech/testpoint.ry (nonexistent) +++ tags/1.0.5/library/symbol/mech/testpoint.ry (revision 10414) @@ -0,0 +1,33 @@ +ha:cschem-group-v1 { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + li:objects { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + name=TP?? + role=symbol + spice/omit=yes + -sym-source = {sch-rnd default symbol lib} + -sym-copyright = {(C) 2022 Tibor 'Igor2' Palinkas} + -sym-license-dist = {GPLv2+} + -sym-license-use = {Public Domain} + } + } +} Index: tags/1.0.5/library/symbol/misc/shterm_in.ry =================================================================== --- tags/1.0.5/library/symbol/misc/shterm_in.ry (nonexistent) +++ tags/1.0.5/library/symbol/misc/shterm_in.ry (revision 10414) @@ -0,0 +1,23 @@ +ha:cschem-group-v1 { + ha:group.1 { + src_uuid=AHibvjaMiL5NH+9/wR0AAAAG; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-5000; y1=-1500; mirx=1; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:line.3 { x1=-4000; y1=0; x2=-5000; y2=2000; stroke=sheet-decor; } + ha:line.4 { x1=-4000; y1=0; x2=-5000; y2=-2000; stroke=sheet-decor; } + ha:line.5 { x1=-5000; y1=-2000; x2=-17000; y2=-2000; stroke=sheet-decor; } + ha:line.6 { x1=-17000; y1=2000; x2=-5000; y2=2000; stroke=sheet-decor; } + ha:line.7 { x1=-17000; y1=2000; x2=-17000; y2=-2000; stroke=sheet-decor; } + } + ha:attrib { + name=TERMNAME + role=terminal + -sym-source = {sch-rnd default symbol lib} + -sym-copyright = {(C) 2024 Tibor 'Igor2' Palinkas} + -sym-license-dist = {GPLv2+} + -sym-license-use = {Public Domain} + -sym-comment = { Sheet level terminal (not really a symbol) for subsheet input net in a hierarchy } + } + } +} Index: tags/1.0.5/library/symbol/misc/shterm_inout.ry =================================================================== --- tags/1.0.5/library/symbol/misc/shterm_inout.ry (nonexistent) +++ tags/1.0.5/library/symbol/misc/shterm_inout.ry (revision 10414) @@ -0,0 +1,24 @@ +ha:cschem-group-v1 { + ha:group.1 { + src_uuid=AHibvjaMiL5NH+9/wR0AAAAK; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-5000; y1=-1500; mirx=1; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:line.3 { x1=-4000; y1=0; x2=-5000; y2=2000; stroke=sheet-decor; } + ha:line.4 { x1=-4000; y1=0; x2=-5000; y2=-2000; stroke=sheet-decor; } + ha:line.5 { x1=-5000; y1=-2000; x2=-16000; y2=-2000; stroke=sheet-decor; } + ha:line.6 { x1=-16000; y1=2000; x2=-5000; y2=2000; stroke=sheet-decor; } + ha:line.7 { x1=-16000; y1=-2000; x2=-17000; y2=0; stroke=sheet-decor; } + ha:line.8 { x1=-17000; y1=0; x2=-16000; y2=2000; stroke=sheet-decor; } + } + ha:attrib { + name=TERMNAME + role=terminal + -sym-source = {sch-rnd default symbol lib} + -sym-copyright = {(C) 2024 Tibor 'Igor2' Palinkas} + -sym-license-dist = {GPLv2+} + -sym-license-use = {Public Domain} + -sym-comment = { Sheet level terminal (not really a symbol) for subsheet input/output net in a hierarchy } + } + } +} Index: tags/1.0.5/library/symbol/misc/shterm_out.ry =================================================================== --- tags/1.0.5/library/symbol/misc/shterm_out.ry (nonexistent) +++ tags/1.0.5/library/symbol/misc/shterm_out.ry (revision 10414) @@ -0,0 +1,24 @@ +ha:cschem-group-v1 { + ha:group.1 { + src_uuid=AHibvjaMiL5NH+9/wR0AAAAI; + mirx=1; + li:objects { + ha:line.1 { x1=4000; y1=0; x2=0; y2=0; stroke=term-decor; } + ha:text.2 { x1=4500; y1=-1500; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:line.3 { x1=17000; y1=0; x2=16000; y2=2000; stroke=sheet-decor; } + ha:line.4 { x1=17000; y1=0; x2=16000; y2=-2000; stroke=sheet-decor; } + ha:line.5 { x1=16000; y1=-2000; x2=4000; y2=-2000; stroke=sheet-decor; } + ha:line.6 { x1=4000; y1=2000; x2=16000; y2=2000; stroke=sheet-decor; } + ha:line.7 { x1=4000; y1=2000; x2=4000; y2=-2000; stroke=sheet-decor; } + } + ha:attrib { + name=TERMNAME + role=terminal + -sym-source = {sch-rnd default symbol lib} + -sym-copyright = {(C) 2024 Tibor 'Igor2' Palinkas} + -sym-license-dist = {GPLv2+} + -sym-license-use = {Public Domain} + -sym-comment = { Sheet level terminal (not really a symbol) for subsheet output net in a hierarchy } + } + } +} Index: tags/1.0.5/library/symbol/misc/spice_command.ry =================================================================== --- tags/1.0.5/library/symbol/misc/spice_command.ry (nonexistent) +++ tags/1.0.5/library/symbol/misc/spice_command.ry (revision 10414) @@ -0,0 +1,28 @@ +ha:cschem-group-v1 { + ha:group.1 { + src_uuid=TeGEOMuew6iCb2kzckAAAAAD; + li:objects { + ha:text.1 { x1=2000; y1=-4000; dyntext=0; stroke=sym-decor; text=raw spice; } + ha:text.2 { x1=2000; y1=-8000; dyntext=0; stroke=sym-decor; text=command; } + ha:polygon.3 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=-10000; } + ha:line { x1=0; y1=-10000; x2=12000; y2=-10000; } + ha:line { x1=12000; y1=-10000; x2=12000; y2=0; } + ha:line { x1=12000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + } + ha:attrib { + role=symbol + spice/command = { } + -sym-source = {sch-rnd default symbol lib} + -sym-copyright = {(C) 2023 Tibor 'Igor2' Palinkas} + -sym-license-dist = {GPLv2+} + -sym-license-use = {Public Domain} + -sym-comment = { Fill in spice/command and use export_spice (e.g. the spice_raw view) to get that string exported at the end of the spice netlist file. } + } + } +} Index: tags/1.0.5/library/symbol/misc/titlebox.ry =================================================================== --- tags/1.0.5/library/symbol/misc/titlebox.ry (nonexistent) +++ tags/1.0.5/library/symbol/misc/titlebox.ry (revision 10414) @@ -0,0 +1,40 @@ +ha:cschem-group-v1 { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAAg; + li:objects { + ha:polygon.11 { + li:outline { + ha:line { x1=0; y1=0; x2=80000; y2=0; } + ha:line { x1=80000; y1=0; x2=80000; y2=20000; } + ha:line { x1=80000; y1=20000; x2=0; y2=20000; } + ha:line { x1=0; y1=20000; x2=0; y2=0; } + } + stroke = titlebox-frame; + fill = titlebox-fill; + } + # grid + ha:line.12 { x1=0; y1=10000; x2=80000; y2=10000; stroke=titlebox-frame; } + ha:line.13 { x1=40000; y1=10000; x2=40000; y2=0; stroke=titlebox-frame; } + + ha:text.20 { x1=1000; y1=16500; stroke=titlebox-big; text=TITLE; } + ha:text.21 { x1=1000; y1=10500; x2=79000; y2=16000; dyntext=1; stroke=titlebox-big; text={%../../A.title%}; } + + ha:text.22 { x1=1000; y1=5500; stroke=titlebox-small; text={PROJECT:}; } + ha:text.23 { x1=13000; y1=5500; x2=39000; y2=9500; dyntext=1; stroke=titlebox-big; text={%project.name%}; } + ha:text.24 { x1=1000; y1=500; stroke=titlebox-small; text={PAGE:}; } + ha:text.25 { x1=10000; y1=500; x2=39000; y2=4500; dyntext=1; stroke=titlebox-big; text={%../../A.page%}; } + + ha:text.26 { x1=41000; y1=5500; stroke=titlebox-small; text={FILE:}; } + ha:text.27 { x1=48000; y1=5500; x2=79000; y2=9500; dyntext=1; stroke=titlebox-big; text={%filename%}; } + ha:text.28 { x1=41000; y1=500; stroke=titlebox-small; text={MAINTAINER:}; } + ha:text.29 { x1=55000; y1=500; x2=79000; y2=4500; dyntext=1; stroke=titlebox-big; text={%../../A.maintainer%}; } + } + ha:attrib { + purpose = titlebox + -sym-source = {sch-rnd default symbol lib} + -sym-copyright = {(C) 2022 Tibor 'Igor2' Palinkas} + -sym-license-dist = {GPLv2+} + -sym-license-use = {Public Domain} + } + } +} Index: tags/1.0.5/library/symbol/passive/capacitor-1.ry =================================================================== --- tags/1.0.5/library/symbol/passive/capacitor-1.ry (nonexistent) +++ tags/1.0.5/library/symbol/passive/capacitor-1.ry (revision 10414) @@ -0,0 +1,48 @@ +ha:cschem-group-v1 { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAAh; + li:objects { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAAi; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=iNOQfJpO6hT/HFDFGjoAAAAj; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.5 { x1=9000; y1=5000; x2=9000; y2=-5000; stroke=sym-decor; } + ha:line.6 { x1=11000; y1=5000; x2=11000; y2=-5000; stroke=sym-decor; } + ha:line.7 { x1=4000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.8 { x1=11000; y1=0; x2=16000; y2=0; stroke=sym-decor; } + } + ha:attrib { + name=C?? + role=symbol + value= + ha:device = { value=capacitor; prio=31050; } + ha:spice/prefix = { value=C; prio=31050; } + -sym-source = {sch-rnd default symbol lib} + -sym-copyright = {(C) 2022 Tibor 'Igor2' Palinkas} + -sym-license-dist = {GPLv2+} + -sym-license-use = {Public Domain} + } + } +} Index: tags/1.0.5/library/symbol/passive/capacitor-2.ry =================================================================== --- tags/1.0.5/library/symbol/passive/capacitor-2.ry (nonexistent) +++ tags/1.0.5/library/symbol/passive/capacitor-2.ry (revision 10414) @@ -0,0 +1,52 @@ +ha:cschem-group-v1 { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAAk; + li:objects { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAAl; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=N + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.2 { + uuid=iNOQfJpO6hT/HFDFGjoAAAAm; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=P + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:text.3 { x1=12000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.5 { x1=9000; y1=5000; x2=9000; y2=-5000; stroke=sym-decor; } + ha:line.6 { x1=4000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.7 { x1=11000; y1=0; x2=16000; y2=0; stroke=sym-decor; } + ha:arc.8 { cx=34000; cy=0; r=23000; sang=167.500000; dang=25.000000; stroke=sym-decor; } + ha:line.9 { x1=6000; y1=-3000; x2=8000; y2=-3000; stroke=sym-decor; } + ha:line.10 { x1=7000; y1=-4000; x2=7000; y2=-2000; stroke=sym-decor; } + } + ha:attrib { + name=C?? + role=symbol + value= + ha:device = { value=capacitor; prio=31050; } + ha:spice/prefix = { value=C; prio=31050; } + -sym-source = {sch-rnd default symbol lib} + -sym-copyright = {(C) 2022 Tibor 'Igor2' Palinkas} + -sym-license-dist = {GPLv2+} + -sym-license-use = {Public Domain} + } + } +} Index: tags/1.0.5/library/symbol/passive/capacitor-3.ry =================================================================== --- tags/1.0.5/library/symbol/passive/capacitor-3.ry (nonexistent) +++ tags/1.0.5/library/symbol/passive/capacitor-3.ry (revision 10414) @@ -0,0 +1,55 @@ +ha:cschem-group-v1 { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAAn; + li:objects { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAAo; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=N + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.2 { + uuid=iNOQfJpO6hT/HFDFGjoAAAAp; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=P + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:text.3 { x1=12000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.5 { x1=9000; y1=5000; x2=9000; y2=-5000; stroke=sym-decor; } + ha:line.6 { x1=11000; y1=5000; x2=11000; y2=-5000; stroke=sym-decor; } + ha:line.7 { x1=11000; y1=0; x2=16000; y2=0; stroke=sym-decor; } + ha:line.8 { x1=9000; y1=5000; x2=7000; y2=5000; stroke=sym-decor; } + ha:line.9 { x1=7000; y1=5000; x2=7000; y2=-5000; stroke=sym-decor; } + ha:line.10 { x1=7000; y1=-5000; x2=9000; y2=-5000; stroke=sym-decor; } + ha:line.11 { x1=7000; y1=0; x2=4000; y2=0; stroke=sym-decor; } + ha:line.12 { x1=5000; y1=-4000; x2=5000; y2=-2000; stroke=sym-decor; } + ha:line.13 { x1=4000; y1=-3000; x2=6000; y2=-3000; stroke=sym-decor; } + } + ha:attrib { + name=C?? + role=symbol + value= + ha:device = { value=capacitor; prio=31050; } + ha:spice/prefix = { value=C; prio=31050; } + -sym-source = {sch-rnd default symbol lib} + -sym-copyright = {(C) 2022 Tibor 'Igor2' Palinkas} + -sym-license-dist = {GPLv2+} + -sym-license-use = {Public Domain} + } + } +} Index: tags/1.0.5/library/symbol/passive/capacitor-var-1.ry =================================================================== --- tags/1.0.5/library/symbol/passive/capacitor-var-1.ry (nonexistent) +++ tags/1.0.5/library/symbol/passive/capacitor-var-1.ry (revision 10414) @@ -0,0 +1,57 @@ +ha:cschem-group-v1 { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAAq; + li:objects { + ha:line.1 { x1=5757; y1=-4243; x2=14243; y2=4243; stroke=sym-decor; } + ha:polygon.2 { + li:outline { + ha:line { x1=12121; y1=3536; x2=13536; y2=2121; } + ha:line { x1=13536; y1=2121; x2=14243; y2=4243; } + ha:line { x1=14243; y1=4243; x2=12121; y2=3536; } + } + stroke=sym-decor; + fill=sym-decor; + } + ha:group.3 { + uuid=iNOQfJpO6hT/HFDFGjoAAAAr; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.4 { + uuid=iNOQfJpO6hT/HFDFGjoAAAAs; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.5 { x1=12000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.6 { x1=8000; y1=6000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.7 { x1=9000; y1=5000; x2=9000; y2=-5000; stroke=sym-decor; } + ha:line.8 { x1=11000; y1=5000; x2=11000; y2=-5000; stroke=sym-decor; } + ha:line.9 { x1=4000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.10 { x1=11000; y1=0; x2=16000; y2=0; stroke=sym-decor; } + } + ha:attrib { + name=REFDES + role=symbol + ha:device = { value=variable-capacitor; prio=31050; } + ha:spice/prefix = { value=C; prio=31050; } + -sym-source = {sch-rnd default symbol lib} + -sym-copyright = {(C) 2022 Tibor 'Igor2' Palinkas} + -sym-license-dist = {GPLv2+} + -sym-license-use = {Public Domain} + } + } +} Index: tags/1.0.5/library/symbol/passive/coil-1.ry =================================================================== --- tags/1.0.5/library/symbol/passive/coil-1.ry (nonexistent) +++ tags/1.0.5/library/symbol/passive/coil-1.ry (revision 10414) @@ -0,0 +1,47 @@ +ha:cschem-group-v1 { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAAt; + li:objects { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAAu; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=iNOQfJpO6hT/HFDFGjoAAAAv; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:arc.5 { cx=6000; cy=0; r=2000; sang=0.000000; dang=180.000000; stroke=sym-decor; } + ha:arc.6 { cx=10000; cy=0; r=2000; sang=0.000000; dang=180.000000; stroke=sym-decor; } + ha:arc.7 { cx=14000; cy=0; r=2000; sang=0.000000; dang=180.000000; stroke=sym-decor; } + } + ha:attrib { + name=L?? + role=symbol + value= + ha:device = { value=coil; prio=31050; } + ha:spice/prefix = { value=L; prio=31050; } + -sym-source = {sch-rnd default symbol lib} + -sym-copyright = {(C) 2022 Tibor 'Igor2' Palinkas} + -sym-license-dist = {GPLv2+} + -sym-license-use = {Public Domain} + } + } +} Index: tags/1.0.5/library/symbol/passive/coil-2.ry =================================================================== --- tags/1.0.5/library/symbol/passive/coil-2.ry (nonexistent) +++ tags/1.0.5/library/symbol/passive/coil-2.ry (revision 10414) @@ -0,0 +1,49 @@ +ha:cschem-group-v1 { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAAw; + li:objects { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAAx; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=iNOQfJpO6hT/HFDFGjoAAAAy; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:arc.5 { cx=7000; cy=0; r=2000; sang=-40.000000; dang=220.000000; stroke=sym-decor; } + ha:arc.6 { cx=13000; cy=0; r=2000; sang=0.000000; dang=220.000000; stroke=sym-decor; } + ha:arc.7 { cx=10000; cy=0; r=2000; sang=-40.000000; dang=260.000000; stroke=sym-decor; } + ha:line.8 { x1=4000; y1=0; x2=5000; y2=0; stroke=sym-decor; } + ha:line.9 { x1=15000; y1=0; x2=16000; y2=0; stroke=sym-decor; } + } + ha:attrib { + name=L?? + role=symbol + value= + ha:device = { value=coil; prio=31050; } + ha:spice/prefix = { value=L; prio=31050; } + -sym-source = {sch-rnd default symbol lib} + -sym-copyright = {(C) 2022 Tibor 'Igor2' Palinkas} + -sym-license-dist = {GPLv2+} + -sym-license-use = {Public Domain} + } + } +} Index: tags/1.0.5/library/symbol/passive/coil-var-1.ry =================================================================== --- tags/1.0.5/library/symbol/passive/coil-var-1.ry (nonexistent) +++ tags/1.0.5/library/symbol/passive/coil-var-1.ry (revision 10414) @@ -0,0 +1,68 @@ +ha:cschem-group-v1 { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAAz; + li:objects { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAA0; + x=8000; y=-4000; rot=90.000000; + li:objects { + ha:line.1 { x1=1000; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=V + role=terminal + } + } + ha:polygon.2 { + li:outline { + ha:line { x1=7000; y1=-3000; x2=9000; y2=-3000; } + ha:line { x1=9000; y1=-3000; x2=8000; y2=0; } + ha:line { x1=8000; y1=0; x2=7000; y2=-3000; } + } + stroke=term-decor; + fill=term-decor; + } + ha:group.3 { + uuid=iNOQfJpO6hT/HFDFGjoAAAA1; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.4 { + uuid=iNOQfJpO6hT/HFDFGjoAAAA2; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.5 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.6 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:arc.7 { cx=6000; cy=0; r=2000; sang=0.000000; dang=180.000000; stroke=sym-decor; } + ha:arc.8 { cx=10000; cy=0; r=2000; sang=0.000000; dang=180.000000; stroke=sym-decor; } + ha:arc.9 { cx=14000; cy=0; r=2000; sang=0.000000; dang=180.000000; stroke=sym-decor; } + } + ha:attrib { + name=L?? + role=symbol + value= + ha:device = { value=variable-coil; prio=31050; } + ha:spice/prefix = { value=L; prio=31050; } + -sym-source = {sch-rnd default symbol lib} + -sym-copyright = {(C) 2022 Tibor 'Igor2' Palinkas} + -sym-license-dist = {GPLv2+} + -sym-license-use = {Public Domain} + } + } +} Index: tags/1.0.5/library/symbol/passive/coil-var-2.ry =================================================================== --- tags/1.0.5/library/symbol/passive/coil-var-2.ry (nonexistent) +++ tags/1.0.5/library/symbol/passive/coil-var-2.ry (revision 10414) @@ -0,0 +1,70 @@ +ha:cschem-group-v1 { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAA3; + li:objects { + ha:polygon.1 { + li:outline { + ha:line { x1=7000; y1=-4000; x2=9000; y2=-4000; } + ha:line { x1=9000; y1=-4000; x2=8000; y2=-1000; } + ha:line { x1=8000; y1=-1000; x2=7000; y2=-4000; } + } + stroke=term-decor; + fill=term-decor; + } + ha:group.2 { + uuid=iNOQfJpO6hT/HFDFGjoAAAA4; + x=8000; y=-4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=V + role=terminal + } + } + ha:group.3 { + uuid=iNOQfJpO6hT/HFDFGjoAAAA5; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.4 { + uuid=iNOQfJpO6hT/HFDFGjoAAAA6; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.5 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.6 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:arc.7 { cx=7000; cy=0; r=2000; sang=-40.000000; dang=220.000000; stroke=sym-decor; } + ha:arc.8 { cx=13000; cy=0; r=2000; sang=0.000000; dang=220.000000; stroke=sym-decor; } + ha:arc.9 { cx=10000; cy=0; r=2000; sang=-40.000000; dang=260.000000; stroke=sym-decor; } + ha:line.10 { x1=4000; y1=0; x2=5000; y2=0; stroke=sym-decor; } + ha:line.11 { x1=15000; y1=0; x2=16000; y2=0; stroke=sym-decor; } + } + ha:attrib { + name=L?? + role=symbol + value= + ha:device = { value=variable-coil; prio=31050; } + ha:spice/prefix = { value=L; prio=31050; } + -sym-source = {sch-rnd default symbol lib} + -sym-copyright = {(C) 2022 Tibor 'Igor2' Palinkas} + -sym-license-dist = {GPLv2+} + -sym-license-use = {Public Domain} + } + } +} Index: tags/1.0.5/library/symbol/passive/coil-var-3.ry =================================================================== --- tags/1.0.5/library/symbol/passive/coil-var-3.ry (nonexistent) +++ tags/1.0.5/library/symbol/passive/coil-var-3.ry (revision 10414) @@ -0,0 +1,57 @@ +ha:cschem-group-v1 { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAA7; + li:objects { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAA9; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=iNOQfJpO6hT/HFDFGjoAAAA+; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:arc.5 { cx=6000; cy=0; r=2000; sang=0.000000; dang=180.000000; stroke=sym-decor; } + ha:arc.6 { cx=10000; cy=0; r=2000; sang=0.000000; dang=180.000000; stroke=sym-decor; } + ha:arc.7 { cx=14000; cy=0; r=2000; sang=0.000000; dang=180.000000; stroke=sym-decor; } + ha:line.8 { x1=5757; y1=-4243; x2=14243; y2=4243; stroke=sym-decor; } + ha:polygon.9 { + li:outline { + ha:line { x1=12121; y1=3536; x2=13536; y2=2121; } + ha:line { x1=13536; y1=2121; x2=14243; y2=4243; } + ha:line { x1=14243; y1=4243; x2=12121; y2=3536; } + } + stroke=sym-decor; + fill=sym-decor; + } + } + ha:attrib { + name=L?? + role=symbol + value= + ha:device = { value=variable-coil; prio=31050; } + ha:spice/prefix = { value=L; prio=31050; } + -sym-source = {sch-rnd default symbol lib} + -sym-copyright = {(C) 2022 Tibor 'Igor2' Palinkas} + -sym-license-dist = {GPLv2+} + -sym-license-use = {Public Domain} + } + } +} Index: tags/1.0.5/library/symbol/passive/coil-var-4.ry =================================================================== --- tags/1.0.5/library/symbol/passive/coil-var-4.ry (nonexistent) +++ tags/1.0.5/library/symbol/passive/coil-var-4.ry (revision 10414) @@ -0,0 +1,59 @@ +ha:cschem-group-v1 { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAA/; + li:objects { + ha:line.1 { x1=5757; y1=-4243; x2=14243; y2=4243; stroke=sym-decor; } + ha:polygon.2 { + li:outline { + ha:line { x1=12121; y1=3536; x2=13536; y2=2121; } + ha:line { x1=13536; y1=2121; x2=14243; y2=4243; } + ha:line { x1=14243; y1=4243; x2=12121; y2=3536; } + } + stroke=sym-decor; + fill=sym-decor; + } + ha:group.3 { + uuid=iNOQfJpO6hT/HFDFGjoAAABA; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.4 { + uuid=iNOQfJpO6hT/HFDFGjoAAABB; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.5 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.6 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:arc.7 { cx=7000; cy=0; r=2000; sang=-40.000000; dang=220.000000; stroke=sym-decor; } + ha:arc.8 { cx=13000; cy=0; r=2000; sang=0.000000; dang=220.000000; stroke=sym-decor; } + ha:arc.9 { cx=10000; cy=0; r=2000; sang=-40.000000; dang=260.000000; stroke=sym-decor; } + ha:line.10 { x1=4000; y1=0; x2=5000; y2=0; stroke=sym-decor; } + ha:line.11 { x1=15000; y1=0; x2=16000; y2=0; stroke=sym-decor; } + } + ha:attrib { + name=L?? + role=symbol + value= + ha:device = { value=variable-coil; prio=31050; } + ha:spice/prefix = { value=L; prio=31050; } + -sym-source = {sch-rnd default symbol lib} + -sym-copyright = {(C) 2022 Tibor 'Igor2' Palinkas} + -sym-license-dist = {GPLv2+} + -sym-license-use = {Public Domain} + } + } +} Index: tags/1.0.5/library/symbol/passive/resistor-1.ry =================================================================== --- tags/1.0.5/library/symbol/passive/resistor-1.ry (nonexistent) +++ tags/1.0.5/library/symbol/passive/resistor-1.ry (revision 10414) @@ -0,0 +1,53 @@ +ha:cschem-group-v1 { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAABC; + li:objects { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + name=R?? + role=symbol + value= + ha:device = { value=resistor; prio=31050; } + ha:spice/prefix = { value=R; prio=31050; } + -sym-source = {sch-rnd default symbol lib} + -sym-copyright = {(C) 2022 Tibor 'Igor2' Palinkas} + -sym-license-dist = {GPLv2+} + -sym-license-use = {Public Domain} + } + } +} Index: tags/1.0.5/library/symbol/passive/resistor-2.ry =================================================================== --- tags/1.0.5/library/symbol/passive/resistor-2.ry (nonexistent) +++ tags/1.0.5/library/symbol/passive/resistor-2.ry (revision 10414) @@ -0,0 +1,53 @@ +ha:cschem-group-v1 { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAABF; + li:objects { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAABG; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=iNOQfJpO6hT/HFDFGjoAAABH; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=4000; y1=-2000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=4000; y1=2000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + name=R?? + role=symbol + value= + ha:device = { value=resistor; prio=31050; } + ha:spice/prefix = { value=R; prio=31050; } + -sym-source = {sch-rnd default symbol lib} + -sym-copyright = {(C) 2022 Tibor 'Igor2' Palinkas} + -sym-license-dist = {GPLv2+} + -sym-license-use = {Public Domain} + } + } +} Index: tags/1.0.5/library/symbol/passive/resistor-3.ry =================================================================== --- tags/1.0.5/library/symbol/passive/resistor-3.ry (nonexistent) +++ tags/1.0.5/library/symbol/passive/resistor-3.ry (revision 10414) @@ -0,0 +1,51 @@ +ha:cschem-group-v1 { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAABI; + li:objects { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAABJ; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=iNOQfJpO6hT/HFDFGjoAAABK; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=14000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=10000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.5 { x1=9000; y1=2000; x2=7000; y2=-2000; stroke=sym-decor; } + ha:line.6 { x1=7000; y1=-2000; x2=5000; y2=2000; stroke=sym-decor; } + ha:line.7 { x1=9000; y1=2000; x2=11000; y2=-2000; stroke=sym-decor; } + ha:line.8 { x1=11000; y1=-2000; x2=13000; y2=2000; stroke=sym-decor; } + ha:line.9 { x1=13000; y1=2000; x2=15000; y2=-2000; stroke=sym-decor; } + ha:line.10 { x1=15000; y1=-2000; x2=16000; y2=0; stroke=sym-decor; } + ha:line.11 { x1=5000; y1=2000; x2=4000; y2=0; stroke=sym-decor; } + } + ha:attrib { + name=R?? + role=symbol + value= + ha:device = {value=resistor; prio=31050; } + ha:spice/prefix = { value=R; prio=31050; } + -sym-source = {sch-rnd default symbol lib} + -sym-copyright = {(C) 2022 Tibor 'Igor2' Palinkas} + -sym-license-dist = {GPLv2+} + -sym-license-use = {Public Domain} + } + } +} Index: tags/1.0.5/library/symbol/passive/resistor-var-1.ry =================================================================== --- tags/1.0.5/library/symbol/passive/resistor-var-1.ry (nonexistent) +++ tags/1.0.5/library/symbol/passive/resistor-var-1.ry (revision 10414) @@ -0,0 +1,74 @@ +ha:cschem-group-v1 { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAABL; + li:objects { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAABM; + x=8000; y=-4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=V + role=terminal + } + } + ha:polygon.2 { + li:outline { + ha:line { x1=7000; y1=-5000; x2=9000; y2=-5000; } + ha:line { x1=9000; y1=-5000; x2=8000; y2=-2000; } + ha:line { x1=8000; y1=-2000; x2=7000; y2=-5000; } + } + stroke=term-decor; + fill=term-decor; + } + ha:group.3 { + uuid=iNOQfJpO6hT/HFDFGjoAAABN; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.4 { + uuid=iNOQfJpO6hT/HFDFGjoAAABO; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.5 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.6 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.7 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + name=R?? + role=symbol + value= + ha:device = { value=variable-resistor; prio=31050; } + ha:spice/prefix = { value=R; prio=31050; } + -sym-source = {sch-rnd default symbol lib} + -sym-copyright = {(C) 2022 Tibor 'Igor2' Palinkas} + -sym-license-dist = {GPLv2+} + -sym-license-use = {Public Domain} + } + } +} Index: tags/1.0.5/library/symbol/passive/resistor-var-2.ry =================================================================== --- tags/1.0.5/library/symbol/passive/resistor-var-2.ry (nonexistent) +++ tags/1.0.5/library/symbol/passive/resistor-var-2.ry (revision 10414) @@ -0,0 +1,74 @@ +ha:cschem-group-v1 { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAABP; + li:objects { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAABQ; + x=8000; y=-4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=V + role=terminal + } + } + ha:polygon.2 { + li:outline { + ha:line { x1=7000; y1=-5000; x2=9000; y2=-5000; } + ha:line { x1=9000; y1=-5000; x2=8000; y2=-2000; } + ha:line { x1=8000; y1=-2000; x2=7000; y2=-5000; } + } + stroke=term-decor; + fill=term-decor; + } + ha:group.3 { + uuid=iNOQfJpO6hT/HFDFGjoAAABR; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.4 { + uuid=iNOQfJpO6hT/HFDFGjoAAABS; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.5 { x1=4000; y1=-2000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.6 { x1=4000; y1=2000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.7 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + name=R?? + role=symbol + value= + ha:device = { value=variable-resistor; prio=31050; } + ha:spice/prefix = { value=R; prio=31050; } + -sym-source = {sch-rnd default symbol lib} + -sym-copyright = {(C) 2022 Tibor 'Igor2' Palinkas} + -sym-license-dist = {GPLv2+} + -sym-license-use = {Public Domain} + } + } +} Index: tags/1.0.5/library/symbol/passive/resistor-var-3.ry =================================================================== --- tags/1.0.5/library/symbol/passive/resistor-var-3.ry (nonexistent) +++ tags/1.0.5/library/symbol/passive/resistor-var-3.ry (revision 10414) @@ -0,0 +1,72 @@ +ha:cschem-group-v1 { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAABT; + li:objects { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAABU; + x=8000; y=-4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=V + role=terminal + } + } + ha:polygon.2 { + li:outline { + ha:line { x1=7000; y1=-5000; x2=9000; y2=-5000; } + ha:line { x1=9000; y1=-5000; x2=8000; y2=-2000; } + ha:line { x1=8000; y1=-2000; x2=7000; y2=-5000; } + } + stroke=term-decor; + fill=term-decor; + } + ha:group.3 { + uuid=iNOQfJpO6hT/HFDFGjoAAABV; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.4 { + uuid=iNOQfJpO6hT/HFDFGjoAAABW; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.5 { x1=14000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.6 { x1=10000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:line.7 { x1=9000; y1=2000; x2=7000; y2=-2000; stroke=sym-decor; } + ha:line.8 { x1=7000; y1=-2000; x2=5000; y2=2000; stroke=sym-decor; } + ha:line.9 { x1=9000; y1=2000; x2=11000; y2=-2000; stroke=sym-decor; } + ha:line.10 { x1=11000; y1=-2000; x2=13000; y2=2000; stroke=sym-decor; } + ha:line.11 { x1=13000; y1=2000; x2=15000; y2=-2000; stroke=sym-decor; } + ha:line.12 { x1=15000; y1=-2000; x2=16000; y2=0; stroke=sym-decor; } + ha:line.13 { x1=5000; y1=2000; x2=4000; y2=0; stroke=sym-decor; } + } + ha:attrib { + name=R?? + role=symbol + value= + ha:device = { value=variable-resistor; prio=31050; } + ha:spice/prefix = { value=R; prio=31050; } + -sym-source = {sch-rnd default symbol lib} + -sym-copyright = {(C) 2022 Tibor 'Igor2' Palinkas} + -sym-license-dist = {GPLv2+} + -sym-license-use = {Public Domain} + } + } +} Index: tags/1.0.5/library/symbol/power/battery-1.ry =================================================================== --- tags/1.0.5/library/symbol/power/battery-1.ry (nonexistent) +++ tags/1.0.5/library/symbol/power/battery-1.ry (revision 10414) @@ -0,0 +1,46 @@ +ha:cschem-group-v1 { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAABX; + li:objects { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAABY; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=N + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.2 { + uuid=iNOQfJpO6hT/HFDFGjoAAABZ; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=P + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:line.3 { x1=9000; y1=5000; x2=9000; y2=-5000; stroke=sym-decor; } + ha:line.4 { x1=11000; y1=2000; x2=11000; y2=-2000; stroke=sym-decor; } + ha:line.5 { x1=4000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=11000; y1=0; x2=16000; y2=0; stroke=sym-decor; } + ha:text.7 { x1=4000; y1=6000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + name=B?? + role=symbol + -sym-source = {sch-rnd default symbol lib} + -sym-copyright = {(C) 2022 Tibor 'Igor2' Palinkas} + -sym-license-dist = {GPLv2+} + -sym-license-use = {Public Domain} + } + } +} Index: tags/1.0.5/library/symbol/power/battery-2.ry =================================================================== --- tags/1.0.5/library/symbol/power/battery-2.ry (nonexistent) +++ tags/1.0.5/library/symbol/power/battery-2.ry (revision 10414) @@ -0,0 +1,48 @@ +ha:cschem-group-v1 { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAABa; + li:objects { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAABb; + x=24000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=N + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.2 { + uuid=iNOQfJpO6hT/HFDFGjoAAABc; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=P + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:line.3 { x1=9000; y1=5000; x2=9000; y2=-5000; stroke=sym-decor; } + ha:line.4 { x1=11000; y1=2000; x2=11000; y2=-2000; stroke=sym-decor; } + ha:line.5 { x1=4000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=15000; y1=0; x2=20000; y2=0; stroke=sym-decor; } + ha:line.7 { x1=15000; y1=2000; x2=15000; y2=-2000; stroke=sym-decor; } + ha:line.8 { x1=13000; y1=5000; x2=13000; y2=-5000; stroke=sym-decor; } + ha:text.9 { x1=4000; y1=6000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + name=B?? + role=symbol + -sym-source = {sch-rnd default symbol lib} + -sym-copyright = {(C) 2022 Tibor 'Igor2' Palinkas} + -sym-license-dist = {GPLv2+} + -sym-license-use = {Public Domain} + } + } +} Index: tags/1.0.5/library/symbol/power/battery-3.ry =================================================================== --- tags/1.0.5/library/symbol/power/battery-3.ry (nonexistent) +++ tags/1.0.5/library/symbol/power/battery-3.ry (revision 10414) @@ -0,0 +1,50 @@ +ha:cschem-group-v1 { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAABd; + li:objects { + ha:line.1 { x1=15000; y1=5000; x2=15000; y2=-5000; stroke=sym-decor; } + ha:line.2 { x1=11000; y1=5000; x2=11000; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=13000; y1=2000; x2=13000; y2=-2000; stroke=sym-decor; } + ha:group.4 { + uuid=iNOQfJpO6hT/HFDFGjoAAABe; + x=24000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=N + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.5 { + uuid=iNOQfJpO6hT/HFDFGjoAAABf; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=P + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:line.6 { x1=4000; y1=0; x2=7000; y2=0; stroke=sym-decor; } + ha:line.7 { x1=17000; y1=2000; x2=17000; y2=-2000; stroke=sym-decor; } + ha:line.8 { x1=7000; y1=5000; x2=7000; y2=-5000; stroke=sym-decor; } + ha:line.9 { x1=9000; y1=2000; x2=9000; y2=-2000; stroke=sym-decor; } + ha:line.10 { x1=17000; y1=0; x2=20000; y2=0; stroke=sym-decor; } + ha:text.11 { x1=4000; y1=6000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + name=B?? + role=symbol + -sym-source = {sch-rnd default symbol lib} + -sym-copyright = {(C) 2022 Tibor 'Igor2' Palinkas} + -sym-license-dist = {GPLv2+} + -sym-license-use = {Public Domain} + } + } +} Index: tags/1.0.5/library/symbol/power/fuse-1.ry =================================================================== --- tags/1.0.5/library/symbol/power/fuse-1.ry (nonexistent) +++ tags/1.0.5/library/symbol/power/fuse-1.ry (revision 10414) @@ -0,0 +1,44 @@ +ha:cschem-group-v1 { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAABg; + li:objects { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAABh; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=iNOQfJpO6hT/HFDFGjoAAABi; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:arc.5 { cx=7000; cy=0; r=3000; sang=180.000000; dang=180.000000; stroke=sym-decor; } + ha:arc.6 { cx=13000; cy=0; r=3000; sang=180.000000; dang=-180.000000; stroke=sym-decor; } + } + ha:attrib { + name=F?? + role=symbol + value= + -sym-source = {sch-rnd default symbol lib} + -sym-copyright = {(C) 2022 Tibor 'Igor2' Palinkas} + -sym-license-dist = {GPLv2+} + -sym-license-use = {Public Domain} + } + } +} Index: tags/1.0.5/library/symbol/power/fuse-2.ry =================================================================== --- tags/1.0.5/library/symbol/power/fuse-2.ry (nonexistent) +++ tags/1.0.5/library/symbol/power/fuse-2.ry (revision 10414) @@ -0,0 +1,52 @@ +ha:cschem-group-v1 { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAABj; + li:objects { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAABk; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=iNOQfJpO6hT/HFDFGjoAAABl; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + ha:line.6 { x1=4000; y1=0; x2=16000; y2=0; stroke=sym-decor; } + } + ha:attrib { + name=F?? + role=symbol + value= + -sym-source = {sch-rnd default symbol lib} + -sym-copyright = {(C) 2022 Tibor 'Igor2' Palinkas} + -sym-license-dist = {GPLv2+} + -sym-license-use = {Public Domain} + } + } +} Index: tags/1.0.5/library/symbol/power/gnd-1.ry =================================================================== --- tags/1.0.5/library/symbol/power/gnd-1.ry (nonexistent) +++ tags/1.0.5/library/symbol/power/gnd-1.ry (revision 10414) @@ -0,0 +1,30 @@ +ha:cschem-group-v1 { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAABm; + li:objects { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + drc/require_graphical_conn=1 + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + role=symbol + li:connect = { {1:GND}; } + -sym-source = {sch-rnd default symbol lib} + -sym-copyright = {(C) 2022 Tibor 'Igor2' Palinkas} + -sym-license-dist = {GPLv2+} + -sym-license-use = {Public Domain} + } + } +} Index: tags/1.0.5/library/symbol/power/ldo.ry =================================================================== --- tags/1.0.5/library/symbol/power/ldo.ry (nonexistent) +++ tags/1.0.5/library/symbol/power/ldo.ry (revision 10414) @@ -0,0 +1,70 @@ +ha:cschem-group-v1 { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAABo; + li:objects { + ha:text.1 { x1=-8000; y1=-4000; rot=0; stroke=sym-primary; dyntext=1; floater=1;text={%../A.name%}; } + ha:polygon.2 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=8000; stroke=sym-decor; } + ha:line { x1=0; y1=8000; x2=24000; y2=8000; stroke=sym-decor; } + ha:line { x1=24000; y1=8000; x2=24000; y2=0; stroke=sym-decor; } + ha:line { x1=24000; y1=0; x2=0; y2=0; stroke=sym-decor; } + } + stroke=sym-decor + } + ha:group.3 { + uuid=iNOQfJpO6hT/HFDFGjoAAABp; + x=0; y=4000; + rot=0; mirx=1; miry=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; rot=0; stroke=term-primary; dyntext=1; text={%../a.display/name%}; } + ha:text.3 { x1=-500; y1=-2000; rot=0; mirx=1term-secondary; stroke=term-secondary; dyntext=1; text={%../A.name%}; } + } + ha:attrib { + role=terminal; + pinnum=1; + name=in; + } + } + ha:group.4 { + uuid=iNOQfJpO6hT/HFDFGjoAAABq; + x=24000; y=4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; rot=0; stroke=term-primary; dyntext=1; text={%../a.display/name%}; } + ha:text.3 { x1=-500; y1=-2000; rot=0; mirx=1term-secondary; stroke=term-secondary; dyntext=1; text={%../A.name%}; } + } + ha:attrib { + role=terminal; + pinnum=3; + name=out; + } + } + ha:group.5 { + uuid=iNOQfJpO6hT/HFDFGjoAAABr; + x=12000; y=0; + rot=-90; mirx=1; miry=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=1000; y1=0; rot=0; stroke=term-primary; dyntext=1; text={%../a.display/name%}; } + ha:text.3 { x1=-500; y1=-2000; rot=0; mirx=1term-secondary; stroke=term-secondary; dyntext=1; text={%../A.name%}; } + } + ha:attrib { + role=terminal; + pinnum=2; + name=gnd; + } + } + } + ha:attrib { + role=symbol; + name={U?}; + -symbol_generator=boxsym-rnd; + -sym-copyright={(C) 2022 Tibor 'Igor2' Palinkas}; + -sym-license-use=Public Domain; + -sym-source=sch-rnd default symbol lib; + -sym-license-dist={GPLv2+}; + } + } +} Index: tags/1.0.5/library/symbol/power/meter.ry =================================================================== --- tags/1.0.5/library/symbol/power/meter.ry (nonexistent) +++ tags/1.0.5/library/symbol/power/meter.ry (revision 10414) @@ -0,0 +1,53 @@ +ha:cschem-group-v1 { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAABs; + li:objects { + ha:arc.1 { cx=10000; cy=0; r=6000; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:group.2 { + uuid=iNOQfJpO6hT/HFDFGjoAAABt; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=N + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.3 { + uuid=iNOQfJpO6hT/HFDFGjoAAABu; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=P + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:polygon.4 { + li:outline { + ha:line { x1=15828; y1=8657; x2=18657; y2=5828; } + ha:line { x1=18657; y1=5828; x2=20071; y2=10071; } + ha:line { x1=20071; y1=10071; x2=15828; y2=8657; } + } + stroke=sym-decor; + fill=sym-decor; + } + ha:line.5 { x1=18000; y1=8000; x2=1000; y2=-9000; stroke=sym-decor; } + ha:text.6 { x1=0; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + name=V?? + role=symbol + -sym-source = {sch-rnd default symbol lib} + -sym-copyright = {(C) 2022 Tibor 'Igor2' Palinkas} + -sym-license-dist = {GPLv2+} + -sym-license-use = {Public Domain} + } + } +} Index: tags/1.0.5/library/symbol/power/rail.ry =================================================================== --- tags/1.0.5/library/symbol/power/rail.ry (nonexistent) +++ tags/1.0.5/library/symbol/power/rail.ry (revision 10414) @@ -0,0 +1,37 @@ +ha:cschem-group-v1 { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAABv; + li:objects { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAABw; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + drc/require_graphical_conn=1 + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-6000; y1=4000; x2=6000; y2=7000; halign=center; dyntext=1; stroke=sym-primary; text=%../A.rail%;; floater=1; } + } + ha:attrib { + role=symbol + rail=power + li:forge { + {delete,forge/tmp} + {scalar,forge/tmp} + {sub,^,1:,forge/tmp} + {suba,$,rail,forge/tmp} + {array,connect} + {append,connect,forge/tmp} + } + -sym-source = {sch-rnd default symbol lib} + -sym-copyright = {(C) 2022 Tibor 'Igor2' Palinkas} + -sym-license-dist = {GPLv2+} + -sym-license-use = {Public Domain} + } + } +} Index: tags/1.0.5/library/symbol/power/source-ac.ry =================================================================== --- tags/1.0.5/library/symbol/power/source-ac.ry (nonexistent) +++ tags/1.0.5/library/symbol/power/source-ac.ry (revision 10414) @@ -0,0 +1,45 @@ +ha:cschem-group-v1 { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAABx; + li:objects { + ha:arc.1 { cx=10000; cy=0; r=6000; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:arc.2 { cx=8000; cy=0; r=2000; sang=0.000000; dang=180.000000; stroke=sym-decor; } + ha:arc.3 { cx=12000; cy=0; r=2000; sang=180.000000; dang=180.000000; stroke=sym-decor; } + ha:group.4 { + uuid=iNOQfJpO6hT/HFDFGjoAAABy; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=N + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.5 { + uuid=iNOQfJpO6hT/HFDFGjoAAABz; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=P + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:text.6 { x1=0; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + name=V?? + role=symbol + -sym-source = {sch-rnd default symbol lib} + -sym-copyright = {(C) 2022 Tibor 'Igor2' Palinkas} + -sym-license-dist = {GPLv2+} + -sym-license-use = {Public Domain} + } + } +} Index: tags/1.0.5/library/symbol/power/source-dc.ry =================================================================== --- tags/1.0.5/library/symbol/power/source-dc.ry (nonexistent) +++ tags/1.0.5/library/symbol/power/source-dc.ry (revision 10414) @@ -0,0 +1,46 @@ +ha:cschem-group-v1 { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAB0; + li:objects { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAB1; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=N + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.2 { + uuid=iNOQfJpO6hT/HFDFGjoAAAB2; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=P + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:arc.3 { cx=10000; cy=0; r=6000; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:line.4 { x1=7000; y1=2000; x2=7000; y2=-2000; stroke=sym-decor; } + ha:line.5 { x1=5000; y1=0; x2=9000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=11000; y1=0; x2=15000; y2=0; stroke=sym-decor; } + ha:text.7 { x1=0; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + name=V?? + role=symbol + -sym-source = {sch-rnd default symbol lib} + -sym-copyright = {(C) 2022 Tibor 'Igor2' Palinkas} + -sym-license-dist = {GPLv2+} + -sym-license-use = {Public Domain} + } + } +} Index: tags/1.0.5/library/symbol/power/source.ry =================================================================== --- tags/1.0.5/library/symbol/power/source.ry (nonexistent) +++ tags/1.0.5/library/symbol/power/source.ry (revision 10414) @@ -0,0 +1,43 @@ +ha:cschem-group-v1 { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAB3; + li:objects { + ha:arc.1 { cx=10000; cy=0; r=6000; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:group.2 { + uuid=iNOQfJpO6hT/HFDFGjoAAAB4; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=N + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.3 { + uuid=iNOQfJpO6hT/HFDFGjoAAAB5; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=P + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:text.4 { x1=0; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + name=V?? + role=symbol + -sym-source = {sch-rnd default symbol lib} + -sym-copyright = {(C) 2022 Tibor 'Igor2' Palinkas} + -sym-license-dist = {GPLv2+} + -sym-license-use = {Public Domain} + } + } +} Index: tags/1.0.5/library/symbol/power/vcc.ry =================================================================== --- tags/1.0.5/library/symbol/power/vcc.ry (nonexistent) +++ tags/1.0.5/library/symbol/power/vcc.ry (revision 10414) @@ -0,0 +1,29 @@ +ha:cschem-group-v1 { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAB6; + li:objects { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAB7; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + drc/require_graphical_conn=1 + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-4000; y1=4000; x2=4000; y2=7000; halign=center; stroke=sym-primary; text=Vcc; } + } + ha:attrib { + role=symbol + li:connect = { {1:Vcc}; } + -sym-source = {sch-rnd default symbol lib} + -sym-copyright = {(C) 2022 Tibor 'Igor2' Palinkas} + -sym-license-dist = {GPLv2+} + -sym-license-use = {Public Domain} + } + } +} Index: tags/1.0.5/library/symbol/power/vdd.ry =================================================================== --- tags/1.0.5/library/symbol/power/vdd.ry (nonexistent) +++ tags/1.0.5/library/symbol/power/vdd.ry (revision 10414) @@ -0,0 +1,29 @@ +ha:cschem-group-v1 { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAB8; + li:objects { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAB9; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + drc/require_graphical_conn=1 + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-4000; y1=4000; x2=4000; y2=7000; halign=center; stroke=sym-primary; text=Vdd; } + } + ha:attrib { + role=symbol + li:connect = { {1:Vdd}; } + -sym-source = {sch-rnd default symbol lib} + -sym-copyright = {(C) 2022 Tibor 'Igor2' Palinkas} + -sym-license-dist = {GPLv2+} + -sym-license-use = {Public Domain} + } + } +} Index: tags/1.0.5/library/symbol/power/vee.ry =================================================================== --- tags/1.0.5/library/symbol/power/vee.ry (nonexistent) +++ tags/1.0.5/library/symbol/power/vee.ry (revision 10414) @@ -0,0 +1,29 @@ +ha:cschem-group-v1 { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAB+; + li:objects { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAAB/; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + drc/require_graphical_conn=1 + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-4000; y1=4000; x2=4000; y2=7000; halign=center; stroke=sym-primary; text=Vee; } + } + ha:attrib { + role=symbol + li:connect = { {1:Vee}; } + -sym-source = {sch-rnd default symbol lib} + -sym-copyright = {(C) 2022 Tibor 'Igor2' Palinkas} + -sym-license-dist = {GPLv2+} + -sym-license-use = {Public Domain} + } + } +} Index: tags/1.0.5/library/symbol/power/vss.ry =================================================================== --- tags/1.0.5/library/symbol/power/vss.ry (nonexistent) +++ tags/1.0.5/library/symbol/power/vss.ry (revision 10414) @@ -0,0 +1,29 @@ +ha:cschem-group-v1 { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAACA; + li:objects { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAACB; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + drc/require_graphical_conn=1 + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-4000; y1=4000; x2=4000; y2=7000; halign=center; stroke=sym-primary; text=Vss; } + } + ha:attrib { + role=symbol + li:connect = { {1:Vss}; } + -sym-source = {sch-rnd default symbol lib} + -sym-copyright = {(C) 2022 Tibor 'Igor2' Palinkas} + -sym-license-dist = {GPLv2+} + -sym-license-use = {Public Domain} + } + } +} Index: tags/1.0.5/library/symbol/transistor/mosfet-n-1.ry =================================================================== --- tags/1.0.5/library/symbol/transistor/mosfet-n-1.ry (nonexistent) +++ tags/1.0.5/library/symbol/transistor/mosfet-n-1.ry (revision 10414) @@ -0,0 +1,86 @@ +ha:cschem-group-v1 { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAACC; + li:objects { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAACD; + x=12000; y=12000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=D + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:group.2 { + uuid=iNOQfJpO6hT/HFDFGjoAAACE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=G + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:text.3 { x1=8000; y1=8000; rot=90.000000; dyntext=1; stroke=sym-secondary; text=%../a.devmap%; floater=1; } + ha:text.4 { x1=4000; y1=8000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:arc.5 { cx=11000; cy=3000; r=5500; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:line.6 { x1=4000; y1=0; x2=8000; y2=0; stroke=sym-decor; } + ha:line.7 { x1=9000; y1=-1000; x2=9000; y2=1000; stroke=sym-decor; } + ha:line.8 { x1=9000; y1=2000; x2=9000; y2=4000; stroke=sym-decor; } + ha:line.9 { x1=9000; y1=5000; x2=9000; y2=7000; stroke=sym-decor; } + ha:line.10 { x1=9000; y1=3000; x2=12000; y2=3000; stroke=sym-decor; } + ha:line.11 { x1=9000; y1=0; x2=12000; y2=0; stroke=sym-decor; } + ha:line.12 { x1=9000; y1=6000; x2=12000; y2=6000; stroke=sym-decor; } + ha:line.13 { x1=12000; y1=6000; x2=12000; y2=8000; stroke=sym-decor; } + ha:line.14 { x1=12000; y1=-4000; x2=12000; y2=3000; stroke=sym-decor; } + ha:line.15 { x1=13000; y1=3000; x2=15000; y2=3000; stroke=sym-decor; } + ha:line.16 { x1=15000; y1=3000; x2=14000; y2=4000; stroke=sym-decor; } + ha:line.17 { x1=14000; y1=4000; x2=13000; y2=3000; stroke=sym-decor; } + ha:line.18 { x1=13000; y1=4000; x2=15000; y2=4000; stroke=sym-decor; } + ha:line.19 { x1=12000; y1=7000; x2=14000; y2=7000; stroke=sym-decor; } + ha:line.20 { x1=14000; y1=-1000; x2=12000; y2=-1000; stroke=sym-decor; } + ha:line.21 { x1=8000; y1=7000; x2=8000; y2=0; stroke=sym-decor; } + ha:polygon.22 { + li:outline { + ha:line { x1=10000; y1=4000; x2=9000; y2=3000; } + ha:line { x1=9000; y1=3000; x2=10000; y2=2000; } + ha:line { x1=10000; y1=2000; x2=10000; y2=4000; } + } + stroke=sym-decor; + fill=sym-decor; + } + ha:group.23 { + uuid=iNOQfJpO6hT/HFDFGjoAAACF; + x=12000; y=-4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=S + role=terminal + ha:spice/pinnum = { value=3; prio=31050; } + } + } + ha:line.24 { x1=14000; y1=-1000; x2=14000; y2=3000; stroke=sym-decor; } + ha:line.25 { x1=14000; y1=4000; x2=14000; y2=7000; stroke=sym-decor; } + } + ha:attrib { + name=Q?? + role=symbol + devmap=2n7002_sot23 + ha:spice/prefix = { value=M; prio=31050; } + -sym-source = {sch-rnd default symbol lib} + -sym-copyright = {(C) 2022 Tibor 'Igor2' Palinkas} + -sym-license-dist = {GPLv2+} + -sym-license-use = {Public Domain} + } + } +} Index: tags/1.0.5/library/symbol/transistor/mosfet-p-1.ry =================================================================== --- tags/1.0.5/library/symbol/transistor/mosfet-p-1.ry (nonexistent) +++ tags/1.0.5/library/symbol/transistor/mosfet-p-1.ry (revision 10414) @@ -0,0 +1,86 @@ +ha:cschem-group-v1 { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAACG; + li:objects { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAACH; + x=12000; y=12000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=D + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:group.2 { + uuid=iNOQfJpO6hT/HFDFGjoAAACI; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=G + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:text.3 { x1=8000; y1=8000; rot=90.000000; dyntext=1; stroke=sym-secondary; text=%../a.devmap%; floater=1; } + ha:text.4 { x1=4000; y1=8000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:arc.5 { cx=11000; cy=3000; r=5500; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:line.6 { x1=4000; y1=0; x2=8000; y2=0; stroke=sym-decor; } + ha:line.7 { x1=9000; y1=-1000; x2=9000; y2=1000; stroke=sym-decor; } + ha:line.8 { x1=9000; y1=2000; x2=9000; y2=4000; stroke=sym-decor; } + ha:line.9 { x1=9000; y1=5000; x2=9000; y2=7000; stroke=sym-decor; } + ha:line.10 { x1=9000; y1=3000; x2=12000; y2=3000; stroke=sym-decor; } + ha:line.11 { x1=9000; y1=0; x2=12000; y2=0; stroke=sym-decor; } + ha:line.12 { x1=9000; y1=6000; x2=12000; y2=6000; stroke=sym-decor; } + ha:line.13 { x1=12000; y1=6000; x2=12000; y2=8000; stroke=sym-decor; } + ha:line.14 { x1=12000; y1=-4000; x2=12000; y2=3000; stroke=sym-decor; } + ha:line.15 { x1=12000; y1=7000; x2=14000; y2=7000; stroke=sym-decor; } + ha:line.16 { x1=14000; y1=-1000; x2=12000; y2=-1000; stroke=sym-decor; } + ha:line.17 { x1=8000; y1=7000; x2=8000; y2=0; stroke=sym-decor; } + ha:group.18 { + uuid=iNOQfJpO6hT/HFDFGjoAAACJ; + x=12000; y=-4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=S + role=terminal + ha:spice/pinnum = { value=3; prio=31050; } + } + } + ha:line.19 { x1=14000; y1=-1000; x2=14000; y2=3000; stroke=sym-decor; } + ha:line.20 { x1=14000; y1=4000; x2=14000; y2=7000; stroke=sym-decor; } + ha:polygon.21 { + li:outline { + ha:line { x1=11000; y1=4000; x2=12000; y2=3000; } + ha:line { x1=12000; y1=3000; x2=11000; y2=2000; } + ha:line { x1=11000; y1=2000; x2=11000; y2=4000; } + } + stroke=sym-decor; + fill=sym-decor; + } + ha:line.22 { x1=15000; y1=4000; x2=13000; y2=4000; stroke=sym-decor; } + ha:line.23 { x1=13000; y1=4000; x2=14000; y2=3000; stroke=sym-decor; } + ha:line.24 { x1=14000; y1=3000; x2=15000; y2=4000; stroke=sym-decor; } + ha:line.25 { x1=15000; y1=3000; x2=13000; y2=3000; stroke=sym-decor; } + } + ha:attrib { + name=Q?? + role=symbol + devmap=bss84_sot23 + ha:spice/prefix = { value=M; prio=31050; } + -sym-source = {sch-rnd default symbol lib} + -sym-copyright = {(C) 2022 Tibor 'Igor2' Palinkas} + -sym-license-dist = {GPLv2+} + -sym-license-use = {Public Domain} + } + } +} Index: tags/1.0.5/library/symbol/transistor/npn-1.ry =================================================================== --- tags/1.0.5/library/symbol/transistor/npn-1.ry (nonexistent) +++ tags/1.0.5/library/symbol/transistor/npn-1.ry (revision 10414) @@ -0,0 +1,72 @@ +ha:cschem-group-v1 { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAACK; + li:objects { + ha:polygon.1 { + li:outline { + ha:line { x1=10266; y1=-1780; x2=9224; y2=-3517; } + ha:line { x1=9224; y1=-3517; x2=10935; y2=-3368; } + ha:line { x1=10935; y1=-3368; x2=10266; y2=-1780; } + } + stroke=sym-decor; + fill=sym-decor; + } + ha:group.2 { + uuid=iNOQfJpO6hT/HFDFGjoAAACL; + x=12000; y=8000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=-4000; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=C + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:group.3 { + uuid=iNOQfJpO6hT/HFDFGjoAAACM; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=B + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.4 { + uuid=iNOQfJpO6hT/HFDFGjoAAACN; + x=12000; y=-4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=-4000; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=E + role=terminal + ha:spice/pinnum = { value=3; prio=31050; } + } + } + ha:text.5 { x1=8000; y1=8000; rot=90.000000; dyntext=1; stroke=sym-secondary; text=%../a.devmap%; floater=1; } + ha:text.6 { x1=4000; y1=8000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:arc.7 { cx=9000; cy=0; r=5500; sang=0.000000; dang=360.000000; stroke=sym-decor; } + ha:line.8 { x1=7000; y1=4000; x2=7000; y2=-4000; stroke=sym-decor; } + ha:line.9 { x1=4000; y1=0; x2=7000; y2=0; stroke=sym-decor; } + ha:line.10 { x1=7000; y1=-1000; x2=12000; y2=-4000; stroke=sym-decor; } + ha:line.11 { x1=7000; y1=1000; x2=12000; y2=4000; stroke=sym-decor; } + } + ha:attrib { + name=Q?? + role=symbol + devmap=bc817_sot23 + ha:spice/prefix = { value=Q; prio=31050; } + -sym-source = {sch-rnd default symbol lib} + -sym-copyright = {(C) 2022 Tibor 'Igor2' Palinkas} + -sym-license-dist = {GPLv2+} + -sym-license-use = {Public Domain} + } + } +} Index: tags/1.0.5/library/symbol/transistor/pnp-1.ry =================================================================== --- tags/1.0.5/library/symbol/transistor/pnp-1.ry (nonexistent) +++ tags/1.0.5/library/symbol/transistor/pnp-1.ry (revision 10414) @@ -0,0 +1,72 @@ +ha:cschem-group-v1 { + ha:group.1 { + uuid=iNOQfJpO6hT/HFDFGjoAAACO; + li:objects { + ha:text.1 { x1=8000; y1=8000; rot=90.000000; dyntext=1; stroke=sym-secondary; text=%../a.devmap%; floater=1; } + ha:text.2 { x1=4000; y1=8000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:group.3 { + uuid=iNOQfJpO6hT/HFDFGjoAAACP; + x=12000; y=4000; rot=90.000000; miry=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-1000; y1=-1000; rot=180.000000; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=E + role=terminal + ha:spice/pinnum = { value=3; prio=31050; } + } + } + ha:line.4 { x1=7000; y1=-4000; x2=7000; y2=4000; stroke=sym-decor; } + ha:line.5 { x1=4000; y1=0; x2=7000; y2=0; stroke=sym-decor; } + ha:arc.6 { cx=9000; cy=0; r=5500; sang=-0.000000; dang=-360.000000; stroke=sym-decor; } + ha:line.7 { x1=7000; y1=-1000; x2=12000; y2=-4000; stroke=sym-decor; } + ha:polygon.8 { + li:outline { + ha:line { x1=9992; y1=3988; x2=11034; y2=2251; } + ha:line { x1=11034; y1=2251; x2=9323; y2=2400; } + ha:line { x1=9323; y1=2400; x2=9992; y2=3988; } + } + stroke=sym-decor; + fill=sym-decor; + } + ha:line.9 { x1=7000; y1=1000; x2=12000; y2=4000; stroke=sym-decor; } + ha:group.10 { + uuid=iNOQfJpO6hT/HFDFGjoAAACQ; + x=12000; y=-8000; rot=90.000000; miry=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-1000; y1=-1000; rot=180.000000; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=C + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:group.11 { + uuid=iNOQfJpO6hT/HFDFGjoAAACR; + mirx=1; miry=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=-3000; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=B + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + } + ha:attrib { + name=Q?? + role=symbol + devmap=bc857_sot23 + ha:spice/prefix = { value=Q; prio=31050; } + -sym-source = {sch-rnd default symbol lib} + -sym-copyright = {(C) 2022 Tibor 'Igor2' Palinkas} + -sym-license-dist = {GPLv2+} + -sym-license-use = {Public Domain} + } + } +} Index: tags/1.0.5/scconfig/Makefile =================================================================== --- tags/1.0.5/scconfig/Makefile (nonexistent) +++ tags/1.0.5/scconfig/Makefile (revision 10414) @@ -0,0 +1,105 @@ +# --- configuration part -- + +# - generic configuration - +# where scconfig source is; this is a path to a partial or full checkout of +# svn://repo.hu/scconfig/trunk/src +LIBRND_PREFIX=/usr +SRC=src/ + +# where compiled binaries (e.g. objects) should land; should be the same as +# $(SRC) the project has its own copy of scconfig embedded +BIN=$(SRC) + +# what cflags to use to compile scconfig +USER_CFLAGS = -I. $(LIBRND_EXTRA_INCLUDE) -DLIBRND_PREFIX="$(LIBRND_PREFIX)" + +# what ldflags to use to link scconfig +USER_LDFLAGS = + +# in case hooks.c needs to link to something local +USER_OBJS = $(BIN)/util/arg_auto_set.o + +# what to build - a ./configure +all: configure revtest + +# This line imports scconfig core and default tests +include $(SRC)/default/Makefile.plugin + +# +# - PLUGINS - +# +# Comment this line if you are not interested in c99 features +#include $(SRC)/c99/Makefile.plugin + +# Comment this line if you do not need script libs to be detected +include $(SRC)/scripts/Makefile.plugin + +# Comment this line if you do not need parser libs to be detected +#include $(SRC)/parser/Makefile.plugin + +# Comment this line if you do not need to detect parser generators +include $(SRC)/parsgen/Makefile.plugin + +# Comment this line if you do not need math related libs +include $(SRC)/math/Makefile.plugin + +# Comment this line if you do not need socket/networking +include $(SRC)/socket/Makefile.plugin + +# Comment this line if you do not need user/password API detection +include $(SRC)/userpass/Makefile.plugin + +# Comment this line if you do not need gui (X11, toolkits) +#include $(SRC)/gui/Makefile.plugin + +# Comment this line if you do not need tty (nurses, slang, pty-related calls) +#include $(SRC)/tty/Makefile.plugin + +# Comment this line if you do not need software utility libs (gen*, glib) +include $(SRC)/sul/Makefile.plugin + +# Comment this line if you do not need to detect POSIX calls +#include $(SRC)/posix/Makefile.plugin + +# Uncomment this line if you need menus +#include $(SRC)/menulib/Makefile.plugin + +# Comment this line if you do not need generator (templating); conflicts with tmpasm +#include $(SRC)/generator/Makefile.plugin + +# Comment this line if you do not need tmpasm (templating); conflicts with generator +include $(SRC)/tmpasm/Makefile.plugin + +# --- you shouldn't edit the lines below --- +OBJS = $(USER_OBJS) hooks.o librnd_ver.o $(DEFAULT_NOMAIN_OBJS) $(SCRIPT_OBJS) $(PARSER_OBJS) $(GENERATOR_OBJS) $(TMPASM_OBJS) $(C99_OBJS) $(PARSGEN_OBJS) $(MATH_OBJS) $(SOCKET_OBJS) $(USERPASS_OBJS) $(GUI_OBJS) $(TTY_OBJS) $(SUL_OBJS) $(POSIX_OBJS) +CFLAGS = $(USER_CFLAGS) $(DEFAULT_CFLAGS) $(SCRIPT_CFLAGS) $(PARSER_CFLAGS) $(GENERATOR_CFLAGS) $(TMPASM_CFLAGS) $(C99_CFLAGS) $(PARSGEN_CFLAGS) $(MATH_CFLAGS) $(SOCKET_CFLAGS) $(USERPASS_CFLAGS) $(GUI_CFLAGS) $(TTY_CFLAGS) $(SUL_CFLAGS) $(POSIX_CFLAGS) $(MENULIB_CFLAGS) -I$(SRC)/default +LDFLAGS = $(USER_LDFLAGS) $(DEFAULT_LDFLAGS) $(SCRIPT_LDFLAGS) $(PARSER_LDFLAGS) $(GENERATOR_LDFLAGS) $(TMPASM_LDFLAGS) $(C99_LDFLAGS) $(PARSGEN_LDFLAGS) $(MATH_LDFLAGS) $(SOCKET_LDFLAGS) $(USERPASS_LDFLAGS) $(GUI_LDFLAGS) $(TTY_LDFLAGS) $(SUL_LDFLAGS) $(POSIX_LDFLAGS) $(MENULIB_LDFLAGS) + +configure: $(OBJS) $(DEFAULT_MAIN_OBJS) sccbox + $(CC) -o configure $(OBJS) $(DEFAULT_MAIN_OBJS) + +menuconfig: $(OBJS) $(MENULIB_OBJS) + $(CC) -o configure $(OBJS) $(MENULIB_OBJS) + +src/util/sccbox.o: src/util/sccbox.c + $(CC) -c $(CFLAGS) -o src/util/sccbox.o src/util/sccbox.c + +sccbox: src/util/sccbox.o + $(CC) $(LDFLAGS) -o sccbox src/util/sccbox.o + +LIBRNDSCC=$(LIBRND_PREFIX)/include/librnd4/librnd/scconfig +RNDHOOKS=$(LIBRNDSCC)/plugin_3state.h $(LIBRNDSCC)/hooks_common.h + +hooks.o: $(RNDHOOKS) plugins.h $(LIBRND_PREFIX)/include/librnd4/librnd/scconfig Rev.h + +librnd_ver.o: librnd_ver.c $(LIBRND_PREFIX)/include/librnd4/librnd/config.h + $(CC) -c $(CFLAGS) -o librnd_ver.o librnd_ver.c + +$(BIN)/util/arg_auto_set.o: $(SRC)/util/arg_auto_set.c $(SRC)/util/arg_auto_set.h + $(CC) -c $(CFLAGS) -o $(BIN)/util/arg_auto_set.o $(SRC)/util/arg_auto_set.c + +clean: + -rm $(OBJS) $(DEFAULT_MAIN_OBJS) configure sccbox + +distclean: clean + -rm Makefile.depgen config.cache config.log \ No newline at end of file Index: tags/1.0.5/scconfig/Rev.h =================================================================== --- tags/1.0.5/scconfig/Rev.h (nonexistent) +++ tags/1.0.5/scconfig/Rev.h (revision 10414) @@ -0,0 +1 @@ +static const int myrev = 10230; Index: tags/1.0.5/scconfig/Rev.tab =================================================================== --- tags/1.0.5/scconfig/Rev.tab (nonexistent) +++ tags/1.0.5/scconfig/Rev.tab (revision 10414) @@ -0,0 +1,80 @@ +10230 configure new plugin for hierarchic library from file system +10028 configure hierarchy support +9983 configure io_orcad: enable by default +9928 configure librnd 4.1.0: remove local implementation of functionality moved into librnd +9823 configure librnd 4.1.0: switch over to librnd font2 +9359 configure drc infrastructure in libcschem +9254 configure new plugin: funcmap +9211 configure lib: per-plugin-per-project storage +9079 configure rubber band wire move +9038 configure move out tEDAx parse/write into a reusable lib plugin +8973 configure new source file for sheet utils +8741 configure enable the sim plugins by default +8712 configure new sources for sim gui and sim config +8169 configure lib_target: support plugin to get some attributes put in the tEDAx netlist +8150 configure bom export plugin +8124 configure sch_dialogs: stance dialog +8078 configure std_forge: conditional scripts +8049 configure new plugins for high level sim support +7737 configure new plugins: export_spice, target_spice +7469 configure new plugin for non-graphical fawk sheets +7468 configure new plugin for non-graphical tEDAx sheets +7370 configure cleanup: get rid of local "inline" defs +7322 configure enable io_altium by default +7257 configure plugin config for io_altium +6946 configure removed excess librnd detection +6740 configure new dialog box: project properties edit +6720 configure new libcschem source file for project support +6294 configure remove excess export API +6180 configure move plug_io_act from lib to sch-rnd as it depends on sch-rnd assumptions on project file naming and file formats and other implementation-specific details +6070 configure rnd_printf support for %rc for printing 'k' coords properly +6035 configure switch over to librnd4's font engine (from local copy of pcb-rnd's) +5676 configure new plugin: act_read (for scripting) +5371 configure new source file for triangle calculations in lib +5098 configure new engine plugin: forge +5089 configure new export plugin: export_abst +5060 configure new feature plugin: renumber +5058 configure std_cschem configuration +4965 configure use pcb-rnd's font engine +4756 configure act_draw plugin for scripting +4703 configure sccbox fix for doc installation +4642 configure back annotation plugin +4503 configure minuid util, libminuid dependency for rebuild +4435 configure make install +4342 configure embed internal config +4317 configure new core actions about selection +4153 configure ./configure detects font dir +4146 configure about box +4039 configure sheet selector GUI in top window +3828 configure centralzie local lib support into libcschem +3699 configure expotr_lpr plugin for printing +3696 configure remove export_animator (it was used for debugging before the official export plugins arrived) +3675 configure upgrade export plugins for better layer visibility control +3667 configure switch over from local copy of export plugin draw code to librnd's new plugins +3663 configure remove local message implementation in favor of using librnd's +3371 configure new dialog: abstract model +3356 configure export_svg, export_ps, export_png +3308 configure new plugin: io_tinycad +3270 configure rename library.[ch] to util_fs_lib.[ch] for naming consistency +3260 configure new engine plugins: target_pcb, target_none +3225 configure new dialog box: view change/edit +3203 configure compile action +3181 configure new plugin: engine for handling cschem attributes (std_cschem) +3099 configure io_geda: plugin configuration +3050 configure new plugin: io_geda; fix classification of std_* plugins +2945 configure new plugin: query +2908 distclean prepare for optionally enabling bison and byaccic +2850 configure workaround on librnd's LIBRND_LIBDIR bug +2645 configure new source for specialized quick edit of attributes +2541 configure emergency/backup saves +2481 configure new source for (symbol) library support +2286 configure (object) tree view dialog +2237 configure new source file in lib for object intersections +2222 configure new source files for buffer support +2153 configure rename attribute dialog source file for consistent naming +2141 configure source file rename for text edit dialog +2110 configure new plugin: place +2028 configure make clean should remove all objects in src_3rd/ +2018 configure bugfix on libminuid cflags +2001 configure libcschem: dyntext support +1912 configure introducing revtab Index: tags/1.0.5/scconfig/hooks.c =================================================================== --- tags/1.0.5/scconfig/hooks.c (nonexistent) +++ tags/1.0.5/scconfig/hooks.c (revision 10414) @@ -0,0 +1,285 @@ +#include +#include +#include "arg.h" +#include "log.h" +#include "dep.h" +#include "db.h" +#include "libs.h" +#include "tmpasm_scconfig.h" +#include "Rev.h" +#include "../util/arg_auto_set.h" + +#include + +/* we are doing /local/csch/ */ +#define LIBRND_SCCONFIG_APP_TREE "csch" + +#include +#include +#include +#include + +#define version "1.0.5" + +#define REQ_LIBRND_MAJOR 4 +#define REQ_LIBRND_MINOR 1 + + +const arg_auto_set_t disable_libs[] = { /* list of --disable-LIBs and the subtree they affect */ + {"enable-bison", "/local/csch/want_bison", arg_true, "$enable generating language files using bison/flex"}, + {"disable-bison", "/local/csch/want_bison", arg_false, "$disable generating language files using bison/flex"}, + {"enable-byaccic", "/local/csch/want_byaccic", arg_true, "$enable generating language files using byaccic/ureglex"}, + {"disable-byaccic", "/local/csch/want_byaccic", arg_false, "$disable generating language files byaccic/ureglex"}, + +#undef plugin_def +#undef plugin_header +#undef plugin_dep +#define plugin_def(name, desc, default_, all_) plugin3_args(name, desc) +#define plugin_header(sect) +#define plugin_dep(plg, on) +#include "plugins.h" + + {NULL, NULL, NULL, NULL} +}; + +#define TO_STR_(payload) #payload +#define TO_STR(payload) TO_STR_(payload) + + +static void help1(void) +{ + rnd_help1("sch-rnd"); + printf(" --dot_sch_rnd=path .sch-rnd config path under $HOME/\n"); +} + +/* Runs when a custom command line argument is found + returns true if no furhter argument processing should be done */ +int hook_custom_arg(const char *key, const char *value) +{ + rnd_hook_custom_arg(key, value, disable_libs); /* call arg_auto_print_options() instead */ + + if (strcmp(key, "dot_sch_rnd") == 0) { + need_value("use --dot_sch_rnd=dir"); + put("/local/csch/dot_sch_rnd", value); + return 1; + } + if (strcmp(key, "fontdir") == 0) { + fprintf(stderr, "*** WARNING ***\n *** --fontdir is obsolete, please remove it from your command line!\n\n"); + return 1; + } +/* if (strcmp(key, "debug") == 0) { + put("/local/csch/debug", strue); + return 1; + } + if (strcmp(key, "profile") == 0) { + put("/local/csch/profile", strue); + return 1; + }*/ + + if (arg_auto_set(key, value, disable_libs) == 0) { + fprintf(stderr, "Error: unknown argument %s\n", key); + exit(1); + } + return 1; /* handled by arg_auto_set() */ + +} + + +/* Runs before anything else */ +int hook_preinit() +{ + return 0; +} + +void librnd_ver_req_min(int exact_major, int min_minor); + +/* Runs after initialization */ +int hook_postinit() +{ + db_mkdir("/local"); + db_mkdir("/local/csch"); + rnd_hook_postinit(); + + /* defaults */ + put("/local/csch/debug", sfalse); + put("/local/csch/profile", sfalse); + + put("/local/csch/librnd_prefix", TO_STR(LIBRND_PREFIX)); + put("/local/csch/dot_sch_rnd", ".sch-rnd"); + + librnd_ver_req_min(REQ_LIBRND_MAJOR, REQ_LIBRND_MINOR); + + return 0; +} + +/* Runs after all arguments are read and parsed */ +int hook_postarg() +{ + char *tmp; + const char *libad; + + put("/local/csch/librnd_template", tmp = str_concat("", TO_STR(LIBRND_PREFIX), "/", get("/local/libarchdir"), "/librnd4/scconfig/template", NULL)); + free(tmp); + + /* if librnd is installed at some custom path, we'll need to have a -I on CFLAGS and -L on LDFLAGS */ + libad = get("/local/libarchdir"); + if (((strncasecmp(TO_STR(LIBRND_PREFIX), "/usr/include", 12) != 0) && (strncasecmp(TO_STR(LIBRND_PREFIX), "/usr/local/include", 18) != 0)) || (strcmp(libad, "lib") != 0)) { + put("/local/csch/librnd_extra_inc", "-I" TO_STR(LIBRND_PREFIX) "/include"); + put("/local/csch/librnd_extra_ldf", tmp = str_concat("", "-L" TO_STR(LIBRND_PREFIX) "/", libad, NULL)); + free(tmp); + } + + return rnd_hook_postarg(TO_STR(LIBRND_PREFIX), "sch-rnd"); +} + +/* Runs when things should be detected for the host system */ +int hook_detect_host() +{ + return rnd_hook_detect_host(); +} + +/* Runs when things should be detected for the target system */ +int hook_detect_target() +{ + const char *host_ansi, *host_ped, *target_ansi, *target_ped, *target_pg, *target_no_pie; + int want_xml2 = plug_is_enabled("io_tinycad"); + + require("cc/cc", 0, 1); + require("cc/fpic", 0, 0); + + rnd_hook_detect_cc(); + if (rnd_hook_detect_sys() != 0) + return 1; + + /* detect inline after fixing up the flags */ + require("cc/inline", 0, 0); + + require("sys/types/size/4_u_int", 0, 1); + + /* yacc/lex - are we able to regenerate languages? */ + if (istrue(get("/local/csch/want_bison"))) { + require("parsgen/flex/*", 0, 0); + require("parsgen/bison/*", 0, 0); + if (!istrue(get("parsgen/flex/presents")) || !istrue(get("parsgen/bison/presents"))) + put("/local/csch/want_parsgen", sfalse); + else + put("/local/csch/want_parsgen", strue); + } + else { + report("Bison/flex are disabled, along with parser generation.\n"); + put("/local/csch/want_parsgen", sfalse); + } + + /* byaccic - are we able to regenerate languages? */ + if (istrue(get("/local/csch/want_byaccic"))) { + require("parsgen/byaccic/*", 0, 0); + require("parsgen/ureglex/*", 0, 0); + if (!istrue(get("parsgen/byaccic/presents")) || !istrue(get("parsgen/ureglex/presents"))) + put("/local/csch/want_parsgen_byaccic", sfalse); + else + put("/local/csch/want_parsgen_byaccic", strue); + } + else { + report("byaccic/ureglex are disabled, along with parser generation.\n"); + put("/local/csch/want_parsgen_byaccic", sfalse); + } + + if (want_xml2) { + require("libs/sul/libxml2/presents", 0, 0); + if (!istrue(get("libs/sul/libxml2/presents"))) { + report("libxml2 is not available, disabling io_tinycad...\n"); + report_repeat("WARNING: Since there's no libxml2 found, disabling the tinycad plugin...\n"); + hook_custom_arg("disable-io_tinycad", NULL); + } + put("/local/csch/want_libxml2", strue); + } + else + put("/local/csch/want_libxml2", sfalse); + + return 0; +} + +static const char *IS_OK(int *generr, int val) +{ + *generr |= val; + if (val == 0) return "ok"; + return "ERROR"; +} + +/* Runs after detection hooks, should generate the output (Makefiles, etc.) */ +int hook_generate() +{ + int generr = 0; + char *tmp, *rev = "non-svn"; + + tmp = svn_info(0, "..", "Revision:"); + if (tmp != NULL) { + rev = str_concat("", "svn r", tmp, NULL); + free(tmp); + } + + logprintf(0, "scconfig generate version info: version='%s' rev='%s'\n", version, rev); + put("/local/revision", rev); + put("/local/version", version); + + put("/local/pup/sccbox", "../../scconfig/sccbox"); + + printf("Generating src/libcschem/config.h... %s\n", IS_OK(&generr, tmpasm(NULL, "../src/libcschem/config.h.in", "../src/libcschem/config.h"))); + printf("Generating src/libcschem/config.sh... %s\n", IS_OK(&generr, tmpasm(NULL, "../src/libcschem/config.sh.in", "../src/libcschem/config.sh"))); + printf("Generating src/libcschem/Makefile... %s\n", IS_OK(&generr, tmpasm(NULL, "../src/libcschem/Makefile.in", "../src/libcschem/Makefile"))); + printf("Generating src/sch-rnd/Makefile... %s\n", IS_OK(&generr, tmpasm(NULL, "../src/sch-rnd/Makefile.in", "../src/sch-rnd/Makefile"))); + printf("Generating src/sch-rnd/config.h... %s\n", IS_OK(&generr, tmpasm(NULL, "../src/sch-rnd/config.h.in", "../src/sch-rnd/config.h"))); + printf("Generating Makefile.conf... %s\n", IS_OK(&generr, tmpasm(NULL, "../Makefile.conf.in", "../Makefile.conf"))); + + if (!generr) { + printf("\n\n"); + printf("=====================\n"); + printf("Configuration summary\n"); + printf("=====================\n"); + + print_sum_setting("/local/csch/debug", "Compilation for debugging"); + print_sum_setting_or("/local/csch/symbols", "Include debug symbols", istrue(get("/local/csch/debug"))); + print_sum_cfg_val("/local/prefix", "installation prefix (--prefix)"); + print_sum_cfg_val("/local/confdir", "configuration directory (--confdir)"); + print_sum_cfg_val("/local/csch/dot_sch_rnd", ".sch_rnd config dir under $HOME"); + +#undef plugin_def +#undef plugin_header +#undef plugin_dep +#define plugin_def(name, desc, default_, all_) plugin3_stat(name, desc) +#define plugin_header(sect) printf(sect); +#define plugin_dep(plg, on) +#include "plugins.h" + + if (all_plugin_check_explicit()) { + printf("\nNevertheless the configuration is complete, if you accept these differences\nyou can go on compiling.\n\n"); + generr = 1; + } + else + printf("\nConfiguration complete, ready to compile.\n\n"); + + + { + FILE *f; + f = fopen("Rev.stamp", "w"); + fprintf(f, "%d", myrev); + fclose(f); + } + + } + else + fprintf(stderr, "\nError generating some of the files\n"); + + return generr; +} + +/* Runs before everything is uninitialized */ +void hook_preuninit() +{ +} + +/* Runs at the very end, when everything is already uninitialized */ +void hook_postuninit() +{ +} + Index: tags/1.0.5/scconfig/librnd_ver.c =================================================================== --- tags/1.0.5/scconfig/librnd_ver.c (nonexistent) +++ tags/1.0.5/scconfig/librnd_ver.c (revision 10414) @@ -0,0 +1,28 @@ +/* Has to be a separate compilation unit to firewall all the extra #defines + in librnd/config.h */ + +#include +#include "log.h" +#include + +unsigned long librnd_ver_get(int *major, int *minor, int *patch) +{ + if (major != NULL) *major = ((unsigned long)RND_API_VER & 0xFF0000UL) >> 16; + if (minor != NULL) *minor = ((unsigned long)RND_API_VER & 0x00FF00UL) >> 8; + if (patch != NULL) *patch = ((unsigned long)RND_API_VER & 0x0000FFUL); + return RND_API_VER; +} + +void librnd_ver_req_min(int exact_major, int min_minor) +{ + int major, minor, patch; + librnd_ver_get(&major, &minor, &patch); + if (major != exact_major) { + report("\n\nERROR: Your currently installed librnd version is %d.%d.%d but %d.x.x (>= %d.%d.0 and < %d.0.0) is required (major version mismatch)\n\n", major, minor, patch, exact_major, exact_major, min_minor, exact_major+1); + exit(1); + } + if (minor < min_minor) { + report("\n\nERROR: Your currently installed librnd version is %d.%d.%d but %d.%d.x (>= %d.%d.0 and < %d.0.0) is required (minor version mismatch)\n\n", major, minor, patch, exact_major, min_minor, exact_major, min_minor, exact_major+1); + exit(1); + } +} Index: tags/1.0.5/scconfig/plugins.h =================================================================== --- tags/1.0.5/scconfig/plugins.h (nonexistent) +++ tags/1.0.5/scconfig/plugins.h (revision 10414) @@ -0,0 +1,98 @@ +/****************************************************************************** + Auto-generated by plugins/map_plugins.sh - do NOT edit, + run make map_plugins in sch-rnd/ - to change any of the data below, + edit plugins/PLUGIN/PLUGIN.pup +******************************************************************************/ + +plugin_header("\nEngine plugins (concrete->abstract compilation):\n") +plugin_def("funcmap", "alternate port functions", sbuildin, 1) +plugin_def("std_cschem", "standard cschem attributes", sbuildin, 1) +plugin_def("std_devmap", "standard device mapper", sbuildin, 1) +plugin_def("std_forge", "standard cschem attr forge", sbuildin, 1) +plugin_def("target_none", "dummy attr. xform", sbuildin, 1) +plugin_def("target_pcb", "attr. xform for PCB workflow", sbuildin, 1) +plugin_def("target_spice", "attr. xform for SPICE workflow", sbuildin, 1) + +plugin_header("\nFeature plugins:\n") +plugin_def("act_draw", "Draw object actions", sbuildin, 1) +plugin_def("act_read", "action wrappers for data access", sbuildin, 1) +plugin_def("backann", "back annotation", sbuildin, 1) +plugin_def("construct", "convert/breakup functionality", sbuildin, 1) +plugin_def("diag", "diagnostic acts. for devs", sbuildin, 1) +plugin_def("place", "place complex objects", sbuildin, 1) +plugin_def("propedit", "object property editor", sbuildin, 1) +plugin_def("query", "query language", sbuildin, 1) +plugin_def("renumber", "renumber symbols", sbuildin, 1) +plugin_def("sim_gui", "high level simulation GUI", sbuildin, 1) +plugin_def("sim_ngspice", "sim exec for ngspice", sbuildin, 1) +plugin_def("sim", "high level simulation", sbuildin, 1) +plugin_def("std_tools", "standard drawing tools", sbuildin, 1) + +plugin_header("\nSymbol library accessors:\n") +plugin_def("hlibrary_fs", "hierarchic sheets (file system)", sbuildin, 1) +plugin_def("symlib_fs", "file system symbols", sbuildin, 1) +plugin_def("symlib_local", "sheet local symbols", sbuildin, 1) + +plugin_header("\nExport plugins:\n") +plugin_def("export_abst", "export abstract model", sbuildin, 1) +plugin_def("export_bom", "export Bill of Materials", sbuildin, 1) +plugin_def("export_lpr", "lpr exporter (printer)", sbuildin, 1) +plugin_def("export_png", "export sheets to png", sbuildin, 1) +plugin_def("export_ps", "export sheets to ps/eps", sbuildin, 1) +plugin_def("export_spice", "export SPICE netlist", sbuildin, 1) +plugin_def("export_svg", "export sheets to svg", sbuildin, 1) +plugin_def("export_tedax_footprint","export sheet to tEDAx silk fp", sbuildin, 1) +plugin_def("export_tedax", "export tEDAx netlist", sbuildin, 1) +plugin_def("lib_anymap", "devmap, funcmap common code", sbuildin, 1) +plugin_def("lib_netlist_exp", "netlist export helper", sbuildin, 1) +plugin_def("lib_target", "target plugin helper", sbuildin, 1) + +plugin_header("\nIO plugins (file formats):\n") +plugin_def("io_altium", "altium schematics", sbuildin, 1) +plugin_def("io_geda", "gEDA schematics and symbols", sbuildin, 1) +plugin_def("io_lihata", "lihata schematics and symbols", sbuildin, 1) +plugin_def("io_ngrp_fawk", "fawk non-graphical sheets", sbuildin, 1) +plugin_def("io_ngrp_tedax", "tEDAx non-graphical sheets", sbuildin, 1) +plugin_def("io_orcad", "OrCAD schematics", sbuildin, 1) +plugin_def("io_tinycad", "TinyCAD schematics", sbuildin, 1) +plugin_def("lib_alien", "alien format helper", sbuildin, 1) +plugin_def("lib_ngrp", "non-graphical seet helper", sbuildin, 1) +plugin_def("lib_tedax", "low level tEDAx support", sbuildin, 1) +plugin_def("lib_ucdf", "read ucdf files", sbuildin, 1) + +plugin_header("\nGUI:\n") +plugin_def("gui", "Graphical User Interface", sbuildin, 1) +plugin_def("lib_plot", "graph plotting", sdisable, 0) +plugin_def("sch_dialogs", "base dialogs", sbuildin, 1) + + +plugin_dep("backann", "lib_tedax") +plugin_dep("export_lpr", "export_ps") +plugin_dep("export_png", "lib_exp_pixmap") +plugin_dep("export_ps", "lib_exp_text") +plugin_dep("export_spice", "lib_netlist_exp") +plugin_dep("export_svg", "lib_exp_text") +plugin_dep("export_tedax", "lib_netlist_exp") +plugin_dep("funcmap", "lib_anymap") +plugin_dep("gui", "lib_hid_common") +plugin_dep("io_altium", "lib_alien") +plugin_dep("io_altium", "lib_ucdf") +plugin_dep("io_geda", "lib_alien") +plugin_dep("io_ngrp_fawk", "lib_ngrp") +plugin_dep("io_ngrp_fawk", "script") +plugin_dep("io_ngrp_tedax", "lib_ngrp") +plugin_dep("io_ngrp_tedax", "lib_tedax") +plugin_dep("io_orcad", "lib_alien") +plugin_dep("io_orcad", "lib_ucdf") +plugin_dep("io_tinycad", "lib_alien") +plugin_dep("lib_alien", "query") +plugin_dep("lib_plot", "query") +plugin_dep("sch_dialogs", "lib_hid_common") +plugin_dep("sim_gui", "lib_plot") +plugin_dep("sim_gui", "sch_dialogs") +plugin_dep("sim_gui", "sim") +plugin_dep("sim_ngspice", "sim") +plugin_dep("sim_ngspice", "target_spice") +plugin_dep("std_devmap", "lib_anymap") +plugin_dep("target_pcb", "lib_target") +plugin_dep("target_spice", "lib_target") Index: tags/1.0.5/scconfig/revtest.c =================================================================== --- tags/1.0.5/scconfig/revtest.c (nonexistent) +++ tags/1.0.5/scconfig/revtest.c (revision 10414) @@ -0,0 +1,85 @@ +#include +#include +#include +#include "Rev.h" + +const char *act_names[] = { + "distclean", + "configure", + "make clean", + NULL +}; + +const char *act_desc[] = { + "run 'make distclean' in trunk/", + "rerun ./configure", + "run 'make clean' in trunk/", + NULL +}; + +int act_needed[16]; + +int main(int argc, char *argv[]) +{ + char line[8192]; + int res = 0, stamp = 0, banner = 0; + FILE *f = NULL; + + if (argc > 1) { + f = fopen(argv[1], "r"); + } + if (f != NULL) { + fscanf(f, "%d", &stamp); + fclose(f); + } + + while(fgets(line, sizeof(line), stdin) != NULL) { + char *end; + int rev; + + if (*line == '#') + continue; + rev = strtol(line, &end, 10); + if (*end != '\t') + continue; + + if (rev > stamp) { + char *act, *txt; + const char **a; + int idx; + res = 1; + act = end; + while(*act == '\t') + act++; + txt = strchr(act, '\t'); + if (txt != NULL) { + *txt = '\0'; + txt++; + while(*txt == '\t') + txt++; + } + if (!banner) { + fprintf(stderr, "\nYour source tree is stale (last configured after config-milestone r%d).\nRecent new features:\n", stamp); + banner = 1; + } + fprintf(stderr, "\nr%d: %s\n", rev, txt); + for(idx = 0, a = act_names; *a != NULL; idx++, a++) + if (strstr(act, *a) != NULL) + act_needed[idx]++; + } + } + + if (res) { + const char **a; + int idx; + + fprintf(stderr, "(Stamp: %d myrev: %d)\n", stamp, myrev); + fprintf(stderr, "\nBefore running make, please do the following actions in this order:\n"); + for(idx = 0, a = act_names; *a != NULL; idx++, a++) + if (act_needed[idx]) + fprintf(stderr, " %s\n", act_desc[idx]); + fprintf(stderr, "\n"); + } + + return res; +} Index: tags/1.0.5/scconfig/template/cc.tmpasm =================================================================== --- tags/1.0.5/scconfig/template/cc.tmpasm (nonexistent) +++ tags/1.0.5/scconfig/template/cc.tmpasm (revision 10414) @@ -0,0 +1,13 @@ +### set up the C compiler and flags ### + +append /local/csch/CFLAGS cc/cflags { } +append /local/csch/CFLAGS cc/fpic { } +append /local/csch/CFLAGS ?/local/csch/cflags_profile { } +append /local/csch/CFLAGS [@-I@/local/csch/root@/src_3rd@] { } +append /local/csch/LDFLAGS cc/ldflags { } +append /local/csch/LDFLAGS ?cc/rdynamic { } +append /local/csch/LDFLAGS ?/local/csch/cflags_profile { } + +put /tmpasm/OFS { } +uniq /local/csch/CFLAGS /local/csch/CFLAGS +uniq /local/csch/LDFLAGS Index: tags/1.0.5/scconfig =================================================================== --- tags/1.0.5/scconfig (nonexistent) +++ tags/1.0.5/scconfig (revision 10414) Property changes on: tags/1.0.5/scconfig ___________________________________________________________________ Added: svn:externals ## -0,0 +1 ## +svn://repo.hu/scconfig/trunk/src@1849 src Index: tags/1.0.5/src/Makefile =================================================================== --- tags/1.0.5/src/Makefile (nonexistent) +++ tags/1.0.5/src/Makefile (revision 10414) @@ -0,0 +1,24 @@ +all: + cd libcschem && $(MAKE) + cd sch-rnd && $(MAKE) + +dep: + cd libcschem && $(MAKE) dep + cd sch-rnd && $(MAKE) dep + +clean: + cd libcschem && $(MAKE) clean + cd sch-rnd && $(MAKE) clean + +distclean: + cd libcschem && $(MAKE) distclean + cd sch-rnd && $(MAKE) distclean + +install: + cd sch-rnd && $(MAKE) install + +linstall: + cd sch-rnd && $(MAKE) linstall + +uninstall: + cd sch-rnd && $(MAKE) uninstall Index: tags/1.0.5/src/libcschem/Makefile.dep =================================================================== --- tags/1.0.5/src/libcschem/Makefile.dep (nonexistent) +++ tags/1.0.5/src/libcschem/Makefile.dep (revision 10414) @@ -0,0 +1,436 @@ +### Generated file, do not edit, run make dep ### + +abstract.o: abstract.c config.h hierarchy.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/config.h ../libcschem/rtree.h \ + ../libcschem/attrib.h ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/abstract.h ../libcschem/TODO.h abstract.h abs_net.c \ + abs_comp.c +actions_csch.o: actions_csch.c config.h actions_csch.h oidpath.h \ + ../libcschem/vtoid.h ../libcschem/common_types.h ../libcschem/config.h +attrib.o: attrib.c config.h ../libcschem/common_types.h \ + ../libcschem/config.h attrib.h cnc_obj.h event.h cnc_pen.h \ + ../libcschem/concrete.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h cnc_text.h \ + ../libcschem/cnc_text_dyn.h ../libcschem/cnc_text.h cnc_grp.h undo.h \ + concrete.h abstract.h TODO.h project.h ../libcschem/engine.h \ + ../libcschem/abstract.h attrib_src.c +cnc_any_obj.o: cnc_any_obj.c config.h cnc_any_obj.h concrete.h \ + ../libcschem/common_types.h ../libcschem/config.h ../libcschem/rtree.h \ + ../libcschem/attrib.h ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h event.h \ + cnc_arc.h ../libcschem/concrete.h cnc_bitmap.h cnc_conn.h \ + ../libcschem/vtoidpath.h cnc_grp.h cnc_line.h cnc_text.h \ + ../libcschem/cnc_text_dyn.h ../libcschem/cnc_text.h cnc_obj.h attrib.h \ + cnc_pen.h cnc_poly.h ../libcschem/vtcoutline.h ../libcschem/cnc_arc.h \ + ../libcschem/cnc_line.h undo.h +cnc_arc.o: cnc_arc.c config.h event.h concrete.h \ + ../libcschem/common_types.h ../libcschem/config.h ../libcschem/rtree.h \ + ../libcschem/attrib.h ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h cnc_arc.h \ + ../libcschem/concrete.h cnc_obj.h attrib.h cnc_pen.h cnc_text.h \ + ../libcschem/cnc_text_dyn.h ../libcschem/cnc_text.h cnc_grp_child.h \ + ../libcschem/cnc_any_obj.h ../libcschem/concrete.h ../libcschem/rotate.h \ + ../../src_3rd/gengeo2d/xform.h ../../src_3rd/gengeo2d/vect.h op_common.h \ + operation.h undo.h rotate.h ../../src_3rd/gengeo2d/sarc.h \ + ../../src_3rd/gengeo2d/carc.h ../../src_3rd/gengeo2d/box.h +cnc_bitmap.o: cnc_bitmap.c config.h event.h concrete.h \ + ../libcschem/common_types.h ../libcschem/config.h ../libcschem/rtree.h \ + ../libcschem/attrib.h ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h cnc_obj.h \ + attrib.h cnc_pen.h ../libcschem/concrete.h cnc_text.h \ + ../libcschem/cnc_text_dyn.h ../libcschem/cnc_text.h cnc_bitmap.h \ + op_common.h operation.h +cnc_conn.o: cnc_conn.c config.h event.h concrete.h \ + ../libcschem/common_types.h ../libcschem/config.h ../libcschem/rtree.h \ + ../libcschem/attrib.h ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h cnc_obj.h \ + attrib.h cnc_pen.h ../libcschem/concrete.h cnc_text.h \ + ../libcschem/cnc_text_dyn.h ../libcschem/cnc_text.h cnc_conn.h \ + ../libcschem/vtoidpath.h cnc_line.h cnc_arc.h op_common.h operation.h \ + intersect.h undo.h ../../src_3rd/gengeo2d/cline.h \ + ../../src_3rd/gengeo2d/vect.h ../../src_3rd/gengeo2d/box.h \ + ../../src_3rd/gengeo2d/carc.h ../../src_3rd/gengeo2d/intersect.h \ + ../../src_3rd/gengeo2d/sline.h ../../src_3rd/gengeo2d/sarc.h +cnc_grp.o: cnc_grp.c config.h concrete.h ../libcschem/common_types.h \ + ../libcschem/config.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../../src_3rd/gengeo2d/xform.h ../../src_3rd/gengeo2d/vect.h \ + ../../src_3rd/gengeo2d/box.h event.h cnc_grp.h ../libcschem/concrete.h \ + cnc_grp_child.h ../libcschem/cnc_any_obj.h ../libcschem/concrete.h \ + ../libcschem/rotate.h cnc_conn.h ../libcschem/vtoidpath.h cnc_obj.h \ + attrib.h cnc_pen.h cnc_text.h ../libcschem/cnc_text_dyn.h \ + ../libcschem/cnc_text.h cnc_any_obj.h cnc_loop.h op_common.h operation.h \ + undo.h util_grp.h rotate.h project.h ../libcschem/engine.h \ + ../libcschem/abstract.h ../libcschem/TODO.h abstract.h libcschem.h \ + cnc_grp_ref.c +cnc_line.o: cnc_line.c config.h event.h concrete.h \ + ../libcschem/common_types.h ../libcschem/config.h ../libcschem/rtree.h \ + ../libcschem/attrib.h ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h cnc_line.h \ + ../libcschem/concrete.h cnc_obj.h attrib.h cnc_pen.h cnc_text.h \ + ../libcschem/cnc_text_dyn.h ../libcschem/cnc_text.h cnc_grp_child.h \ + ../libcschem/cnc_any_obj.h ../libcschem/concrete.h ../libcschem/rotate.h \ + ../../src_3rd/gengeo2d/xform.h ../../src_3rd/gengeo2d/vect.h cnc_grp.h \ + cnc_conn.h ../libcschem/vtoidpath.h op_common.h operation.h undo.h \ + rotate.h util_wirenet.h ../libcschem/cnc_line.h \ + ../../src_3rd/gengeo2d/sline.h ../../src_3rd/gengeo2d/box.h \ + ../../src_3rd/gengeo2d/cline.h +cnc_obj.o: cnc_obj.c config.h event.h undo.h concrete.h \ + ../libcschem/common_types.h ../libcschem/config.h ../libcschem/rtree.h \ + ../libcschem/attrib.h ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h cnc_obj.h \ + attrib.h cnc_pen.h ../libcschem/concrete.h cnc_text.h \ + ../libcschem/cnc_text_dyn.h ../libcschem/cnc_text.h cnc_poly.h \ + ../libcschem/vtcoutline.h ../libcschem/cnc_arc.h ../libcschem/cnc_line.h +cnc_pen.o: cnc_pen.c config.h event.h concrete.h \ + ../libcschem/common_types.h ../libcschem/config.h ../libcschem/rtree.h \ + ../libcschem/attrib.h ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h cnc_obj.h \ + attrib.h cnc_pen.h ../libcschem/concrete.h cnc_text.h \ + ../libcschem/cnc_text_dyn.h ../libcschem/cnc_text.h cnc_any_obj.h undo.h \ + op_common.h operation.h +cnc_poly.o: cnc_poly.c config.h event.h concrete.h \ + ../libcschem/common_types.h ../libcschem/config.h ../libcschem/rtree.h \ + ../libcschem/attrib.h ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h cnc_obj.h \ + attrib.h cnc_pen.h ../libcschem/concrete.h cnc_text.h \ + ../libcschem/cnc_text_dyn.h ../libcschem/cnc_text.h cnc_any_obj.h \ + cnc_arc.h operation.h op_common.h ../../src_3rd/gengeo2d/box.h \ + ../../src_3rd/gengeo2d/vect.h ../../src_3rd/gengeo2d/xform.h undo.h \ + rotate.h cnc_poly.h ../libcschem/vtcoutline.h ../libcschem/cnc_arc.h \ + ../libcschem/cnc_line.h +cnc_text.o: cnc_text.c config.h event.h concrete.h \ + ../libcschem/common_types.h ../libcschem/config.h ../libcschem/rtree.h \ + ../libcschem/attrib.h ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h cnc_text.h \ + ../libcschem/concrete.h ../libcschem/cnc_text_dyn.h \ + ../libcschem/cnc_text.h cnc_obj.h attrib.h cnc_pen.h cnc_grp.h \ + cnc_grp_child.h ../libcschem/cnc_any_obj.h ../libcschem/concrete.h \ + ../libcschem/rotate.h ../../src_3rd/gengeo2d/xform.h \ + ../../src_3rd/gengeo2d/vect.h op_common.h operation.h undo.h rotate.h \ + project.h ../libcschem/engine.h ../libcschem/abstract.h \ + ../libcschem/TODO.h triangle.h ../../src_3rd/gengeo2d/box.h \ + ../../src_3rd/gengeo2d/cline.h +cnc_text_dyn.o: cnc_text_dyn.c config.h abstract.h \ + ../libcschem/common_types.h ../libcschem/config.h ../libcschem/attrib.h \ + TODO.h cnc_text.h ../libcschem/concrete.h ../libcschem/rtree.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/cnc_text_dyn.h ../libcschem/cnc_text.h cnc_grp.h \ + cnc_text_dyn.h project.h ../libcschem/engine.h ../libcschem/abstract.h +compile.o: compile.c config.h abstract.h ../libcschem/common_types.h \ + ../libcschem/config.h ../libcschem/attrib.h TODO.h actions_csch.h \ + concrete.h ../libcschem/rtree.h ../libcschem/oidpath.h \ + ../libcschem/vtoid.h ../../src_3rd/libuundo/uundo.h \ + ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h event.h \ + cnc_line.h ../libcschem/concrete.h cnc_arc.h cnc_poly.h \ + ../libcschem/vtcoutline.h ../libcschem/cnc_arc.h ../libcschem/cnc_line.h \ + cnc_text.h ../libcschem/cnc_text_dyn.h ../libcschem/cnc_text.h \ + cnc_bitmap.h cnc_conn.h ../libcschem/vtoidpath.h cnc_grp.h cnc_pen.h \ + cnc_obj.h attrib.h engine.h ../libcschem/abstract.h project.h \ + ../libcschem/engine.h util_compile.h util_project.h libcschem.h \ + non_graphical.h ../libcschem/hierarchy.h hierarchy.h compile.h \ + ../libcschem/project.h +concrete.o: concrete.c concrete.h ../libcschem/common_types.h \ + ../libcschem/config.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h event.h \ + cnc_obj.h attrib.h cnc_pen.h ../libcschem/concrete.h cnc_text.h \ + ../libcschem/cnc_text_dyn.h ../libcschem/cnc_text.h cnc_grp.h \ + non_graphical.h ../libcschem/hierarchy.h ../libcschem/abstract.h \ + ../libcschem/TODO.h project.h ../libcschem/engine.h plug_library.h +csch_printf.o: csch_printf.c config.h csch_printf.h +drc.o: drc.c config.h actions_csch.h drc.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/config.h ../libcschem/rtree.h \ + ../libcschem/attrib.h ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h event.h +engine.o: engine.c config.h actions_csch.h project.h \ + ../libcschem/common_types.h ../libcschem/config.h \ + ../libcschem/concrete.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/engine.h ../libcschem/abstract.h ../libcschem/TODO.h \ + engine.h +event.o: event.c event.h +hierarchy.o: hierarchy.c config.h concrete.h ../libcschem/common_types.h \ + ../libcschem/config.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h cnc_grp.h \ + ../libcschem/concrete.h project.h ../libcschem/engine.h \ + ../libcschem/abstract.h ../libcschem/TODO.h plug_library.h hierarchy.h +htPo.o: htPo.c htPo.h config.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h +htepu.o: htepu.c htepu.h config.h concrete.h ../libcschem/common_types.h \ + ../libcschem/config.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h +integrity.o: integrity.c config.h project.h ../libcschem/common_types.h \ + ../libcschem/config.h ../libcschem/concrete.h ../libcschem/rtree.h \ + ../libcschem/attrib.h ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/engine.h ../libcschem/abstract.h ../libcschem/TODO.h \ + cnc_any_obj.h concrete.h cnc_conn.h ../libcschem/vtoidpath.h intersect.h \ + integrity.h +intersect.o: intersect.c config.h concrete.h ../libcschem/common_types.h \ + ../libcschem/config.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h cnc_line.h \ + ../libcschem/concrete.h cnc_arc.h cnc_poly.h ../libcschem/vtcoutline.h \ + ../libcschem/cnc_arc.h ../libcschem/cnc_line.h cnc_grp.h \ + ../../src_3rd/gengeo2d/cline.h ../../src_3rd/gengeo2d/vect.h \ + ../../src_3rd/gengeo2d/box.h ../../src_3rd/gengeo2d/carc.h \ + ../../src_3rd/gengeo2d/intersect.h ../../src_3rd/gengeo2d/sline.h \ + ../../src_3rd/gengeo2d/sarc.h intersect.h +libcschem.o: libcschem.c config.h libcschem.h \ + ../../src_3rd/libminuid/libminuid.h buildin.h project_act.h project.h \ + ../libcschem/common_types.h ../libcschem/config.h \ + ../libcschem/concrete.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/engine.h ../libcschem/abstract.h ../libcschem/TODO.h \ + project_p4.h ../libcschem/project.h plug_library.h plug_io.h integrity.h \ + concrete.h undo.h actions_csch.h drc.h +non_graphical.o: non_graphical.c config.h concrete.h \ + ../libcschem/common_types.h ../libcschem/config.h ../libcschem/rtree.h \ + ../libcschem/attrib.h ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + non_graphical.h ../libcschem/hierarchy.h ../libcschem/concrete.h \ + ../libcschem/abstract.h ../libcschem/TODO.h +oidpath.o: oidpath.c config.h oidpath.h ../libcschem/vtoid.h \ + ../libcschem/common_types.h ../libcschem/config.h concrete.h \ + ../libcschem/rtree.h ../libcschem/attrib.h ../libcschem/oidpath.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h +op_common.o: op_common.c config.h event.h cnc_obj.h attrib.h \ + ../libcschem/common_types.h ../libcschem/config.h cnc_pen.h \ + ../libcschem/concrete.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h cnc_text.h \ + ../libcschem/cnc_text_dyn.h ../libcschem/cnc_text.h operation.h \ + concrete.h cnc_conn.h ../libcschem/vtoidpath.h undo.h util_wirenet.h \ + ../libcschem/cnc_line.h op_common.h +operation.o: operation.c config.h concrete.h ../libcschem/common_types.h \ + ../libcschem/config.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../../src_3rd/gengeo2d/xform.h ../../src_3rd/gengeo2d/vect.h event.h \ + cnc_obj.h attrib.h cnc_pen.h ../libcschem/concrete.h cnc_text.h \ + ../libcschem/cnc_text_dyn.h ../libcschem/cnc_text.h cnc_grp.h \ + cnc_grp_child.h ../libcschem/cnc_any_obj.h ../libcschem/concrete.h \ + ../libcschem/rotate.h cnc_conn.h ../libcschem/vtoidpath.h cnc_any_obj.h \ + operation.h search.h op_common.h undo.h util_wirenet.h \ + ../libcschem/cnc_line.h +plug_io.o: plug_io.c config.h cnc_grp.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/config.h ../libcschem/rtree.h \ + ../libcschem/attrib.h ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h cnc_obj.h \ + event.h attrib.h cnc_pen.h cnc_text.h ../libcschem/cnc_text_dyn.h \ + ../libcschem/cnc_text.h cnc_any_obj.h concrete.h plug_io.h \ + ../libcschem/abstract.h ../libcschem/TODO.h project.h \ + ../libcschem/engine.h integrity.h +plug_library.o: plug_library.c config.h concrete.h \ + ../libcschem/common_types.h ../libcschem/config.h ../libcschem/rtree.h \ + ../libcschem/attrib.h ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h cnc_obj.h \ + event.h attrib.h cnc_pen.h ../libcschem/concrete.h cnc_text.h \ + ../libcschem/cnc_text_dyn.h ../libcschem/cnc_text.h plug_library.h +project.o: project.c config.h project.h ../libcschem/common_types.h \ + ../libcschem/config.h ../libcschem/concrete.h ../libcschem/rtree.h \ + ../libcschem/attrib.h ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/engine.h ../libcschem/abstract.h ../libcschem/TODO.h \ + libcschem.h plug_io.h event.h project_p4.h ../libcschem/project.h +project_act.o: project_act.c config.h event.h project.h \ + ../libcschem/common_types.h ../libcschem/config.h \ + ../libcschem/concrete.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/engine.h ../libcschem/abstract.h ../libcschem/TODO.h \ + compile.h ../libcschem/project.h project_act.h +project_p4.o: project_p4.c project_p4.h ../libcschem/project.h \ + ../libcschem/common_types.h ../libcschem/config.h \ + ../libcschem/concrete.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/engine.h ../libcschem/abstract.h ../libcschem/TODO.h +rtree.o: rtree.c rtree.h ../libcschem/common_types.h \ + ../libcschem/config.h +search.o: search.c config.h operation.h concrete.h \ + ../libcschem/common_types.h ../libcschem/config.h ../libcschem/rtree.h \ + ../libcschem/attrib.h ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h search.h \ + ../libcschem/concrete.h cnc_obj.h event.h attrib.h cnc_pen.h cnc_text.h \ + ../libcschem/cnc_text_dyn.h ../libcschem/cnc_text.h +triangle.o: triangle.c config.h triangle.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h +undo.o: undo.c config.h event.h undo.h concrete.h \ + ../libcschem/common_types.h ../libcschem/config.h ../libcschem/rtree.h \ + ../libcschem/attrib.h ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h +util_abst.o: util_abst.c config.h util_abst.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/config.h ../libcschem/rtree.h \ + ../libcschem/attrib.h ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/abstract.h ../libcschem/TODO.h +util_compile.o: util_compile.c config.h abstract.h \ + ../libcschem/common_types.h ../libcschem/config.h ../libcschem/attrib.h \ + TODO.h compile.h ../libcschem/abstract.h ../libcschem/concrete.h \ + ../libcschem/rtree.h ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/project.h ../libcschem/engine.h libcschem.h engine.h \ + actions_csch.h util_compile.h +util_endpoint.o: util_endpoint.c config.h cnc_line.h \ + ../libcschem/concrete.h ../libcschem/common_types.h \ + ../libcschem/config.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + intersect.h ../../src_3rd/gengeo2d/cline.h ../../src_3rd/gengeo2d/vect.h \ + ../../src_3rd/gengeo2d/box.h util_endpoint.h ../libcschem/htepu.h \ + ../libcschem/config.h ../libcschem/concrete.h +util_export.o: util_export.c config.h concrete.h \ + ../libcschem/common_types.h ../libcschem/config.h ../libcschem/rtree.h \ + ../libcschem/attrib.h ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h compile.h \ + ../libcschem/abstract.h ../libcschem/TODO.h ../libcschem/concrete.h \ + ../libcschem/project.h ../libcschem/engine.h plug_io.h util_export.h +util_grp.o: util_grp.c config.h concrete.h ../libcschem/common_types.h \ + ../libcschem/config.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h cnc_grp.h \ + ../libcschem/concrete.h cnc_pen.h cnc_text.h ../libcschem/cnc_text_dyn.h \ + ../libcschem/cnc_text.h cnc_any_obj.h cnc_obj.h event.h attrib.h \ + cnc_conn.h ../libcschem/vtoidpath.h operation.h op_common.h \ + util_wirenet.h ../libcschem/cnc_line.h util_grp.h +util_lib_fs.o: util_lib_fs.c config.h util_lib_fs.h \ + ../libcschem/plug_library.h ../libcschem/common_types.h \ + ../libcschem/config.h +util_loclib.o: util_loclib.c config.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/config.h ../libcschem/rtree.h \ + ../libcschem/attrib.h ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/cnc_grp.h util_loclib.h ../libcschem/plug_library.h +util_parse.o: util_parse.c config.h ../../src_3rd/load_cache/load_cache.h \ + cnc_any_obj.h concrete.h ../libcschem/common_types.h \ + ../libcschem/config.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h engine.h \ + ../libcschem/abstract.h ../libcschem/TODO.h project.h \ + ../libcschem/concrete.h ../libcschem/engine.h util_parse.h \ + ../libcschem/project.h +util_project.o: util_project.c config.h project.h \ + ../libcschem/common_types.h ../libcschem/config.h \ + ../libcschem/concrete.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/engine.h ../libcschem/abstract.h ../libcschem/TODO.h \ + util_export.h ../libcschem/project.h util_project.h +util_wirenet.o: util_wirenet.c config.h search.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/config.h ../libcschem/rtree.h \ + ../libcschem/attrib.h ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + operation.h concrete.h cnc_line.h cnc_grp.h cnc_pen.h cnc_conn.h \ + ../libcschem/vtoidpath.h cnc_text.h ../libcschem/cnc_text_dyn.h \ + ../libcschem/cnc_text.h cnc_text_dyn.h ../../src_3rd/gengeo2d/cline.h \ + ../../src_3rd/gengeo2d/vect.h ../../src_3rd/gengeo2d/box.h \ + ../../src_3rd/gengeo2d/xform.h htPo.h intersect.h util_wirenet.h \ + ../libcschem/cnc_line.h +vtcoutline.o: vtcoutline.c ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/config.h ../libcschem/rtree.h \ + ../libcschem/attrib.h ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + vtcoutline.h ../libcschem/cnc_arc.h ../libcschem/cnc_line.h +vtoid.o: vtoid.c vtoid.h ../libcschem/common_types.h \ + ../libcschem/config.h +vtoidpath.o: vtoidpath.c vtoid.h ../libcschem/common_types.h \ + ../libcschem/config.h vtoidpath.h ../libcschem/oidpath.h \ + ../libcschem/vtoid.h Index: tags/1.0.5/src/libcschem/Makefile.in =================================================================== --- tags/1.0.5/src/libcschem/Makefile.in (nonexistent) +++ tags/1.0.5/src/libcschem/Makefile.in (revision 10414) @@ -0,0 +1,144 @@ +put /local/csch/root {../..} +put /local/csch/CFLAGS {-I.. } +put /local/csch/DEPCFLAGS /local/csch/CFLAGS +put /local/rnd/DEPDEPS {} +put /local/rnd/DEPCFLAGS {} + +include {template/cc.tmpasm} +include [@@/local/csch/librnd_template@/debug.tmpasm@] + + +put /local/csch/OBJS [@ + abstract.o + actions_csch.o + attrib.o + concrete.o + drc.o + cnc_any_obj.o + cnc_arc.o + cnc_bitmap.o + cnc_conn.o + cnc_grp.o + cnc_line.o + cnc_obj.o + cnc_pen.o + cnc_poly.o + cnc_text.o + cnc_text_dyn.o + csch_printf.o + compile.o + engine.o + event.o + hierarchy.o + htPo.o + htepu.o + integrity.o + intersect.o + libcschem.o + non_graphical.o + oidpath.o + op_common.o + operation.o + plug_io.o + plug_library.o + project.o + project_act.o + project_p4.o + rtree.o + triangle.o + search.o + undo.o + util_abst.o + util_compile.o + util_endpoint.o + util_export.o + util_grp.o + util_lib_fs.o + util_loclib.o + util_parse.o + util_project.o + util_wirenet.o + vtcoutline.o + vtoid.o + vtoidpath.o +@] + +uniq /local/csch/OBJS + +put /local/csch/LIBS_3RD [@ + $(ROOT)/src_3rd/libminuid/libminuid.a + $(ROOT)/src_3rd/load_cache/load_cache.o +@] +uniq /local/csch/LIBS_3RD + +put /local/csch/DEPDEPS {} + +### Makefile ### + +print [@ +ROOT=@/local/csch/root@ +include $(ROOT)/Makefile.conf +include $(LIBRND_MAK) + +CC=@cc/cc@ +CFLAGS=@/local/csch/CFLAGS@ @/local/csch/c89flags@ @?/local/rnd/CFLAGS@ $(CFLAGS_LIBRND) @?/local/csch/librnd_extra_inc@ +C89FLAGS=$(CFLAGS) +LDFLAGS=@/local/csch/LDFLAGS@ @?/local/rnd/LDFLAGS@ $(LDFLAGS_LIBRND) @?/local/csch/librnd_extra_ldf@ +OBJS = @/local/csch/OBJS@ +LIBRND_LIBDIR=$(LIBRND_PREFIX)/$(LIBRND_LIBARCHDIR)/librnd4 +PLUGDIR=$(ROOT)/src/plugins + +LIBMINUID_CFLAGS=@/local/csch/CFLAGS@ @?/local/rnd/CFLAGS@ +LIBMINUID_LDFLAGS=@/local/csch/LDFLAGS@ @?/local/rnd/LDFLAGS@ + +LIBA=libcschem.a +CLEAN_FILES = $(LIBA) + +all: + $(MAKE) revcheck + $(MAKE) all_lib + +revcheck: + cd $(ROOT)/scconfig && ./revtest Rev.stamp < Rev.tab + +all_lib: $(LIBA) + +$(LIBA): $(OBJS) @/local/csch/LIBS_3RD@ + ar rvu $(LIBA) $(OBJS) + +$(ROOT)/src_3rd/libminuid/libminuid.a $(ROOT)/src_3rd/libminuid/minuid: $(ROOT)/src_3rd/libminuid/libminuid.h $(ROOT)/src_3rd/libminuid/libminuid.c + cd $(ROOT)/src_3rd/libminuid && $(MAKE) LIBMINUID_CFLAGS="$(LIBMINUID_CFLAGS)" LIBMINUID_LDFLAGS="$(LIBMINUID_LDFLAGS)" + +buildin.c: $(PLUGDIR)/.builtin.pups $(PUPLUG) + cd $(PLUGDIR) && $(PUPLUG) buildin.c "-" < $(PLUGDIR)/.builtin.pups > $(ROOT)/src/libcschem/buildin.c + +buildin.h: $(PLUGDIR)/.builtin.pups $(PUPLUG) + $(PUPLUG) buildin.h > buildin.h + +clean: + -rm $(LIBA) $(OBJS) + +distclean: clean + -rm config.h config.sh buildin.h Makefile + +@] + +put /local/comp/OBJS_C89 /local/csch/OBJS +put /local/comp/C89FLAGS {$(C89FLAGS)} +include [@@/local/csch/librnd_template@/compile.tmpasm@] + + +put /local/dep/OUTFN {../src/libcschem/Makefile.depgen} +put /local/dep/SRCS /local/csch/OBJS +put /local/dep/CFLAGS /local/csch/CFLAGS +gsub /local/dep/SRCS {.o } {.c } +include [@@/local/csch/librnd_template@/cdep.tmpasm@] + +redir {../src/libcschem/Makefile.objs} +put /local/csch/o /local/csch/OBJS +sub /local/csch/o {[ ]*$} {} +sub /local/csch/o {^[ ]*} {} +gsub /local/csch/o { } { $(LIBCSCHEM)/} +print [@ +LIBCSCHEM_OBJS=$(LIBCSCHEM)/@/local/csch/o@ +@] Index: tags/1.0.5/src/libcschem/TODO.h =================================================================== --- tags/1.0.5/src/libcschem/TODO.h (nonexistent) +++ tags/1.0.5/src/libcschem/TODO.h (revision 10414) @@ -0,0 +1,6 @@ +#ifndef TODO_H +#define TODO_H + +typedef int htul_t; + +#endif Index: tags/1.0.5/src/libcschem/abs_comp.c =================================================================== --- tags/1.0.5/src/libcschem/abs_comp.c (nonexistent) +++ tags/1.0.5/src/libcschem/abs_comp.c (revision 10414) @@ -0,0 +1,146 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2024 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust in 2023) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/* included from abstract.c */ + +/* Search component for v/name in all hlev parents. Return NULL if not found. */ +RND_INLINE csch_acomp_t *comp_search_subtree_up(csch_abstract_t *abs, csch_hlevel_t *hlev, const char *name) +{ + for(hlev = hlev->parent; hlev != NULL; hlev = hlev->parent) { + csch_acomp_t *comp = htsp_get(&hlev->comps, name); + if ((comp != NULL) && (comp->scope == CSCH_ASCOPE_SUBTREE_LOCAL)) + return comp; + } + + return NULL; +} + +csch_acomp_t *csch_acomp_get_at(csch_abstract_t *abs, csch_hlevel_t *hlev, csch_ascope_t scope, const char *name) +{ + csch_acomp_t *comp = NULL; + csch_ascope_t prefix_scope; + const char *orig_name = name; + + if (name == NULL) + return NULL; + + prefix_scope = csch_split_name_scope(&name); + if (scope != CSCH_ASCOPE_unknown) { + if ((prefix_scope != CSCH_ASCOPE_AUTO) && (prefix_scope != scope)) { + rnd_message(RND_MSG_ERROR, "Failed to resolve component '%s': conflicting scopes\n", orig_name); + return NULL; + } + } + else + scope = prefix_scope; + + + switch(scope) { + case CSCH_ASCOPE_AUTO: + /* first search on sheet local and parents for v/ components */ + if (hlev != NULL) { + comp = htsp_get(&hlev->comps, name); + if (comp != NULL) + return comp; + comp = comp_search_subtree_up(abs, hlev, name); + if (comp != NULL) + return comp; + } + return htsp_get(&abs->comps, name); /* fall back to global */ + + case CSCH_ASCOPE_GLOBAL: return htsp_get(&abs->comps, name); + case CSCH_ASCOPE_SHEET_LOCAL: return htsp_get(&hlev->comps, name); + case CSCH_ASCOPE_SUBTREE_LOCAL: + /* search in sheet only so that multuple v/foo are merged together; + sub-sheets are compiled later so they can find this comp searching upward */ + return htsp_get(&hlev->comps, name); + + case CSCH_ASCOPE_SUBTREE_AUTO: /* The ^/ prefix */ + if (hlev == NULL) { + rnd_message(RND_MSG_ERROR, "Failed to resolve component '%s': scope requires hierarchy which is not available\n", orig_name); + return NULL; + } + /* search on sheet local and parents for v/ comps */ + return comp_search_subtree_up(abs, hlev, name); + + case CSCH_ASCOPE_unknown: + rnd_message(RND_MSG_ERROR, "Failed to resolve component '%s': unknown scope\n", orig_name); + return NULL; + } + return NULL; +} + +csch_acomp_t *csch_acomp_get(csch_abstract_t *abs, const char *name) +{ + return csch_acomp_get_at(abs, NULL, CSCH_ASCOPE_unknown, name); +} + +csch_acomp_t *csch_acomp_new(csch_abstract_t *abs, csch_hlevel_t *hlev, csch_ascope_t scope, const char *name_glob, const char *name_loc) +{ + csch_acomp_t *comp = calloc(sizeof(csch_acomp_t), 1); + int short_name; + + if (scope == CSCH_ASCOPE_SUBTREE_AUTO) { + rnd_message(RND_MSG_ERROR, "Can not find subtree-local component v/%s\n", name_loc); + return NULL; + } + + /* create global comps with the short name; AUTO is taken GLOBAL: if we got + here no other binding worked for it */ + short_name = (scope == CSCH_ASCOPE_GLOBAL) || (scope == CSCH_ASCOPE_AUTO); + + + csch_aobj_init(abs, &comp->hdr, CSCH_ATYPE_COMP); + comp->name = rnd_strdup(short_name ? name_loc : name_glob); + comp->name_loc = rnd_strdup(name_loc); + comp->scope = scope; + comp->hlev = hlev; + comp->hdepth = hlev->hdepth; + htsp_init(&comp->ports, strhash, strkeyeq); + + htsp_set(&abs->comps, comp->name, comp); + + if (hlev != NULL) { + switch(scope) { + case CSCH_ASCOPE_AUTO: /* if we got here, we are adding it as global */ + case CSCH_ASCOPE_GLOBAL: + case CSCH_ASCOPE_unknown: + break; /* has no impact on local */ + + case CSCH_ASCOPE_SUBTREE_LOCAL: + case CSCH_ASCOPE_SHEET_LOCAL: + htsp_set(&hlev->comps, comp->name_loc, comp); + break; + + case CSCH_ASCOPE_SUBTREE_AUTO: + return NULL; /* can't get here */ + } + } + + return comp; +} Index: tags/1.0.5/src/libcschem/abs_net.c =================================================================== --- tags/1.0.5/src/libcschem/abs_net.c (nonexistent) +++ tags/1.0.5/src/libcschem/abs_net.c (revision 10414) @@ -0,0 +1,143 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2024 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust in 2023) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/* included from abstract.c */ + +/* Search netname for v/netname in all hlev parents. Return NULL if not found. */ +RND_INLINE csch_anet_t *net_search_subtree_up(csch_abstract_t *abs, csch_hlevel_t *hlev, const char *netname) +{ + for(hlev = hlev->parent; hlev != NULL; hlev = hlev->parent) { + csch_anet_t *net = htsp_get(&hlev->nets, netname); + if ((net != NULL) && (net->scope == CSCH_ASCOPE_SUBTREE_LOCAL)) + return net; + } + + return NULL; +} + +csch_anet_t *csch_anet_get_at(csch_abstract_t *abs, csch_hlevel_t *hlev, csch_ascope_t scope, const char *netname) +{ + csch_anet_t *net = NULL; + csch_ascope_t prefix_scope; + const char *orig_name = netname; + + prefix_scope = csch_split_name_scope(&netname); + if (scope != CSCH_ASCOPE_unknown) { + if ((prefix_scope != CSCH_ASCOPE_AUTO) && (prefix_scope != scope)) { + rnd_message(RND_MSG_ERROR, "Failed to resolve net '%s': conflicting scopes\n", orig_name); + return NULL; + } + } + else + scope = prefix_scope; + + + switch(scope) { + case CSCH_ASCOPE_AUTO: + /* first search on sheet local and parents for v/ nets */ + if (hlev != NULL) { + net = htsp_get(&hlev->nets, netname); + if (net != NULL) + return net; + net = net_search_subtree_up(abs, hlev, netname); + if (net != NULL) + return net; + } + return htsp_get(&abs->nets, netname); /* fall back to global */ + + case CSCH_ASCOPE_GLOBAL: return htsp_get(&abs->nets, netname); + case CSCH_ASCOPE_SHEET_LOCAL: return htsp_get(&hlev->nets, netname); + case CSCH_ASCOPE_SUBTREE_LOCAL: + /* search in sheet only so that multuple v/foo are merged together; + sub-sheets are compiled later so they can find this net searching upward */ + return htsp_get(&hlev->nets, netname); + + case CSCH_ASCOPE_SUBTREE_AUTO: /* The ^/ prefix */ + if (hlev == NULL) { + rnd_message(RND_MSG_ERROR, "Failed to resolve net '%s': scope requires hierarchy which is not available\n", orig_name); + return NULL; + } + /* search on sheet local and parents for v/ nets */ + return net_search_subtree_up(abs, hlev, netname); + + case CSCH_ASCOPE_unknown: + rnd_message(RND_MSG_ERROR, "Failed to resolve net '%s': unknown scope\n", orig_name); + return NULL; + } + return NULL; +} + +csch_anet_t *csch_anet_get(csch_abstract_t *abs, const char *netname) +{ + return csch_anet_get_at(abs, NULL, CSCH_ASCOPE_unknown, netname); +} + + +csch_anet_t *csch_anet_new(csch_abstract_t *abs, csch_hlevel_t *hlev, csch_ascope_t scope, const char *name_glob, const char *name_loc, int set_no_uname) +{ + csch_anet_t *net = calloc(sizeof(csch_anet_t), 1); + int short_name; + + if (scope == CSCH_ASCOPE_SUBTREE_AUTO) { + rnd_message(RND_MSG_ERROR, "Can not find subtree-local net v/%s\n", name_loc); + return NULL; + } + + + /* create global nets with the short name; AUTO is taken GLOBAL: if we got + here no other binding worked for it */ + short_name = (scope == CSCH_ASCOPE_GLOBAL) || (scope == CSCH_ASCOPE_AUTO); + + csch_aobj_init(abs, &net->hdr, CSCH_ATYPE_NET); + net->name = rnd_strdup(short_name ? name_loc : name_glob); + net->name_loc = rnd_strdup(name_loc); + net->no_uname = set_no_uname; + net->hlev = hlev; + net->hdepth = (hlev == NULL) ? 0 : hlev->hdepth; + + htsp_set(&abs->nets, net->name, net); + if (hlev != NULL) { + switch(scope) { + case CSCH_ASCOPE_AUTO: /* if we got here, we are adding it as global */ + case CSCH_ASCOPE_GLOBAL: + case CSCH_ASCOPE_unknown: + break; /* has no impact on local */ + + case CSCH_ASCOPE_SUBTREE_LOCAL: + case CSCH_ASCOPE_SHEET_LOCAL: + htsp_set(&hlev->nets, net->name_loc, net); + break; + + case CSCH_ASCOPE_SUBTREE_AUTO: + return NULL; /* can't get here */ + } + } + net->scope = scope; + return net; +} + Index: tags/1.0.5/src/libcschem/abstract.c =================================================================== --- tags/1.0.5/src/libcschem/abstract.c (nonexistent) +++ tags/1.0.5/src/libcschem/abstract.c (revision 10414) @@ -0,0 +1,281 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2019, 2024 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust in 2023) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include "config.h" + +#include +#include +#include + +#include +#include + +#include "hierarchy.h" + +#include "abstract.h" + +static const char *atype_names[] = { + "", + "net", + "busnet", + "buschan", + "port", + "busport", + "component", + "hub" +}; + +const char *csch_atype_name(csch_atype_t type) +{ + if ((type <= 0) || (type >= (sizeof(atype_names)/sizeof(atype_names[0])))) + return atype_names[CSCH_ATYPE_INVALID]; + return atype_names[type]; +} + +void csch_ahdr_uninit(csch_ahdr_t *hdr) +{ + csch_attrib_uninit(&hdr->attr); + vtp0_uninit(&hdr->srcs); +} + +void csch_anet_free_fields(csch_anet_t *net) +{ + vtp0_uninit(&net->conns); + free(net->name); + free(net->name_loc); + csch_ahdr_uninit(&net->hdr); +} + +void csch_aport_free_fields(csch_aport_t *port) +{ + free(port->name); + csch_ahdr_uninit(&port->hdr); +} + + +void csch_acomp_free_fields(csch_acomp_t *comp) +{ + htsp_entry_t *e; + + for(e = htsp_first(&comp->ports); e != NULL; e = htsp_next(&comp->ports, e)) { + csch_aport_free_fields(e->value); + free(e->value); e->value = NULL; + } + for(e = htsp_first(&comp->busports); e != NULL; e = htsp_next(&comp->busports, e)) { + abort(); + } + + htsp_uninit(&comp->ports); + htsp_uninit(&comp->busports); + free(comp->name); + free(comp->name_loc); + csch_ahdr_uninit(&comp->hdr); +} + + +void csch_abstract_init(csch_abstract_t *abs) +{ + memset(abs, 0, sizeof(csch_abstract_t)); + htsp_init(&abs->nets, strhash, strkeyeq); + htsp_init(&abs->comps, strhash, strkeyeq); + htip_init(&abs->aid2obj, longhash, longkeyeq); + abs->hroot = csch_hlevel_new(NULL, NULL, NULL); + abs->next_aid = 1; +} + +void csch_abstract_uninit(csch_abstract_t *abs) +{ + htsp_entry_t *e; + long n; + + csch_hlevel_free_tree(abs->hroot); + + for(e = htsp_first(&abs->nets); e != NULL; e = htsp_next(&abs->nets, e)) { + csch_anet_free_fields(e->value); + free(e->value); e->value = NULL; + } + + for(e = htsp_first(&abs->comps); e != NULL; e = htsp_next(&abs->comps, e)) { + csch_acomp_free_fields(e->value); + free(e->value); e->value = NULL; + } + + for(n = 0; n < abs->orphaned_ports.used; n++) { + csch_aport_free_fields(abs->orphaned_ports.array[n]); + free(abs->orphaned_ports.array[n]); + } + + htsp_uninit(&abs->nets); + htsp_uninit(&abs->comps); + htip_uninit(&abs->aid2obj); + vtp0_uninit(&abs->orphaned_ports); + + memset(abs, 0, sizeof(csch_abstract_t)); +} + + +/* Initialize an object by setting the common header fields; the only purpose + of this function is to get compiler warnings at every caller when the header + is extended (because the number of args would be extended here) */ +RND_INLINE void csch_aobj_init(csch_abstract_t *abs, csch_ahdr_t *dst, csch_atype_t type) +{ + dst->type = type; + csch_attrib_init(&dst->attr); + dst->abst = abs; + + /* assign unique aid */ + dst->aid = abs->next_aid; + abs->next_aid++; + if (abs->next_aid < 1) + abs->next_aid = 1; + htip_set(&abs->aid2obj, dst->aid, dst); + + switch(type) { + case CSCH_ATYPE_INVALID: + case CSCH_ATYPE_BUSNET: + case CSCH_ATYPE_BUSCHAN: + case CSCH_ATYPE_BUSPORT: + case CSCH_ATYPE_HUB: + break; + case CSCH_ATYPE_PORT: abs->new_ports = 1; break; + case CSCH_ATYPE_NET: abs->new_nets = 1; break; + case CSCH_ATYPE_COMP: abs->new_comps = 1; break; + } +} + +csch_ascope_t csch_split_name_scope(const char **name) +{ + const char *nm = *name; + + if (nm[0] == '/') { + (*name) += 1; + return CSCH_ASCOPE_GLOBAL; + } + + /* check this so nm[1] is safe to address */ + if (nm[0] == '\0') + return CSCH_ASCOPE_AUTO; + + if (nm[1] == '/') { + if (nm[0] == '.') { + (*name) += 2; + return CSCH_ASCOPE_SHEET_LOCAL; + } + if (nm[0] == '^') { + (*name) += 2; + return CSCH_ASCOPE_SUBTREE_AUTO; + } + if (nm[0] == 'v') { + (*name) += 2; + return CSCH_ASCOPE_SUBTREE_LOCAL; + } + } + + /* no usable prefix */ + return CSCH_ASCOPE_AUTO; +} + +#include "abs_net.c" +#include "abs_comp.c" + +csch_aport_t *csch_aport_get(csch_abstract_t *abs, csch_acomp_t *comp, const char *name, int alloc) +{ + csch_aport_t *port; + + if (comp != NULL) { + port = htsp_get(&comp->ports, name); + if ((port != NULL) || (!alloc)) + return port; + } + + port = calloc(sizeof(csch_aport_t), 1); + csch_aobj_init(abs, &port->hdr, CSCH_ATYPE_PORT); + port->name = rnd_strdup(name); + port->parent = comp; + + if (comp != NULL) + htsp_set(&comp->ports, port->name, port); + else + vtp0_append(&abs->orphaned_ports, port); + return port; +} + + +static void dump_attr(const csch_attribs_t *attr, FILE *f, const char *prefix1, const char *prefix2) +{ + htsp_entry_t *e; + fprintf(f, "%s%sAttributes:\n", prefix1, prefix2); + for(e = htsp_first(attr); e != NULL; e = htsp_next(attr, e)) { + const csch_attrib_t *a = e->value; + if (a->deleted) continue; + if (a->val == NULL) { + long n; + fprintf(f, "%s%s %s={\n", prefix1, prefix2, a->key); + for(n = 0; n < a->arr.used; n++) + fprintf(f, "%s%s %s\n", prefix1, prefix2, a->arr.array[n]); + fprintf(f, "%s%s }\n", prefix1, prefix2); + } + else + fprintf(f, "%s%s %s=%s\n", prefix1, prefix2, a->key, a->val); + } +} + +void csch_abstract_dump(const csch_abstract_t *abs, FILE *f, const char *prefix) +{ + htsp_entry_t *e; + + fprintf(f, "%sNets:\n", prefix); + for(e = htsp_first(&abs->nets); e != NULL; e = htsp_next(&abs->nets, e)) { + csch_anet_t *net = e->value; + long n; + + fprintf(f, "%s %s\n", prefix, net->name); + fprintf(f, "%s ports:\n", prefix); + for(n = 0; n < net->conns.used; n++) { + csch_aport_t *port = net->conns.array[n]; + fprintf(f, "%s %s-%s\n", prefix, port->parent->name, port->name); + } + dump_attr(&net->hdr.attr, f, prefix, " "); + } + + fprintf(f, "%sComponents:\n", prefix); + for(e = htsp_first(&abs->comps); e != NULL; e = htsp_next(&abs->comps, e)) { + htsp_entry_t *pe; + csch_acomp_t *comp = e->value; + + fprintf(f, "%s %s\n", prefix, comp->name); + + fprintf(f, "%s Ports:\n", prefix); + for(pe = htsp_first(&comp->ports); pe != NULL; pe = htsp_next(&comp->ports, pe)) { + csch_aport_t *port = pe->value; + fprintf(f, "%s %s\n", prefix, port->name); + dump_attr(&port->hdr.attr, f, prefix, " "); + } + dump_attr(&comp->hdr.attr, f, prefix, " "); + } +} Index: tags/1.0.5/src/libcschem/abstract.h =================================================================== --- tags/1.0.5/src/libcschem/abstract.h (nonexistent) +++ tags/1.0.5/src/libcschem/abstract.h (revision 10414) @@ -0,0 +1,237 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2018 Tibor 'Igor2' Palinkas + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#ifndef CSCH_ABSTRACT_H +#define CSCH_ABSTRACT_H + +#include + +#include +#include +#include +#include +#include + +#include "libcschem/common_types.h" +#include "libcschem/attrib.h" +#include "TODO.h" + + +typedef struct csch_hlevel_s csch_hlevel_t; +typedef struct csch_hier_path_s csch_hier_path_t; + +/* A single level of hierarchy storing local objects with short (local) names; + objects are not allocated, just referenced from the global (flat) abstract + model (csch_abstract_t) */ +struct csch_hlevel_s { + htsp_t nets; /* local netname -> csch_anet_t */ + htsp_t comps; /* local name -> csch_acomp_t */ + + char *name; + int hdepth; + + csch_cgrp_t *sym; /* the sheetref symbol that created this level (NULL in root) */ + csch_hlevel_t *parent; /* NULL in root */ + gdl_elem_t link; /* doubly linked list of siblings; not used in root */ + gdl_list_t children; /* of (csch_hlevel_t *) */ +}; + +struct csch_abstract_s { + htip_t aid2obj; /* primary storage: global aid -> (csch_ahdr_t *) */ + htul_t uid2id; /* UID -> object id (cache) */ + htsp_t nets; /* global netname -> csch_anet_t */ + htsp_t comps; /* global name -> csch_acomp_t */ + vtp0_t orphaned_ports; /* ports without a component parent; typical for sheet ports in a hierarchy */ + long next_aid; + + /* counters for unique names */ + struct { + long wirenet, comp, port; + long target_tmp; /* next id for temporary object created by the target plugin(s) - post-increment */ + } ucnt; + + /* compilation state */ + unsigned new_comps:1; /* set to 1 whe a new component is created */ + unsigned new_nets:1; /* set to 1 whe a new net is created */ + unsigned new_ports:1; /* set to 1 whe a new port is created */ + csch_project_t *prj; /* only during compilation */ + long view_id; /* which view the abstract model is compiled for; only during compilation */ + htpp_t eng_transient; /* private data used during compilation by engines; typically set in the project_before hook and removed/freed in the project_after hook; key is a const char *cookie */ + + /* hierarchy */ + csch_hlevel_t *hroot; /* the common hierarchy level of all root sheets */ +}; + +typedef enum csch_atype_e { + CSCH_ATYPE_INVALID = 0, + CSCH_ATYPE_NET, + CSCH_ATYPE_BUSNET, + CSCH_ATYPE_BUSCHAN, + CSCH_ATYPE_PORT, + CSCH_ATYPE_BUSPORT, + CSCH_ATYPE_COMP, + CSCH_ATYPE_HUB +} csch_atype_t; +const char *csch_atype_name(csch_atype_t type); + +typedef enum csch_ascope_e { /* implements {des6:8} */ + CSCH_ASCOPE_unknown = -1, + CSCH_ASCOPE_GLOBAL=1, /* syntax: /name */ + CSCH_ASCOPE_SUBTREE_LOCAL, /* syntax: v/name */ + CSCH_ASCOPE_SHEET_LOCAL, /* syntax: ./name */ + CSCH_ASCOPE_AUTO, /* syntax: name */ + CSCH_ASCOPE_SUBTREE_AUTO /* syntax: ^/name */ +} csch_ascope_t; + + +struct csch_ahdr_s { + csch_atype_t type; + csch_attribs_t attr; + long aid; + vtp0_t srcs; /* list of pointers to concrete objects that were source to this abstract object */ + csch_abstract_t *abst; + const char *ghost; /* if not NULL, the given object is only an empty shell (got used once during the compilation, but was emptied later, probably merged into something else) */ + unsigned compiled:1; /* already compiled, compiler should skip it */ + + /* cached from attributes to speed up render */ + unsigned dnp:1; /* attribute display/dnp: do not populate */ + unsigned omit:1; /* attribute display/dnp: omit from export */ +}; + +typedef struct csch_acomp_s csch_acomp_t; + + +/* type = CSCH_ATYPE_NET */ +typedef struct csch_anet_s { + csch_ahdr_t hdr; + vtp0_t conns; /* a list of (csch_ahdr_t *) connections, ports and bus-ports */ + char *name; /* global unique name for the hash (flat model); includes hierarchic path of some sort */ + char *name_loc; /* local name within the hierarchic level (doesn't include hierarchic path) */ + + /* hierarchy */ + csch_ascope_t scope; /* coming from name prefix */ + csch_hlevel_t *hlev; /* subtree the net is in */ + + + unsigned no_uname:1; /* 1 if there is no user assigned net name */ + unsigned term_term:1; /* the net was created for a "hidden" terminal-terminal connection */ + long hdepth; /* how deep the net is in the hierarchy; 0 means it's on a root sheet */ + + /* cached from attributes: */ + const char *chan; +} csch_anet_t; + + +/* type = CSCH_ATYPE_BUSCHAN */ +typedef struct csch_anet_s csch_abuschan_t; + +/* type = CSCH_ATYPE_BUSNET */ +typedef struct csch_abusnet_s { + csch_ahdr_t hdr; + htsp_t *chans; /* of (csch_abuschan_t *), key is ->chan */ + + /* cached from attributes: */ + const char *name; +} csch_abus_t; + +/* type = CSCH_ATYPE_PORT */ +typedef struct csch_aport_s csch_aport_t; +struct csch_aport_s { + csch_ahdr_t hdr; + csch_acomp_t *parent; + char *name; + + struct { + csch_anet_t *net; /* net the port is connected to */ + /* TODO: bus */ + } conn; + + /* cached from attributes: */ + const char *chan; + unsigned sheet_port:1; /* set to 1 if this port is directly on the sheet (hierarchy) */ + csch_acomp_t *referer; /* if sheet_port is 1, this is the referer component on the parent sheet; this component is a subsheet component */ + csch_aport_t *subsheet_port; /* port is on a subsheet symbol; this field shows which port it is connected to within the subsheet */ +}; + +/* type = CSCH_ATYPE_BUSPORT */ +typedef struct csch_abusport_s { + csch_ahdr_t hdr; + csch_acomp_t *parent; + + /* cached from attributes: */ + const char *name; + void *chan_rewrite; +} csch_abusport_t; + +/* type = CSCH_ATYPE_COMP */ +struct csch_acomp_s { + csch_ahdr_t hdr; + char *name; /* global unique name for the hash (flat model); includes hierarchic path of some sort */ + char *name_loc; /* local name within the hierarchic level (doesn't include hierarchic path) */ + + /* hierarchy */ + csch_ascope_t scope; /* coming from name prefix */ + csch_hlevel_t *hlev; /* subtree the component is in */ + long hdepth; /* how deep the comp is in the hierarchy; 0 means it's on a root sheet */ + + htsp_t ports; /* of csch_aport_t, key is ->name */ + htsp_t busports; /* of csch_abusport_t, key is ->name */ + + csch_sheet_t *child_sheet; /* set when symbol is referencing a hierarchic sheet down */ + + /* cache/temporary for compilation */ + unsigned postprocessed:1; +}; + +/* type = CSCH_ATYPE_HUB */ +typedef struct csch_ahub_s { + csch_ahdr_t hdr; +} csch_ahub_t; + + +/*** abs ***/ +void csch_abstract_init(csch_abstract_t *abs); +void csch_abstract_uninit(csch_abstract_t *abs); +void csch_abstract_dump(const csch_abstract_t *abs, FILE *f, const char *prefix); + +/*** generic ***/ +/* Modify name ptr to remove prefix and return the scope specified in the prefix */ +csch_ascope_t csch_split_name_scope(const char **name); + + +/*** net ***/ +csch_anet_t *csch_anet_get(csch_abstract_t *abs, const char *netname); /* does NOT handle hierarchy (prefixed netnames) */ +csch_anet_t *csch_anet_get_at(csch_abstract_t *abs, csch_hlevel_t *hlev, csch_ascope_t scope, const char *netname); +csch_anet_t *csch_anet_new(csch_abstract_t *abs, csch_hlevel_t *hlev, csch_ascope_t scope, const char *name_glob, const char *name_loc, int set_no_uname); + +/*** component and port ***/ +csch_acomp_t *csch_acomp_get(csch_abstract_t *abs, const char *name); /* does NOT handle hierarchy (prefixed netnames) */ +csch_acomp_t *csch_acomp_get_at(csch_abstract_t *abs, csch_hlevel_t *hlev, csch_ascope_t scope, const char *name); +csch_acomp_t *csch_acomp_new(csch_abstract_t *abs, csch_hlevel_t *hlev, csch_ascope_t scope, const char *name_glob, const char *name_loc); + +csch_aport_t *csch_aport_get(csch_abstract_t *abs, csch_acomp_t *comp, const char *name, int alloc); + +#endif Index: tags/1.0.5/src/libcschem/actions_csch.c =================================================================== --- tags/1.0.5/src/libcschem/actions_csch.c (nonexistent) +++ tags/1.0.5/src/libcschem/actions_csch.c (revision 10414) @@ -0,0 +1,166 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2019 Tibor 'Igor2' Palinkas + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include "config.h" + +/* fungw type extensions for cschem-only actions */ + +#include "config.h" + +#include + +#include + +#include +#include "actions_csch.h" +#include "oidpath.h" + +const char *CSCH_PTR_DOMAIN_COBJ = "csch_fgw_ptr_domain_cobj"; +const char *CSCH_PTR_DOMAIN_AOBJ = "csch_fgw_ptr_domain_aobj"; +const char *CSCH_PTR_DOMAIN_PROJECT = "csch_fgw_ptr_domain_project"; +const char *CSCH_PTR_DOMAIN_SHEET = "csch_fgw_ptr_domain_sheet"; +const char *CSCH_PTR_DOMAIN_ATTRIB = "csch_fgw_ptr_domain_attrib"; +const char *CSCH_PTR_DOMAIN_HPATH = "csch_fgw_ptr_domain_attrib"; +const char *CSCH_PTR_DOMAIN_COBJ_ARR = "csch_fgw_ptr_domain_cobj_arr"; + + +static int cobj_arg_conv(fgw_ctx_t *ctx, fgw_arg_t *arg, fgw_type_t target) +{ + if (target == FGW_LAYERID) { /* convert to layer id */ + csch_chdr_t *tmp = NULL; + switch(FGW_BASE_TYPE(arg->type)) { + ARG_CONV_CASE_LONG(tmp, conv_err) + ARG_CONV_CASE_LLONG(tmp, conv_err) + ARG_CONV_CASE_DOUBLE(tmp, conv_err) + ARG_CONV_CASE_LDOUBLE(tmp, conv_err) + ARG_CONV_CASE_PTR(tmp, conv_err) + ARG_CONV_CASE_CLASS(tmp, conv_err) + ARG_CONV_CASE_INVALID(tmp, conv_err) + case FGW_STR: + { + csch_oidpath_t oidp; + csch_sheet_t *sheet; + int res = csch_oidpath_parse(&oidp, arg->val.str); + if (res < 0) return -1; + TODO("figure how to get sheet from hidlib"); + sheet = NULL; + abort(); + tmp = csch_oidpath_resolve(sheet, &oidp); + csch_oidpath_free(&oidp); + } + } + if (tmp == NULL) return -1; + arg->type = FGW_COBJ; + fgw_cobj(arg) = tmp; + return 0; + } + if (arg->type == FGW_COBJ) { /* convert from cobj */ + csch_chdr_t *tmp = fgw_cobj(arg); + switch(target) { + ARG_CONV_CASE_LONG(tmp, conv_err) + ARG_CONV_CASE_LLONG(tmp, conv_err) + ARG_CONV_CASE_DOUBLE(tmp, conv_err) + ARG_CONV_CASE_LDOUBLE(tmp, conv_err) + ARG_CONV_CASE_PTR(tmp, conv_err) + ARG_CONV_CASE_CLASS(tmp, conv_err) + ARG_CONV_CASE_INVALID(tmp, conv_err) + case FGW_AUTO: + case FGW_STR: + { + const csch_oidpath_t oidp; + TODO("map oid path of an object"); + abort(); + arg->val.str = csch_oidpath_to_str(&oidp); + arg->type = FGW_STR | FGW_DYN; + return 0; + } + } + (void)tmp; /* supress compiler warning */ + arg->type = target; + return 0; + } + fprintf(stderr, "Neither side of the conversion is a cobj\n"); + abort(); +} + +#define conv_struct_from_str(str, DOMAIN, TYPE) \ + if ((str[0] == '0') && (str[1] == 'x')) { \ + fgw_arg_conv(&rnd_fgw, arg, FGW_PTR); \ + if (fgw_ptr_in_domain(&rnd_fgw, arg, DOMAIN)) { \ + arg->type = TYPE | FGW_PTR; \ + return 0; \ + } \ + arg->type = FGW_INVALID; \ + return -1; \ + } + +static int idpath_arg_conv(fgw_ctx_t *ctx, fgw_arg_t *arg, fgw_type_t target) +{ + if (target == FGW_IDPATH) { /* convert to idpath */ + if (FGW_BASE_TYPE(arg->type) == FGW_STR) { + const char *str = arg->val.str; + csch_oidpath_t *idp; + + conv_struct_from_str(str, RND_PTR_DOMAIN_IDPATH, FGW_IDPATH); + idp = malloc(sizeof(csch_oidpath_t)); + if (csch_oidpath_parse(idp, str) == 0) { + fgw_ptr_reg(&rnd_fgw, arg, RND_PTR_DOMAIN_IDPATH, FGW_IDPATH, idp); + return 0; + } + else + free(idp); + } + if (FGW_BASE_TYPE(arg->type) == (FGW_PTR | FGW_STRUCT) && fgw_ptr_in_domain(&rnd_fgw, arg, RND_PTR_DOMAIN_IDPATH)) + return 0; + arg->type = FGW_INVALID; + return -1; + } + if (arg->type == FGW_IDPATH) { /* convert from idpath */ + if (fgw_ptr_in_domain(&rnd_fgw, arg, RND_PTR_DOMAIN_IDPATH)) { + char *name = csch_oidpath_to_str(arg->val.ptr_void); + if (name != NULL) { + arg->val.str = name; + arg->type = FGW_STR | FGW_DYN; + } + return 0; + } + return -1; + } + fprintf(stderr, "Neither side of the conversion is idpath\n"); + abort(); +} + +void csch_actions_init(fgw_ctx_t *ctx) +{ + if (fgw_reg_custom_type(ctx, FGW_COBJ, "cobj", cobj_arg_conv, NULL) != FGW_COBJ) { + fprintf(stderr, "csch_actions_init: failed to register FGW_COBJ\n"); + abort(); + } + if (fgw_reg_custom_type(&rnd_fgw, FGW_IDPATH, "idpath", idpath_arg_conv, NULL) != FGW_IDPATH) { + fprintf(stderr, "pcb_actions_init: failed to register FGW_IDPATH\n"); + abort(); + } +} Index: tags/1.0.5/src/libcschem/actions_csch.h =================================================================== --- tags/1.0.5/src/libcschem/actions_csch.h (nonexistent) +++ tags/1.0.5/src/libcschem/actions_csch.h (revision 10414) @@ -0,0 +1,95 @@ +#ifndef ACTIONS_CSCH_H +#define ACTIONS_CSCH_H + +#include + +typedef enum { + FGW_COBJ_ = FGW_CUSTOM + 20, + FGW_AOBJ_, + FGW_PROJECT_, + FGW_SHEET_, + FGW_ATTRIB_, + FGW_HPATH_ /* hiearchy path: csch_hier_path_t */ +} csch_fgw_types_e; +#define fgw_cobj(arg) ((arg)->val.ptr_void) +#define fgw_aobj(arg) ((arg)->val.ptr_void) +#define fgw_project(arg) ((arg)->val.ptr_void) +#define fgw_sheet(arg) ((arg)->val.ptr_void) +#define fgw_attrib(arg) ((arg)->val.ptr_void) +#define fgw_hpath(arg) ((arg)->val.ptr_void) +#define FGW_COBJ ((fgw_type_t)FGW_COBJ_) +#define FGW_AOBJ ((fgw_type_t)FGW_AOBJ_) +#define FGW_PROJECT ((fgw_type_t)FGW_PROJECT_) +#define FGW_SHEET ((fgw_type_t)FGW_SHEET_) +#define FGW_ATTRIB ((fgw_type_t)FGW_ATTRIB_) +#define FGW_HPATH ((fgw_type_t)FGW_HPATH_) + +extern const char *CSCH_PTR_DOMAIN_COBJ; +extern const char *CSCH_PTR_DOMAIN_AOBJ; +extern const char *CSCH_PTR_DOMAIN_PROJECT; +extern const char *CSCH_PTR_DOMAIN_SHEET; +extern const char *CSCH_PTR_DOMAIN_ATTRIB; +extern const char *CSCH_PTR_DOMAIN_HPATH; +extern const char *CSCH_PTR_DOMAIN_COBJ_ARR; + +void csch_actions_init(fgw_ctx_t *ctx); + +#define CSCH_HOOK_FAIL(idx, type, aname) \ + rnd_message(RND_MSG_ERROR, "Internal error: unexpected hook argument %d in %s (expected %s)\n", idx, #aname, #type) + +/* Require argument idx to exist and convert it to type; on success, also execute stmt */ +#define CSCH_HOOK_CONVARG(idx, type, aname, stmt) \ +do { \ + if (argc <= idx) { \ + CSCH_HOOK_FAIL(idx, type, aname); \ + return FGW_ERR_ARGC; \ + } \ + if (fgw_arg_conv(&rnd_fgw, &argv[idx], type) != 0) { \ + CSCH_HOOK_FAIL(idx, type, aname); \ + return FGW_ERR_ARG_CONV; \ + } \ + { stmt; } \ +} while(0) + +/* If argument idx exists, convert it to type; on success, also execute stmt */ +#define CSCH_HOOK_MAY_CONVARG(idx, type, aname, stmt) \ +do { \ + if (argc > idx) { \ + if (fgw_arg_conv(&rnd_fgw, &argv[idx], type) != 0) { \ + CSCH_HOOK_FAIL(idx, type, aname); \ + return FGW_ERR_ARG_CONV; \ + } \ + { stmt; } \ + } \ +} while(0) + + +/* Convert argv[argid] into keyword cmd. If it's F_Object, accept optional + =oidpath or :oidpath suffix and require that to point to an existing object, + which is loaded into obj. obj is NULL if suffix is missing */ +#define CSCH_ACT_CONVARG_OBJ(argid, ACTNAME, cmd, obj) \ + do { \ + const char *__tmp__; \ + RND_ACT_CONVARG(argid, FGW_STR, ACTNAME, __tmp__ = argv[argid].val.str); \ + if ((strncmp(__tmp__, "object", 6) == 0) && ((__tmp__[6] == ':') || (__tmp__[6] == '='))) { \ + csch_oidpath_t __oidp__ = {0}; \ + if (csch_oidpath_parse(&__oidp__, __tmp__+7) != 0) { \ + rnd_message(RND_MSG_ERROR, #ACTNAME ": Invalid oidpath: %s\n", __tmp__+7); \ + return FGW_ERR_ARG_CONV; \ + } \ + obj = csch_oidpath_resolve(sheet, &__oidp__); \ + csch_oidpath_free(&__oidp__); \ + if (obj == NULL) { \ + rnd_message(RND_MSG_ERROR, #ACTNAME ": No such object: %s\n", __tmp__+7); \ + return FGW_ERR_ARG_CONV; \ + } \ + cmd = F_Object; \ + } \ + else { \ + obj = NULL; \ + fgw_arg_conv(&rnd_fgw, &argv[1], FGW_KEYWORD); \ + cmd = fgw_keyword(&argv[1]); \ + } \ + } while(0); + +#endif Index: tags/1.0.5/src/libcschem/attrib.c =================================================================== --- tags/1.0.5/src/libcschem/attrib.c (nonexistent) +++ tags/1.0.5/src/libcschem/attrib.c (revision 10414) @@ -0,0 +1,1130 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2018,2019,2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include "config.h" +#include "libcschem/common_types.h" +#include +#include +#include +#include +#include +#include +#include "attrib.h" +#include "cnc_obj.h" +#include "cnc_grp.h" +#include "undo.h" +#include "concrete.h" +#include "abstract.h" +#include "project.h" +#include +#include +#include +#include + +/*** low level attribute manipulation */ + +static csch_attrib_t *attr_alloc(const char *key, int prio) +{ + csch_attrib_t *a = calloc(sizeof(csch_attrib_t), 1); + a->key = rnd_strdup(key); + a->prio = prio; + return a; +} + +static void attr_free_vts(vts0_t *vt) +{ + size_t n; + for(n = 0; n < vts0_len(vt); n++) + free(vt->array[n]); + vts0_uninit(vt); +} + + +static void attr_free_val(csch_attrib_t *a) +{ + if (a->val != NULL) { + free(a->val); + a->val = NULL; + } + else + attr_free_vts(&a->arr); +} + + +static void attr_free(csch_attrib_t *a) +{ + free(a->key); + attr_free_val(a); + attr_free_vts(&a->source); + free(a->export_name); + free(a); +} + +void csch_attr_free(csch_attrib_t *a) +{ + attr_free(a); +} + + +#include "attrib_src.c" + +/*** API functions ***/ + +void csch_attrib_init(csch_attribs_t *attribs) +{ + htsp_init(attribs, strhash, strkeyeq); +} + +void csch_attrib_uninit(csch_attribs_t *attribs) +{ + htsp_entry_t *e; + for(e = htsp_first(attribs); e; e = htsp_next(attribs, e)) + attr_free(e->value); + htsp_uninit(attribs); +} + + + +static int attrib_sort_cmp(const void *a1_, const void *a2_) +{ + csch_attrib_t * const *a1 = a1_; + csch_attrib_t * const *a2 = a2_; + return strcmp((*a1)->key, (*a2)->key); +} + +void csch_attrib_sort(vtp0_t *dst, const csch_attribs_t *attribs) +{ + htsp_entry_t *e; + + /* optimization: make room for all the elements, avoiding realloc()s down the road */ + vtp0_enlarge(dst, vtp0_len(dst) + attribs->used - 1); + dst->used = 0; + + for(e = htsp_first(attribs); e; e = htsp_next(attribs, e)) + vtp0_append(dst, e->value); + + qsort(dst->array, vtp0_len(dst), sizeof(csch_attrib_t *), attrib_sort_cmp); +} + +/* Does not free src. Strdups val only if requested */ +static int csch_attrib_set_nofree(csch_attribs_t *attribs, int prio, const char *key, const char *val, csch_source_arg_t *source, csch_attrib_t **attr_out, int strdup_val) +{ + csch_attrib_t *a = htsp_get(attribs, key); + + if (a == NULL) { + a = attr_alloc(key, prio); + if (attr_out != NULL) *attr_out = a; + htsp_set(attribs, a->key, a); + } + else { + if (prio > a->prio) { + append_src(a, prio, source, 1); + if (attr_out != NULL) *attr_out = a; + return -1; + } + attr_free_val(a); + } + if (strdup_val) + a->val = ((val == NULL) ? NULL : rnd_strdup(val)); + else + a->val = (char *)val; /* caller explicitly asked for this cast */ + append_src(a, prio, source, 0); + if (attr_out != NULL) *attr_out = a; + return 0; +} + +int csch_attrib_set(csch_attribs_t *attribs, int prio, const char *key, const char *val, csch_source_arg_t *source, csch_attrib_t **attr_out) +{ + int res = csch_attrib_set_nofree(attribs, prio, key, val, source, attr_out, 1); + csch_attr_src_free(source); + return res; +} + + +int csch_attrib_setptr(csch_attribs_t *attribs, int prio, char *key, const char *val, csch_source_arg_t *source, csch_attrib_t **attr_out) +{ + int res = csch_attrib_set_nofree(attribs, prio, key, val, source, attr_out, 0); + csch_attr_src_free(source); + return res; +} + + +int csch_attrib_seti(csch_attribs_t *attribs, int prio, const char *key, long idx, const char *val, csch_source_arg_t *source, csch_attrib_t **attr_out) +{ + csch_attrib_t *a = htsp_get(attribs, key); + char *nval; + + if (idx < 0) + goto error; + + if (a == NULL) { + a = attr_alloc(key, prio); + if (attr_out != NULL) *attr_out = a; + htsp_set(attribs, a->key, a); + } + else { + if (a->val != NULL) + goto error; + if (prio > a->prio) { + append_src(a, prio, source, 1); + if (attr_out != NULL) *attr_out = a; + goto error; + } + } + append_src(a, prio, source, 0); + nval = rnd_strdup(val); + if (idx < a->arr.used) { + free(a->arr.array[idx]); + a->arr.array[idx] = nval; + } + vts0_set(&a->arr, idx, nval); + if (attr_out != NULL) *attr_out = a; + csch_attr_src_free(source); + return 0; + + error:; + csch_attr_src_free(source); + return -1; +} + +/* how is: 0=overwrite whole arr; -1=prepend; +1=append; does not free src */ +static int csch_attrib_set_arr_nofree(csch_attribs_t *attribs, int prio, const char *key, const vts0_t *val, csch_source_arg_t *source, csch_attrib_t **attr_out, int how) +{ + long n; + csch_attrib_t *a = htsp_get(attribs, key); + + if (a == NULL) { + a = attr_alloc(key, prio); + if (attr_out != NULL) *attr_out = a; + htsp_set(attribs, a->key, a); + } + else { + if (a->val != NULL) + return -1; + if (prio > a->prio) { + append_src(a, prio, source, 1); + if (attr_out != NULL) *attr_out = a; + return -1; + } + if (how == 0) + attr_free_val(a); + } + append_src(a, prio, source, 0); + + if (how == 0) { + /* overwrite */ + for(n = 0; n < a->arr.used; n++) + free(a->arr.array[n]); + a->arr.used = 0; + for(n = 0; n < val->used; n++) + vts0_set(&a->arr, n, rnd_strdup(val->array[n])); + } + else if (how > 1) { + /* append */ + for(n = 0; n < val->used; n++) + vts0_append(&a->arr, rnd_strdup(val->array[n])); + } + else { + /* prepend */ + for(n = 0; n < val->used; n++) + vts0_append(&a->arr, rnd_strdup(val->array[n])); + } + + if (attr_out != NULL) *attr_out = a; + return 0; +} + +int csch_attrib_set_arr(csch_attribs_t *attribs, int prio, const char *key, const vts0_t *val, csch_source_arg_t *source, csch_attrib_t **attr_out) +{ + int res = csch_attrib_set_arr_nofree(attribs, prio, key, val, source, attr_out, 0); + csch_attr_src_free(source); + return res; +} + +int csch_attrib_append(csch_attribs_t *attribs, int prio, const char *key, const char *val, csch_source_arg_t *source) +{ + int res; + vts0_t tmp = {0}; + + tmp.used = tmp.alloced = 1; + tmp.array = (char **)&val; + + res = csch_attrib_set_arr_nofree(attribs, prio, key, &tmp, source, NULL, 1); + csch_attr_src_free(source); + return res; +} + +int csch_attrib_prepend(csch_attribs_t *attribs, int prio, const char *key, const char *val, csch_source_arg_t *source) +{ + int res; + vts0_t tmp = {0}; + + tmp.used = tmp.alloced = 1; + tmp.array = (char **)&val; + + res = csch_attrib_set_arr_nofree(attribs, prio, key, &tmp, source, NULL, -1); + csch_attr_src_free(source); + return res; +} + +int csch_attrib_append_val(csch_attribs_t *attribs, int prio, const char *key, const csch_attrib_t *srca, csch_source_arg_t *source) +{ + if (srca->val != NULL) + return csch_attrib_append(attribs, prio, key, srca->val, source); + + return csch_attrib_set_arr_nofree(attribs, prio, key, &srca->arr, source, NULL, 1); +} + +int csch_attrib_set_arr_c(csch_attribs_t *attribs, int prio, const char *key, const char **val, csch_source_arg_t *source, csch_attrib_t **attr_out) +{ + int res; + const char **s; + vts0_t tmp = {0}; + + for(s = val; *s != NULL; s++) + tmp.used++; + tmp.alloced = tmp.used; + tmp.array = (char **)val; + + res = csch_attrib_set_arr_nofree(attribs, prio, key, &tmp, source, attr_out, 0); + csch_attr_src_free(source); + return res; +} + +void csch_attrib_set_export_name(csch_attrib_t *dst, const char *expname) +{ + free(dst->export_name); + dst->export_name = rnd_strdup(expname); +} + +csch_attrib_t *csch_attrib_dup_rename(csch_attrib_t *src, const char *new_key) +{ + size_t n; + csch_attrib_t *dst = calloc(sizeof(csch_attrib_t), 1); + + dst->key = rnd_strdup(new_key); + if (src->val != NULL) + dst->val = rnd_strdup(src->val); + else + dst->val = NULL; + dst->prio = src->prio; + + if (src->arr.used > 0) { + vts0_enlarge(&dst->arr, src->arr.used); + dst->arr.used = 0; + for(n = 0; n < src->arr.used; n++) + vts0_append(&dst->arr, rnd_strdup(src->arr.array[n])); + } + if (src->source.used > 0) { + vts0_enlarge(&dst->source, src->source.used); + dst->source.used = 0; + for(n = 0; n < src->source.used; n++) + vts0_append(&dst->source, rnd_strdup_null(src->source.array[n])); + } + + return dst; +} + +csch_attrib_t *csch_attrib_dup(csch_attrib_t *src) +{ + return csch_attrib_dup_rename(src, src->key); +} + + +int csch_attrib_del(csch_attribs_t *attribs, int prio, const char *key, csch_source_arg_t *source) +{ + csch_attrib_t *a = htsp_get((csch_attribs_t *)attribs, key); + + if (a == NULL) { + csch_attr_src_free(source); + return -1; + } + + a->deleted = 1; + append_src(a, prio, source, 0); + csch_attr_src_free(source); + return 0; +} + +void csch_attrib_copy_all(csch_attribs_t *dst, const csch_attribs_t *src) +{ + htsp_entry_t *e; + + for(e = htsp_first(src); e; e = htsp_next(src, e)) { + csch_attrib_t *a = csch_attrib_dup(e->value); + htsp_set(dst, a->key, a); + } +} + +static csch_source_arg_t *attr_copy_gen_source(csch_attrib_t *s) +{ + char *sep, *ssrc = s->source.array[0]; + long len; + csch_source_arg_t *src; + + sep = strchr(ssrc, ':'); + sep++; + len = strlen(sep); + + src = malloc(sizeof(csch_source_arg_t) + len + 1); + src->type[0] = 'c'; + src->type[1] = '\0'; + memcpy(src->src_desc, sep, len+1); + + return src; +} + +void csch_attrib_copy_all_undoable(csch_sheet_t *sheet, csch_cgrp_t *dst_obj, csch_attribs_t *dst, const csch_attribs_t *src, int undoable) +{ + htsp_entry_t *e; + + assert((dst != NULL) || (dst_obj != NULL)); + + if (undoable) { + assert(dst_obj != NULL); + assert(sheet != NULL); + } + + if (dst == NULL) + dst = &dst_obj->attr; + + for(e = htsp_first(src); e; e = htsp_next(src, e)) { + csch_attrib_t *s = csch_attrib_dup(e->value); + csch_attrib_t *d = csch_attrib_get(dst, e->key); + + if ((s != NULL) && (d != NULL) && (csch_attrib_val_eq_(s, d))) { + /* do not merge if values are the same */ + attr_free(s); + continue; + } + + if (s->val == NULL) { /* source is an array */ + int done = 0; + + if (s->arr.used > 0) { + if ((d == NULL) || ((d->arr.used == 0) && (d->val == NULL))) { + /* source has an array, destination has nothing: simply copy the array */ + long n; + + if (undoable) { + if (d == NULL) { + d = attr_alloc(e->key, s->prio); + htsp_set(dst, e->key, d); + } + vts0_append(&d->arr, NULL); /* dummy cursor for insert before */ + for(n = 0; n < s->arr.used; n++) + csch_attr_arr_modify_ins_before(sheet, dst_obj, e->key, n, s->arr.array[n], 1); + d->arr.used--; /* remove dummy cursor */ + done = 1; + } + else { + csch_source_arg_t *source = attr_copy_gen_source(s); + csch_attrib_set_arr(dst, s->prio, e->key, &s->arr, source, NULL); + done = 1; + } + } + } + +TODO("figure how to merge arrays with differing content"); + if (!done) + rnd_message(RND_MSG_ERROR, "csch_attrib_copy_all_undoable(): internal error: can't copy/merge array type attribte '%s'\n", e->key); + } + else { /* source is scalar */ +TODO("handle if dst is an array"); + if ((d == NULL) || ((d->val != NULL))) { + csch_source_arg_t *source = attr_copy_gen_source(s); + + if (undoable) + csch_attr_modify_str(sheet, dst_obj, s->prio, e->key, s->val, source, 1); + else + csch_attrib_set(dst, s->prio, e->key, s->val, source, NULL); + attr_free(s); + s = NULL; + } + } + } +} + +int csch_attrib_apply(csch_attribs_t *dst, const csch_attribs_t *src, csch_source_arg_t *source, int *force_prio) +{ + htsp_entry_t *e; + int err = 0; + + for(e = htsp_first(src); e; e = htsp_next(src, e)) { + csch_attrib_t *a = e->value; + int prio = (force_prio != NULL) ? *force_prio : a->prio; + if (a->val != NULL) + err |= csch_attrib_set_nofree(dst, prio, a->key, a->val, source, NULL, 1); + else + err |= csch_attrib_set_arr_nofree(dst, prio, a->key, &a->arr, source, NULL, 0); + } + + csch_attr_src_free(source); + return err; +} + +/* invalidate all dyntext on attr change to make sure the new value is visible */ +static void attr_side_dyntext(csch_cgrp_t *grp) +{ + htip_entry_t *e; + for(e = htip_first(&grp->id2obj); e != NULL; e = htip_next(&grp->id2obj, e)) { + csch_chdr_t *o = e->value; + if (csch_obj_is_grp(o)) + attr_side_dyntext((csch_cgrp_t *)o); + else if (o->type == CSCH_CTYPE_TEXT) { + csch_text_t *t = (csch_text_t *)o; + if (t->dyntext) { + csch_text_dyntext_inval(t); + csch_text_invalidate_font(t); + } + } + } +} + +void csch_attr_side_effects(csch_cgrp_t *grp, const char *key) +{ + if (!csch_obj_is_grp(&grp->hdr)) + return; + + attr_side_dyntext(grp); + + if (key != NULL) { + const char *val = csch_attrib_get_str(&grp->attr, key); + csch_cgrp_attrib_update(grp->hdr.sheet, grp, 0, key, val); + } +} + +RND_INLINE void notify(csch_chdr_t *obj) +{ + rnd_event(&obj->sheet->hidlib, CSCH_EVENT_OBJ_ATTR_EDITED, "p", obj); + csch_cobj_redraw(obj); +} + +unsigned csch_attrib_hash(const csch_attribs_t *attr) +{ + unsigned res = 0; + htsp_entry_t *e; + + for(e = htsp_first(attr); e != NULL; e = htsp_next(attr, e)) { + long n; + csch_attrib_t *a = e->value; + + res ^= strhash(a->key); + res ^= ((unsigned)a->prio) << 3; + res ^= ((unsigned)a->deleted) << 15; + if (a->val != NULL) + res ^= strhash(a->val); + res ^= ((unsigned)a->arr.used) << 12; + + for(n = 0; n < a->arr.used; n++) + if (a->arr.array[n] != NULL) + res ^= strhash(a->arr.array[n]); + } + + return res; +} + +int csch_attrib_val_eq_(const csch_attrib_t *a1, const csch_attrib_t *a2) +{ + long n; + + if (a1->val != NULL) { + if (a2->val == NULL) return 0; + if (strcmp(a1->val, a2->val) != 0) return 0; + } + else + if (a2->val != NULL) return 0; + if (a1->arr.used != a2->arr.used) return 0; + + for(n = 0; n < a1->arr.used; n++) { + if (a1->arr.array[n] != NULL) { + if (a2->arr.array[n] == NULL) return 0; + if (strcmp(a1->arr.array[n], a2->arr.array[n]) != 0) return 0; + } + else + if (a2->arr.array[n] != NULL) return 0; + } + + return 1; +} + +int csch_attrib_eq_(const csch_attrib_t *a1, const csch_attrib_t *a2) +{ + /* assume keys match */ + if (a1->prio != a2->prio) return 0; + if (a1->deleted != a2->deleted) return 0; + + return csch_attrib_val_eq_(a1, a2); +} + +int csch_attrib_eq(const csch_attribs_t *attr1, const csch_attribs_t *attr2) +{ + htsp_entry_t *e; + + if (htsp_length(attr1) != htsp_length(attr2)) return 0; + + for(e = htsp_first((htsp_t *)attr1); e != NULL; e = htsp_next((htsp_t *)attr1, e)) { + csch_attrib_t *a1 = e->value, *a2 = htsp_get((htsp_t *)attr2, e->key); + + if (a2 == NULL) return 0; + if (!csch_attrib_eq_(a1, a2)) return 0; + } + + return 1; +} + +/*** Modify ***/ +typedef struct { + csch_cgrp_t *obj; /* it is safe to save the object pointer because it is persistent (through the removed object list) */ + csch_attrib_t *a; + char *key; /* need to store a copy of key separately because on deletion key is free'd */ +} undo_attr_modify_t; + + +static int undo_attr_modify_swap(void *udata) +{ + undo_attr_modify_t *u = udata; + csch_attrib_t *a; + + csch_cobj_redraw(u->obj); + + a = htsp_get(&u->obj->attr, u->key); + if (u->a != NULL) + htsp_set(&u->obj->attr, u->a->key, u->a); + else + htsp_popentry(&u->obj->attr, u->key); + u->a = a; + + csch_attr_side_effects(u->obj, u->key); + + csch_sheet_set_changed(u->obj->hdr.sheet, 1); + notify(&u->obj->hdr); + return 0; +} + +static void undo_attr_modify_print(void *udata, char *dst, size_t dst_len) +{ + undo_attr_modify_t *u = udata; + + rnd_snprintf(dst, dst_len, "attr change, key=%s", u->key); +} + +static void undo_attr_modify_free(void *udata) +{ + undo_attr_modify_t *u = udata; + if (u->a != NULL) { + attr_free(u->a); + u->a = NULL; + } + free(u->key); + u->key = NULL; +} + +static const char core_attr_cookie[] = "libcschem/core/attrib.c"; + +static const uundo_oper_t undo_attr_modify = { + core_attr_cookie, + undo_attr_modify_free, + undo_attr_modify_swap, + undo_attr_modify_swap, + undo_attr_modify_print +}; + + +void csch_attr_modify_str(csch_sheet_t *sheet, csch_cgrp_t *obj, int prio, const char *key, const char *val, csch_source_arg_t *source, int undoable) +{ + undo_attr_modify_t utmp, *u = &utmp; + + if (undoable) u = uundo_append(&sheet->undo, &undo_attr_modify, sizeof(undo_attr_modify_t)); + + if (prio < 0) { + csch_attrib_t *a = htsp_get(&obj->attr, key); + if (a != NULL) + prio = a->prio; + else + prio = -prio; + } + + u->obj = obj; + u->a = attr_alloc(key, prio); + u->a->val = val == NULL ? NULL : rnd_strdup(val); + u->key = rnd_strdup(key); + append_src(u->a, prio, source, 0); + + undo_attr_modify_swap(u); + if (undoable) csch_undo_inc_serial(sheet); + + csch_attr_src_free(source); +} + +void csch_attr_modify_del(csch_sheet_t *sheet, csch_cgrp_t *obj, const char *key, int undoable) +{ + undo_attr_modify_t utmp, *u = &utmp; + csch_attrib_t *a; + + /* skip creating an undo slot for a non-existing attribute's del (no-op) */ + a = htsp_get(&obj->attr, key); + if (a == NULL) + return; + + if (undoable) u = uundo_append(&sheet->undo, &undo_attr_modify, sizeof(undo_attr_modify_t)); + + u->obj = obj; + u->a = NULL; + u->key = rnd_strdup(key); + + undo_attr_modify_swap(u); + if (undoable) csch_undo_inc_serial(sheet); +} + +void csch_attr_modify_rename(csch_sheet_t *sheet, csch_cgrp_t *grp, csch_attrib_t *a, const char *new_name, csch_source_arg_t *src, int undoable) +{ + int prio = a->prio; + + assert(strcmp(new_name, a->key) != 0); + + if (undoable) + uundo_freeze_serial(&sheet->undo); + + csch_attr_modify_str(sheet, grp, prio, new_name, a->val, src, undoable); + csch_attr_modify_del(sheet, grp, a->key, undoable); + + if (undoable) { + uundo_unfreeze_serial(&sheet->undo); + uundo_inc_serial(&sheet->undo); + } +} + +typedef struct { + csch_chdr_t *obj; + csch_attrib_t *a; + short int prio; +} undo_attr_modify_prio_t; + + +static int undo_attr_modify_prio_swap(void *udata) +{ + undo_attr_modify_prio_t *u = udata; + short int tmp; + + tmp = u->a->prio; + u->a->prio = u->prio; + u->prio = tmp; + + csch_sheet_set_changed(u->obj->sheet, 1); + notify(u->obj); + return 0; +} + +static void undo_attr_modify_prio_print(void *udata, char *dst, size_t dst_len) +{ + undo_attr_modify_prio_t *u = udata; + + rnd_snprintf(dst, dst_len, "attr prio change, key=%s %d %d", u->a->key, u->a->prio, u->prio); +} + +static const uundo_oper_t undo_attr_modify_prio = { + core_attr_cookie, + /*undo_attr_modify_free*/ NULL, + undo_attr_modify_prio_swap, + undo_attr_modify_prio_swap, + undo_attr_modify_prio_print +}; + + +void csch_attr_modify_prio(csch_sheet_t *sheet, csch_cgrp_t *grp, csch_attrib_t *a, int prio, csch_source_arg_t *source, int undoable) +{ + undo_attr_modify_prio_t utmp, *u = &utmp; + + if (undoable) u = uundo_append(&sheet->undo, &undo_attr_modify_prio, sizeof(undo_attr_modify_prio_t)); + + u->obj = &grp->hdr; + u->a = a; + u->prio = prio; + append_src(u->a, prio, source, 0); + + undo_attr_modify_prio_swap(u); + if (undoable) csch_undo_inc_serial(sheet); + + csch_attr_src_free(source); +} + + + +static const char *NEWVAL_DEL = "NEWVAL_DEL"; +typedef struct { + csch_cgrp_t *obj; /* it is safe to save the object pointer because it is persistent (through the removed object list) */ + char *key; + long idx; /* current index */ + long delta; /* if non-zero, move item within the list */ + char *newval; /* if non-NULL, replace item content; if NEWVAL_DEL, remove item */ + + char *saved; /* saved string value if newval is NEWVAL_DEL */ +} undo_attr_arr_modify_t; + +/* returns delta achieved */ +RND_INLINE long attr_arr_move(csch_attrib_t *a, long idx, long delta) +{ + long n, end, res = 0; + char *save; + + if (delta == 0) + return 0; + + if (delta > 0) { + if (idx >= a->arr.used-1) + return 0; /* moving last item in positive dir -> noop */ + end = idx + delta; + if (end > a->arr.used-1) + end = a->arr.used-1; + save = a->arr.array[idx]; + for(n = idx; n < end; n++,res++) + a->arr.array[n] = a->arr.array[n+1]; + a->arr.array[end] = save; + } + else { /* delta < 0 */ + if (idx <= 0) + return 0; /* moving first item in negative dir -> noop */ + end = idx + delta; + if (end < 0) + end = 0; + save = a->arr.array[idx]; + for(n = idx; n > end; n--,res++) + a->arr.array[n] = a->arr.array[n-1]; + a->arr.array[end] = save; + } + + return res; +} + +RND_INLINE void attr_arr_del(csch_attrib_t *a, long idx) +{ + long n, end = a->arr.used-1; + + for(n = idx; n < end; n++) + a->arr.array[n] = a->arr.array[n+1]; + + a->arr.used--; +} + +/* create a new, empty slot at [idx], moving all items starting from + idx to +1. Effectively inserts an empty slot at idx, before the + item that was at idx. */ +RND_INLINE void attr_arr_ins_before(csch_attrib_t *a, long idx) +{ + long n, end = a->arr.used; + + + vts0_enlarge(&a->arr, a->arr.used); + for(n = end; n > idx; n--) + a->arr.array[n] = a->arr.array[n-1]; + + a->arr.array[idx] = NULL; +} + +static int undo_attr_arr_modify_swap(void *udata) +{ + undo_attr_arr_modify_t *u = udata; + csch_attrib_t *a; + long end; + + a = htsp_get(&u->obj->attr, u->key); + if (a == NULL) { + rnd_message(RND_MSG_ERROR, "undo_attr_arr_modify_swap(): no such attribute '%s' in object\n", u->key); + return -1; + } + + end = a->arr.used; + if ((u->newval == NEWVAL_DEL) && (u->saved != NULL)) + end++; /* special case: allow (re-)insert after the last item */ + + if ((u->idx < 0) || (u->idx >= end)) { + rnd_message(RND_MSG_ERROR, "undo_attr_arr_modify_swap(): arr index %ld out of range (0..%ld)\n", u->idx, a->arr.used); + return -1; + } + + csch_cobj_redraw(u->obj); + if (u->delta != 0) + u->delta = -attr_arr_move(a, u->idx, u->delta); + if (u->newval == NEWVAL_DEL) { + if (u->saved == NULL) { + u->saved = a->arr.array[u->idx]; + attr_arr_del(a, u->idx); + } + else { + attr_arr_ins_before(a, u->idx); + a->arr.array[u->idx] = u->saved; + u->saved = NULL; + } + + } + else if (u->newval != NULL) + rnd_swap(char *, a->arr.array[u->idx], u->newval); + + csch_attr_side_effects(u->obj, u->key); + + csch_sheet_set_changed(u->obj->hdr.sheet, 1); + notify(&u->obj->hdr); + return 0; +} + +static void undo_attr_arr_modify_print(void *udata, char *dst, size_t dst_len) +{ + undo_attr_arr_modify_t *u = udata; + + if (u->newval == NEWVAL_DEL) + rnd_snprintf(dst, dst_len, "attr arr %s, key=%s:%ld", (u->saved == NULL ? "del" : "ins"), u->key, u->idx); + else if (u->newval != NULL) + rnd_snprintf(dst, dst_len, "attr arr change, key=%s:%ld '%s'", u->key, u->idx, u->newval); + else if (u->delta != 0) + rnd_snprintf(dst, dst_len, "attr arr move, key=%s:%ld by %ld", u->key, u->idx, u->delta); + else + rnd_snprintf(dst, dst_len, "attr arr noop, key=%s:%ld", u->key, u->idx); +} + +static void undo_attr_arr_modify_free(void *udata) +{ + undo_attr_arr_modify_t *u = udata; + free(u->key); + u->key = NULL; + if (u->newval != NEWVAL_DEL) + free(u->newval); + u->newval = NULL; + free(u->saved); + u->saved = NULL; +} + +static const uundo_oper_t undo_attr_arr_modify = { + core_attr_cookie, + undo_attr_arr_modify_free, + undo_attr_arr_modify_swap, + undo_attr_arr_modify_swap, + undo_attr_arr_modify_print +}; + + +void csch_attr_arr_modify_str(csch_sheet_t *sheet, csch_cgrp_t *obj, const char *key, long idx, const char *newval, int undoable) +{ + undo_attr_arr_modify_t utmp, *u = &utmp; + + if (undoable) u = uundo_append(&sheet->undo, &undo_attr_arr_modify, sizeof(undo_attr_arr_modify_t)); + + u->obj = obj; + u->key = rnd_strdup(key); + u->idx = idx; + u->delta = 0; + u->newval = (newval == NEWVAL_DEL ? (char *)NEWVAL_DEL : rnd_strdup(newval)); + u->saved = NULL; + + undo_attr_arr_modify_swap(u); + if (undoable) csch_undo_inc_serial(sheet); +} + +void csch_attr_arr_modify_del(csch_sheet_t *sheet, csch_cgrp_t *obj, const char *key, long idx, int undoable) +{ + csch_attr_arr_modify_str(sheet, obj, key, idx, NEWVAL_DEL, undoable); +} + + +void csch_attr_arr_modify_move(csch_sheet_t *sheet, csch_cgrp_t *obj, const char *key, long idx, long delta, int undoable) +{ + undo_attr_arr_modify_t utmp, *u = &utmp; + csch_attrib_t *a = htsp_get(&obj->attr, key); + + /* don't do anything on edges to save undo slots */ + if (a == NULL) + return; + if ((idx < 0) || (idx >= a->arr.used)) + return; + if (delta == 0) + return; + if ((idx == 0) && (delta < 0)) + return; + if ((idx == a->arr.used-1) && (delta > 0)) + return; + + if (undoable) u = uundo_append(&sheet->undo, &undo_attr_arr_modify, sizeof(undo_attr_arr_modify_t)); + + u->obj = obj; + u->key = rnd_strdup(key); + u->idx = idx; + u->delta = delta; + u->newval = NULL; + u->saved = NULL; + + undo_attr_arr_modify_swap(u); + if (undoable) csch_undo_inc_serial(sheet); +} + +void csch_attr_arr_modify_ins_before(csch_sheet_t *sheet, csch_cgrp_t *obj, const char *key, long idx, const char *newval, int undoable) +{ + undo_attr_arr_modify_t utmp, *u = &utmp; + + if (undoable) u = uundo_append(&sheet->undo, &undo_attr_arr_modify, sizeof(undo_attr_arr_modify_t)); + + u->obj = obj; + u->key = rnd_strdup(key); + u->idx = idx; + u->delta = 0; + u->newval = (char *)NEWVAL_DEL; + u->saved = rnd_strdup(newval); + + undo_attr_arr_modify_swap(u); + if (undoable) csch_undo_inc_serial(sheet); +} + + + +typedef struct { + csch_cgrp_t *obj; /* it is safe to save the object pointer because it is persistent (through the removed object list) */ + char *key; + + /* swap values */ + char *val; /* scalar; if NULL, use arr */ + vts0_t arr; +} undo_attr_modify_conv_t; + + +static int undo_attr_modify_conv_swap(void *udata) +{ + undo_attr_modify_conv_t *u = udata; + csch_attrib_t *a; + + a = htsp_get(&u->obj->attr, u->key); + if (a == NULL) { + rnd_message(RND_MSG_ERROR, "Internal error: undo_attr_modify_conv_swap(): attrib not found\n"); + return -1; + } + + if (u->val == NULL) { + if (a->val == NULL) { + rnd_message(RND_MSG_ERROR, "Internal error: undo_attr_modify_conv_swap(): converting array to array?\n"); + return -1; + } + u->val = a->val; + a->val = NULL; + a->arr = u->arr; + memset(&u->arr, 0, sizeof(u->arr)); + } + else { /* u->val != NULL */ + if (a->val != NULL) { + rnd_message(RND_MSG_ERROR, "Internal error: undo_attr_modify_conv_swap(): converting string to string?\n"); + return -1; + } + a->val = u->val; + u->val = NULL; + u->arr = a->arr; + memset(&a->arr, 0, sizeof(a->arr)); + } + + csch_cobj_redraw(u->obj); + csch_attr_side_effects(u->obj, u->key); + csch_sheet_set_changed(u->obj->hdr.sheet, 1); + notify(&u->obj->hdr); + return 0; +} + +static void undo_attr_modify_conv_print(void *udata, char *dst, size_t dst_len) +{ + undo_attr_modify_conv_t *u = udata; + + rnd_snprintf(dst, dst_len, "attr conversion between string and array key=%s", u->key); +} + +static void undo_attr_modify_conv_free(void *udata) +{ + undo_attr_modify_conv_t *u = udata; + + free(u->val); + u->val = NULL; + attr_free_vts(&u->arr); + + free(u->key); + u->key = NULL; +} + +static const uundo_oper_t undo_attr_modify_conv = { + core_attr_cookie, + undo_attr_modify_conv_free, + undo_attr_modify_conv_swap, + undo_attr_modify_conv_swap, + undo_attr_modify_conv_print +}; + + +void csch_attr_modify_conv_to_arr(csch_sheet_t *sheet, csch_cgrp_t *obj, const char *key, int undoable) +{ + undo_attr_modify_conv_t utmp, *u = &utmp; + csch_attrib_t *a = htsp_get(&obj->attr, key); + + if ((a == NULL) || (a->val == NULL)) + return; /* doesn't exist or already a string */ + + if (undoable) u = uundo_append(&sheet->undo, &undo_attr_modify_conv, sizeof(undo_attr_modify_conv_t)); + + memset(u, 0, sizeof(undo_attr_modify_conv_t)); + u->obj = obj; + u->key = rnd_strdup(key); + if (*a->val != '\0') + vts0_append(&u->arr, rnd_strdup(a->val)); + + undo_attr_modify_conv_swap(u); + if (undoable) csch_undo_inc_serial(sheet); +} + +void csch_attr_modify_conv_to_str(csch_sheet_t *sheet, csch_cgrp_t *obj, const char *key, int undoable) +{ + undo_attr_modify_conv_t utmp, *u = &utmp; + csch_attrib_t *a = htsp_get(&obj->attr, key); + long n; + gds_t tmp = {0}; + + if ((a == NULL) || (a->val != NULL)) + return; /* doesn't exist or already a string */ + + if (undoable) u = uundo_append(&sheet->undo, &undo_attr_modify_conv, sizeof(undo_attr_modify_conv_t)); + + memset(u, 0, sizeof(undo_attr_modify_conv_t)); + u->obj = obj; + u->key = rnd_strdup(key); + + /* concat array members with ';' as separator */ + for(n = 0; n < a->arr.used; n++) { + if (n > 0) + gds_append(&tmp, ';'); + gds_append_str(&tmp, a->arr.array[n]); + } + + if (tmp.array == NULL) + u->val = rnd_strdup(""); + else + u->val = tmp.array; + + undo_attr_modify_conv_swap(u); + if (undoable) csch_undo_inc_serial(sheet); +} Index: tags/1.0.5/src/libcschem/attrib.h =================================================================== --- tags/1.0.5/src/libcschem/attrib.h (nonexistent) +++ tags/1.0.5/src/libcschem/attrib.h (revision 10414) @@ -0,0 +1,210 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2018,2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + + +#ifndef CSCH_ATTRIB_H +#define CSCH_ATTRIB_H +#include "libcschem/common_types.h" +#include +#include +#include + +typedef enum { + CSCH_ATP_HARDWIRED = 0, + CSCH_ATP_USER_DEFAULT = 250 +} csch_attrib_prio_t; + +typedef struct csch_attrib_s { + char *key; + int prio; + + unsigned int deleted:1; + + char *val; /* scalar; if NULL, use arr */ + vts0_t arr; + vts0_t source; + + char *export_name; /* abstract model: if not NULL, export this attribute using this name (always strdup'd) */ +} csch_attrib_t; + +/* Opaque struct for temporarily holding attribute source information */ +typedef struct csch_source_arg_s csch_source_arg_t; + +/* Create source info in dst for different source addressing schemes, as + specified in {des4:19} */ +csch_source_arg_t *csch_attrib_src_c(const char *filename, long line, long col, const char *desc); +csch_source_arg_t *csch_attrib_src_ac(csch_chdr_t *cobj, const char *attr_name, const char *desc); +csch_source_arg_t *csch_attrib_src_pa(csch_ahdr_t *aobj, const char *attr_name, const char *plugin_name, const char *desc); +csch_source_arg_t *csch_attrib_src_p(const char *plugin_name, const char *desc); + +typedef enum csch_attrib_src_type_e { /* bitfield */ + CSCH_ASRCT_P = 1, + CSCH_ASRCT_C = 2, + CSCH_ASRCT_A = 4, + CSCH_ASRCT_E = 8, + CSCH_ASRCT_FAIL = 16 +} csch_attrib_src_type_t; + +/* Parse a source string found in attribute history; return 0 on success; out: + - prio: if not NULL: integer priority + - type: if not NULL: bitfield of type letters + - cobj: if not NULL: loaded with concrete object if addr is concrete + - aobj: if not NULL: loaded with abstract object if addr is abstract + - attr: if not NULL: loaded with strdup()'d attribute name if available + - desc: if not NULL: loaded with pointer into the original source to description + Returned values are valid only until any change to the data model in + the project or recompilation. *attr needs to be free()'d be the caller. + Any output may be NULL if field is not available. +*/ +int csch_attrib_src_parse(csch_sheet_t *sheet, const char *source, int *prio, csch_attrib_src_type_t *type, csch_chdr_t **cobj, csch_ahdr_t **aobj, char **attr, const char **desc); + + +typedef htsp_t csch_attribs_t; + +void csch_attrib_init(csch_attribs_t *attribs); +void csch_attrib_uninit(csch_attribs_t *attribs); + +#define csch_attrib_get(attribs, key) htsp_get((csch_attribs_t *)attribs, key) + +/* Returns the string value (or arr value) of an attribute or NULL if + the attribute doesn't exist or is not a string (or arr) */ +RND_INLINE const char *csch_attrib_get_str(const csch_attribs_t *attribs, const char *key); +RND_INLINE const vts0_t *csch_attrib_get_arr(const csch_attribs_t *attribs, const char *key); + + +/* Set a scalar attribute; the ptr version takes malloc()'d val and source; + return 0 on write, -1 on failure or if the attrib didn't change because of prios + (ptr means "use the ptr provided, don't strdup"). src is always free'd. */ +int csch_attrib_set(csch_attribs_t *attribs, int prio, const char *key, const char *val, csch_source_arg_t *source, csch_attrib_t **attr_out); +int csch_attrib_setptr(csch_attribs_t *attribs, int prio, char *key, const char *val, csch_source_arg_t *source, csch_attrib_t **attr_out); + +/* Overwrite an array; src is always free'd. Items are strdup'd */ +int csch_attrib_set_arr(csch_attribs_t *attribs, int prio, const char *key, const vts0_t *val, csch_source_arg_t *source, csch_attrib_t **attr_out); +int csch_attrib_set_arr_c(csch_attribs_t *attribs, int prio, const char *key, const char **val, csch_source_arg_t *source, csch_attrib_t **attr_out); + +/* Same as above, but for arrays: overwrite an existing item; src is always free'd. */ +int csch_attrib_seti(csch_attribs_t *attribs, int prio, const char *key, long idx, const char *val, csch_source_arg_t *source, csch_attrib_t **attr_out); +int csch_attrib_setiptr(csch_attribs_t *attribs, int prio, const char *key, long idx, char *val, csch_source_arg_t *source, csch_attrib_t **attr_out); + +/* Prepend or append to an array; src is always free'd.*/ +int csch_attrib_prepend(csch_attribs_t *attribs, int prio, const char *key, const char *val, csch_source_arg_t *source); +int csch_attrib_prependptr(csch_attribs_t *attribs, int prio, const char *key, char *val, csch_source_arg_t *source); +int csch_attrib_append(csch_attribs_t *attribs, int prio, const char *key, const char *val, csch_source_arg_t *source); +int csch_attrib_appendptr(csch_attribs_t *attribs, int prio, const char *key, char *val, csch_source_arg_t *source); + +/* Append the value of srca; if it's an array, append all elements in order */ +int csch_attrib_append_val(csch_attribs_t *attribs, int prio, const char *key, const csch_attrib_t *srca, csch_source_arg_t *source); + + +/* Del a key from an attribute hash; if history is not NULL, the key is kept + and the value is emptied so source history is preserved. + src is always free'd. */ +int csch_attrib_del(csch_attribs_t *attribs, int prio, const char *key, csch_source_arg_t *source); + + +/* Build an ordered list of attributes; vector items point to + (const csch_attrib_t *) */ +void csch_attrib_sort(vtp0_t *dst, const csch_attribs_t *attribs); + +/* Overwrites the export name from expname */ +void csch_attrib_set_export_name(csch_attrib_t *dst, const char *expname); + + +/* Allocate a new attribute, duplicate src with all sources (deep copy); does + not copy export name. */ +csch_attrib_t *csch_attrib_dup(csch_attrib_t *src); +csch_attrib_t *csch_attrib_dup_rename(csch_attrib_t *src, const char *new_key); + + +/* copy each src attrib to dst */ +void csch_attrib_copy_all(csch_attribs_t *dst, const csch_attribs_t *src); +void csch_attrib_copy_all_undoable(csch_sheet_t *sheet, csch_cgrp_t *dst_obj, csch_attribs_t *dst, const csch_attribs_t *src, int undoable); + +/* copy each src attrib to dst using a forced source; returns 0 on success; + src is always free'd. If force_prio is not NULL, use that as the new + attributes prio - plugins shall do this normally. */ +int csch_attrib_apply(csch_attribs_t *dst, const csch_attribs_t *src, csch_source_arg_t *source, int *force_prio); + +unsigned csch_attrib_hash(const csch_attribs_t *attr); +int csch_attrib_eq(const csch_attribs_t *a1, const csch_attribs_t *a2); +int csch_attrib_eq_(const csch_attrib_t *a1, const csch_attrib_t *a2); +int csch_attrib_val_eq_(const csch_attrib_t *a1, const csch_attrib_t *a2); + + +/* Standard undoable mod functions; negative prio means: keep original if + possible, use positive version of the prio if original is not available; + src is always free'd. */ +void csch_attr_modify_str(csch_sheet_t *sheet, csch_cgrp_t *obj, int prio, const char *key, const char *val, csch_source_arg_t *source, int undoable); +void csch_attr_modify_del(csch_sheet_t *sheet, csch_cgrp_t *obj, const char *key, int undoable); + +/* Undoable modification of attribute priority */ +void csch_attr_modify_prio(csch_sheet_t *sheet, csch_cgrp_t *obj, csch_attrib_t *a, int prio, csch_source_arg_t *source, int undoable); + + +/* Rename an attribute (by creating a new one and removing the old one); + new_name must not be the same as a->key */ +void csch_attr_modify_rename(csch_sheet_t *sheet, csch_cgrp_t *grp, csch_attrib_t *a, const char *new_name, csch_source_arg_t *src, int undoable); + +void csch_attr_arr_modify_ins_before(csch_sheet_t *sheet, csch_cgrp_t *obj, const char *key, long idx, const char *newval, int undoable); +void csch_attr_arr_modify_str(csch_sheet_t *sheet, csch_cgrp_t *obj, const char *key, long idx, const char *newval, int undoable); +void csch_attr_arr_modify_del(csch_sheet_t *sheet, csch_cgrp_t *obj, const char *key, long idx, int undoable); +void csch_attr_arr_modify_move(csch_sheet_t *sheet, csch_cgrp_t *obj, const char *key, long idx, long delta, int undoable); +void csch_attr_modify_conv_to_arr(csch_sheet_t *sheet, csch_cgrp_t *obj, const char *key, int undoable); +void csch_attr_modify_conv_to_str(csch_sheet_t *sheet, csch_cgrp_t *obj, const char *key, int undoable); + +/* Free fields of src and src itself */ +void csch_attr_src_free(csch_source_arg_t *src); + +/* allocate new csch_source_arg_t and copy src */ +csch_source_arg_t *csch_attr_src_dup(csch_source_arg_t *src); + +/* Append src to history of abstract attribute a; useful to log failed + attribute sets */ +void csch_attrib_append_src(csch_attrib_t *a, int prio, csch_source_arg_t *source, int fail); + +void csch_attr_side_effects(csch_cgrp_t *grp, const char *key); + +/* Some alien I/O code need to remove attributes after creating them on load */ +void csch_attr_free(csch_attrib_t *a); + +/*** implementation ***/ +RND_INLINE const char *csch_attrib_get_str(const csch_attribs_t *attribs, const char *key) +{ + csch_attrib_t *a = csch_attrib_get(attribs, key); + if ((a == NULL) || (a->deleted)) return NULL; + return a->val; +} + +RND_INLINE const vts0_t *csch_attrib_get_arr(const csch_attribs_t *attribs, const char *key) +{ + csch_attrib_t *a = csch_attrib_get(attribs, key); + if ((a == NULL) || (a->deleted) || (a->val != NULL)) return NULL; + return &a->arr; +} + +#endif Index: tags/1.0.5/src/libcschem/attrib_src.c =================================================================== --- tags/1.0.5/src/libcschem/attrib_src.c (nonexistent) +++ tags/1.0.5/src/libcschem/attrib_src.c (revision 10414) @@ -0,0 +1,344 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2018,2019,2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/* include-lib for attrib.c */ + +struct csch_source_arg_s { + char type[8]; + char src_desc[1]; /* "source::desc"; dynamic length, allocated together with csch_source_arg_s */ +}; + +void csch_attr_src_free(csch_source_arg_t *src) +{ + if (src == NULL) + return; + src->type[0] = '\0'; + free(src); +} + +static void append_src(csch_attrib_t *a, int prio, csch_source_arg_t *source, int fail) +{ + char tmp[32]; + gds_t s; + gds_init(&s); + sprintf(tmp, "%d::%s", prio, source->type); + gds_append_str(&s, tmp); + if (fail) + gds_append(&s, '-'); + gds_append_str(&s, "::"); + if (*source->src_desc == '\0') + gds_append(&s, '-'); + else + gds_append_str(&s, source->src_desc); + vts0_append(&a->source, s.array); +} + +void csch_attrib_append_src(csch_attrib_t *a, int prio, csch_source_arg_t *source, int fail) +{ + append_src(a, prio, source, fail); +} + +static csch_sheet_t *csch_attrib_src_lookup_sheet(csch_project_t *prj, const char *name, long name_len) +{ + long n; + for(n = 0; n < prj->hdr.designs.used; n++) { + csch_sheet_t *sheet = prj->hdr.designs.array[n]; + if (sheet->hidlib.loadname != NULL) { + long slen = strlen(sheet->hidlib.loadname); + if ((slen == name_len) && (memcmp(sheet->hidlib.loadname, name, slen) == 0)) + return sheet; + } + } + return NULL; +} + +/* Return the first occurance of cc in str (cheap assuming str is short) */ +static char *strdchr(const char *str, char c) +{ + for(;;) { + if ((str[0] == c) && (str[1] == c)) + return (char *)str; + if (str[0] == '\0') + return NULL; + str++; + } +} + +static int csch_attrib_src_parse_c(csch_sheet_t *ssheet, const char *source, csch_chdr_t **cobj, char **attr, const char **desc) +{ + char *sep, *end, *attr_start, *attr_end; + csch_sheet_t *sheet; + char *tmp; + + + if (*source == '-') source++; + if ((source[0] != ':') || (source[1] != ':')) return -1; + source += 2; + + sep = strchr(source, ','); + if (sep == NULL) return -1; + + sheet = csch_attrib_src_lookup_sheet((csch_project_t *)ssheet->hidlib.project, source, sep-source); + if (sheet == NULL) + return -1; + + + /* split off desc, strdup "oidpath,..." into tmp */ + sep++; + end = strdchr(sep, ':'); + if (end != NULL) { + tmp = rnd_strndup(sep, end - sep); + if (desc != NULL) *desc = end+2; + } + else + tmp = rnd_strdup(end); + + /* find the comma after oidpath */ + attr_start = strchr(tmp, ','); + if (attr_start == NULL) { + free(tmp); + return -1; + } + *attr_start = '\0'; + attr_start++; + + if (cobj != NULL) { + csch_oidpath_t oidp = {0}; + csch_oidpath_parse(&oidp, tmp); + *cobj = csch_oidpath_resolve(sheet, &oidp); + csch_oidpath_free(&oidp); + } + + if (attr != NULL) { + /* figure end of attributes, move it in front of tmp */ + attr_end = strchr(attr_start, ','); + if (attr_end != NULL) { + *attr_end = '\0'; + attr_end++; + memmove(tmp, attr_start, attr_end-attr_start); + } + else { + long l = strlen(attr_start); + memmove(tmp, attr_start, l); + tmp[l] = '\0'; + } + + *attr = tmp; + } + else + free(tmp); + + return 0; +} + +static int csch_attrib_src_parse_a(csch_sheet_t *sheet, const char *source, csch_ahdr_t **aobj, char **attr, const char **desc) +{ + csch_project_t *prj = (csch_project_t *)sheet->hidlib.project; + long aid; + char *end, *tmp, *d; + + if (*source == '-') source++; + if ((source[0] != ':') || (source[1] != ':')) return -1; + source += 2; + + aid = strtol(source, &end, 10); + if (*end != ',') + return -1; + if (aobj != NULL) + *aobj = htip_get(&prj->abst->aid2obj, aid); + + end++; + d = strdchr(end, ':'); + if (d != NULL) { + if (attr != NULL) + tmp = rnd_strndup(end, d - end); + if (desc != NULL) + *desc = d+2; + } + else if (attr != NULL) + tmp = rnd_strdup(end); + + if (attr != NULL) { + /* cut off ,plugin from attr name */ + end = strchr(tmp, ','); + if (end != NULL) + *end = '\0'; + + *attr = tmp; + } + + return 0; +} + +#define CMP1(c0) \ + ((end[0] == c0) && ((end[1] == ':') || (end[1] == '-'))) +#define CMP2(c0, c1) \ + ((end[0] == c0) && (end[1] == c1) && ((end[2] == ':') || (end[2] == '-'))) + +int csch_attrib_src_parse(csch_sheet_t *sheet, const char *source, int *prio, csch_attrib_src_type_t *type, csch_chdr_t **cobj, csch_ahdr_t **aobj, char **attr, const char **desc) +{ + char *end, *s; + long priol; + + if (prio != NULL) *prio = -1; + if (cobj != NULL) *cobj = NULL; + if (aobj != NULL) *aobj = NULL; + if (attr != NULL) *attr = NULL; + if (desc != NULL) *desc = NULL; + + priol = strtol(source, &end, 10); + if ((end[0] != ':') || (end[1] != ':') || (priol < 0) || (priol > 65535)) + return -1; + + if (prio != NULL) *prio = priol; + + end+=2; + + if (type != NULL) { + *type = 0; + for(s = end; (*s != ':') && (*s != '\0'); s++) { + switch(*s) { + case 'p': *type |= CSCH_ASRCT_P; break; + case 'c': *type |= CSCH_ASRCT_C; break; + case 'a': *type |= CSCH_ASRCT_A; break; + case 'e': *type |= CSCH_ASRCT_E; break; + case '-': *type |= CSCH_ASRCT_FAIL; break; + } + } + } + + if (CMP1('c')) return 0; /* concrete model address */ + if (CMP1('p')) return 0; /* no attribute address */ + if (CMP2('a', 'c')) return csch_attrib_src_parse_c(sheet, end+2, cobj, attr, desc); + if (CMP2('p', 'c')) return csch_attrib_src_parse_c(sheet, end+2, cobj, attr, desc); + if (CMP2('p', 'a')) return csch_attrib_src_parse_a(sheet, end+2, aobj, attr, desc); + return -1; +} + +#undef CMP1 +#undef CMP2 + +#define ATTRIB_SRC_INIT \ + gds_t tmp = {0}; \ + csch_source_arg_t *dst; \ + gds_enlarge(&tmp, sizeof(csch_source_arg_t)+32); \ + tmp.used = offsetof(csch_source_arg_t, src_desc); \ + dst = (csch_source_arg_t *)tmp.array + +csch_source_arg_t *csch_attrib_src_c(const char *filename, long line, long col, const char *desc) +{ + ATTRIB_SRC_INIT; + + dst->type[0] = 'c'; + dst->type[1] = '\0'; + + if (filename == NULL) filename = "-"; + + if ((line > 0) && (col > 0)) + rnd_append_printf(&tmp, "%s,%ld,%ld::", filename, line, col); + else if (line > 0) + rnd_append_printf(&tmp, "%s,%ld::", filename, line); + else { + gds_append_str(&tmp, filename); + rnd_append_printf(&tmp, "%s::", filename); + } + + if (desc != NULL) + gds_append_str(&tmp, desc); + + return (csch_source_arg_t *)tmp.array; +} + +csch_source_arg_t *csch_attrib_src_ac(csch_chdr_t *cobj, const char *attr_name, const char *desc) +{ + csch_oidpath_t oidp = {0}; + ATTRIB_SRC_INIT; + + dst->type[0] = 'a'; + dst->type[1] = 'c'; + dst->type[2] = '\0'; + + if (attr_name == NULL) attr_name = ""; + if (desc == NULL) desc = ""; + + if (cobj->sheet->hidlib.loadname != NULL) + gds_append_str(&tmp, cobj->sheet->hidlib.loadname); + else + gds_append_str(&tmp, ""); + gds_append(&tmp, ','); + csch_oidpath_from_obj(&oidp, cobj); + csch_oidpath_to_str_append(&tmp, &oidp); + csch_oidpath_free(&oidp); + gds_append(&tmp, ','); + gds_append_str(&tmp, attr_name); + gds_append_str(&tmp, "::"); + + if (desc != NULL) + gds_append_str(&tmp, desc); + + return (csch_source_arg_t *)tmp.array; +} + + +csch_source_arg_t *csch_attrib_src_pa(csch_ahdr_t *aobj, const char *attr_name, const char *plugin_name, const char *desc) +{ + ATTRIB_SRC_INIT; + + dst->type[0] = 'p'; + dst->type[1] = 'a'; + dst->type[2] = '\0'; + + if (attr_name == NULL) attr_name = ""; + if (plugin_name == NULL) plugin_name = ""; + + rnd_append_printf(&tmp, "%ld,%s,%s::", aobj->aid, attr_name, plugin_name); + if (desc != NULL) + gds_append_str(&tmp, desc); + + return (csch_source_arg_t *)tmp.array; +} + +csch_source_arg_t *csch_attrib_src_p(const char *plugin_name, const char *desc) +{ + ATTRIB_SRC_INIT; + + dst->type[0] = 'p'; + dst->type[1] = '\0'; + + if (plugin_name == NULL) plugin_name = ""; + if (desc == NULL) desc = ""; + + gds_append_str(&tmp, plugin_name); + gds_append_str(&tmp, "::"); + + if (desc != NULL) + gds_append_str(&tmp, desc); + + return (csch_source_arg_t *)tmp.array; +} + Index: tags/1.0.5/src/libcschem/cnc_any_obj.c =================================================================== --- tags/1.0.5/src/libcschem/cnc_any_obj.c (nonexistent) +++ tags/1.0.5/src/libcschem/cnc_any_obj.c (revision 10414) @@ -0,0 +1,316 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2019 Tibor 'Igor2' Palinkas + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include "config.h" + +#include +#include +#include +#include + +#include "cnc_any_obj.h" + +#include "event.h" +#include "concrete.h" +#include "cnc_arc.h" +#include "cnc_bitmap.h" +#include "cnc_conn.h" +#include "cnc_grp.h" +#include "cnc_line.h" +#include "cnc_text.h" +#include "cnc_obj.h" +#include "cnc_pen.h" +#include "cnc_poly.h" +#include "undo.h" + +void csch_cobj_free(csch_chdr_t *obj) +{ + switch(obj->type) { + case CSCH_CTYPE_max: + case CSCH_CTYPE_invalid: break; + case CSCH_CTYPE_LINE: csch_line_free((csch_line_t *)obj); break; + case CSCH_CTYPE_ARC: csch_arc_free((csch_arc_t *)obj); break; + case CSCH_CTYPE_POLY: csch_cpoly_free((csch_cpoly_t *)obj); break; + case CSCH_CTYPE_TEXT: csch_text_free((csch_text_t *)obj); break; + case CSCH_CTYPE_BITMAP: csch_cbitmap_free((csch_cbitmap_t *)obj); break; + case CSCH_CTYPE_CONN: csch_conn_free((csch_conn_t *)obj); break; + case CSCH_CTYPE_GRP: csch_cgrp_free((csch_cgrp_t *)obj); break; + case CSCH_CTYPE_GRP_REF: csch_cgrp_ref_free((csch_cgrp_t *)obj); break; + case CSCH_CTYPE_PEN: csch_pen_free((csch_cpen_t *)obj); break; + } +} + + +csch_chdr_t *csch_cobj_dup(csch_sheet_t *sheet, csch_cgrp_t *grp, const csch_chdr_t *src, int keep_id, int inst2spec) +{ + void *dst; + + switch(src->type) { + case CSCH_CTYPE_max: + case CSCH_CTYPE_invalid: return NULL; + case CSCH_CTYPE_LINE: dst = csch_line_dup(sheet, grp, (const csch_line_t *)src, keep_id, inst2spec); break; + case CSCH_CTYPE_ARC: dst = csch_arc_dup(sheet, grp, (const csch_arc_t *)src, keep_id); break; + case CSCH_CTYPE_POLY: dst = csch_cpoly_dup(sheet, grp, (const csch_cpoly_t *)src, keep_id); break; + case CSCH_CTYPE_TEXT: dst = csch_text_dup(sheet, grp, (const csch_text_t *)src, keep_id, inst2spec); break; + case CSCH_CTYPE_BITMAP: dst = csch_cbitmap_dup(sheet, grp, (const csch_cbitmap_t *)src, keep_id); break; + case CSCH_CTYPE_CONN: abort(); + case CSCH_CTYPE_GRP: + case CSCH_CTYPE_GRP_REF: dst = csch_cgrp_dup(sheet, grp, (const csch_cgrp_t *)src, keep_id); break; + case CSCH_CTYPE_PEN: dst = csch_pen_dup(sheet, grp, (const csch_cpen_t *)src); break; /* id is name and is always kept */ + } + return dst; +} + +void csch_cobj_update(csch_sheet_t *sheet, csch_chdr_t *src, int do_xform) +{ + switch(src->type) { + case CSCH_CTYPE_max: + case CSCH_CTYPE_invalid: abort(); + case CSCH_CTYPE_LINE: csch_line_update(sheet, (csch_line_t *)src, do_xform); break; + case CSCH_CTYPE_ARC: csch_arc_update(sheet, (csch_arc_t *)src, do_xform); break; + case CSCH_CTYPE_POLY: csch_poly_update(sheet, (csch_cpoly_t *)src, do_xform); break; + case CSCH_CTYPE_TEXT: csch_text_update(sheet, (csch_text_t *)src, do_xform); break; + case CSCH_CTYPE_BITMAP: abort(); + case CSCH_CTYPE_CONN: csch_conn_update(sheet, (csch_conn_t *)src, do_xform); break; + case CSCH_CTYPE_GRP: csch_cgrp_update(sheet, (csch_cgrp_t *)src, do_xform); break; + case CSCH_CTYPE_GRP_REF: csch_cgrp_ref_update(sheet, (csch_cgrp_t *)src, do_xform); break; + case CSCH_CTYPE_PEN: /* nop */ break; + } +} + +int csch_cobj_attrib_set(csch_sheet_t *sheet, csch_cgrp_t *obj, int prio, const char *key, const char *val, csch_source_arg_t *source) +{ + csch_attrib_t *a; + int res; + + assert(csch_obj_is_grp(&obj->hdr)); + + res = csch_attrib_set(&obj->attr, prio, key, val, source, &a); + if (res == 0) /* attribute value changed */ + csch_cgrp_attrib_update(sheet, obj, prio, a->key, a->val); + return res; +} + +int csch_cobj_attrib_seti(csch_sheet_t *sheet, csch_cgrp_t *obj, int prio, const char *key, long idx, const char *val, csch_source_arg_t *source) +{ + TODO("call csch_cobj_attrib_update() with idx"); + assert(csch_obj_is_grp(&obj->hdr)); + return csch_attrib_seti(&obj->attr, prio, key, idx, val, source, NULL); +} + + +void csch_cobj_attrib_copy_all(csch_sheet_t *sheet, csch_cgrp_t *dst, const csch_cgrp_t *src) +{ + csch_attrib_t *a, *b; + htsp_entry_t *e; + + assert(csch_obj_is_grp(&dst->hdr) && csch_obj_is_grp(&src->hdr)); + + for(e = htsp_first(&src->attr); e; e = htsp_next(&src->attr, e)) { + a = e->value; + b = csch_attrib_dup(a); + htsp_set(&dst->attr, b->key, b); + csch_cgrp_attrib_update(sheet, dst, b->prio, b->key, b->val); + } +} + +unsigned csch_cobj_hash_(csch_chdr_t *obj, csch_hash_ignore_t ignore) +{ + switch(obj->type) { + case CSCH_CTYPE_LINE: return csch_line_hash((csch_line_t *)obj, ignore); + case CSCH_CTYPE_ARC: return csch_arc_hash((csch_arc_t *)obj, ignore); + case CSCH_CTYPE_POLY: return csch_cpoly_hash((csch_cpoly_t *)obj, ignore); + case CSCH_CTYPE_TEXT: return csch_text_hash((csch_text_t *)obj, ignore); + case CSCH_CTYPE_BITMAP: /*return csch_bitmap_hash((csch_bitmap_t *)obj, ignore);*/ + case CSCH_CTYPE_CONN: /*return csch_conn_hash((csch_conn_t *)obj, ignore);*/ + case CSCH_CTYPE_GRP: + case CSCH_CTYPE_GRP_REF: return csch_cgrp_hash_((csch_cgrp_t *)obj, ignore); + case CSCH_CTYPE_PEN: return csch_pen_hash((csch_cpen_t *)obj, ignore); + case CSCH_CTYPE_max: + case CSCH_CTYPE_invalid: + break; + } + return 0; +} + +unsigned csch_cobj_hash(csch_chdr_t *obj) +{ + return csch_cobj_hash_(obj, 0); +} + + +int csch_cobj_keyeq_(csch_chdr_t *obj1, csch_chdr_t *obj2, csch_hash_ignore_t ignore) +{ + if (obj1->type != obj2->type) return 0; + switch(obj1->type) { + case CSCH_CTYPE_LINE: return csch_line_keyeq((csch_line_t *)obj1, (csch_line_t *)obj2, ignore); + case CSCH_CTYPE_ARC: return csch_arc_keyeq((csch_arc_t *)obj1, (csch_arc_t *)obj2, ignore); + case CSCH_CTYPE_POLY: return csch_cpoly_keyeq((csch_cpoly_t *)obj1, (csch_cpoly_t *)obj2, ignore); + case CSCH_CTYPE_TEXT: return csch_text_keyeq((csch_text_t *)obj1, (csch_text_t *)obj2, ignore); + case CSCH_CTYPE_BITMAP: /*return csch_bitmap_keyeq((csch_bitmap_t *)obj1, (csch_bitmap_t *)obj2, ignore);*/ + case CSCH_CTYPE_CONN: /*return csch_conn_keyeq((csch_conn_t *)obj1, (csch_conn_t *)obj2, ignore);*/ + case CSCH_CTYPE_GRP: + case CSCH_CTYPE_GRP_REF: return csch_cgrp_keyeq_((csch_cgrp_t *)obj1, (csch_cgrp_t *)obj2, ignore); + case CSCH_CTYPE_PEN: return csch_pen_keyeq((csch_cpen_t *)obj1, (csch_cpen_t *)obj2, ignore); + case CSCH_CTYPE_max: + case CSCH_CTYPE_invalid: + break; + } + return 0; +} + +int csch_cobj_keyeq(csch_chdr_t *obj1, csch_chdr_t *obj2) +{ + return csch_cobj_keyeq_(obj1, obj2, 0); +} + + +int csch_cobj_get_endxy(const csch_chdr_t *src, int side, csch_coord_t *x, csch_coord_t *y) +{ + switch(src->type) { + case CSCH_CTYPE_LINE: return csch_line_get_endxy((csch_line_t *)src, side, x, y); + case CSCH_CTYPE_ARC: return csch_arc_get_endxy((csch_arc_t *)src, side, x, y); + case CSCH_CTYPE_POLY: + case CSCH_CTYPE_TEXT: + case CSCH_CTYPE_BITMAP: + case CSCH_CTYPE_CONN: + case CSCH_CTYPE_GRP: + case CSCH_CTYPE_GRP_REF: + case CSCH_CTYPE_PEN: + case CSCH_CTYPE_max: + case CSCH_CTYPE_invalid: + break; + } + return -1; +} + + +static const char core_any_obj_cookie[] = "libcschem/core/cnc_any_obj.c"; + +/*** undoable pen name mod ***/ +typedef struct { + csch_chdr_t *obj; + csch_comm_str_t stroke_name; + csch_comm_str_t fill_name; +} undo_pen_name_modify_t; + +static int undo_pen_name_modify_swap(void *udata) +{ + undo_pen_name_modify_t *u = udata; + + rnd_swap(csch_comm_str_t, u->stroke_name, u->obj->stroke_name); + rnd_swap(csch_comm_str_t, u->fill_name, u->obj->fill_name); + u->obj->stroke = NULL; + u->obj->fill = NULL; + csch_cobj_update_pen(u->obj); + + return 0; +} + +static void undo_pen_name_modify_print(void *udata, char *dst, size_t dst_len) +{ + undo_pen_name_modify_t *u = udata; + rnd_snprintf(dst, dst_len, "obj pen name change: stroke: %s <--> %s fill: %s <--> %s", u->obj->stroke_name, u->stroke_name, u->obj->fill_name, u->fill_name); +} + +static const uundo_oper_t undo_pen_name_modify = { + core_any_obj_cookie, + NULL, + undo_pen_name_modify_swap, + undo_pen_name_modify_swap, + undo_pen_name_modify_print +}; + + + +void csch_chdr_pen_name_modify(csch_sheet_t *sheet, csch_chdr_t *obj, csch_comm_str_t *stroke_name, csch_comm_str_t *fill_name, int undoable) +{ + undo_pen_name_modify_t utmp, *u = &utmp; + + if (undoable) u = uundo_append(&sheet->undo, &undo_pen_name_modify, sizeof(undo_pen_name_modify_t)); + + u->obj = obj; + u->stroke_name = stroke_name == NULL ? obj->stroke_name : *stroke_name; + u->fill_name = fill_name == NULL ? obj->fill_name : *fill_name; + + undo_pen_name_modify_swap(u); + if (undoable) csch_undo_inc_serial(sheet); +} + + +RND_INLINE void select_side_effects(csch_sheet_t *sheet, csch_chdr_t *obj, int root) +{ + if (obj->type == CSCH_CTYPE_TEXT) + csch_text_invalidate_font((csch_text_t *)obj); /* may need to re-render for indicate selection */ + if (csch_obj_is_grp(obj)) { + csch_cgrp_t *grp = (csch_cgrp_t *)obj; + htip_entry_t *e; + for(e = htip_first(&grp->id2obj); e != NULL; e = htip_next(&grp->id2obj, e)) + select_side_effects(sheet, e->value, 0); + } + if (root) + csch_cobj_redraw(obj); +} + +void csch_cobj_select(csch_sheet_t *sheet, csch_chdr_t *obj) +{ + if (!obj->selected) { + obj->selected = 1; + select_side_effects(sheet, obj, 1); + } +} + + +void csch_cobj_unselect(csch_sheet_t *sheet, csch_chdr_t *obj) +{ + if (obj->selected) { + obj->selected = 0; + select_side_effects(sheet, obj, 1); + } +} + +int csch_cobj_is_direct(const csch_chdr_t *obj) +{ + csch_cgrp_t *g, *direct = &obj->sheet->direct; + + for(g = obj->parent; g != NULL; g = g->hdr.parent) + if (g == direct) + return 1; + + return 0; +} + +int csch_cobj_is_indirect(const csch_chdr_t *obj) +{ + csch_cgrp_t *g, *indirect = &obj->sheet->indirect; + + for(g = obj->parent; g != NULL; g = g->hdr.parent) + if (g == indirect) + return 1; + + return 0; +} + Index: tags/1.0.5/src/libcschem/cnc_any_obj.h =================================================================== --- tags/1.0.5/src/libcschem/cnc_any_obj.h (nonexistent) +++ tags/1.0.5/src/libcschem/cnc_any_obj.h (revision 10414) @@ -0,0 +1,76 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2019 Tibor 'Igor2' Palinkas + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#ifndef CSCH_CNC_ANY_OBJ_H +#define CSCH_CNC_ANY_OBJ_H + +#include "concrete.h" + +void csch_cobj_free(csch_chdr_t *obj); + +/* If inst2spec is true, take target groups transformations and modify dup'd + object's spec so that it ends up in the same installed coords */ +csch_chdr_t *csch_cobj_dup(csch_sheet_t *sheet, csch_cgrp_t *grp, const csch_chdr_t *src, int keep_id, int inst2spec); + +void csch_cobj_update(csch_sheet_t *sheet, csch_chdr_t *src, int do_xform); +void csch_cobj_attrib_copy_all(csch_sheet_t *sheet, csch_cgrp_t *dst, const csch_cgrp_t *src); + +/* source is free'd */ +int csch_cobj_attrib_set(csch_sheet_t *sheet, csch_cgrp_t *obj, int prio, const char *key, const char *val, csch_source_arg_t *source); +int csch_cobj_attrib_seti(csch_sheet_t *sheet, csch_cgrp_t *obj, int prio, const char *key, long idx, const char *val, csch_source_arg_t *source); + +unsigned csch_cobj_hash(csch_chdr_t *obj); +unsigned csch_cobj_hash_(csch_chdr_t *obj, csch_hash_ignore_t ignore); +int csch_cobj_keyeq(csch_chdr_t *obj1, csch_chdr_t *obj2); +int csch_cobj_keyeq_(csch_chdr_t *obj1, csch_chdr_t *obj2, csch_hash_ignore_t ignore); + + +/* Fill in endpoint coords of object in x and y; side: 0 means query start, + 1 means end. Returns 0 on success. Works only on line and arc */ +int csch_cobj_get_endxy(const csch_chdr_t *src, int side, csch_coord_t *x, csch_coord_t *y); + +/* Returns 1 if obj is in the (in)direct subrtee, else 0 */ +int csch_cobj_is_direct(const csch_chdr_t *obj); +int csch_cobj_is_indirect(const csch_chdr_t *obj); + +/* Select or unselect object; TODO: undoable? */ +void csch_cobj_select(csch_sheet_t *sheet, csch_chdr_t *obj); +void csch_cobj_unselect(csch_sheet_t *sheet, csch_chdr_t *obj); + +/* Unselet object and all parent objects */ +RND_INLINE void csch_chdr_unselect_wp(csch_chdr_t *obj) +{ + csch_sheet_t *sheet = obj->sheet; + for(;obj != NULL; obj = &obj->parent->hdr) + csch_cobj_unselect(sheet, obj); +} + + +/* Modify obj's pen name(s) if not NULL; if unodable, add the operation to the + undo list */ +void csch_chdr_pen_name_modify(csch_sheet_t *sheet, csch_chdr_t *obj, csch_comm_str_t *stroke_name, csch_comm_str_t *fill_name, int undoable); + +#endif Index: tags/1.0.5/src/libcschem/cnc_arc.c =================================================================== --- tags/1.0.5/src/libcschem/cnc_arc.c (nonexistent) +++ tags/1.0.5/src/libcschem/cnc_arc.c (revision 10414) @@ -0,0 +1,431 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2018,2022 Tibor 'Igor2' Palinkas + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + + +#include "config.h" + +#include +#include +#include + +#include "event.h" +#include "concrete.h" +#include "cnc_arc.h" +#include "cnc_obj.h" +#include "cnc_grp_child.h" +#include "op_common.h" +#include "operation.h" +#include "undo.h" +#include "rotate.h" + +#include "gengeo2d/sarc.h" +#include "gengeo2d/xform.h" + +csch_arc_t *csch_arc_alloc(csch_sheet_t *sheet, csch_cgrp_t *parent, csch_oid_t oid) +{ + csch_arc_t *arc; + + arc = htip_get(&parent->id2obj, oid); + if (arc != NULL) + return NULL; + arc = calloc(sizeof(csch_arc_t), 1); + + csch_cobj_init(&arc->hdr, sheet, parent, oid, CSCH_CTYPE_ARC); + return arc; +} + +csch_arc_t *csch_arc_dup(csch_sheet_t *sheet, csch_cgrp_t *parent, const csch_arc_t *src, int keep_id) +{ + csch_arc_t *dst = csch_arc_alloc(sheet, parent, CSCH_KEEP_OID(parent, src->hdr.oid)); + dst->inst = src->inst; + dst->spec = src->spec; + csch_chdr_copy_meta4dup(&dst->hdr, &src->hdr); + return dst; +} + + + +void csch_arc_free(csch_arc_t *arc) +{ + csch_cobj_uninit(&arc->hdr); + free(arc); +} + +csch_arc_t *csch_arc_get(csch_sheet_t *sheet, csch_cgrp_t *grp, csch_oid_t oid) +{ + csch_arc_t *arc = htip_get(&grp->id2obj, oid); + if ((arc != NULL) && (arc->hdr.type != CSCH_CTYPE_ARC)) + return NULL; + return arc; +} + +void csch_arc_update_xform(csch_sheet_t *sheet, csch_arc_t *arc) +{ + arc->inst.c = arc->spec; /* copies radius and angles */ + if (arc->hdr.parent != NULL) { + csch_coord_t centx, centy; + double start, delta, rot; + csch_child_xform_t *cx; + g2d_xform_t mx = csch_grp_ref_parent_mx(&arc->hdr, &cx); + + arc->inst.c.c = g2d_xform_vect2vect(mx, arc->spec.c); + csch_arc_mirror_(arc, + arc->hdr.parent->xform.x + cx->movex, arc->hdr.parent->xform.y + cx->movey, + arc->hdr.parent->xform.mirx ^ cx->mirx, arc->hdr.parent->xform.miry ^ cx->miry, + ¢x, ¢y, &start, &delta); + + arc->inst.c.start = start; + arc->inst.c.delta = delta; + + rot = (arc->hdr.parent->xform.rot + cx->rot) / RND_RAD_TO_DEG; + arc->inst.c.start += fmod(rot, 2.0*G2D_PI); + } + else + arc->inst.c = arc->spec; + if (arc->hdr.stroke != NULL) { + arc->inst.s.width = arc->hdr.stroke->size; + arc->inst.s.cap = (arc->hdr.stroke->shape == CSCH_PSHP_ROUND) ? G2D_CAP_ROUND : G2D_CAP_SQUARE; + } +} + +void csch_arc_update_bbox(csch_sheet_t *sheet, csch_arc_t *arc) +{ + g2d_box_t gb; + + csch_obj_bbox_reset(arc); + gb = g2d_sarc_bbox(&arc->inst); + arc->hdr.bbox.x1 = gb.p1.x; arc->hdr.bbox.y1 = gb.p1.y; + arc->hdr.bbox.x2 = gb.p2.x; arc->hdr.bbox.y2 = gb.p2.y; +} + +void csch_arc_center_bbox(csch_sheet_t *sheet, const csch_arc_t *arc, csch_rtree_box_t *dst) +{ + g2d_box_t gb = g2d_carc_bbox(&arc->inst.c); + dst->x1 = gb.p1.x; dst->y1 = gb.p1.y; + dst->x2 = gb.p2.x; dst->y2 = gb.p2.y; +} + +void csch_arc_update(csch_sheet_t *sheet, csch_arc_t *arc, int do_xform) +{ + + csch_cobj_update_pen(&arc->hdr); + + if (do_xform) + csch_arc_update_xform(sheet, arc); + + csch_cobj_rtree_del(sheet, &arc->hdr); + csch_arc_update_bbox(sheet, arc); + csch_cobj_rtree_add(sheet, &arc->hdr); + + csch_cobj_bbox_changed(sheet, &arc->hdr); +} + + +int csch_arc_get_endxy(const csch_arc_t *arc, int side, csch_coord_t *x, csch_coord_t *y) +{ + g2d_vect_t v = g2d_carc_offs(&arc->inst.c, ((side == 0) ? 0.0 : 1.0)); + *x = v.x; + *y = v.y; + return 0; +} + + +static csch_chdr_t *arc_create(csch_sheet_t *sheet, csch_cgrp_t *parent) +{ + csch_arc_t *arc = csch_arc_alloc(sheet, parent, csch_oid_new(sheet, parent)); + if (arc == NULL) return NULL; + return &arc->hdr; +} + +static void arc_remove_alloc(csch_undo_remove_t *slot) +{ +} + +static void arc_remove_redo(csch_undo_remove_t *slot) +{ + csch_cnc_common_remove_redo(slot, CSCH_REM_FROM_RTREE | CSCH_REM_FROM_PARENT | CSCH_REM_DEL_EMPTY_PARENT); +} + +static void arc_remove_undo(csch_undo_remove_t *slot) +{ + csch_cnc_common_remove_undo(slot, CSCH_REM_FROM_RTREE | CSCH_REM_FROM_PARENT | CSCH_REM_DEL_EMPTY_PARENT); +} + +static int arc_isc_with_box(csch_chdr_t *obj, csch_rtree_box_t *box) +{ + csch_arc_t *arc = (csch_arc_t *)obj; + g2d_box_t gbox, abox; + g2d_carc_t outer, inner; + g2d_vect_t tmp1[8]; + g2d_offs_t tmp2[8]; + + gbox.p1.x = box->x1; gbox.p1.y = box->y1; + gbox.p2.x = box->x2; gbox.p2.y = box->y2; + abox.p1.x = arc->hdr.bbox.x1; abox.p1.y = arc->hdr.bbox.y1; + abox.p2.x = arc->hdr.bbox.x2; abox.p2.y = arc->hdr.bbox.y2; + + /* arc fully within the box (cheap) */ + if (g2d_box_in_box(&gbox, &abox)) return 1; + + g2d_sarc_sides(&arc->inst, &outer, &inner); + + /* check if outer arc is hit by the box; this is the most common case: + if the box crosses the arc, it surely hits outer arc */ + if (g2d_iscp_carc_box(&outer, &gbox, tmp1, tmp2)) return 1; + + /* special cases, cheaper first */ +TODO("check end cap circle"); + + /* the corner of a small box within the sarc may hit the inner arc... */ + return g2d_iscp_carc_box(&inner, &gbox, tmp1, tmp2); +} + + +static void arc_move(csch_sheet_t *sheet, csch_chdr_t *obj, csch_coord_t dx, csch_coord_t dy, int undoable) +{ + csch_arc_t *arc = (csch_arc_t *)obj; + csch_arc_modify(sheet, arc, &dx, &dy, NULL, NULL, NULL, undoable, 1); +} + +static void arc_copy(csch_sheet_t *sheet, csch_chdr_t *obj, csch_coord_t dx, csch_coord_t dy, int undoable) +{ + csch_arc_t *arc = csch_arc_dup(sheet, obj->parent, (csch_arc_t *)obj, 0); + if (arc != NULL) { + arc->spec.c.x += dx; arc->spec.c.y += dy; + csch_arc_update(sheet, arc, 1); + csch_op_inserted(sheet, obj->parent, &arc->hdr); + } + +} + +void csch_arc_rotate_(csch_arc_t *arc, csch_coord_t rcx, csch_coord_t rcy, double da, double cs, double sn, csch_coord_t *cx_out, csch_coord_t *cy_out, double *start_out) +{ + csch_coord_t ncx = arc->spec.c.x, ncy = arc->spec.c.y; + + csch_rotate_pt(&ncx, &ncy, rcx, rcy, cs, sn); + + *cx_out = ncx; + *cy_out = ncy; + *start_out = fmod(arc->spec.start + da / RND_RAD_TO_DEG, 2.0*G2D_PI); +} + +static void arc_rotate(csch_sheet_t *sheet, csch_chdr_t *obj, csch_coord_t rcx, csch_coord_t rcy, double da, int undoable) +{ + csch_arc_t *arc = (csch_arc_t *)obj; + double rad = -da / RND_RAD_TO_DEG; + csch_coord_t ncx, ncy; + double nstart; + + csch_arc_rotate_(arc, rcx, rcy, da, cos(rad), sin(rad), &ncx, &ncy, &nstart); + csch_arc_modify(sheet, arc, &ncx, &ncy, NULL, &nstart, NULL, undoable, 0); +} + +void csch_arc_rotate90_(csch_arc_t *arc, csch_coord_t rcx, csch_coord_t rcy, int n, csch_coord_t *cx_out, csch_coord_t *cy_out, double *start_out) +{ + csch_coord_t ncx = arc->spec.c.x, ncy = arc->spec.c.y; + + csch_rotate90_pt(&ncx, &ncy, rcx, rcy, n); + + *cx_out = ncx; + *cy_out = ncy; + *start_out = fmod(arc->spec.start + (double)n * G2D_PI/2.0, 2.0*G2D_PI); +} + +static void arc_rotate90(csch_sheet_t *sheet, csch_chdr_t *obj, csch_coord_t rcx, csch_coord_t rcy, int n, int undoable) +{ + csch_arc_t *arc = (csch_arc_t *)obj; + csch_coord_t ncx, ncy; + double nstart; + + csch_arc_rotate90_(arc, rcx, rcy, n, &ncx, &ncy, &nstart); + csch_arc_modify(sheet, arc, &ncx, &ncy, NULL, &nstart, NULL, undoable, 0); +} + +void csch_arc_mirror_(csch_arc_t *arc, csch_coord_t mcx, csch_coord_t mcy, int mirx, int miry, csch_coord_t *cx_out, csch_coord_t *cy_out, double *start_out, double *delta_out) +{ + csch_coord_t ncx = arc->spec.c.x, ncy = arc->spec.c.y; + double nstart = arc->spec.start, ndelta = arc->spec.delta, nend = nstart+ndelta; + double sdx = cos(nstart), sdy = sin(nstart), edx = cos(nend), edy = sin(nend); + int delta_pos = (ndelta > 0); + int delta_full = (ndelta >= G2D_PI * 2.0) || (ndelta <= -(G2D_PI * 2.0)); + + csch_mirror_pt(&ncx, &ncy, mcx, mcy, mirx, miry); + if (mirx) { + sdx = -sdx; + edx = -edx; + delta_pos = !delta_pos; + } + if (miry) { + sdy = -sdy; + edy = -edy; + delta_pos = !delta_pos; + } + + + nstart = atan2(sdy, sdx); + if (!delta_full) { + nend = atan2(edy, edx); + ndelta = nend - nstart; + + if (delta_pos && (ndelta < 0)) ndelta += G2D_PI * 2.0; + if (!delta_pos && (ndelta > 0)) ndelta -= G2D_PI * 2.0; + } + else + ndelta = G2D_PI * 2.0; + + *cx_out = ncx; + *cy_out = ncy; + *start_out = nstart; + *delta_out = ndelta; +} + +static void arc_mirror(csch_sheet_t *sheet, csch_chdr_t *obj, csch_coord_t mcx, csch_coord_t mcy, int mirx, int miry, int undoable) +{ + csch_arc_t *arc = (csch_arc_t *)obj; + csch_coord_t ncx, ncy; + double nstart, ndelta; + + csch_arc_mirror_(arc, mcx, mcy, mirx, miry, &ncx, &ncy, &nstart, &ndelta); + csch_arc_modify(sheet, arc, &ncx, &ncy, NULL, &nstart, &ndelta, undoable, 0); +} + +static void arc_inst2spec(csch_sheet_t *sheet, csch_chdr_t *obj, const csch_chdr_t *in, int undoable) +{ + csch_arc_t *arc = (csch_arc_t *)in; + csch_coord_t cx = arc->inst.c.c.x, cy = arc->inst.c.c.y, r = arc->inst.c.r; + double start = arc->inst.c.start, delta = arc->inst.c.delta; + + csch_arc_modify(sheet, (csch_arc_t *)obj, &cx, &cy, &r, &start, &delta, undoable, 0); +} + + +const csch_ops_t csch_ops_arc = { + arc_create, arc_remove_alloc, arc_remove_redo, arc_remove_undo, + arc_isc_with_box, + arc_move, arc_copy, arc_rotate, arc_rotate90, arc_mirror, + arc_inst2spec +}; + +/*** Hash ***/ +unsigned csch_arc_hash_(const csch_arc_t *arc, csch_hash_ignore_t ignore, int in_contour) +{ + unsigned res = 0; + + if (!in_contour) res ^= csch_chdr_hash(&arc->hdr); + if (!(ignore & CSCH_HIGN_FLOATER_GEO) || !arc->hdr.floater) { + res ^= csch_coord_hash(arc->spec.c.x); + res ^= csch_coord_hash(arc->spec.c.y); + /* angles change with rotation, thus they are part of the floater set */ + res ^= csch_angle_hash(arc->spec.start); + res ^= csch_angle_hash(arc->spec.delta); + } + res ^= csch_coord_hash(arc->spec.r); + return res; +} + +unsigned csch_arc_hash(const csch_arc_t *arc, csch_hash_ignore_t ignore) +{ + return csch_arc_hash_(arc, ignore, 0); +} + +int csch_arc_keyeq_(const csch_arc_t *a1, const csch_arc_t *a2, csch_hash_ignore_t ignore, int in_contour) +{ + if (!in_contour && !csch_chdr_eq(&a1->hdr, &a2->hdr)) return 0; + + if (!(ignore & CSCH_HIGN_FLOATER_GEO) || !a1->hdr.floater || !a2->hdr.floater) { + if (a1->spec.c.x != a2->spec.c.x) return 0; + if (a1->spec.c.y != a2->spec.c.y) return 0; + /* angles change with rotation, thus they are part of the floater set */ + if (!csch_angle_eq(a1->spec.start, a2->spec.start)) return 0; + if (!csch_angle_eq(a1->spec.delta, a2->spec.delta)) return 0; + } + if (a1->spec.r != a2->spec.r) return 0; + return 1; +} + +int csch_arc_keyeq(const csch_arc_t *a1, const csch_arc_t *a2, csch_hash_ignore_t ignore) +{ + return csch_arc_keyeq_(a1, a2, ignore, 0); +} + + +/*** Modify ***/ +typedef struct { + csch_arc_t *arc; /* it is safe to save the object pointer because it is persistent (through the removed object list) */ + g2d_carc_t spec; +} undo_arc_modify_t; + + +static int undo_arc_modify_swap(void *udata) +{ + undo_arc_modify_t *u = udata; + + + csch_cobj_redraw(u->arc); + + rnd_swap(g2d_carc_t, u->spec, u->arc->spec); + csch_arc_update(u->arc->hdr.sheet, u->arc, 1); + csch_sheet_set_changed(u->arc->hdr.sheet, 1); + + csch_cobj_redraw(u->arc); + + return 0; +} + +static void undo_arc_modify_print(void *udata, char *dst, size_t dst_len) +{ + rnd_snprintf(dst, dst_len, "arc geometry change"); +} + +static const char core_arc_cookie[] = "libcschem/core/cnc_arc.c"; + +static const uundo_oper_t undo_arc_modify = { + core_arc_cookie, + NULL, + undo_arc_modify_swap, + undo_arc_modify_swap, + undo_arc_modify_print +}; + + +void csch_arc_modify(csch_sheet_t *sheet, csch_arc_t *arc, csch_coord_t *cx, csch_coord_t *cy, csch_coord_t *r, double *start, double *delta, int undoable, int relative) +{ + undo_arc_modify_t utmp, *u = &utmp; + + if (undoable) u = uundo_append(&sheet->undo, &undo_arc_modify, sizeof(undo_arc_modify_t)); + + u->arc = arc; + u->spec = arc->spec; /* copy all fields */ + u->spec.c.x = (cx == NULL) ? arc->spec.c.x : (relative ? arc->spec.c.x + *cx : *cx); + u->spec.c.y = (cy == NULL) ? arc->spec.c.y : (relative ? arc->spec.c.y + *cy : *cy); + u->spec.r = (r == NULL) ? arc->spec.r : (relative ? arc->spec.r + *r : *r); + u->spec.start = (start == NULL) ? arc->spec.start : (relative ? arc->spec.start + *start : *start); + u->spec.delta = (delta == NULL) ? arc->spec.delta : (relative ? arc->spec.delta + *delta : *delta); + + undo_arc_modify_swap(u); + if (undoable) csch_undo_inc_serial(sheet); +} + Index: tags/1.0.5/src/libcschem/cnc_arc.h =================================================================== --- tags/1.0.5/src/libcschem/cnc_arc.h (nonexistent) +++ tags/1.0.5/src/libcschem/cnc_arc.h (revision 10414) @@ -0,0 +1,72 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2018 Tibor 'Igor2' Palinkas + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + + +#ifndef CSCH_CONCRETE_ARC_H +#define CSCH_CONCRETE_ARC_H +#include "libcschem/concrete.h" +#include GENGEO2D_TYPECFG +#include "gengeo2d/prim.h" + +/* type=CSCH_CTYPE_ARC */ + +typedef struct csch_arc_s { + csch_chdr_t hdr; + g2d_sarc_t inst; /* as installed: group-transformed version (in absolute sheet coordinates) */ + g2d_carc_t spec; /* as specified: file format version (in relative group coordinates) */ + csch_coord_t spec_sx, spec_sy, spec_ex, spec_ey; /* cached start/end coords */ + unsigned svalid:1; + unsigned evalid:1; +} csch_arc_t; + +csch_arc_t *csch_arc_alloc(csch_sheet_t *sheet, csch_cgrp_t *parent, csch_oid_t oid); +csch_arc_t *csch_arc_dup(csch_sheet_t *sheet, csch_cgrp_t *parent, const csch_arc_t *src, int keep_id); +void csch_arc_free(csch_arc_t *arc); +csch_arc_t *csch_arc_get(csch_sheet_t *sheet, csch_cgrp_t *grp, csch_oid_t oid); +void csch_arc_update(csch_sheet_t *sheet, csch_arc_t *arc, int do_xform); + +unsigned csch_arc_hash_(const csch_arc_t *arc, csch_hash_ignore_t ignore, int in_contour); +unsigned csch_arc_hash(const csch_arc_t *arc, csch_hash_ignore_t ignore); +int csch_arc_keyeq_(const csch_arc_t *a1, const csch_arc_t *a2, csch_hash_ignore_t ignore, int in_contour); +int csch_arc_keyeq(const csch_arc_t *a1, const csch_arc_t *a2, csch_hash_ignore_t ignore); + +void csch_arc_modify(csch_sheet_t *sheet, csch_arc_t *arc, csch_coord_t *cx, csch_coord_t *cy, csch_coord_t *r, double *start, double *delta, int undoable, int relative); + +/* fill in dst with centerline bounding box */ +void csch_arc_center_bbox(csch_sheet_t *sheet, const csch_arc_t *arc, csch_rtree_box_t *dst); + +/* non-standard calls */ +void csch_arc_update_xform(csch_sheet_t *sheet, csch_arc_t *arc); +void csch_arc_update_bbox(csch_sheet_t *sheet, csch_arc_t *arc); + +/* internal calls */ +int csch_arc_get_endxy(const csch_arc_t *arc, int side, csch_coord_t *x, csch_coord_t *y); +void csch_arc_rotate_(csch_arc_t *arc, csch_coord_t rcx, csch_coord_t rcy, double da, double cs, double sn, csch_coord_t *cx_out, csch_coord_t *cy_out, double *start_out); +void csch_arc_rotate90_(csch_arc_t *arc, csch_coord_t rcx, csch_coord_t rcy, int n, csch_coord_t *cx_out, csch_coord_t *cy_out, double *start_out); +void csch_arc_mirror_(csch_arc_t *arc, csch_coord_t mcx, csch_coord_t mcy, int mirx, int miry, csch_coord_t *cx_out, csch_coord_t *cy_out, double *start_out, double *delta_out); + + +#endif Index: tags/1.0.5/src/libcschem/cnc_bitmap.c =================================================================== --- tags/1.0.5/src/libcschem/cnc_bitmap.c (nonexistent) +++ tags/1.0.5/src/libcschem/cnc_bitmap.c (revision 10414) @@ -0,0 +1,77 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2018 Tibor 'Igor2' Palinkas + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + + +#include "config.h" + +#include "event.h" +#include "concrete.h" +#include "cnc_obj.h" +#include "cnc_bitmap.h" +#include "op_common.h" + +csch_cbitmap_t *csch_cbitmap_alloc(csch_sheet_t *sheet, csch_cgrp_t *parent, csch_oid_t oid) +{ + csch_cbitmap_t *bitmap; + + bitmap = htip_get(&parent->id2obj, oid); + if (bitmap != NULL) + return NULL; + bitmap = calloc(sizeof(csch_cbitmap_t), 1); + + csch_cobj_init(&bitmap->hdr, sheet, parent, oid, CSCH_CTYPE_BITMAP); + return bitmap; +} + +csch_cbitmap_t *csch_cbitmap_dup(csch_sheet_t *sheet, csch_cgrp_t *parent, const csch_cbitmap_t *src, int keep_id) +{ + csch_cbitmap_t *dst = csch_cbitmap_alloc(sheet, parent, CSCH_KEEP_OID(parent, src->hdr.oid)); + dst->inst_x1 = src->inst_x1; + dst->inst_y1 = src->inst_y1; + dst->spec_x1 = src->spec_x1; + dst->spec_y1 = src->spec_y1; + dst->sx = src->sx; + dst->sy = src->sy; + dst->transp = src->transp; + TODO("bitmap: copy or reference the pixmap?"); + return dst; +} + + +void csch_cbitmap_free(csch_cbitmap_t *bitmap) +{ + csch_cobj_uninit(&bitmap->hdr); + free(bitmap); +} + +csch_cbitmap_t *csch_cbitmap_get(csch_sheet_t *sheet, csch_cgrp_t *grp, csch_oid_t oid) +{ + csch_cbitmap_t *bitmap = htip_get(&grp->id2obj, oid); + if ((bitmap != NULL) && (bitmap->hdr.type != CSCH_CTYPE_BITMAP)) + return NULL; + return bitmap; +} + Index: tags/1.0.5/src/libcschem/cnc_bitmap.h =================================================================== --- tags/1.0.5/src/libcschem/cnc_bitmap.h (nonexistent) +++ tags/1.0.5/src/libcschem/cnc_bitmap.h (revision 10414) @@ -0,0 +1,49 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2018 Tibor 'Igor2' Palinkas + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + + +#ifndef CSCH_CONCRETE_BITMAP_H +#define CSCH_CONCRETE_BITMAP_H +#include "libcschem/concrete.h" + +typedef csch_uint32_t csch_pixel_t; /* rgb(a) color of pixelated objects */ + +/* type=CSCH_CTYPE_BITMAP */ +typedef struct csch_cbitmap_s { + csch_chdr_t hdr; + csch_coord_t inst_x1, inst_y1; + csch_coord_t spec_x1, spec_y1; + csch_pixel_t transp; + int sx, sy; /* size in pixels */ + csch_pixel_t *bitmap; +} csch_cbitmap_t; + +csch_cbitmap_t *csch_cbitmap_alloc(csch_sheet_t *sheet, csch_cgrp_t *parent, csch_oid_t oid); +csch_cbitmap_t *csch_cbitmap_dup(csch_sheet_t *sheet, csch_cgrp_t *parent, const csch_cbitmap_t *src, int keep_id); +void csch_cbitmap_free(csch_cbitmap_t *bitmap); +csch_cbitmap_t *csch_cbitmap_get(csch_sheet_t *sheet, csch_cgrp_t *grp, csch_oid_t oid); + +#endif Index: tags/1.0.5/src/libcschem/cnc_conn.c =================================================================== --- tags/1.0.5/src/libcschem/cnc_conn.c (nonexistent) +++ tags/1.0.5/src/libcschem/cnc_conn.c (revision 10414) @@ -0,0 +1,761 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2018,2022,2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022, Entrust in 2023) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + + +#include "config.h" + +#include +#include + +#include "event.h" +#include "concrete.h" +#include "cnc_obj.h" +#include "cnc_conn.h" +#include "cnc_line.h" +#include "cnc_arc.h" +#include "op_common.h" +#include "operation.h" +#include "intersect.h" +#include "undo.h" + +#include +#include +#include + +csch_conn_t *csch_conn_alloc(csch_sheet_t *sheet, csch_cgrp_t *parent, csch_oid_t oid) +{ + csch_conn_t *conn; + + conn = htip_get(&parent->id2obj, oid); + if (conn != NULL) + return NULL; + conn = calloc(sizeof(csch_conn_t), 1); + + csch_cobj_init(&conn->hdr, sheet, parent, oid, CSCH_CTYPE_CONN); + return conn; +} + +void csch_conn_free(csch_conn_t *conn) +{ + long n; + + for(n = 0; n < conn->conn_path.used; n++) + csch_oidpath_free(&conn->conn_path.array[n]); + + vtp0_uninit(&conn->conn); + vtl0_uninit(&conn->coords); + csch_vtoidpath_uninit(&conn->conn_path); + csch_cobj_uninit(&conn->hdr); + free(conn); +} + +csch_conn_t *csch_conn_get(csch_sheet_t *sheet, csch_oid_t oid) +{ + csch_conn_t *conn = htip_get(&sheet->direct.id2obj, oid); + if ((conn != NULL) && (conn->hdr.type != CSCH_CTYPE_CONN)) + return NULL; + return conn; +} + + +void csch_conn_text2ptr(csch_sheet_t *sheet, csch_conn_t *conn) +{ + long n; + + vtp0_enlarge(&conn->conn, conn->conn_path.used); + conn->conn.used = 0; + for(n = 0; n < conn->conn_path.used; n++) { + csch_chdr_t *obj = csch_oidpath_resolve(sheet, &conn->conn_path.array[n]); + csch_chdr_t *grp; + if (obj != NULL) { + grp = (csch_chdr_t *)obj->parent; + if (csch_obj_is_grp(grp)) + csch_conn_add_obj(sheet, conn, obj, 0); + else + rnd_msg_error("Invalid oid path in connection %ld: not a group or group-ref\n", conn->hdr.oid); + } + else + rnd_msg_error("Can not resolve oid path in connection %ld\n", conn->hdr.oid); + + csch_oidpath_free(&conn->conn_path.array[n]); + } + csch_vtoidpath_truncate(&conn->conn_path, 0); +} + +/* append one or more connection points of o to tmp in x;y form */ +RND_INLINE void conn_append_pts(csch_conn_t *conn, csch_chdr_t *o, vtl0_t *tmp) +{ + switch(o->type) { + case CSCH_CTYPE_LINE: + { + csch_line_t *l = (csch_line_t *)o; + vtl0_append(tmp, l->inst.c.p1.x); + vtl0_append(tmp, l->inst.c.p1.y); + vtl0_append(tmp, l->inst.c.p2.x); + vtl0_append(tmp, l->inst.c.p2.y); + vtl0_append(tmp, (l->inst.c.p1.x + l->inst.c.p2.x)/2); + vtl0_append(tmp, (l->inst.c.p1.y + l->inst.c.p2.y)/2); + } + break; + case CSCH_CTYPE_ARC: + { + csch_arc_t *a = (csch_arc_t *)o; + g2d_vect_t v; + + v = g2d_carc_offs(&a->inst.c, 0); + vtl0_append(tmp, v.x); vtl0_append(tmp, v.y); + if (a->inst.c.delta < 1.8 * G2D_PI) { + v = g2d_carc_offs(&a->inst.c, 1); + vtl0_append(tmp, v.x); vtl0_append(tmp, v.y); + } + if (a->inst.c.delta > 0.5*G2D_PI) { + v = g2d_carc_offs(&a->inst.c, 0.5); + vtl0_append(tmp, v.x); vtl0_append(tmp, v.y); + } + } + break; + default: + /* fallback: bbox center */ + vtl0_append(tmp, (o->bbox.x1 + o->bbox.x2)/2); + vtl0_append(tmp, (o->bbox.y1 + o->bbox.y2)/2); + break; + } +} + +/* append a single line of shortest connection between o1 and o2 notable points + to tmp in x1;y1;x2;y2 line form */ +RND_INLINE void conn_recalc_add_line_npts(csch_conn_t *conn, csch_chdr_t *o1, csch_chdr_t *o2, vtl0_t *tmp) +{ + int o2_start, besti1 = -1, besti2 = -1, i1, i2; + double best = (double)CSCH_COORD_MAX * (double)CSCH_COORD_MAX; + + /* collect o1 and o2 points in tmp */ + tmp->used = 0; + conn_append_pts(conn, o1, tmp); + o2_start = tmp->used; + conn_append_pts(conn, o2, tmp); + + /* find shortest line */ + for(i1 = 0; i1 < o2_start; i1+=2) { + csch_coord_t x1 = tmp->array[i1], y1 = tmp->array[i1+1]; + + for(i2 = o2_start; i2 < tmp->used; i2+=2) { + csch_coord_t x2 = tmp->array[i2], y2 = tmp->array[i2+1]; + double dx = x2 - x1, dy = y2 - y1, dist = dx*dx + dy*dy; + + if (dist < best) { + best = dist; + besti1 = i1; + besti2 = i2; + } + } + } + + /* append results */ + assert(besti1 >= 0); + assert(besti2 > besti1); + vtl0_append(&conn->coords, tmp->array[besti1]); + vtl0_append(&conn->coords, tmp->array[besti1+1]); + vtl0_append(&conn->coords, tmp->array[besti2]); + vtl0_append(&conn->coords, tmp->array[besti2+1]); + + csch_bbox_bump(&conn->hdr.bbox, x, tmp->array[besti1]); + csch_bbox_bump(&conn->hdr.bbox, y, tmp->array[besti1+1]); + csch_bbox_bump(&conn->hdr.bbox, x, tmp->array[besti2]); + csch_bbox_bump(&conn->hdr.bbox, y, tmp->array[besti2+1]); +} + +/* Search for centerline intersections between o1 and o2, create zero-length + conn lines in those points and return the number of points found. */ +RND_INLINE int conn_recalc_add_line_cent_isc(csch_conn_t *conn, csch_chdr_t *o1, csch_chdr_t *o2, vtl0_t *tmp) +{ + csch_sheet_t *sheet = o1->sheet; + g2d_vect_t iscp[32]; + int maxlen = sizeof(iscp) / sizeof(iscp[0]); + long n, len; + + if (o1->parent == o2->parent) + return 0; + + len = csch_obj_intersect_obj(sheet, o1, o2, iscp, maxlen); + if (len > maxlen) + len = maxlen; + + for(n = 0; n < len; n++) { + vtl0_append(&conn->coords, iscp[n].x); + vtl0_append(&conn->coords, iscp[n].y); + vtl0_append(&conn->coords, iscp[n].x); + vtl0_append(&conn->coords, iscp[n].y); + csch_bbox_bump(&conn->hdr.bbox, x, iscp[n].x); + csch_bbox_bump(&conn->hdr.bbox, y, iscp[n].y); + } + + return len; +} + +/* Append new connection line(s) between o1 and o2; prefer zero-length conns at + center-line intersections, fall back to non-zero-length conns between + notable points when there's no centerline intersection */ +RND_INLINE void conn_recalc_add_line(csch_conn_t *conn, csch_chdr_t *o1, csch_chdr_t *o2, vtl0_t *tmp) +{ + if (o1->parent == o2->parent) + return; /* corner case: never indicate connection within the same group */ + if (conn_recalc_add_line_cent_isc(conn, o1, o2, tmp) == 0) + conn_recalc_add_line_npts(conn, o1, o2, tmp); /* fallback */ +} + +void csch_conn_recalc_coords(csch_conn_t *conn) +{ + int i1, i2, readd_rtree; + vtl0_t tmp = {0}; + csch_sheet_t *sheet = conn->hdr.sheet; + + /* try removing the object from its rtree; if it succeeds, add it back after the recalculation */ + readd_rtree = (sheet != NULL) && (csch_cobj_rtree_del(sheet, &conn->hdr) == 0); + + csch_bbox_reset(&conn->hdr.bbox); + conn->coords.used = 0; + for(i1 = 0; i1 < conn->conn.used; i1++) + for(i2 = i1+1; i2 < conn->conn.used; i2++) + conn_recalc_add_line(conn, conn->conn.array[i1], conn->conn.array[i2], &tmp); + + if (readd_rtree) + csch_cobj_rtree_add(sheet, &conn->hdr); + + vtl0_uninit(&tmp); +} + +void csch_conn_update(csch_sheet_t *sheet, csch_conn_t *conn, int do_xform) +{ + /* live data has pointers, not oid paths */ + if ((conn->conn_path.used > 0) && (conn->conn.used == 0)) { + csch_conn_text2ptr(sheet, conn); + } + + csch_cobj_rtree_del(sheet, &conn->hdr); + csch_conn_recalc_coords(conn); + csch_cobj_rtree_add(sheet, &conn->hdr); + + csch_cobj_bbox_changed(sheet, &conn->hdr); + conn->dirty = 0; +} + +static long find_obj_in_conn(const csch_chdr_t *obj, const csch_conn_t *conn) +{ + long n; + for(n = 0; n < conn->conn.used; n++) + if (conn->conn.array[n] == obj) + return n; + return -1; +} + +static long find_conn_in_obj(const csch_conn_t *conn, const csch_chdr_t *obj) +{ + long n; + for(n = 0; n < obj->conn.used; n++) + if (obj->conn.array[n] == conn) + return n; + return -1; +} + +RND_INLINE long csch_conn_add_obj_(csch_sheet_t *sheet, csch_conn_t *conn, csch_chdr_t *obj, long *cidx) +{ + long ci, gi; + + ci = find_obj_in_conn(obj, conn); + if (ci >= 0) { + if (cidx != NULL) + *cidx = -1; + return -1; + } + gi = find_conn_in_obj(conn, obj); + if (gi >= 0) { + if (cidx != NULL) + *cidx = gi; + return -1; + } + + vtp0_append(&conn->conn, obj); + vtp0_append(&obj->conn, conn); + if (cidx != NULL) + *cidx = obj->conn.used - 1; + return 0; +} + + +RND_INLINE int csch_conn_del_obj_(csch_sheet_t *sheet, csch_conn_t *conn, csch_chdr_t *obj) +{ + long ci, gi; + + ci = find_obj_in_conn(obj, conn); + gi = find_conn_in_obj(conn, obj); + if (ci >= 0) vtp0_remove(&conn->conn, ci, 1); + if (gi >= 0) vtp0_remove(&obj->conn, gi, 1); + if ((ci < 0) || (gi < 0)) + return -1; + return 0; +} + +void csch_conn_ptr2text(csch_sheet_t *sheet, csch_conn_t *conn) +{ + long n; + + csch_vtoidpath_enlarge(&conn->conn_path, conn->conn.used); + conn->conn_path.used = conn->conn.used; + for(n = 0; n < conn->conn.used; n++) + csch_oidpath_from_obj(&conn->conn_path.array[n], conn->conn.array[n]); + + /* this changes conn->conn, so go backward */ + for(n = conn->conn.used-1; n >= 0; n--) + csch_conn_del_obj_(sheet, conn, conn->conn.array[n]); + + conn->conn.used = 0; /* just in case... to make sure the code resolves the oidpaths */ + conn->dirty = 1; +} + +/*** undoable conn-obj add/del ***/ +typedef struct { + csch_sheet_t *sheet; + csch_conn_t *conn; + csch_chdr_t *obj; + long last_cidx; + unsigned add:1; /* if 1, swap should add, else swap should del (swap always inverts afterwards) */ +} undo_conn_obj_t; + +static int undo_conn_obj_swap_(void *udata, int update) +{ + undo_conn_obj_t *u = udata; + + if (u->add) + csch_conn_add_obj_(u->sheet, u->conn, u->obj, &u->last_cidx); + else + csch_conn_del_obj_(u->sheet, u->conn, u->obj); + + if (update) /* recalc coords (the graphics) when called from undo/redo */ + csch_conn_update(u->sheet, u->conn, 0); + + u->add = !u->add; + + return 0; +} + +static int undo_conn_obj_swap(void *udata) +{ + return undo_conn_obj_swap_(udata, 1); +} + +static void undo_conn_obj_print(void *udata, char *dst, size_t dst_len) +{ + undo_conn_obj_t *u = udata; + gds_t tmp; + csch_oidpath_t oidp = {0}; + + + tmp.used = 0; + tmp.alloced = dst_len; + tmp.array = dst; + tmp.no_realloc = 1; + + csch_oidpath_from_obj(&oidp, u->obj); + + rnd_append_printf(&tmp, "%s object ", u->add ? "add" : "del"); + csch_oidpath_to_str_append(&tmp, &oidp); + rnd_append_printf(&tmp, " in conn #%ld", (long)u->conn->hdr.oid); + + csch_oidpath_free(&oidp); +} + +static const char core_conn_cookie[] = "libcschem/core/cnc_conn.c"; + +static const uundo_oper_t undo_conn_obj_modify = { + core_conn_cookie, + NULL, + undo_conn_obj_swap, + undo_conn_obj_swap, + undo_conn_obj_print +}; + + +RND_INLINE int csch_conn_do_obj(csch_sheet_t *sheet, csch_conn_t *conn, csch_chdr_t *obj, int add, long *cidx, int undoable) +{ + int res; + undo_conn_obj_t utmp, *u = &utmp; + + if (undoable) u = uundo_append(&sheet->undo, &undo_conn_obj_modify, sizeof(undo_conn_obj_t)); + + u->sheet = sheet; + u->conn = conn; + u->obj = obj; + u->add = add; + + res = undo_conn_obj_swap_(u, 0); /* update 0: expect the caller to do the update */ + if (undoable) csch_undo_inc_serial(sheet); + if (cidx != NULL) + *cidx = u->last_cidx; + + return res; +} + +int csch_conn_del_obj(csch_sheet_t *sheet, csch_conn_t *conn, csch_chdr_t *obj, int undoable) +{ + return csch_conn_do_obj(sheet, conn, obj, 0, NULL, undoable); +} + +int csch_conn_add_obj(csch_sheet_t *sheet, csch_conn_t *conn, csch_chdr_t *obj, int undoable) +{ + return csch_conn_do_obj(sheet, conn, obj, 1, NULL, undoable); +} + +/* returns conn index in obj or -1 on error */ +long csch_conn_add_obji(csch_sheet_t *sheet, csch_conn_t *conn, csch_chdr_t *obj, int undoable) +{ + long res; + csch_conn_do_obj(sheet, conn, obj, 1, &res, undoable); + return res; +} + +/* Return conn where: + obj1 is in the connection and another object from obj2's parent is in too + (or return NULL if not found) */ +RND_INLINE csch_conn_t *conn_find_common(csch_chdr_t *obj1, csch_chdr_t *obj2, long *o1i, csch_conn_t *ignore) +{ + long n, m; + csch_conn_t *conn; + csch_chdr_t *o; + + for(n = 0; n < obj1->conn.used; n++) { + conn = obj1->conn.array[n]; + if (conn == ignore) + continue; + for(m = 0; m < conn->conn.used; m++) { + o = conn->conn.array[m]; + if (o->parent == obj2->parent) { + if (o1i != NULL) + *o1i = n; + return conn; + } + } + } + + if (o1i != NULL) + *o1i = -1; + return NULL; +} + +csch_conn_t *csch_conn_find_mergable(csch_sheet_t *sheet, csch_conn_t *conn, csch_chdr_t *owner) +{ + long n; + + for(n = 0; n < conn->conn.used; n++) { + csch_chdr_t *co = conn->conn.array[n]; + csch_conn_t *res = conn_find_common(co, owner, NULL, conn); + if (res != NULL) + return res; + } + return NULL; +} + +RND_INLINE csch_conn_t *csch_conn_auto_add_(csch_sheet_t *sheet, csch_chdr_t *obj1, csch_chdr_t *obj2, long *obj1i) +{ + csch_conn_t *conn; + + /* check if there's an existing connection we can extend; requirement is: + obj1/2 is in the connection and another object from obj2/1's parent is in too */ + conn = conn_find_common(obj1, obj2, obj1i, NULL); + if (conn != NULL) { + if (find_obj_in_conn(obj2, conn) < 0) { + csch_conn_add_obj(sheet, conn, obj2, 1); + csch_conn_update(sheet, conn, 1); + } + return conn; + } + + conn = conn_find_common(obj2, obj1, NULL, NULL); + if (conn != NULL) { + *obj1i = find_obj_in_conn(obj1, conn); + if (*obj1i < 0) { + *obj1i = csch_conn_add_obji(sheet, conn, obj1, 1); + csch_conn_update(sheet, conn, 1); + } + return conn; + } + + + /* there was no common conn, create a new one */ + conn = (csch_conn_t *)csch_op_create(sheet, &sheet->direct, CSCH_CTYPE_CONN); + *obj1i = csch_conn_add_obji(sheet, conn, obj1, 1); + csch_conn_add_obj(sheet, conn, obj2, 1); + csch_conn_update(sheet, conn, 1); + return conn; +} + +csch_conn_t *csch_conn_auto_add(csch_sheet_t *sheet, csch_chdr_t *obj1, csch_chdr_t *obj2) +{ + long tmp; + return csch_conn_auto_add_(sheet, obj1, obj2, &tmp); +} + +long csch_conn_auto_addi(csch_sheet_t *sheet, csch_chdr_t *obj1, csch_chdr_t *obj2) +{ + long tmp = -1; + csch_conn_auto_add_(sheet, obj1, obj2, &tmp); + + return tmp; +} + +/* Return 1 if the connection lists at least 2 objects with different parent + groups (so that the connection is valid) */ +static int conn_has_multiple_groups(csch_sheet_t *sheet, csch_conn_t *conn) +{ + long n; + csch_chdr_t *obj; + csch_cgrp_t *par; + + if (conn->conn.used < 2) + return 0; + + obj = conn->conn.array[0]; + par = obj->parent; + for(n = 1; n < conn->conn.used; n++) { + obj = conn->conn.array[n]; + if (obj->parent != par) + return 1; + } + + return 0; +} + +int csch_conn_auto_del_obj(csch_sheet_t *sheet, csch_conn_t *conn, csch_chdr_t *obj) +{ + int res; + + TODO("This may not be undoable; check with 3 objects crossing"); + res = csch_conn_del_obj(sheet, conn, obj, 1); + if (res != 0) + return res; + + /* if connection doesn't connect two groups anymore, remove it */ + if (!conn_has_multiple_groups(sheet, conn)) { + long n; + + res = 0; + for(n = conn->conn.used-1; n >= 0; n--) + res |= csch_conn_del_obj(sheet, conn, conn->conn.array[n], 1); + if (res != 0) + return res; + } + + if (conn->conn.used == 0) + csch_op_remove(sheet, &conn->hdr); + else + csch_conn_update(sheet, conn, 1); + return 0; +} + + +int csch_conn_auto_del_obj_all(csch_sheet_t *sheet, csch_chdr_t *obj) +{ + long n; + int res = 0; + + for(n = obj->conn.used-1; n >= 0; n--) + res |= csch_conn_auto_del_obj(sheet, obj->conn.array[n], obj); + + return res; +} + + + +static csch_chdr_t *conn_create(csch_sheet_t *sheet, csch_cgrp_t *parent) +{ + csch_conn_t *conn = csch_conn_alloc(sheet, parent, csch_oid_new(sheet, parent)); + if (conn == NULL) return NULL; + return &conn->hdr; +} + +static void conn_remove_alloc(csch_undo_remove_t *slot) +{ +} + +static void conn_remove_redo(csch_undo_remove_t *slot) +{ + csch_cnc_common_remove_redo(slot, CSCH_REM_FROM_RTREE | CSCH_REM_FROM_PARENT | CSCH_REM_DEL_EMPTY_PARENT); +} + +static void conn_remove_undo(csch_undo_remove_t *slot) +{ + csch_cnc_common_remove_undo(slot, CSCH_REM_FROM_RTREE | CSCH_REM_FROM_PARENT | CSCH_REM_DEL_EMPTY_PARENT); +} + +static int conn_isc_with_box(csch_chdr_t *obj, csch_rtree_box_t *box) +{ + return 0; /* a connection is a purely logical concept, has no geometry */ +} + +const csch_ops_t csch_ops_conn = { + conn_create, conn_remove_alloc, conn_remove_redo, conn_remove_undo, + conn_isc_with_box +}; + + +/*** conn recalc ***/ + +typedef struct { + csch_sheet_t *sheet; + csch_chdr_t *wobj; + gds_t keep; +} find_conn_t; + +static csch_rtree_dir_t find_conn_cb(void *ctx_, void *obj_, const csch_rtree_box_t *box) +{ + find_conn_t *ctx = ctx_; + csch_chdr_t *obj = obj_; + long ci; + char *keep; + + if ((obj == ctx->wobj) || (obj->parent == ctx->wobj->parent)) + return csch_RTREE_DIR_NOT_FOUND_CONT; + + if (csch_obj_is_grp(obj)) + return csch_RTREE_DIR_NOT_FOUND_CONT; + + if (csch_obj_intersect_obj(obj->sheet, ctx->wobj, obj, NULL, 0) <= 0) + return csch_RTREE_DIR_NOT_FOUND_CONT; + + ci = csch_conn_auto_addi(obj->sheet, ctx->wobj, obj); + + keep = gds_get(&ctx->keep, ci, 1); + *keep = 1; + + return csch_RTREE_DIR_FOUND_CONT; +} + +/* Remove objects from conn that are not intersecting with main_obj */ +static void csch_conn_remove_disconnected_objs(csch_sheet_t *sheet, csch_conn_t *conn, csch_chdr_t *main_obj) +{ + long n; + for(n = conn->conn.used-1; n >= 0; n--) { + csch_chdr_t *obj = conn->conn.array[n]; + if (csch_obj_intersect_obj(obj->sheet, main_obj, obj, NULL, 0) <= 0) + csch_conn_auto_del_obj(sheet, conn, obj); + } +} + +void csch_recalc_obj_conn(csch_sheet_t *sheet, csch_chdr_t *wobj, csch_displayer_t target, csch_displayer_t target2) +{ + find_conn_t ctx = {0}; + long n; + + ctx.sheet = sheet; + ctx.wobj = (csch_chdr_t *)wobj; + + + if (wobj->conn.used != 0) { + gds_enlarge(&ctx.keep, wobj->conn.used+4); + memset(ctx.keep.array, 0, wobj->conn.used+4); + ctx.keep.used = wobj->conn.used; + } + + /* we may be called on deleted objects to get their conns removed */ + if (!csch_obj_is_deleted(wobj)) { + csch_rtree_search_obj(&sheet->dsply[target], &wobj->bbox, find_conn_cb, &ctx); + if (target2 != CSCH_DSPLY_invalid) + csch_rtree_search_obj(&sheet->dsply[target2], &wobj->bbox, find_conn_cb, &ctx); + } + + for(n = ctx.keep.used-1; n >= 0; n--) { + if (ctx.keep.array[n]) { + csch_conn_remove_disconnected_objs(sheet, wobj->conn.array[n], wobj); + if (wobj->conn.used > n) + csch_conn_update(sheet, wobj->conn.array[n], 1); + continue; + } + rnd_trace("! remove conn %ld\n", n); + csch_conn_auto_del_obj(sheet, wobj->conn.array[n], wobj); + } +} + + +static void csch_conn_auto_recalc_(csch_sheet_t *sheet, csch_chdr_t *obj, int in_term, int is_deleted) +{ + if (csch_obj_is_grp(obj)) { + csch_cgrp_t *grp = (csch_cgrp_t *)obj; + htip_entry_t *e; + + if (grp->role == CSCH_ROLE_TERMINAL) + in_term = 1; + + for(e = htip_first(&grp->id2obj); e != NULL; e = htip_next(&grp->id2obj, e)) + csch_conn_auto_recalc_(sheet, e->value, in_term, is_deleted); + } + else { + if ((in_term) || ((obj->parent != NULL) && (obj->parent->role == CSCH_ROLE_WIRE_NET))) { + if (is_deleted) + csch_conn_auto_del_obj_all(sheet, obj); + else + csch_recalc_obj_conn(sheet, obj, in_term ? CSCH_DSPLY_WIRE : CSCH_DSPLY_HUBTERM, in_term ? CSCH_DSPLY_HUBTERM : CSCH_DSPLY_invalid); + } + } +} + +void csch_conn_auto_recalc(csch_sheet_t *sheet, csch_chdr_t *obj) +{ + csch_conn_auto_recalc_(sheet, obj, 0, csch_obj_is_deleted(obj)); +} + + +void csch_conn_auto_recalc_geo(csch_sheet_t *sheet, csch_chdr_t *obj) +{ + long n; + for(n = 0; n < obj->conn.used; n++) + csch_conn_recalc_coords((csch_conn_t *)obj->conn.array[n]); + + /* recurse into children */ + if (csch_obj_is_grp(obj)) { + csch_cgrp_t *grp = (csch_cgrp_t *)obj; + htip_entry_t *e; + for(e = htip_first(&grp->id2obj); e != NULL; e = htip_next(&grp->id2obj, e)) + csch_conn_auto_recalc_geo(sheet, e->value); + } + else if (obj->type == CSCH_CTYPE_CONN) + csch_conn_recalc_coords((csch_conn_t *)obj); +} + +void csch_conn_update_dirties(csch_sheet_t *sheet, csch_cgrp_t *grp, int do_xform) +{ + htip_entry_t *e; + + for(e = htip_first(&grp->id2obj); e != NULL; e = htip_next(&grp->id2obj, e)) { + csch_cgrp_t *g = e->value; + csch_conn_t *c = e->value; + if ((c->hdr.type == CSCH_CTYPE_CONN) && c->dirty) + csch_conn_update(sheet, c, do_xform); + else if (csch_obj_is_grp(&g->hdr)) + csch_conn_update_dirties(sheet, g, do_xform); + } +} Index: tags/1.0.5/src/libcschem/cnc_conn.h =================================================================== --- tags/1.0.5/src/libcschem/cnc_conn.h (nonexistent) +++ tags/1.0.5/src/libcschem/cnc_conn.h (revision 10414) @@ -0,0 +1,100 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2018 Tibor 'Igor2' Palinkas + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + + +#ifndef CSCH_CONCRETE_CONN_H +#define CSCH_CONCRETE_CONN_H +#include "libcschem/concrete.h" +#include "libcschem/vtoidpath.h" + +/* type=CSCH_CTYPE_CONN */ + +typedef struct csch_conn_s { + csch_chdr_t hdr; + vtp0_t conn; /* (csch_chdr_t *); xorcache: if not empty, ->conn_path is empty */ + csch_oid_t gfx; + unsigned dirty:1; /* mark connections that need to be updated */ + + /* cache: file I/O version */ + csch_vtoidpath_t conn_path; /* xorcache: if not empty, ->conn is empty */ + + /* cache/debug: coordinates of connection points in x1;y1;x2;y2 lines form */ + vtl0_t coords; +} csch_conn_t; + +csch_conn_t *csch_conn_alloc(csch_sheet_t *sheet, csch_cgrp_t *parent, csch_oid_t oid); +void csch_conn_free(csch_conn_t *conn); +csch_conn_t *csch_conn_get(csch_sheet_t *sheet, csch_oid_t oid); +void csch_conn_update(csch_sheet_t *sheet, csch_conn_t *conn, int do_xform); + +/* Add drawing obj in a connection; returns -1 if it is already in */ +int csch_conn_add_obj(csch_sheet_t *sheet, csch_conn_t *conn, csch_chdr_t *obj, int undoable); + +/* Del obj from a connection; returns -1 if it is not in */ +int csch_conn_del_obj(csch_sheet_t *sheet, csch_conn_t *conn, csch_chdr_t *obj, int undoable); + +/* Undoable connection creation between obj1 and obj2; automatically reuses + existing shared conn or creates a new conn object; addi returns the index of + conn in obj1 (or -1 on error) */ +csch_conn_t *csch_conn_auto_add(csch_sheet_t *sheet, csch_chdr_t *obj1, csch_chdr_t *obj2); +long csch_conn_auto_addi(csch_sheet_t *sheet, csch_chdr_t *obj1, csch_chdr_t *obj2); + +/* Undoable conn obj remove; if conn becomes empty or single-object, the + conn is removed too. */ +int csch_conn_auto_del_obj(csch_sheet_t *sheet, csch_conn_t *conn, csch_chdr_t *obj); + +/* Remove all connections of an object using auto_del */ +int csch_conn_auto_del_obj_all(csch_sheet_t *sheet, csch_chdr_t *obj); + +/* Automatically recalculate connections of an object (e.g. wire or + terminal). Recursive for groups. Always undoable. */ +void csch_conn_auto_recalc(csch_sheet_t *sheet, csch_chdr_t *obj); + +/* Recursive recalc the geometry of connection objects; does not add or remove + connections. Since conn geo is not saved, there is nothing to be undone */ +void csch_conn_auto_recalc_geo(csch_sheet_t *sheet, csch_chdr_t *obj); + + +/* Convert conn's oid-path field into object pointers */ +void csch_conn_text2ptr(csch_sheet_t *sheet, csch_conn_t *conn); + +/* Convert conn's object pointers into the oid-path field; useful if some an + object is recreated (changing pointer), which would make the object's + old dangling pointer remain in the pointer vector */ +void csch_conn_ptr2text(csch_sheet_t *sheet, csch_conn_t *conn); + + +/* Return an existing connection if owner's (maybe currently removed) conn + could be merged into it. Useful when owner is moved from one group to + another: its connections need to be moved but if there are existing conn + in the target group overlapping, that is returned here and should be + reused/extended. */ +csch_conn_t *csch_conn_find_mergable(csch_sheet_t *sheet, csch_conn_t *conn, csch_chdr_t *owner); + +/* Update all connections that are marked dirty, recursively */ +void csch_conn_update_dirties(csch_sheet_t *sheet, csch_cgrp_t *grp, int do_xform); + +#endif Index: tags/1.0.5/src/libcschem/cnc_grp.c =================================================================== --- tags/1.0.5/src/libcschem/cnc_grp.c (nonexistent) +++ tags/1.0.5/src/libcschem/cnc_grp.c (revision 10414) @@ -0,0 +1,778 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2018..2020,2022,2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022, Entrust in 2023) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + + +#include "config.h" + +#include + +#include "concrete.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "event.h" +#include "cnc_grp.h" +#include "cnc_grp_child.h" +#include "cnc_conn.h" +#include "cnc_obj.h" +#include "cnc_any_obj.h" +#include "cnc_loop.h" +#include "op_common.h" +#include "operation.h" +#include "undo.h" +#include "util_grp.h" +#include "op_common.h" +#include "rotate.h" +#include "project.h" +#include "abstract.h" +#include "libcschem.h" + +RND_INLINE csch_role_t csch_role_str2role(const char *str) +{ + if ((str == NULL) || (*str == '\0')) return CSCH_ROLE_empty; + if (strcmp(str, "bus-net") == 0) return CSCH_ROLE_BUS_NET; + if (strcmp(str, "bus-terminal") == 0) return CSCH_ROLE_BUS_TERMINAL; + if (strcmp(str, "hub-point") == 0) return CSCH_ROLE_HUB_POINT; + if (strcmp(str, "symbol") == 0) return CSCH_ROLE_SYMBOL; + if (strcmp(str, "terminal") == 0) return CSCH_ROLE_TERMINAL; + if (strcmp(str, "wire-net") == 0) return CSCH_ROLE_WIRE_NET; + if (strcmp(str, "junction") == 0) return CSCH_ROLE_JUNCTION; + return CSCH_ROLE_invalid; +} + +RND_INLINE void csch_role_set(csch_cgrp_t *grp, const char *val) +{ + grp->srole = val; + grp->role = csch_role_str2role(val); +} + + +csch_cgrp_t *csch_cgrp_init(csch_sheet_t *sheet, csch_cgrp_t *grp, csch_cgrp_t *parent, csch_oid_t oid) +{ + csch_cobj_init(&grp->hdr, sheet, parent, oid, CSCH_CTYPE_GRP); + csch_attrib_init(&grp->attr); + htip_init(&grp->id2obj, longhash, longkeyeq); + htsp_init(&grp->name2pen, strhash, strkeyeq); + csch_cgrp_xform_update(sheet, grp); + grp->role = csch_role_str2role(NULL); /* role is explicit empty on start */ + return grp; +} + + +csch_cgrp_t *csch_cgrp_alloc(csch_sheet_t *sheet, csch_cgrp_t *parent, csch_oid_t oid) +{ + csch_cgrp_t *grp; + + if (parent != NULL) { + grp = htip_get(&parent->id2obj, oid); + if (grp != NULL) + return NULL; + } + grp = calloc(sizeof(csch_cgrp_t), 1); + grp->data.grp.next_id = 1; + minuid_gen(&csch_minuid, grp->uuid); + /* src_uuid is all-zero for new groups */ + + return csch_cgrp_init(sheet, grp, parent, oid); +} + +csch_cgrp_t *csch_cgrp_dup_into(csch_sheet_t *sheet, csch_cgrp_t *dst, const csch_cgrp_t *src, int copy_attr) +{ + htip_entry_t *e; + + if (dst->hdr.type == CSCH_CTYPE_GRP) { + if (minuid_is_nil(src->data.grp.src_uuid)) + minuid_cpy(dst->data.grp.src_uuid, src->uuid); + else + minuid_cpy(dst->data.grp.src_uuid, src->data.grp.src_uuid); /* share original source if available */ + } + + for(e = htip_first(&src->id2obj); e != NULL; e = htip_next(&src->id2obj, e)) + csch_cobj_dup(sheet, dst, (csch_chdr_t *)e->value, 1, 0); + + if (copy_attr) + csch_cobj_attrib_copy_all(sheet, dst, src); + + return dst; +} + +csch_cgrp_t *csch_cgrp_dup(csch_sheet_t *sheet, csch_cgrp_t *parent, const csch_cgrp_t *src, int keep_id) +{ + csch_cgrp_t *dst; + if (src->hdr.type == CSCH_CTYPE_GRP) { + dst = csch_cgrp_alloc(sheet, parent, CSCH_KEEP_OID(parent, src->hdr.oid)); + if (dst == NULL) + return NULL; + dst->data.grp = src->data.grp; + } + else { + dst = csch_cgrp_ref_alloc(sheet, parent, CSCH_KEEP_OID(parent, src->hdr.oid)); + dst->data.ref = src->data.ref; + } + dst->x = src->x; + dst->y = src->y; + dst->spec_rot = src->spec_rot; + dst->mirx = src->mirx; + dst->miry = src->miry; + dst->sym_prefer_loclib = src->sym_prefer_loclib; + dst->loclib_name = (src->loclib_name == NULL) ? NULL : rnd_strdup(src->loclib_name); + dst->file_name = (src->file_name == NULL) ? NULL : rnd_strdup(src->file_name); + + return csch_cgrp_dup_into(sheet, dst, src, 1); +} + +void csch_cgrp_clear(csch_cgrp_t *grp) +{ + htip_entry_t *e; + for(e = htip_first(&grp->id2obj); e != NULL; e = htip_next(&grp->id2obj, e)) + csch_cobj_free(e->value); + htip_clear(&grp->id2obj); +} + +void csch_cgrp_uninit(csch_cgrp_t *grp) +{ + csch_cgrp_clear(grp); + htip_uninit(&grp->id2obj); + htsp_uninit(&grp->name2pen); + vtl0_uninit(&grp->aid); + csch_cobj_uninit(&grp->hdr); + csch_attrib_uninit(&grp->attr); + free(grp->loclib_name); + free(grp->file_name); +} + + +void csch_cgrp_free(csch_cgrp_t *grp) +{ + csch_cgrp_uninit(grp); + free(grp); +} + +csch_cgrp_t *csch_cgrp_get(csch_sheet_t *sheet, csch_cgrp_t *parent, csch_oid_t oid) +{ + csch_cgrp_t *grp = htip_get(&parent->id2obj, oid); + if ((grp != NULL) && (grp->hdr.type != CSCH_CTYPE_GRP)) + return NULL; + return grp; +} + + +void csch_cgrp_xform_update(csch_sheet_t *sheet, csch_cgrp_t *grp) +{ + static const g2d_xform_t ind = G2D_XFORM_IDENT; + csch_child_xform_t cx0 = {0}, *cx = &cx0; + + if (grp->hdr.parent == NULL) { + grp->xform.mx = ind; + grp->xform.rot = 0; + grp->xform.x = 0; + grp->xform.y = 0; + grp->xform.mirx = 0; + grp->xform.miry = 0; + } + else { + csch_grp_ref_parent_mx(&grp->hdr, &cx); + grp->xform = grp->hdr.parent->xform; + } + + if (((grp->x + cx->movex) != 0) || ((grp->y + cx->movey) != 0)) { + grp->xform.mx = g2d_xform_translate(grp->xform.mx, (grp->x + cx->movex), (grp->y + cx->movey)); + grp->xform.x += grp->x + cx->movex; + grp->xform.y += grp->y + cx->movey; + } + if (grp->mirx ^ cx->mirx) { + grp->xform.mx = g2d_xform_mirrory(grp->xform.mx); + grp->xform.mirx = !grp->xform.mirx; + } + if (grp->miry ^ cx->miry) { + grp->xform.mx = g2d_xform_mirrorx(grp->xform.mx); + grp->xform.miry = !grp->xform.miry; + } + + if ((grp->spec_rot + cx->rot) != 0) { + grp->xform.mx = g2d_xform_rotate(grp->xform.mx, -(grp->spec_rot + cx->rot) / RND_RAD_TO_DEG); + if (grp->xform.mirx ^ grp->xform.miry) + grp->xform.rot -= (grp->spec_rot + cx->rot); + else + grp->xform.rot += (grp->spec_rot + cx->rot); + } +} + +void csch_cgrp_role_update(csch_sheet_t *sheet, csch_cgrp_t *grp) +{ + grp->hdr.dsply = csch_cobj_dsply(&grp->hdr); +} + + +void csch_cgrp_bbox_update(csch_sheet_t *sheet, csch_cgrp_t *grp) +{ + csch_chdr_t *h; + csch_grpo_iter_t it; + + csch_bbox_reset(&grp->hdr.bbox); + csch_bbox_reset(&grp->bbox_flt); + for(h = csch_grpo_first(&it, sheet, grp); h != NULL; h = csch_grpo_next(&it)) { + if (csch_bbox_is_invalid(&h->bbox)) + continue; + + if (csch_obj_is_grp(h)) { /* group child: should use the child's bbox that includes floaters */ + csch_cgrp_t *hg = (csch_cgrp_t *)h; + assert(hg->bbox_flt.x1 != CSCH_COORD_INV); /* floater bbox of child can not be invalid if the above bbox validity check passed because normal bbx and flt bbox are updated in parallel */ + csch_bbox_bump(&grp->bbox_flt, x, hg->bbox_flt.x1); + csch_bbox_bump(&grp->bbox_flt, x, hg->bbox_flt.x2); + csch_bbox_bump(&grp->bbox_flt, y, hg->bbox_flt.y1); + csch_bbox_bump(&grp->bbox_flt, y, hg->bbox_flt.y2); + } + else { + csch_bbox_bump(&grp->bbox_flt, x, h->bbox.x1); + csch_bbox_bump(&grp->bbox_flt, x, h->bbox.x2); + csch_bbox_bump(&grp->bbox_flt, y, h->bbox.y1); + csch_bbox_bump(&grp->bbox_flt, y, h->bbox.y2); + } + + if (!h->floater) { + csch_bbox_bump(&grp->hdr.bbox, x, h->bbox.x1); + csch_bbox_bump(&grp->hdr.bbox, x, h->bbox.x2); + csch_bbox_bump(&grp->hdr.bbox, y, h->bbox.y1); + csch_bbox_bump(&grp->hdr.bbox, y, h->bbox.y2); + } + } +} + +void csch_cgrp_update(csch_sheet_t *sheet, csch_cgrp_t *grp, int do_xform) +{ + htip_entry_t *e; + int has_conn = 0; + + if (do_xform) + csch_cgrp_xform_update(sheet, grp); + + for(e = htip_first(&grp->id2obj); e != NULL; e = htip_next(&grp->id2obj, e)) { + csch_chdr_t *obj = e->value; + if (obj->type != CSCH_CTYPE_CONN) + csch_cobj_update(sheet, obj, do_xform); + else + has_conn = 1; + } + + if (has_conn) { + /* need to udpate connections in a second pass because they depend on other (referenced) objects already updated */ + for(e = htip_first(&grp->id2obj); e != NULL; e = htip_next(&grp->id2obj, e)) { + csch_chdr_t *obj = e->value; + if (obj->type == CSCH_CTYPE_CONN) + csch_cobj_update(sheet, obj, do_xform); + } + } + + csch_cobj_rtree_del(sheet, &grp->hdr); + csch_cgrp_bbox_update(sheet, grp); + csch_cobj_rtree_add(sheet, &grp->hdr); + + csch_cobj_bbox_changed(sheet, &grp->hdr); +} + +void csch_cgrp_render(csch_sheet_t *sheet, csch_cgrp_t *grp) +{ + csch_cgrp_update(sheet, grp, 1); +} + +void csch_cgrp_render_all(csch_sheet_t *sheet, csch_cgrp_t *grp) +{ + htip_entry_t *e; + for(e = htip_first(&grp->id2obj); e != NULL; e = htip_next(&grp->id2obj, e)) { + csch_cgrp_t *g = e->value; + if (g->hdr.type == CSCH_CTYPE_GRP_REF) + csch_cgrp_ref_render(sheet, g); /* this is recursive */ + else if (g->hdr.type == CSCH_CTYPE_GRP) + csch_cgrp_render_all(sheet, g); /* need to recurse to find sub-group-refs */ + } + + csch_conn_update_dirties(sheet, grp, 0); +} + +void csch_cgrp_attrib_update(csch_sheet_t *sheet, csch_cgrp_t *grp, int prio, const char *key, const char *val) +{ + if (strcmp(key, "role") == 0) { + csch_role_set(grp, val); + csch_cgrp_update_dsply_recurse(sheet, grp); /* need to move all opjects to the wire layer */ + } +} + +csch_ahdr_t *csch_cgrp_get_abstract(csch_sheet_t *sheet, const csch_cgrp_t *grp, long idx) +{ + csch_project_t *prj = (csch_project_t *)sheet->hidlib.project; + + if ((prj == NULL) || (prj->abst == NULL)) + return NULL; + if ((idx < 0) || (idx >= grp->aid.used)) + return NULL; + + return htip_get(&prj->abst->aid2obj, grp->aid.array[idx]); +} + +unsigned csch_cgrp_hash_(csch_cgrp_t *grp, csch_hash_ignore_t ignore) +{ + htip_entry_t *e; + unsigned res; + + if (grp->hdr.type == CSCH_CTYPE_GRP_REF) { + if (grp->data.ref.grp == NULL) + if (csch_cgrp_ref_text2ptr(grp->hdr.sheet, grp) != 0) + return 0; + grp = grp->data.ref.grp; + } + + res = csch_chdr_hash(&grp->hdr); + if (!(ignore & CSCH_HIGN_GRP_ATTRIB)) + res ^= csch_attrib_hash(&grp->attr); + if (!(ignore & CSCH_HIGN_GRP_PLACEMENT)) { + res ^= csch_angle_hash(grp->spec_rot); + res ^= csch_coord_hash(grp->x); + res ^= csch_coord_hash(grp->y); + res ^= ((unsigned)grp->mirx) << 9; + res ^= ((unsigned)grp->miry) << 10; + } + + /* ->loclib_name is omitted on purpose: a lib vs. instance match would + be impossible with that */ + + for(e = htip_first(&grp->id2obj); e != NULL; e = htip_next(&grp->id2obj, e)) { + csch_chdr_t *obj = e->value; + res ^= csch_cobj_hash_(obj, (ignore & CSCH_HIGN_FLOATER_GEO)); + } + + return res; +} + +int csch_cgrp_keyeq_(csch_cgrp_t *g1, csch_cgrp_t *g2, csch_hash_ignore_t ignore) +{ + htip_entry_t *e; + + if (g1->hdr.type == CSCH_CTYPE_GRP_REF) { + if (g1->data.ref.grp == NULL) + if (csch_cgrp_ref_text2ptr(g1->hdr.sheet, g1) != 0) + return 0; + g1 = g1->data.ref.grp; + } + if (g2->hdr.type == CSCH_CTYPE_GRP_REF) { + if (g2->data.ref.grp == NULL) + if (csch_cgrp_ref_text2ptr(g2->hdr.sheet, g2) != 0) + return 0; + g2 = g2->data.ref.grp; + } + + if (!csch_chdr_eq(&g1->hdr, &g2->hdr)) return 0; + if (!(ignore & CSCH_HIGN_GRP_PLACEMENT)) { + if (!csch_angle_eq(g1->spec_rot, g2->spec_rot)) return 0; + if (g1->x != g2->x) return 0; + if (g1->y != g2->y) return 0; + if (g1->mirx != g2->mirx) return 0; + if (g1->miry != g2->miry) return 0; + } + if (htip_length(&g1->id2obj) != htip_length(&g2->id2obj)) return 0; + + /* ->loclib_name is omitted on purpose: a lib vs. instance match would + be impossible with that */ + + /* expensive tests */ + if (!(ignore & CSCH_HIGN_GRP_ATTRIB)) { + if (!csch_attrib_eq(&g1->attr, &g2->attr)) return 0; + } + + for(e = htip_first(&g1->id2obj); e != NULL; e = htip_next(&g1->id2obj, e)) { + csch_chdr_t *o2 = htip_get(&g2->id2obj, e->key), *o1 = e->value; + if (o2 == NULL) return 0; + if (!csch_cobj_keyeq_(o1, o2, (ignore & CSCH_HIGN_FLOATER_GEO))) return 0; + } + + return 1; +} + +#include "cnc_grp_ref.c" + +static csch_chdr_t *cgrp_create(csch_sheet_t *sheet, csch_cgrp_t *parent) +{ + csch_cgrp_t *grp = csch_cgrp_alloc(sheet, parent, csch_oid_new(sheet, parent)); + if (grp == NULL) return NULL; + return &grp->hdr; +} + + +/* recursively remove an object from the rtree */ +static void csch_rtree_remove_recursive(csch_sheet_t *sheet, csch_chdr_t *obj) +{ + csch_cobj_rtree_del(obj->sheet, obj); + if (csch_obj_is_grp(obj)) { /* remove all part-objects from rtree */ + htip_entry_t *e; + csch_cgrp_t *grp = (csch_cgrp_t *)obj; + for(e = htip_first(&grp->id2obj); e != NULL; e = htip_next(&grp->id2obj, e)) + csch_rtree_remove_recursive(sheet, e->value); + } +} + +static void cgrp_remove_alloc(csch_undo_remove_t *slot) +{ + +} + +static void cgrp_remove_redo(csch_undo_remove_t *slot) +{ + csch_rtree_remove_recursive(slot->sheet, slot->obj); /* need to manually remove from rtree because children are also added */ + csch_cnc_common_remove_redo(slot, CSCH_REM_FROM_PARENT | CSCH_REM_DEL_EMPTY_PARENT); +} + +static void cgrp_remove_undo(csch_undo_remove_t *slot) +{ + csch_cnc_common_remove_undo(slot, CSCH_REM_FROM_PARENT | CSCH_REM_DEL_EMPTY_PARENT); + csch_cgrp_update(slot->sheet, (csch_cgrp_t *)slot->obj, 1); /* need to redo transformations for text object update */ +} + +static int cgrp_isc_with_box(csch_chdr_t *obj, csch_rtree_box_t *box_) +{ + g2d_box_t obb, box; + box.p1.x = box_->x1; box.p1.y = box_->y1; + box.p2.x = box_->x2; box.p2.y = box_->y2; + obb.p1.x = obj->bbox.x1; obb.p1.y = obj->bbox.y1; + obb.p2.x = obj->bbox.x2; obb.p2.y = obj->bbox.y2; + return g2d_isc_box_box(&obb, &box); +} + +static void cgrp_move(csch_sheet_t *sheet, csch_chdr_t *obj, csch_coord_t dx, csch_coord_t dy, int undoable) +{ + csch_cgrp_t *cgrp = (csch_cgrp_t *)obj; + csch_cgrp_modify(sheet, cgrp, &dx, &dy, NULL, NULL, NULL, undoable, 1); +} + +static void cgrp_copy(csch_sheet_t *sheet, csch_chdr_t *obj, csch_coord_t dx, csch_coord_t dy, int undoable) +{ + csch_cgrp_t *cgrp = csch_cgrp_dup(sheet, obj->parent, (csch_cgrp_t *)obj, 0); + if (cgrp != NULL) { + cgrp->x += dx; cgrp->y += dy; + csch_cgrp_update(sheet, cgrp, 1); + csch_op_inserted(sheet, obj->parent, &cgrp->hdr); + } +} + +RND_INLINE double cgrp_rotdir(csch_cgrp_t *cgrp) +{ + return cgrp->mirx ^ cgrp->miry ? -1.0 : 1.0; +} + +static void cgrp_rotate(csch_sheet_t *sheet, csch_chdr_t *obj, csch_coord_t rcx, csch_coord_t rcy, double da, int undoable) +{ + csch_cgrp_t *cgrp = (csch_cgrp_t *)obj; + csch_coord_t nx = cgrp->x, ny = cgrp->y; + double nrot, cs, sn, rad; + + nrot = cgrp->spec_rot + da * cgrp_rotdir(cgrp); + rad = -da / RND_RAD_TO_DEG; + cs = cos(rad); sn = sin(rad); + + csch_rotate_pt(&nx, &ny, rcx, rcy, cs, sn); + + csch_cgrp_modify(sheet, cgrp, &nx, &ny, &nrot, NULL, NULL, undoable, 0); +} + +static void cgrp_rotate90(csch_sheet_t *sheet, csch_chdr_t *obj, csch_coord_t rcx, csch_coord_t rcy, int n, int undoable) +{ + csch_cgrp_t *cgrp = (csch_cgrp_t *)obj; + csch_coord_t nx = cgrp->x, ny = cgrp->y; + double nrot; + + nrot = fmod(cgrp->spec_rot + (double)n * 90.0 * cgrp_rotdir(cgrp), 360.0); + csch_rotate90_pt(&nx, &ny, rcx, rcy, n); + + csch_cgrp_modify(sheet, cgrp, &nx, &ny, &nrot, NULL, NULL, undoable, 0); +} + +static void cgrp_mirror(csch_sheet_t *sheet, csch_chdr_t *obj, csch_coord_t mcx, csch_coord_t mcy, int mirx, int miry, int undoable) +{ + csch_cgrp_t *cgrp = (csch_cgrp_t *)obj; + csch_coord_t nx = cgrp->x, ny = cgrp->y; + int nmirx = cgrp->mirx, nmiry = cgrp->miry; + + csch_mirror_pt(&nx, &ny, mcx, mcy, mirx, miry); + if (mirx) nmirx = !nmirx; + if (miry) nmiry = !nmiry; + + csch_cgrp_modify(sheet, cgrp, &nx, &ny, NULL, &nmirx, &nmiry, undoable, 0); +} + +static g2d_calc_t mx33det(g2d_xform_t mx) +{ + double det = 0; + det += mx.v[0] * (mx.v[4] * mx.v[8] - mx.v[5] * mx.v[7]); + det -= mx.v[1] * (mx.v[3] * mx.v[8] - mx.v[5] * mx.v[6]); + det += mx.v[2] * (mx.v[3] * mx.v[7] - mx.v[4] * mx.v[6]); + return det; +} + +static g2d_xform_t mx33adj(g2d_xform_t mx) +{ + g2d_xform_t res; + res.v[0] = (mx.v[4] * mx.v[8] - mx.v[5] * mx.v[7]); + res.v[3] = (mx.v[3] * mx.v[8] - mx.v[5] * mx.v[6]); + res.v[6] = (mx.v[3] * mx.v[7] - mx.v[4] * mx.v[6]); + res.v[1] = (mx.v[1] * mx.v[8] - mx.v[2] * mx.v[7]); + res.v[4] = (mx.v[0] * mx.v[8] - mx.v[2] * mx.v[6]); + res.v[7] = (mx.v[0] * mx.v[7] - mx.v[1] * mx.v[6]); + res.v[2] = (mx.v[1] * mx.v[5] - mx.v[2] * mx.v[4]); + res.v[5] = (mx.v[0] * mx.v[5] - mx.v[2] * mx.v[3]); + res.v[8] = (mx.v[0] * mx.v[4] - mx.v[1] * mx.v[3]); + return res; +} + +RND_INLINE void csch_cgrp_inverse_matrix_(g2d_xform_t *dst, const csch_cgrp_t *cgrp) +{ + double det = mx33det(cgrp->xform.mx); + g2d_xform_t mx = mx33adj(cgrp->xform.mx); + int n; + + for(n = 0; n < 9; n++) { + mx.v[n] = mx.v[n] / det; + if ((n % 2) == 1) + mx.v[n] = -mx.v[n]; + } + + *dst = mx; +} + +void csch_cgrp_inverse_matrix(g2d_xform_t *dst, const csch_cgrp_t *cgrp) +{ + csch_cgrp_inverse_matrix_(dst, cgrp); +} + + +static void cgrp_inst2spec(csch_sheet_t *sheet, csch_chdr_t *obj, const csch_chdr_t *in, int undoable) +{ + const csch_cgrp_t *cgrp = (const csch_cgrp_t *)in; + csch_coord_t nx = cgrp->hdr.parent->xform.x, ny = cgrp->hdr.parent->xform.y; + int nmirx = cgrp->xform.mirx, nmiry = cgrp->xform.miry; + double nrot = cgrp->xform.rot; + g2d_vect_t v; + + v.x = cgrp->x; v.y = cgrp->y; + v = g2d_xform_vect2vect(cgrp->hdr.parent->xform.mx, v); + nx = v.x; + ny = v.y; + if (nmirx ^ nmiry) + nrot = -nrot; + + csch_cgrp_modify(sheet, (csch_cgrp_t *)obj, &nx, &ny, &nrot, &nmirx, &nmiry, undoable, 0); +} + + +const csch_ops_t csch_ops_cgrp = { + cgrp_create, cgrp_remove_alloc, cgrp_remove_redo, cgrp_remove_undo, + cgrp_isc_with_box, + cgrp_move, cgrp_copy, cgrp_rotate, cgrp_rotate90, cgrp_mirror, + cgrp_inst2spec +}; + + +const csch_ops_t csch_ops_cgrp_ref = { + NULL, cgrp_remove_alloc, cgrp_remove_redo, cgrp_remove_undo, + cgrp_isc_with_box, + cgrp_move, cgrp_copy, cgrp_rotate, cgrp_rotate90, cgrp_mirror +}; + + + +/*** Modify ***/ +typedef struct { + csch_cgrp_t *grp; /* it is safe to save the object pointer because it is persistent (through the removed object list) */ + + unsigned mirx:1, miry:1; + double spec_rot; + csch_coord_t x, y; +} undo_cgrp_modify_t; + + +static int undo_cgrp_modify_swap(void *udata) +{ + undo_cgrp_modify_t *u = udata; + + csch_cobj_redraw(u->grp); + + rnd_swap(csch_coord_t, u->x, u->grp->x); + rnd_swap(csch_coord_t, u->y, u->grp->y); + rnd_swap(int, u->mirx, u->grp->mirx); + rnd_swap(int, u->miry, u->grp->miry); + rnd_swap(double, u->spec_rot, u->grp->spec_rot); + + csch_cgrp_update(u->grp->hdr.sheet, u->grp, 1); + csch_conn_auto_recalc_geo(u->grp->hdr.sheet, &u->grp->hdr); + csch_sheet_set_changed(u->grp->hdr.sheet, 1); + + csch_cobj_redraw(u->grp); + return 0; +} + +static void undo_cgrp_modify_print(void *udata, char *dst, size_t dst_len) +{ + rnd_snprintf(dst, dst_len, "cgrp geometry change"); +} + +static const char core_cgrp_cookie[] = "libcschem/core/cnc_cgrp.c"; + +static const uundo_oper_t undo_cgrp_modify = { + core_cgrp_cookie, + NULL, + undo_cgrp_modify_swap, + undo_cgrp_modify_swap, + undo_cgrp_modify_print +}; + + +void csch_cgrp_modify(csch_sheet_t *sheet, csch_cgrp_t *grp, csch_coord_t *x, csch_coord_t *y, double *spec_rot, int *mirx, int *miry, int undoable, int relative) +{ + undo_cgrp_modify_t utmp, *u = &utmp; + + if (undoable) u = uundo_append(&sheet->undo, &undo_cgrp_modify, sizeof(undo_cgrp_modify_t)); + + u->grp = grp; + u->x = CSCH_UNDO_RMODIFY(grp, x); + u->y = CSCH_UNDO_RMODIFY(grp, y); + u->spec_rot = CSCH_UNDO_RMODIFY(grp, spec_rot); + u->mirx = CSCH_UNDO_MODIFY(grp, mirx); + u->miry = CSCH_UNDO_MODIFY(grp, miry); + + undo_cgrp_modify_swap(u); + if (undoable) csch_undo_inc_serial(sheet); +} + + +typedef struct { + csch_cgrp_t *grp; /* it is safe to save the object pointer because it is persistent (through the removed object list) */ + minuid_bin_t uuid, src_uuid; +} undo_cgrp_modify_uuid_t; + + +static int undo_cgrp_modify_uuid_swap(void *udata) +{ + undo_cgrp_modify_uuid_t *u = udata; + + minuid_swap(u->uuid, u->grp->uuid); + if (u->grp->hdr.type == CSCH_CTYPE_GRP) + minuid_swap(u->src_uuid, u->grp->data.grp.src_uuid); + + csch_cgrp_update(u->grp->hdr.sheet, u->grp, 1); + csch_sheet_set_changed(u->grp->hdr.sheet, 1); + + return 0; +} + +static void undo_cgrp_modify_uuid_print(void *udata, char *dst, size_t dst_len) +{ + rnd_snprintf(dst, dst_len, "cgrp uuid change"); +} + +static const uundo_oper_t undo_cgrp_modify_uuid = { + core_cgrp_cookie, + NULL, + undo_cgrp_modify_uuid_swap, + undo_cgrp_modify_uuid_swap, + undo_cgrp_modify_uuid_print +}; + + +void csch_cgrp_modify_uuid(csch_sheet_t *sheet, csch_cgrp_t *grp, minuid_bin_t *uuid, minuid_bin_t *src_uuid, int undoable) +{ + undo_cgrp_modify_uuid_t utmp, *u = &utmp; + + if (undoable) u = uundo_append(&sheet->undo, &undo_cgrp_modify_uuid, sizeof(undo_cgrp_modify_uuid_t)); + + u->grp = grp; + minuid_cpy(u->uuid, (uuid != NULL) ? *uuid : grp->uuid); + if (u->grp->hdr.type == CSCH_CTYPE_GRP) + minuid_cpy(u->src_uuid, (src_uuid != NULL) ? *src_uuid : grp->data.grp.src_uuid); + + undo_cgrp_modify_uuid_swap(u); + if (undoable) csch_undo_inc_serial(sheet); +} + + +/*** transformations ***/ +void csch_cgrp_inverse_xform(csch_cgrp_t *parent, csch_coord_t *x, csch_coord_t *y, long num_crds) +{ + g2d_xform_t mx; + + csch_cgrp_inverse_matrix(&mx, parent); + + for(; num_crds > 0; num_crds--,x++,y++) { + g2d_vect_t v1; + v1.x = *x; v1.y = *y; + v1 = g2d_xform_vect2vect(mx, v1); + *x = v1.x; *y = v1.y; + } +} + +void csch_cgrp_vinverse_xform(csch_cgrp_t *parent, ...) +{ + g2d_xform_t mx; + va_list ap; + + csch_cgrp_inverse_matrix(&mx, parent); + va_start(ap, parent); + + for(;;) { + g2d_vect_t v1; + csch_coord_t *x, *y; + + x = va_arg(ap, csch_coord_t *); if (x == NULL) break; + y = va_arg(ap, csch_coord_t *); if (y == NULL) break; + + v1.x = *x; v1.y = *y; + v1 = g2d_xform_vect2vect(mx, v1); + *x = v1.x; *y = v1.y; + } + + va_end(ap); +} + +/* based on https://math.stackexchange.com/questions/13150/extracting-rotation-scale-values-from-2d-transformation-matrix/13165#13165 */ +double csch_cgrp_extract_rot(g2d_xform_t mx) +{ + return atan2(mx.v[3], mx.v[4]) * RND_RAD_TO_DEG; +} + +void csch_cgrp_extract_scale(g2d_xform_t mx, double *sx, double *sy) +{ + *sx = sqrt(mx.v[0] * mx.v[0] + mx.v[1] * mx.v[1]); + *sy = sqrt(mx.v[3] * mx.v[3] + mx.v[4] * mx.v[4]); + + /* This is needed for mirroring */ + if (mx.v[0] < 0) *sx = -(*sx); + if (mx.v[4] < 0) *sy = -(*sy); +} Index: tags/1.0.5/src/libcschem/cnc_grp.h =================================================================== --- tags/1.0.5/src/libcschem/cnc_grp.h (nonexistent) +++ tags/1.0.5/src/libcschem/cnc_grp.h (revision 10414) @@ -0,0 +1,111 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2018 Tibor 'Igor2' Palinkas + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + + +#ifndef CSCH_CONCRETE_GRP_H +#define CSCH_CONCRETE_GRP_H +#include "libcschem/concrete.h" + +/*** standard calls on groups ***/ + +csch_cgrp_t *csch_cgrp_alloc(csch_sheet_t *sheet, csch_cgrp_t *parent, csch_oid_t oid); +void csch_cgrp_uninit(csch_cgrp_t *grp); +void csch_cgrp_free(csch_cgrp_t *grp); +csch_cgrp_t *csch_cgrp_get(csch_sheet_t *sheet, csch_cgrp_t *parent, csch_oid_t oid); +void csch_cgrp_update(csch_sheet_t *sheet, csch_cgrp_t *grp, int do_xform); +void csch_cgrp_attrib_update(csch_sheet_t *sheet, csch_cgrp_t *grp, int prio, const char *key, const char *val); +csch_cgrp_t *csch_cgrp_dup(csch_sheet_t *sheet, csch_cgrp_t *parent, const csch_cgrp_t *src, int keep_id); + +csch_cgrp_t *csch_cgrp_init(csch_sheet_t *sheet, csch_cgrp_t *grp, csch_cgrp_t *parent, csch_oid_t oid); + +void csch_cgrp_render_all(csch_sheet_t *sheet, csch_cgrp_t *grp); +void csch_cgrp_xform_update(csch_sheet_t *sheet, csch_cgrp_t *grp); +void csch_cgrp_role_update(csch_sheet_t *sheet, csch_cgrp_t *grp); + +/* Remove and free all child objects */ +void csch_cgrp_clear(csch_cgrp_t *grp); + +/* Returns the idxth abstract object generated for a grp from sheet's + project's last compilation. Returns NULL if no such object or not compiled */ +csch_ahdr_t *csch_cgrp_get_abstract(csch_sheet_t *sheet, const csch_cgrp_t *grp, long idx); + +unsigned csch_cgrp_hash_(csch_cgrp_t *grp, csch_hash_ignore_t ignore); +int csch_cgrp_keyeq_(csch_cgrp_t *g1, csch_cgrp_t *g2, csch_hash_ignore_t ignore); + + +/*** standard calls on group refs ***/ + +csch_cgrp_t *csch_cgrp_ref_alloc(csch_sheet_t *sheet, csch_cgrp_t *parent, csch_oid_t oid); +void csch_cgrp_ref_free(csch_cgrp_t *grp); +void csch_cgrp_ref_update(csch_sheet_t *sheet, csch_cgrp_t *grpref, int do_xform); + +void csch_cgrp_modify(csch_sheet_t *sheet, csch_cgrp_t *grp, csch_coord_t *x, csch_coord_t *y, double *rot, int *mirx, int *miry, int undoable, int relative); +void csch_cgrp_modify_uuid(csch_sheet_t *sheet, csch_cgrp_t *grp, minuid_bin_t *uuid, minuid_bin_t *src_uuid, int undoable); + + +/*** non-standard calls on group refs ***/ + +/* remove all objects from the ref; NOTE: this converts some conns from + object pointers back to object path list. The caller needs to update + dirty conns. */ +void csch_cgrp_ref_clean(csch_sheet_t *sheet, csch_cgrp_t *grpref); + +/* copy objects from the referenced group; may call csch_cgrp_ref_clean(), + thus may need conn dirty recalc, see csch_cgrp_ref_clean() */ +void csch_cgrp_ref_render(csch_sheet_t *sheet, csch_cgrp_t *grpref); + +/* Return an attribute by key, before the merge, considering both grpref and the referenced group */ +csch_attrib_t *csch_cgrp_ref_get_attr(csch_cgrp_t *grpref, const char *key); + +/* Convert a group ref into a group in-place */ +void csch_grp_ref_embed(csch_cgrp_t *grpref); + +/* Calculate cgrp's inverse transformation matrix in dst; useful for + determining how a sheet coord system oepration translates into a + group's coord system, e.g. when moving floaters */ +void csch_cgrp_inverse_matrix(g2d_xform_t *dst, const csch_cgrp_t *cgrp); + + +void csch_cgrp_bbox_update(csch_sheet_t *sheet, csch_cgrp_t *grp); + + +/* Resolve referee from text version (oidpath) to pointer */ +int csch_cgrp_ref_text2ptr(csch_sheet_t *sheet, csch_cgrp_t *grpref); + +/* Encode pointer reference into textual ref (resets pointer ref to NULL) */ +int csch_cgrp_ref_ptr2text(csch_sheet_t *sheet, csch_cgrp_t *grpref); + +/* inverse-transform pairs of coords using parent's xform matrix; the v + variant takes pairs of (csch_coord_t *x, csch_coord_t *y) and then a NULL */ +void csch_cgrp_inverse_xform(csch_cgrp_t *parent, csch_coord_t *x, csch_coord_t *y, long num_crds); +void csch_cgrp_vinverse_xform(csch_cgrp_t *parent, ...); + +/* Extract discrete transformations from a matrix */ +double csch_cgrp_extract_rot(g2d_xform_t mx); +void csch_cgrp_extract_scale(g2d_xform_t mx, double *sx, double *sy); + + +#endif Index: tags/1.0.5/src/libcschem/cnc_grp_child.h =================================================================== --- tags/1.0.5/src/libcschem/cnc_grp_child.h (nonexistent) +++ tags/1.0.5/src/libcschem/cnc_grp_child.h (revision 10414) @@ -0,0 +1,271 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + + +#ifndef CSCH_CONCRETE_GRP_CHILD_H +#define CSCH_CONCRETE_GRP_CHILD_H +#include +#include +#include +#include + +#include +#include +#include + +/* child entry transformation of a group ref */ +typedef struct csch_child_xform_s { + csch_oidpath_t path; + double rot; + csch_coord_t movex, movey; + unsigned remove:1; + unsigned mirx:1; + unsigned miry:1; + + unsigned cache:1; /* if 1, this entry is only a copy cached from some sub-ref and shall not be saved */ + unsigned removed:1; /* if 1, this entry got removed (free slot) */ +} csch_child_xform_t; + + +/* For internal use: undoable modification of a child xform entry */ +void csch_child_xform_modify(csch_sheet_t *sheet, csch_cgrp_t *grpref, long idx, csch_chdr_t *obj, + double *rot, csch_coord_t *movex, csch_coord_t *movey, int *remove, + int *mirx, int *miry, int *cache, int undoable, int relative); + + + +RND_INLINE csch_child_xform_t *csch_grp_ref_get_child_xform(csch_cgrp_t *grp, long idx) +{ + if (grp->hdr.type != CSCH_CTYPE_GRP_REF) return NULL; + if ((idx < 0) || (idx >= grp->data.ref.child_xform.used)) return NULL; + return grp->data.ref.child_xform.array[idx]; +} + +RND_INLINE g2d_xform_t csch_grp_ref_parent_mx(csch_chdr_t *obj, csch_child_xform_t **cx_out) +{ + g2d_xform_t mx; + csch_child_xform_t *cx; + static csch_child_xform_t zero_cx = {0}; + + if (obj->grp_ref_xform.g == NULL) { + if (cx_out != NULL) *cx_out = &zero_cx; + return obj->parent->xform.mx; + } + + cx = csch_grp_ref_get_child_xform(obj->grp_ref_xform.g, obj->grp_ref_xform.idx); + if (cx_out != NULL) *cx_out = cx; + + if (cx == NULL) return obj->parent->xform.mx; + + mx = obj->parent->xform.mx; + + if ((cx->movex != 0) || (cx->movey != 0)) + mx = g2d_xform_translate(mx, cx->movex, cx->movey); + if (cx->mirx) + mx = g2d_xform_mirrory(mx); + if (cx->miry) + mx = g2d_xform_mirrorx(mx); + if (cx->rot != 0) + mx = g2d_xform_rotate(mx, -cx->rot / RND_RAD_TO_DEG); + + /* ->remove is not yet implemented because it may be confusing */ + + return mx; +} + +RND_INLINE int csch_grp_ref_child_xform_is_empty(csch_child_xform_t *cx) +{ + if (cx->movex != 0) return 0; + if (cx->movey != 0) return 0; + if (cx->rot != 0) return 0; + if (cx->mirx != 0) return 0; + if (cx->miry != 0) return 0; + if (cx->remove != 0) return 0; + return 1; +} + + +/* find the topmost group reference above obj (or return NULL if no group ref + is found in the ancestry) */ +RND_INLINE csch_cgrp_t *csch_grp_ref_get_top(csch_sheet_t *sheet, csch_chdr_t *obj) +{ + csch_cgrp_t *g, *last = NULL; + + g = (csch_cgrp_t *)obj; + if ((g == &sheet->direct) || (g == &sheet->indirect) || (obj->parent == NULL)) + return NULL; + + for(g = obj->parent; (g != &sheet->direct) && (g != &sheet->indirect); g = g->hdr.parent) + if (g->hdr.type == CSCH_CTYPE_GRP_REF) + last = g; + + return last; +} + + +RND_INLINE csch_child_xform_t *csch_grp_ref_child_get_cx(csch_cgrp_t *grpref, csch_chdr_t *obj, long *idx_out) +{ + csch_oidpath_t path = {0}; + csch_cgrp_t *g; + long n, v; + csch_child_xform_t *cx; + + csch_vtoid_append(&path.vt, obj->oid); + + for(g = obj->parent; g != grpref; g = g->hdr.parent) { + assert(g != NULL); /* happens if grpgref is not an ancestor of obj - caller messed up */ + csch_vtoid_append(&path.vt, g->hdr.oid); + } + + + /* need to reverse the list so it goes from the group to the object */ + for(n = 0, v = path.vt.used/2; n < v; n++) + rnd_swap(csch_oid_t, path.vt.array[n], path.vt.array[path.vt.used-n-1]); + + /* look for an existing entry by path; assume there are only a few, linear + search is okay */ + for(n = 0; n < grpref->data.ref.child_xform.used; n++) { + csch_child_xform_t *cx = grpref->data.ref.child_xform.array[n]; + if (csch_oidpath_eq(&path, &cx->path)) { + csch_vtoid_uninit(&path.vt); + *idx_out = n; + return cx; + } + } + + /* not found, need to alloc a new item */ + cx = calloc(sizeof(csch_child_xform_t), 1); + cx->path.vt = path.vt; + *idx_out = grpref->data.ref.child_xform.used; + vtp0_append(&grpref->data.ref.child_xform, cx); + obj->grp_ref_xform.g = grpref; + obj->grp_ref_xform.idx = *idx_out; + + return cx; +} + +#define CSCH_PREPARE_GRPREF \ + csch_cgrp_t *grpref = obj->grp_ref_xform.g; \ + long idx = obj->grp_ref_xform.idx; \ + csch_child_xform_t *cx; \ + if (grpref == NULL) { \ + grpref = csch_grp_ref_get_top(sheet, obj); \ + idx = -1; \ + } \ + if (grpref == NULL) \ + return 0; \ + if ((idx >= 0) && (idx < grpref->data.ref.child_xform.used)) \ + cx = grpref->data.ref.child_xform.array[idx]; \ + else \ + cx = csch_grp_ref_child_get_cx(grpref, obj, &idx); \ + assert(cx != NULL); + +/* returns 1 if child is part of a group ref (directly or indirectly) */ +RND_INLINE int csch_obj_is_grp_ref_child(csch_sheet_t *sheet, csch_chdr_t *obj) +{ + CSCH_PREPARE_GRPREF; + return grpref != NULL; +} + +/* returns 0 if obj is not affected and normal move should be performed */ +RND_INLINE int csch_grp_ref_child_moved(csch_sheet_t *sheet, csch_chdr_t *obj, csch_coord_t dx, csch_coord_t dy, int undoable) +{ + int zero = 0; + CSCH_PREPARE_GRPREF; + + csch_child_xform_modify(sheet, grpref, idx, obj, + NULL, &dx, &dy, NULL, NULL, NULL, &zero, 1, 1); + + csch_cobj_update(sheet, obj, 1); + + return 1; +} + +/* returns 0 if obj is not affected and normal move should be performed */ +RND_INLINE int csch_grp_ref_child_rotated(csch_sheet_t *sheet, csch_chdr_t *obj, csch_coord_t rcx, csch_coord_t rcy, double da, int undoable) +{ + int zero = 0; + csch_coord_t x, y; + double rot, rad; + CSCH_PREPARE_GRPREF; + + rot = cx->rot + da; + rad = -rot / RND_RAD_TO_DEG; + x = cx->movex; + y = cx->movey; + csch_rotate_pt(&x, &y, rcx, rcy, cos(rad), sin(rad)); + + csch_child_xform_modify(sheet, grpref, idx, obj, + &rot, &x, &y, NULL, NULL, NULL, &zero, 1, 0); + + csch_cobj_update(sheet, obj, 1); + + return 1; +} + +/* returns 0 if obj is not affected and normal move should be performed */ +RND_INLINE int csch_grp_ref_child_rotated90(csch_sheet_t *sheet, csch_chdr_t *obj, csch_coord_t rcx, csch_coord_t rcy, int steps, int undoable) +{ + int zero = 0; + csch_coord_t x, y; + double rot; + CSCH_PREPARE_GRPREF; + + rot = fmod(cx->rot + (double)steps * 90.0, 360.0); + x = cx->movex; + y = cx->movey; + csch_rotate90_pt(&x, &y, rcx, rcy, steps); + + csch_child_xform_modify(sheet, grpref, idx, obj, + &rot, &x, &y, NULL, NULL, NULL, &zero, 1, 0); + + csch_cobj_update(sheet, obj, 1); + + return 1; +} + +/* returns 0 if obj is not affected and normal move should be performed */ +RND_INLINE int csch_grp_ref_child_mirrored(csch_sheet_t *sheet, csch_chdr_t *obj, csch_coord_t mcx, csch_coord_t mcy, int mirx, int miry, int undoable) +{ + int zero = 0; + csch_coord_t x, y; + CSCH_PREPARE_GRPREF; + + x = cx->movex; + y = cx->movey; + csch_mirror_pt(&x, &y, mcx, mcy, mirx, miry); + + csch_child_xform_modify(sheet, grpref, idx, obj, + NULL, &x, &y, NULL, &mirx, &miry, &zero, 1, 0); + + csch_cobj_update(sheet, obj, 1); + + return 1; +} + +#undef CSCH_PREPARE_GRPREF + +#endif Index: tags/1.0.5/src/libcschem/cnc_grp_ref.c =================================================================== --- tags/1.0.5/src/libcschem/cnc_grp_ref.c (nonexistent) +++ tags/1.0.5/src/libcschem/cnc_grp_ref.c (revision 10414) @@ -0,0 +1,418 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2018..2020,2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/* Included from cnc_grp.c; contains grp_ref specific functions only */ + +csch_cgrp_t *csch_cgrp_ref_alloc(csch_sheet_t *sheet, csch_cgrp_t *parent, csch_oid_t oid) +{ + csch_cgrp_t *grp; + + grp = htip_get(&parent->id2obj, oid); + if (grp != NULL) + return NULL; + grp = calloc(sizeof(csch_cgrp_t), 1); + minuid_gen(&csch_minuid, grp->uuid); + + csch_cobj_init(&grp->hdr, sheet, parent, oid, CSCH_CTYPE_GRP_REF); + csch_attrib_init(&grp->attr); + htip_init(&grp->id2obj, longhash, longkeyeq); + htsp_init(&grp->name2pen, strhash, strkeyeq); + csch_cgrp_xform_update(sheet, grp); + return grp; +} + + +void csch_cgrp_ref_free(csch_cgrp_t *grpref) +{ + long n; + + assert(grpref->hdr.type == CSCH_CTYPE_GRP_REF); + + csch_cgrp_uninit(grpref); + + for(n = 0; n < grpref->data.ref.child_xform.used; n++) { + csch_child_xform_t *cx = grpref->data.ref.child_xform.array[n]; + if (cx != NULL) { + csch_oidpath_free(&cx->path); + free(cx); + } + } + vtp0_uninit(&grpref->data.ref.child_xform); + + free(grpref); +} + +csch_cgrp_t *csch_cgrp_refget(csch_sheet_t *sheet, csch_cgrp_t *parent, csch_oid_t oid) +{ + csch_cgrp_t *grp = htip_get(&parent->id2obj, oid); + + if ((grp != NULL) && (grp->hdr.type != CSCH_CTYPE_GRP)) + return NULL; + return grp; +} + +/* convert all connections back to oidpath format because the object is + free'd but will be re-created later */ +static void csch_cgrp_ref_clean_conns(csch_sheet_t *sheet, csch_chdr_t *o) +{ + long n; + + for(n = o->conn.used-1; n >= 0; n--) /* go backward because csch_conn_ptr2text() removes from this list */ + if (o->conn.array[n] != NULL) + csch_conn_ptr2text(sheet, o->conn.array[n]); + + if (csch_obj_is_grp(o)) { + htip_entry_t *e; + csch_cgrp_t *g = (csch_cgrp_t *)o; + + for(e = htip_first(&g->id2obj); e != NULL; e = htip_next(&g->id2obj, e)) + csch_cgrp_ref_clean_conns(sheet, e->value); + } + +} + +void csch_cgrp_ref_clean(csch_sheet_t *sheet, csch_cgrp_t *grpref) +{ + htip_entry_t *e; + + assert(grpref->hdr.type == CSCH_CTYPE_GRP_REF); + + for(e = htip_first(&grpref->id2obj); e != NULL; e = htip_next(&grpref->id2obj, e)) { + csch_chdr_t *o = e->value; + csch_cgrp_ref_clean_conns(sheet, o); + csch_cobj_free(o); + } +} + + +void csch_cgrp_ref_update(csch_sheet_t *sheet, csch_cgrp_t *grpref, int do_xform) +{ + csch_cgrp_update(sheet, grpref, do_xform); +} + +csch_attrib_t *csch_cgrp_ref_get_attr(csch_cgrp_t *grpref, const char *key) +{ + csch_attrib_t *instance, *refd = NULL; + + instance = htsp_get(&grpref->attr, key); + + assert(grpref->data.ref.grp != NULL); /* indicates a bug; stop in debug mode */ + if (grpref->data.ref.grp != NULL) + refd = htsp_get(&grpref->data.ref.grp->attr, key); + + if (refd == NULL) return instance; + if (instance == NULL) return refd; + + return (instance->prio <= refd->prio) ? instance : refd; +} + +int csch_cgrp_ref_text2ptr(csch_sheet_t *sheet, csch_cgrp_t *grpref) +{ + csch_oidpath_t ref_oidp = {0}; + + csch_vtoid_init(&ref_oidp.vt); + grpref->data.ref.grp = NULL; + if (csch_oidpath_parse(&ref_oidp, grpref->data.ref.ref_str) != 0) { + rnd_msg_error("Invalid oid path in group ref: '%s' (syntax)\n", grpref->data.ref.ref_str); + return -1; + } + + /* resolve the target group */ + grpref->data.ref.grp = (csch_cgrp_t *)csch_oidpath_resolve(sheet, &ref_oidp); + csch_oidpath_free(&ref_oidp); + if (grpref->data.ref.grp == NULL) { + rnd_msg_error("Invalid oid path in group ref: '%s' (does not resolve)\n", grpref->data.ref.ref_str); + return -1; + } + if (grpref->data.ref.grp->hdr.type != CSCH_CTYPE_GRP) { + grpref->data.ref.grp = NULL; + rnd_msg_error("Invalid oid path in group ref: '%s' (refered object is not a group)\n", grpref->data.ref.ref_str); + return -1; + } + + /* xorcache: free text version */ + free(grpref->data.ref.ref_str); + grpref->data.ref.ref_str = NULL; + + return 0; +} + +int csch_cgrp_ref_ptr2text(csch_sheet_t *sheet, csch_cgrp_t *grpref) +{ + csch_oidpath_t oidp = {0}; + + if (grpref->data.ref.grp == NULL) + return -1; + + csch_oidpath_from_obj(&oidp, &grpref->data.ref.grp->hdr); + grpref->data.ref.ref_str = csch_oidpath_to_str(&oidp); + csch_oidpath_free(&oidp); + + if (grpref->data.ref.ref_str == NULL) + return -1; + + grpref->data.ref.grp = NULL; + return 0; +} + + +RND_INLINE void csch_cgrp_childr_xform_apply(csch_sheet_t *sheet, csch_cgrp_t *grpref, csch_child_xform_t *cx, csch_chdr_t *child, long cx_idx) +{ + child->grp_ref_xform.g = grpref; + child->grp_ref_xform.idx = cx_idx; +} + +RND_INLINE void csch_cgrp_children_xform_apply(csch_sheet_t *sheet, csch_cgrp_t *grpref) +{ + long n; + for(n = 0; n < grpref->data.ref.child_xform.used; n++) { + csch_child_xform_t *cx = grpref->data.ref.child_xform.array[n]; + if ((cx != NULL) && !cx->removed) { + csch_chdr_t *child = csch_oidpath_resolve_in(grpref, &cx->path); + if ((child == NULL) || (child == &grpref->hdr)) { + /* referenced child not found */ + if (!cx->remove) + rnd_message(RND_MSG_ERROR, "csch_cgrp_children_xform_apply(): child not found\n"); + } + else { + /* referenced child found */ + if (cx->remove) + csch_cobj_free(child); + else + csch_cgrp_childr_xform_apply(sheet, grpref, cx, child, n); + } + } + } +} + +TODO( + "TODO#38: cache sub-ref-child-xforms in top level group_ref;" + "for now just disallow and assume the editor will do it on top and/or" + "there will be only loclib kind of single-level group refs") +static void csch_cgrp_ref_cache_deep_child_xforms(csch_sheet_t *sheet, csch_cgrp_t *top, csch_cgrp_t *from) +{ + htip_entry_t *e; + for(e = htip_first(&from->id2obj); e != NULL; e = htip_next(&from->id2obj, e)) { + csch_cgrp_t *grp = e->value; + if (!csch_obj_is_grp(&grp->hdr)) continue; + if ((grp->data.ref.child_xform.used > 0) && (from != top)) { + rnd_message(RND_MSG_ERROR, "csch_cgrp_ref_cache_deep_child_xforms(): grpref in grpref with child transformations is not yet supported\n"); + } + } +} + +/* Remove each entry marked as cache */ +void csch_cgrp_ref_clean_child_xform_cache(csch_sheet_t *sheet, csch_cgrp_t *grpref) +{ + long n; + + for(n = 0; n < grpref->data.ref.child_xform.used; n++) { + csch_child_xform_t *cx = grpref->data.ref.child_xform.array[n]; + if (cx->cache) { + csch_chdr_t *child = csch_oidpath_resolve_in(grpref, &cx->path); + if ((child != NULL) && (child != &grpref->hdr)) { + child->grp_ref_xform.g = NULL; + child->grp_ref_xform.idx = -1; + } + cx->cache = 0; + cx->removed = 1; + } + } +} + + +void csch_cgrp_ref_render(csch_sheet_t *sheet, csch_cgrp_t *grpref) +{ + csch_attrib_t *arole; + assert(grpref->hdr.type == CSCH_CTYPE_GRP_REF); + + /* update the referenced grp cache from the string version, if needed */ + if (grpref->data.ref.grp == NULL) + if (csch_cgrp_ref_text2ptr(sheet, grpref) != 0) + return; + + /* render: copy and transform all objects from the target group */ + csch_cgrp_ref_clean(sheet, grpref); + csch_cgrp_dup_into(sheet, grpref, grpref->data.ref.grp, 0); + + arole = csch_cgrp_ref_get_attr(grpref, "role"); + if (arole != NULL) + csch_role_set(grpref, arole->val); + csch_cgrp_role_update(sheet, grpref); + + csch_cgrp_ref_clean_child_xform_cache(sheet, grpref); + csch_cgrp_ref_cache_deep_child_xforms(sheet, grpref, grpref); + + csch_cgrp_children_xform_apply(sheet, grpref); + + csch_cgrp_ref_update(sheet, grpref, 1); +} + +static void grp_ref_child_embed(csch_chdr_t *obj, csch_cgrp_t *egrp) +{ + csch_sheet_t *sheet = obj->sheet; + if (obj->grp_ref_xform.g == egrp) { + obj->grp_ref_xform.g = NULL; + + TODO("loclib: need to apply cx transformations on the object as if it was its own"); +#if 0 + csch_child_xform_t *cx = csch_grp_ref_get_child_xform(obj->grp_ref_xform.g, obj->grp_ref_xform.idx); + egrp->hdr.type = CSCH_CTYPE_GRP; /* need to fake this temporarily so that the transformation is not captured and made to the grp ref we are trying to remove */ + csch_rotate(...) + egrp->hdr.type = CSCH_CTYPE_GRP_REF; +#endif + } + + /* recurse */ + if (csch_obj_is_grp(obj)) { + csch_cgrp_t *g = (csch_cgrp_t *)obj; + htip_entry_t *e; + + for(e = htip_first(&g->id2obj); e != NULL; e = htip_next(&g->id2obj, e)) + grp_ref_child_embed(e->value, egrp); + } + + csch_sheet_set_changed(sheet, 1); +} + +void csch_grp_ref_embed(csch_cgrp_t *grpref) +{ + csch_oid_t nid = 0; + htip_entry_t *e; + + assert(grpref->hdr.type == CSCH_CTYPE_GRP_REF); + + /* copy attributes that were originally inherited */ + { + htsp_entry_t *e; + csch_cgrp_t *referee = grpref->data.ref.grp; + + for(e = htsp_first(&referee->attr); e; e = htsp_next(&referee->attr, e)) { + csch_attrib_t *asrc = e->value; + csch_attrib_t *adst = csch_attrib_get(&grpref->attr, e->key); + if (adst == NULL) { + csch_attrib_t *anew = csch_attrib_dup(asrc); + htsp_set(&grpref->attr, anew->key, anew); + } + } + } + + /* find the largest ID */ + for(e = htip_first(&grpref->id2obj); e != NULL; e = htip_next(&grpref->id2obj, e)) + if (e->key > nid) + nid = e->key; + + /* remove group ref transformation */ + grp_ref_child_embed(&grpref->hdr, grpref); + + grpref->hdr.type = CSCH_CTYPE_GRP; + grpref->data.grp.next_id = nid+1; + csch_cgrp_update(grpref->hdr.sheet, grpref, 1); +} + + +/*** Undoable child xform edit ***/ +typedef struct { + csch_sheet_t *sheet; + csch_cgrp_t *grpref; + long idx; + csch_chdr_t *obj; + csch_child_xform_t cx; +} undo_child_xform_modify_t; + + +static int undo_child_xform_modify_swap(void *udata) +{ + undo_child_xform_modify_t *u = udata; + csch_child_xform_t *cx = u->grpref->data.ref.child_xform.array[u->idx]; + + rnd_swap(double, cx->rot, u->cx.rot); + rnd_swap(csch_coord_t, cx->movex, u->cx.movex); + rnd_swap(csch_coord_t, cx->movey, u->cx.movey); + rnd_swap(int, cx->mirx, u->cx.mirx); + rnd_swap(int, cx->miry, u->cx.miry); + rnd_swap(int, cx->remove, u->cx.remove); + rnd_swap(int, cx->cache, u->cx.cache); + rnd_swap(int, cx->removed, u->cx.removed); + + csch_cobj_update(u->sheet, u->obj, 1); + + return 0; +} + +static void undo_child_xform_modify_print(void *udata, char *dst, size_t dst_len) +{ + undo_child_xform_modify_t *u = udata; + csch_child_xform_t *cx = u->grpref->data.ref.child_xform.array[u->idx]; + + rnd_snprintf(dst, dst_len, "group ref child xform move=%d;%d<->%d;%d rot=%.02f<->%.02f mir=%d;%d<->%d;%d remove=%d<->%d cache=%d<->%d removed=%d<->%d", + u->cx.movex, u->cx.movey, cx->movex, cx->movey, u->cx.rot, cx->rot, + u->cx.mirx, cx->mirx, u->cx.miry, cx->miry, + u->cx.remove, cx->remove, u->cx.cache, cx->cache, u->cx.removed, cx->removed); +} + +static const char core_child_xform_cookie[] = "libcschem/core/cnc_text.c"; + +static const uundo_oper_t undo_child_xform_modify = { + core_child_xform_cookie, + NULL, + undo_child_xform_modify_swap, + undo_child_xform_modify_swap, + undo_child_xform_modify_print +}; + + +void csch_child_xform_modify(csch_sheet_t *sheet, csch_cgrp_t *grpref, long idx, csch_chdr_t *obj, + double *rot, csch_coord_t *movex, csch_coord_t *movey, int *remove, + int *mirx, int *miry, int *cache, int undoable, int relative) +{ + undo_child_xform_modify_t utmp, *u = &utmp; + csch_child_xform_t *cx; + + if (undoable) u = uundo_append(&sheet->undo, &undo_child_xform_modify, sizeof(undo_child_xform_modify_t)); + + cx = grpref->data.ref.child_xform.array[idx]; + + u->sheet = sheet; + u->grpref = grpref; + u->idx = idx; + u->obj = obj; + + u->cx.movex = (movex == NULL) ? cx->movex : (relative ? (cx->movex + *movex) : *movex); + u->cx.movey = (movey == NULL) ? cx->movey : (relative ? (cx->movey + *movey) : *movey); + u->cx.rot = CSCH_UNDO_RMODIFY(cx, rot); + u->cx.mirx = CSCH_UNDO_MODIFY(cx, mirx); + u->cx.miry = CSCH_UNDO_MODIFY(cx, miry); + u->cx.remove = CSCH_UNDO_MODIFY(cx, remove); + u->cx.cache = CSCH_UNDO_MODIFY(cx, cache); + u->cx.removed = cx->removed; + + undo_child_xform_modify_swap(u); + if (undoable) csch_undo_inc_serial(sheet); +} + Index: tags/1.0.5/src/libcschem/cnc_line.c =================================================================== --- tags/1.0.5/src/libcschem/cnc_line.c (nonexistent) +++ tags/1.0.5/src/libcschem/cnc_line.c (revision 10414) @@ -0,0 +1,451 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2018,2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + + +#include "config.h" + +#include +#include +#include + +#include "event.h" +#include "concrete.h" +#include "cnc_line.h" +#include "cnc_obj.h" +#include "cnc_grp_child.h" +#include "cnc_grp.h" +#include "cnc_conn.h" +#include "op_common.h" +#include "operation.h" +#include "undo.h" +#include "rotate.h" +#include "util_wirenet.h" + +#include "gengeo2d/sline.h" +#include "gengeo2d/xform.h" + +csch_line_t *csch_line_alloc(csch_sheet_t *sheet, csch_cgrp_t *parent, csch_oid_t oid) +{ + csch_line_t *line; + + line = htip_get(&parent->id2obj, oid); + if (line != NULL) + return NULL; + line = calloc(sizeof(csch_line_t), 1); + + csch_cobj_init(&line->hdr, sheet, parent, oid, CSCH_CTYPE_LINE); + return line; +} + +csch_line_t *csch_line_dup(csch_sheet_t *sheet, csch_cgrp_t *parent, const csch_line_t *src, int keep_id, int inst2spec) +{ + csch_line_t *dst = csch_line_alloc(sheet, parent, CSCH_KEEP_OID(parent, src->hdr.oid)); + + csch_chdr_copy_meta4dup(&dst->hdr, &src->hdr); + + if (inst2spec) { + g2d_xform_t mx; + g2d_vect_t v1 = src->inst.c.p1, v2 = src->inst.c.p2; + + csch_cgrp_inverse_matrix(&mx, parent); + v1 = g2d_xform_vect2vect(mx, v1); + v2 = g2d_xform_vect2vect(mx, v2); + dst->spec.p1 = v1; + dst->spec.p2 = v2; + csch_line_update(sheet, dst, 1); + } + else { + dst->inst = src->inst; + dst->spec = src->spec; + } + + return dst; +} + + +void csch_line_free(csch_line_t *line) +{ + csch_cobj_uninit(&line->hdr); + free(line); +} + +csch_line_t *csch_line_get(csch_sheet_t *sheet, csch_cgrp_t *grp, csch_oid_t oid) +{ + csch_line_t *line = htip_get(&grp->id2obj, oid); + if ((line != NULL) && (line->hdr.type != CSCH_CTYPE_LINE)) + return NULL; + return line; +} + +void csch_line_update_xform(csch_sheet_t *sheet, csch_line_t *line) +{ + if (line->hdr.parent != NULL) { + g2d_xform_t mx = csch_grp_ref_parent_mx(&line->hdr, NULL); + line->inst.c.p1 = g2d_xform_vect2vect(mx, line->spec.p1); + line->inst.c.p2 = g2d_xform_vect2vect(mx, line->spec.p2); + } + else + line->inst.c = line->spec; + if (line->hdr.stroke != NULL) { + line->inst.s.width = line->hdr.stroke->size; + line->inst.s.cap = (line->hdr.stroke->shape == CSCH_PSHP_ROUND) ? G2D_CAP_ROUND : G2D_CAP_SQUARE; + } +} + +void csch_line_update_bbox(csch_sheet_t *sheet, csch_line_t *line) +{ + g2d_box_t gb; + + csch_obj_bbox_reset(line); + gb = g2d_sline_bbox(&line->inst); + line->hdr.bbox.x1 = gb.p1.x; line->hdr.bbox.y1 = gb.p1.y; + line->hdr.bbox.x2 = gb.p2.x; line->hdr.bbox.y2 = gb.p2.y; +} + +void csch_line_center_bbox(csch_sheet_t *sheet, const csch_line_t *line, csch_rtree_box_t *dst) +{ + g2d_box_t gb = g2d_cline_bbox(&line->inst.c); + + dst->x1 = gb.p1.x; dst->y1 = gb.p1.y; + dst->x2 = gb.p2.x; dst->y2 = gb.p2.y; +} + +void csch_line_update(csch_sheet_t *sheet, csch_line_t *line, int do_xform) +{ + csch_cobj_update_pen(&line->hdr); + + if (do_xform) + csch_line_update_xform(sheet, line); + + csch_cobj_rtree_del(sheet, &line->hdr); + csch_line_update_bbox(sheet, line); + csch_cobj_rtree_add(sheet, &line->hdr); + + csch_cobj_bbox_changed(sheet, &line->hdr); +} + +int csch_line_get_endxy(const csch_line_t *line, int side, csch_coord_t *x, csch_coord_t *y) +{ + if (side == 0) { + *x = line->inst.c.p1.x; + *y = line->inst.c.p1.y; + } + else { + *x = line->inst.c.p2.x; + *y = line->inst.c.p2.y; + } + return 0; +} + + +static csch_chdr_t *line_create(csch_sheet_t *sheet, csch_cgrp_t *parent) +{ + csch_line_t *line = csch_line_alloc(sheet, parent, csch_oid_new(sheet, parent)); + if (line == NULL) return NULL; + return &line->hdr; +} + +static void line_remove_alloc(csch_undo_remove_t *slot) +{ +} + +static void line_remove_redo(csch_undo_remove_t *slot) +{ + csch_cgrp_t *parent_wn = NULL; + + if (slot->side_effects) { + parent_wn = slot->obj->parent; + csch_conn_auto_del_obj_all(slot->sheet, slot->obj); /* note: any object may be in conn, not only wires! */ + if ((parent_wn != NULL) && (parent_wn->role != CSCH_ROLE_WIRE_NET)) + parent_wn = NULL; /* do not recalc wirenet side effects for non-wirenets */ + } + + csch_cnc_common_remove_redo(slot, CSCH_REM_FROM_RTREE | CSCH_REM_FROM_PARENT | CSCH_REM_DEL_EMPTY_PARENT); + + if (parent_wn != NULL) + csch_wirenet_recalc_junctions(slot->sheet, parent_wn); +} + +static void line_remove_undo(csch_undo_remove_t *slot) +{ + csch_cnc_common_remove_undo(slot, CSCH_REM_FROM_RTREE | CSCH_REM_FROM_PARENT | CSCH_REM_DEL_EMPTY_PARENT); +} + +static int line_isc_with_box(csch_chdr_t *obj, csch_rtree_box_t *box) +{ + csch_line_t *line = (csch_line_t *)obj; + g2d_cline_t l1, l2; + g2d_box_t gbox; + g2d_calc_t w2; + + gbox.p1.x = box->x1; gbox.p1.y = box->y1; + gbox.p2.x = box->x2; gbox.p2.y = box->y2; + + /* line fully within the box and/or cheap case: endpoint of line within the box */ + if (g2d_point_in_box(&gbox, line->inst.c.p1) || g2d_point_in_box(&gbox, line->inst.c.p2)) return 1; + + /* box fully within the sline (any box point inside) */ + w2 = line->inst.s.width/2; + if (g2d_dist2_cline_pt(&line->inst.c, gbox.p1) <= w2*w2) return 1; + + + g2d_sline_sides(&line->inst, &l1, &l2); + + /* box side crosses sline sides */ + if (g2d_isc_cline_box(&l1, &gbox) || g2d_isc_cline_box(&l1, &gbox)) return 1; + + +TODO("check end cap circle"); + + return 0; +} + +static void line_move(csch_sheet_t *sheet, csch_chdr_t *obj, csch_coord_t dx, csch_coord_t dy, int undoable) +{ + csch_line_t *line = (csch_line_t *)obj; + csch_line_modify(sheet, line, &dx, &dy, &dx, &dy, undoable, 1, 0); + + if ((line->hdr.parent != NULL) && (line->hdr.parent->role == CSCH_ROLE_WIRE_NET)) + csch_wirenet_recalc_obj_conn(sheet, &line->hdr); + + /* no need to call csch_wirenet_recalc_line_chg() even in a wirenet, line_modify does that */ +} + +static void line_copy(csch_sheet_t *sheet, csch_chdr_t *obj, csch_coord_t dx, csch_coord_t dy, int undoable) +{ + csch_line_t *line = csch_line_dup(sheet, obj->parent, (csch_line_t *)obj, 0, 0); + if (line != NULL) { + line->spec.p1.x += dx; line->spec.p1.y += dy; + line->spec.p2.x += dx; line->spec.p2.y += dy; + csch_line_update(sheet, line, 1); + if (obj->parent->role == CSCH_ROLE_WIRE_NET) + csch_wirenet_recalc_line_chg(line->hdr.sheet, line); + csch_op_inserted(sheet, obj->parent, &line->hdr); + } +} + +static void line_rotate(csch_sheet_t *sheet, csch_chdr_t *obj, csch_coord_t rcx, csch_coord_t rcy, double da, int undoable) +{ + csch_line_t *line = (csch_line_t *)obj; + csch_coord_t ncx1 = line->spec.p1.x, ncy1 = line->spec.p1.y; + csch_coord_t ncx2 = line->spec.p2.x, ncy2 = line->spec.p2.y; + double rad = -da / RND_RAD_TO_DEG; + double cs = cos(rad), sn = sin(rad); + + csch_rotate_pt(&ncx1, &ncy1, rcx, rcy, cs, sn); + csch_rotate_pt(&ncx2, &ncy2, rcx, rcy, cs, sn); + + csch_line_modify(sheet, line, &ncx1, &ncy1, &ncx2, &ncy2, undoable, 0, 0); +} + +static void line_rotate90(csch_sheet_t *sheet, csch_chdr_t *obj, csch_coord_t rcx, csch_coord_t rcy, int n, int undoable) +{ + csch_line_t *line = (csch_line_t *)obj; + csch_coord_t ncx1 = line->spec.p1.x, ncy1 = line->spec.p1.y; + csch_coord_t ncx2 = line->spec.p2.x, ncy2 = line->spec.p2.y; + + csch_rotate90_pt(&ncx1, &ncy1, rcx, rcy, n); + csch_rotate90_pt(&ncx2, &ncy2, rcx, rcy, n); + + csch_line_modify(sheet, line, &ncx1, &ncy1, &ncx2, &ncy2, undoable, 0, 0); +} + +static void line_mirror(csch_sheet_t *sheet, csch_chdr_t *obj, csch_coord_t mcx, csch_coord_t mcy, int mirx, int miry, int undoable) +{ + csch_line_t *line = (csch_line_t *)obj; + csch_coord_t ncx1 = line->spec.p1.x, ncy1 = line->spec.p1.y; + csch_coord_t ncx2 = line->spec.p2.x, ncy2 = line->spec.p2.y; + + csch_mirror_pt(&ncx1, &ncy1, mcx, mcy, mirx, miry); + csch_mirror_pt(&ncx2, &ncy2, mcx, mcy, mirx, miry); + + csch_line_modify(sheet, line, &ncx1, &ncy1, &ncx2, &ncy2, undoable, 0, 0); +} + + +static void line_inst2spec(csch_sheet_t *sheet, csch_chdr_t *obj, const csch_chdr_t *in, int undoable) +{ + csch_line_t *line = (csch_line_t *)in; + csch_coord_t x1 = line->inst.c.p1.x, y1 = line->inst.c.p1.y; + csch_coord_t x2 = line->inst.c.p2.x, y2 = line->inst.c.p2.y; + + csch_line_modify(sheet, (csch_line_t *)obj, &x1, &y1, &x2, &y2, undoable, 0, 0); +} + +const csch_ops_t csch_ops_line = { + line_create, line_remove_alloc, line_remove_redo, line_remove_undo, + line_isc_with_box, + line_move, line_copy, line_rotate, line_rotate90, line_mirror, + line_inst2spec +}; + +/*** hash ***/ + +unsigned csch_line_hash_(const csch_line_t *line, csch_hash_ignore_t ignore, int in_contour) +{ + unsigned res = 0; + if (!in_contour) res ^= csch_chdr_hash(&line->hdr); + if (!(ignore & CSCH_HIGN_FLOATER_GEO) || !line->hdr.floater) { + res ^= csch_coord_hash(line->spec.p1.x) + csch_coord_hash(line->spec.p2.x); + res ^= csch_coord_hash(line->spec.p1.y) + csch_coord_hash(line->spec.p2.y); + } + else + res ^= (unsigned)rnd_distance2(line->spec.p1.x, line->spec.p1.y, line->spec.p2.x, line->spec.p2.y); + return res; +} + +int csch_line_keyeq_(const csch_line_t *l1, const csch_line_t *l2, csch_hash_ignore_t ignore, int in_contour) +{ + if (!in_contour && !csch_chdr_eq(&l1->hdr, &l2->hdr)) return 0; + if (!(ignore & CSCH_HIGN_FLOATER_GEO) || !l1->hdr.floater || !l2->hdr.floater) { + if (l1->spec.p1.x != l2->spec.p1.x) return 0; + if (l1->spec.p1.y != l2->spec.p1.y) return 0; + if (l1->spec.p2.x != l2->spec.p2.x) return 0; + if (l1->spec.p2.y != l2->spec.p2.y) return 0; + } + else { + double d1 = rnd_distance2(l1->spec.p1.x, l1->spec.p1.y, l1->spec.p2.x, l1->spec.p2.y); + double d2 = rnd_distance2(l2->spec.p1.x, l2->spec.p1.y, l2->spec.p2.x, l2->spec.p2.y); + if (d1 != d2) return 0; + } + return 1; +} + +unsigned csch_line_hash(const csch_line_t *line, csch_hash_ignore_t ignore) +{ + return csch_line_hash_(line, ignore, 0); +} + +int csch_line_keyeq(const csch_line_t *l1, const csch_line_t *l2, csch_hash_ignore_t ignore) +{ + return csch_line_keyeq_(l1, l2, ignore, 0); +} + + + +/*** Modify ***/ +typedef struct { + csch_line_t *line; /* it is safe to save the object pointer because it is persistent (through the removed object list) */ + g2d_cline_t spec; + unsigned disable_recalc:1; + unsigned recalc_conn_geo:1; +} undo_line_modify_t; + + +static int undo_line_modify_swap(void *udata) +{ + undo_line_modify_t *u = udata; + + csch_cobj_redraw(u->line); + + rnd_swap(g2d_cline_t, u->spec, u->line->spec); + csch_line_update(u->line->hdr.sheet, u->line, 1); + if (!u->disable_recalc && (u->line->hdr.parent != NULL) && (u->line->hdr.parent->role == CSCH_ROLE_WIRE_NET)) + csch_wirenet_recalc_line_chg(u->line->hdr.sheet, u->line); + if (u->recalc_conn_geo) { + long n; + for(n = 0; n < u->line->hdr.conn.used; n++) + csch_conn_auto_recalc_geo(u->line->hdr.sheet, u->line->hdr.conn.array[n]); + } + csch_sheet_set_changed(u->line->hdr.sheet, 1); + + csch_cobj_redraw(u->line); + + return 0; +} + +static void undo_line_modify_print(void *udata, char *dst, size_t dst_len) +{ + rnd_snprintf(dst, dst_len, "line geometry change"); +} + +static const char core_line_cookie[] = "libcschem/core/cnc_line.c"; + +static const uundo_oper_t undo_line_modify = { + core_line_cookie, + NULL, + undo_line_modify_swap, + undo_line_modify_swap, + undo_line_modify_print +}; + +RND_INLINE void line_modify_endp(g2d_xform_t imx, csch_cgrp_t *parent, g2d_vect_t *dst_spec, g2d_vect_t *spec, g2d_vect_t *inst, csch_coord_t *x, csch_coord_t *y, int relative, int invxform) +{ + g2d_vect_t t; + + if ((x == NULL) && (y == NULL)) { + /* cheap */ + dst_spec->x = spec->x; + dst_spec->y = spec->y; + } + + if (relative) { + t.x = (x == NULL) ? 0 : *x; + t.y = (y == NULL) ? 0 : *y; + if (invxform) { + t.x += parent->xform.x; + t.y += parent->xform.y; + t = g2d_xform_vect2vect(imx, t); + } + dst_spec->x = spec->x + t.x; + dst_spec->y = spec->y + t.y; + } + else { + t.x = (x == NULL) ? spec->x : *x; + t.y = (y == NULL) ? spec->y : *y; + if (invxform) + t = g2d_xform_vect2vect(imx, t); + dst_spec->x = t.x; + dst_spec->y = t.y; + } +} + +void csch_line_modify(csch_sheet_t *sheet, csch_line_t *line, csch_coord_t *x1, csch_coord_t *y1, csch_coord_t *x2, csch_coord_t *y2, int undoable, int relative, int invxform) +{ + undo_line_modify_t utmp, *u = &utmp; + g2d_xform_t imx; + + if (undoable) u = uundo_append(&sheet->undo, &undo_line_modify, sizeof(undo_line_modify_t)); + + u->line = line; + u->spec = line->spec; /* copy all fields */ + + if (invxform) + csch_cgrp_inverse_matrix(&imx, line->hdr.parent); + + line_modify_endp(imx, line->hdr.parent, &u->spec.p1, &line->spec.p1, &line->inst.c.p1, x1, y1, relative, invxform); + line_modify_endp(imx, line->hdr.parent, &u->spec.p2, &line->spec.p2, &line->inst.c.p2, x2, y2, relative, invxform); + + u->disable_recalc = 0; + u->recalc_conn_geo = 0; + undo_line_modify_swap(u); + u->recalc_conn_geo = 1; /* undo should recalc coord geo */ + u->disable_recalc = 1; /* undo shouldn't have side effects */ + + if (undoable) csch_undo_inc_serial(sheet); +} Index: tags/1.0.5/src/libcschem/cnc_line.h =================================================================== --- tags/1.0.5/src/libcschem/cnc_line.h (nonexistent) +++ tags/1.0.5/src/libcschem/cnc_line.h (revision 10414) @@ -0,0 +1,66 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2018 Tibor 'Igor2' Palinkas + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + + +#ifndef CSCH_CONCRETE_LINE_H +#define CSCH_CONCRETE_LINE_H +#include "libcschem/concrete.h" +#include GENGEO2D_TYPECFG +#include "gengeo2d/prim.h" + +/* type=CSCH_CTYPE_LINE */ + +typedef struct csch_line_s { + csch_chdr_t hdr; + g2d_sline_t inst; /* as installed: group-transformed version (in absolute sheet coordinates) */ + g2d_cline_t spec; /* as specified: file format version (in relative group coordinates) */ +} csch_line_t; + +csch_line_t *csch_line_alloc(csch_sheet_t *sheet, csch_cgrp_t *parent, csch_oid_t oid); +csch_line_t *csch_line_dup(csch_sheet_t *sheet, csch_cgrp_t *parent, const csch_line_t *src, int keep_id, int inst2spec); +void csch_line_free(csch_line_t *line); +csch_line_t *csch_line_get(csch_sheet_t *sheet, csch_cgrp_t *grp, csch_oid_t oid); +void csch_line_update(csch_sheet_t *sheet, csch_line_t *line, int do_xform); + +unsigned csch_line_hash_(const csch_line_t *line, csch_hash_ignore_t ignore, int in_contour); +unsigned csch_line_hash(const csch_line_t *line, csch_hash_ignore_t ignore); +int csch_line_keyeq_(const csch_line_t *l1, const csch_line_t *l2, csch_hash_ignore_t ignore, int in_contour); +int csch_line_keyeq(const csch_line_t *l1, const csch_line_t *l2, csch_hash_ignore_t ignore); + +/* fill in dst with centerline bounding box */ +void csch_line_center_bbox(csch_sheet_t *sheet, const csch_line_t *line, csch_rtree_box_t *dst); + +/* non-standard calls */ +void csch_line_update_xform(csch_sheet_t *sheet, csch_line_t *line); +void csch_line_update_bbox(csch_sheet_t *sheet, csch_line_t *line); + +/* internal */ +int csch_line_get_endxy(const csch_line_t *line, int side, csch_coord_t *x, csch_coord_t *y); + +void csch_line_modify(csch_sheet_t *sheet, csch_line_t *line, csch_coord_t *x1, csch_coord_t *y1, csch_coord_t *x2, csch_coord_t *y2, int undoable, int relative, int invxform); + + +#endif Index: tags/1.0.5/src/libcschem/cnc_loop.h =================================================================== --- tags/1.0.5/src/libcschem/cnc_loop.h (nonexistent) +++ tags/1.0.5/src/libcschem/cnc_loop.h (revision 10414) @@ -0,0 +1,62 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2018,2019 Tibor 'Igor2' Palinkas + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include "concrete.h" + +/*** API ***/ + +/* Iterate over sheet objects */ +typedef struct csch_grpo_iter_s csch_grpo_iter_t; +RND_INLINE csch_chdr_t *csch_grpo_first(csch_grpo_iter_t *it, const csch_sheet_t *sheet, const csch_cgrp_t *grp); +RND_INLINE csch_chdr_t *csch_grpo_next(csch_grpo_iter_t *it); + +/*** Implementation ***/ + +struct csch_grpo_iter_s { + const csch_sheet_t *sheet; + const csch_cgrp_t *grp; + htip_entry_t *e; +}; + +RND_INLINE csch_chdr_t *csch_grpo_first(csch_grpo_iter_t *it, const csch_sheet_t *sheet, const csch_cgrp_t *grp) +{ + it->sheet = sheet; + it->grp = grp; + it->e = htip_first(&it->grp->id2obj); + if (it->e == NULL) + return NULL; + + return it->e->value; +} + +RND_INLINE csch_chdr_t *csch_grpo_next(csch_grpo_iter_t *it) +{ + it->e = htip_next(&it->grp->id2obj, it->e); + if (it->e == NULL) + return NULL; + + return it->e->value; +} Index: tags/1.0.5/src/libcschem/cnc_obj.c =================================================================== --- tags/1.0.5/src/libcschem/cnc_obj.c (nonexistent) +++ tags/1.0.5/src/libcschem/cnc_obj.c (revision 10414) @@ -0,0 +1,271 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2019 Tibor 'Igor2' Palinkas + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include "config.h" + +#include +#include + +#include "event.h" +#include "undo.h" + +#include "cnc_obj.h" +#include "cnc_poly.h" + +RND_INLINE csch_displayer_t role2ly(csch_role_t role, csch_chdr_t *obj) +{ + switch(role) { + case CSCH_ROLE_BUS_NET: return CSCH_DSPLY_BUS; + case CSCH_ROLE_BUS_TERMINAL: return CSCH_DSPLY_HUBTERM; + case CSCH_ROLE_HUB_POINT: return CSCH_DSPLY_HUBTERM; + case CSCH_ROLE_TERMINAL: return CSCH_DSPLY_HUBTERM; + case CSCH_ROLE_SYMBOL: return CSCH_DSPLY_SYMBOL; + case CSCH_ROLE_WIRE_NET: return CSCH_DSPLY_WIRE; + case CSCH_ROLE_JUNCTION: return CSCH_DSPLY_WIRE; + case CSCH_ROLE_empty: return obj->type == CSCH_CTYPE_POLY ? CSCH_DSPLY_BACKGROUND : CSCH_DSPLY_DECORATION; /* top level user grouping */ + case CSCH_ROLE_invalid: break; + } + return CSCH_DSPLY_invalid; +} + +csch_displayer_t csch_cobj_dsply(csch_chdr_t *obj) +{ + csch_cgrp_t *parent = obj->parent; + csch_displayer_t ly; + + /* a connection object is always on the connection layer */ + if (obj->type == CSCH_CTYPE_CONN) + return CSCH_DSPLY_CONN; + + /* a group is on a layer by its own right usually */ + if (csch_obj_is_grp(obj)) { + csch_cgrp_t *grp = (csch_cgrp_t *)obj; + csch_sheet_t *sheet = grp->hdr.sheet; + + if (grp == &sheet->direct) + return CSCH_DSPLY_invalid; + + ly = role2ly(grp->role, obj); + if (ly != CSCH_DSPLY_invalid) + return ly; + } + + if (parent == NULL) + return CSCH_DSPLY_invalid; + + /* if parent is a top level group, object must be decoration as + anything non-decoration is in a group with role */ + if (parent->hdr.parent == NULL) + return obj->type == CSCH_CTYPE_POLY ? CSCH_DSPLY_BACKGROUND : CSCH_DSPLY_DECORATION; + + /* direct descendant of known-role groups */ + ly = role2ly(parent->role, obj); + if (ly != CSCH_DSPLY_invalid) + return ly; + + /* grandchildren of known-role groups; parent group already has the layer set */ + switch(parent->hdr.dsply) { + case CSCH_DSPLY_BACKGROUND: /* first level of objects without any role */ + return CSCH_DSPLY_DECORATION; + default: + return parent->hdr.dsply; + } + return CSCH_DSPLY_invalid; +} + +int csch_cobj_update_dsply(csch_sheet_t *sheet, csch_chdr_t *obj) +{ + csch_displayer_t newly = csch_cobj_dsply(obj); + + if (obj->dsply == newly) + return 0; + + csch_cobj_rtree_del(sheet, obj); + obj->dsply = newly; + csch_cobj_rtree_add(sheet, obj); + return 1; +} + + +int csch_cobj_insert(csch_sheet_t *sheet, csch_cgrp_t *parent, csch_chdr_t *obj, csch_oid_t oid) +{ + if ((obj->parent != NULL) || (htip_get(&parent->id2obj, oid) != NULL)) + return -1; + + /* moving between sheets! */ + if ((sheet != obj->sheet) && (obj->sheet != NULL)) { + gdl_remove(&obj->sheet->active, obj, link); + obj->sheet = NULL; + } + + csch_cobj_insert_(obj, sheet, parent, oid); + return 0; +} + +void csch_cobj_bbox_changed(csch_sheet_t *sheet, csch_chdr_t *obj) +{ + csch_cgrp_t *prn = obj->parent; + csch_chdr_t *phd; + csch_rtree_box_t *bxfl; + int changed = 0; + + if (prn == NULL) { + if (!sheet->non_graphical && (obj == &sheet->direct.hdr)) { + sheet->bbox = sheet->direct.bbox_flt; + sheet->bbox_changed = 1; + } + return; /* happens in top groups, like direct or indirect */ + } + + phd = &prn->hdr; + + /* bbox-with-floaters-included: only if it did grow */ + if (csch_obj_is_grp(obj)) { /* use group's floater bbox instead of naked bbox */ + csch_cgrp_t *g = (csch_cgrp_t *)obj; + bxfl = &g->bbox_flt; + } + else + bxfl = &obj->bbox; + if ((bxfl->x1 < prn->bbox_flt.x1) || (bxfl->y1 < prn->bbox_flt.y1) || (bxfl->x2 > prn->bbox_flt.x2) || (bxfl->y2 > prn->bbox_flt.y2)) { + if (bxfl->x1 < prn->bbox_flt.x1) prn->bbox_flt.x1 = bxfl->x1; + if (bxfl->y1 < prn->bbox_flt.y1) prn->bbox_flt.y1 = bxfl->y1; + if (bxfl->x2 > prn->bbox_flt.x2) prn->bbox_flt.x2 = bxfl->x2; + if (bxfl->y2 > prn->bbox_flt.y2) prn->bbox_flt.y2 = bxfl->y2; + changed = 1; + } + + if (!obj->floater) { + /* only if it did grow */ + if ((obj->bbox.x1 < phd->bbox.x1) || (obj->bbox.y1 < phd->bbox.y1) || (obj->bbox.x2 > phd->bbox.x2) || (obj->bbox.y2 > phd->bbox.y2)) { + csch_cobj_rtree_del(sheet, phd); + if (obj->bbox.x1 < phd->bbox.x1) phd->bbox.x1 = obj->bbox.x1; + if (obj->bbox.y1 < phd->bbox.y1) phd->bbox.y1 = obj->bbox.y1; + if (obj->bbox.x2 > phd->bbox.x2) phd->bbox.x2 = obj->bbox.x2; + if (obj->bbox.y2 > phd->bbox.y2) phd->bbox.y2 = obj->bbox.y2; + csch_cobj_rtree_add(sheet, phd); + changed = 1; + } + } + + if (changed) + csch_cobj_bbox_changed(sheet, phd); +} + +static const char core_commprp_cookie[] = "libcschem/core/cnc_obj.c"; + +typedef struct { + csch_chdr_t *obj; /* it is safe to save the object pointer because it is persistent (through the removed object list) */ + + unsigned lock:1; + unsigned floater:1; +} undo_commprp_modify_t; + + +static int undo_commprp_modify_swap(void *udata) +{ + undo_commprp_modify_t *u = udata; + + rnd_swap(int, u->lock, u->obj->lock); + rnd_swap(int, u->floater, u->obj->floater); + + csch_sheet_set_changed(u->obj->sheet, 1); + return 0; +} + +static void undo_commprp_modify_print(void *udata, char *dst, size_t dst_len) +{ + undo_commprp_modify_t *u = udata; + rnd_snprintf(dst, dst_len, "common properties modified (lock: %d<->%d floater: %d<->%d)", u->obj->lock, u->lock, u->obj->floater, u->floater); +} + + +static const uundo_oper_t undo_commprp_modify = { + core_commprp_cookie, + NULL, + undo_commprp_modify_swap, + undo_commprp_modify_swap, + undo_commprp_modify_print +}; + + +void csch_commprp_modify(csch_sheet_t *sheet, csch_chdr_t *obj, int *lock, int *floater, int undoable) +{ + undo_commprp_modify_t utmp, *u = &utmp; + + if (undoable) u = uundo_append(&sheet->undo, &undo_commprp_modify, sizeof(undo_commprp_modify_t)); + + u->obj = obj; + u->lock = CSCH_UNDO_MODIFY(obj, lock); + u->floater = CSCH_UNDO_MODIFY(obj, floater); + + undo_commprp_modify_swap(u); + if (undoable) csch_undo_inc_serial(sheet); +} + + +unsigned csch_chdr_hash(const csch_chdr_t *hdr) +{ + unsigned res = hdr->type; + + if (hdr->stroke_name.str != NULL) + res ^= strhash(hdr->stroke_name.str); + + if (hdr->fill_name.str != NULL) + res ^= strhash(hdr->fill_name.str); + + res ^= ((unsigned)hdr->floater) << 9; + + return res; +} + + +unsigned csch_chdr_eq(const csch_chdr_t *hdr1, const csch_chdr_t *hdr2) +{ + if (hdr1->type != hdr2->type) return 0; + + if (hdr1->sheet == hdr2->sheet) { + if (hdr1->stroke_name.str != hdr2->stroke_name.str) return 0; + if (hdr1->fill_name.str != hdr2->fill_name.str) return 0; + } + else { + if ((hdr1->stroke_name.str == NULL) && (hdr2->stroke_name.str != NULL)) return 0; + if ((hdr1->stroke_name.str != NULL) && (hdr2->stroke_name.str == NULL)) return 0; + if ((hdr1->fill_name.str == NULL) && (hdr2->fill_name.str != NULL)) return 0; + if ((hdr1->fill_name.str != NULL) && (hdr2->fill_name.str == NULL)) return 0; + if ((hdr1->stroke_name.str != NULL) && (strcmp(hdr1->stroke_name.str, hdr2->stroke_name.str) != 0)) return 0; + if ((hdr1->fill_name.str != NULL) && (strcmp(hdr1->fill_name.str, hdr2->fill_name.str) != 0)) return 0; + } + + if (hdr1->floater != hdr2->floater) return 0; + + return 1; +} + +int csch_cobj_has_fill_(csch_chdr_t *obj) +{ + return csch_cpoly_has_fill((csch_cpoly_t *)obj); +} + Index: tags/1.0.5/src/libcschem/cnc_obj.h =================================================================== --- tags/1.0.5/src/libcschem/cnc_obj.h (nonexistent) +++ tags/1.0.5/src/libcschem/cnc_obj.h (revision 10414) @@ -0,0 +1,343 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2018 Tibor 'Igor2' Palinkas + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/* Generic object helpers */ + +#ifndef CSCH_CONCRETE_OBJ_H +#define CSCH_CONCRETE_OBJ_H + +#include +#include +#include + +#include "event.h" +#include "attrib.h" +#include "cnc_pen.h" +#include "cnc_text.h" + +#define csch_obj_bbox_reset(obj) csch_bbox_reset(&((obj)->hdr.bbox)) + +#define csch_cobj_redraw(obj) \ +do { \ + csch_chdr_t *__obj__ = (csch_chdr_t *)obj; \ + if (__obj__->bbox.x1 < __obj__->bbox.x2) { \ + if (__obj__->sheet->redraw_inhibit == 0) \ + rnd_event(&__obj__->sheet->hidlib, CSCH_EVENT_BOX_NEEDS_REDRAW, "p", &__obj__->bbox); \ + else \ + csch_sheet_inval_lr(__obj__->sheet, &__obj__->bbox); \ + } \ +} while(0) + +/* Stop generating redraw events on object changes */ +RND_INLINE void csch_cobj_redraw_freeze(csch_sheet_t *sheet); +RND_INLINE void csch_cobj_redraw_unfreeze(csch_sheet_t *sheet); + +/* implement heuristics to figure on which display layer an object is supposed to go */ +csch_displayer_t csch_cobj_dsply(csch_chdr_t *obj); + +/* Recalculates the display layer of obj and do all the rtree administration + if it has changed. Returns whether it has changed. */ +int csch_cobj_update_dsply(csch_sheet_t *sheet, csch_chdr_t *obj); + + +/* Object rtree management; del returns 0 on success (object got removed + from the tree) and non-zero when the object was not in the tree. */ +RND_INLINE int csch_cobj_rtree_del(csch_sheet_t *sheet, csch_chdr_t *obj); +RND_INLINE void csch_cobj_rtree_add(csch_sheet_t *sheet, csch_chdr_t *obj); + +/* Insert an object in a group by setting the common header fields; do not use + directly, use csch_cobj_insert() */ +RND_INLINE void csch_cobj_insert_(csch_chdr_t *dst, csch_sheet_t *sheet, csch_cgrp_t *parent, csch_oid_t oid); + +/* Initialize an object by setting the common header fields; the only purpose + of this function is to get compiler warnings at every caller when the header + is extended (because the number of args would be extended here) */ +RND_INLINE void csch_cobj_init(csch_chdr_t *dst, csch_sheet_t *sheet, csch_cgrp_t *parent, csch_oid_t oid, csch_ctype_t type); + +/* free common fields */ +RND_INLINE void csch_cobj_uninit(csch_chdr_t *dst); + +/* Recalculate stroke/fill cache in dst */ +RND_INLINE void csch_cobj_update_pen(csch_chdr_t *dst); + +/* Insert an object in parent group, using new oid, if the object is not + already in a group (so obj->parent must be NULL). Sheet is (the new) + parent's sheet. Returns 0 on success. */ +int csch_cobj_insert(csch_sheet_t *sheet, csch_cgrp_t *parent, csch_chdr_t *obj, csch_oid_t oid); + +/* Returns whether the group is atomic (group parts are not directly editable) */ +RND_INLINE int csch_grp_is_atomic(csch_sheet_t *sheet, csch_cgrp_t *grp); + +/* Returns 1 if obj is locked for any reason (lock property, group-lock); this + means obj should not be edited directly. */ +RND_INLINE int csch_cobj_is_locked(csch_chdr_t *obj); + +/* Returns 1 if obj is locked with the lock property directly or through + parent, but ignores group locking */ +RND_INLINE int csch_cobj_is_explicit_locked(csch_chdr_t *obj); + +/* Similar to csch_cobj_is_locked() but returns the first parent that is + not locked; doesn't return sheet->direct; returns NULL if no such + parent found */ +RND_INLINE csch_chdr_t *csch_cobj_first_unlocked(csch_chdr_t *obj); + +/* Similar to csch_cobj_is_locked() but returns the first parent that is + explicitly locked using the lock attr; doesn't return sheet->direct; + returns NULL if no such parent found */ +RND_INLINE csch_chdr_t *csch_cobj_first_explicit_locked(csch_chdr_t *obj); + +/* Modify common properties (doc: {des3:81}) of any object */ +void csch_commprp_modify(csch_sheet_t *sheet, csch_chdr_t *obj, int *lock, int *floater, int undoable); + +/* Call this after obj's bbox changed; updates parent group's bbox recursively + up to the root group, as needed */ +void csch_cobj_bbox_changed(csch_sheet_t *sheet, csch_chdr_t *obj); + +/*** Hash ***/ + +unsigned csch_chdr_hash(const csch_chdr_t *hdr); +RND_INLINE unsigned csch_coord_hash(csch_coord_t crd); +RND_INLINE unsigned csch_angle_hash(double angle); + +unsigned csch_chdr_eq(const csch_chdr_t *hdr1, const csch_chdr_t *hdr2); +RND_INLINE unsigned csch_angle_eq(double angle1, double angle2); + + + +/*** Implementation ***/ + +/* Internal call for csch_cobj_redraw(): add box to the redraw bbox + (sheet->inbbox) without any immediate redraw */ +RND_INLINE void csch_sheet_inval_lr(csch_sheet_t *sheet, csch_rtree_box_t *box) +{ + if (box->x1 < sheet->invbox.x1) sheet->invbox.x1 = box->x1; + if (box->x2 > sheet->invbox.x2) sheet->invbox.x2 = box->x2; + if (box->y1 < sheet->invbox.y1) sheet->invbox.y1 = box->y1; + if (box->y2 > sheet->invbox.y2) sheet->invbox.y2 = box->y2; + sheet->invbox_valid = 1; +} + +RND_INLINE void csch_cobj_redraw_freeze(csch_sheet_t *sheet) +{ + sheet->redraw_inhibit++; + if (sheet->redraw_inhibit == 1) { + sheet->invbox.x1 = sheet->invbox.y1 = CSCH_COORD_MAX; + sheet->invbox.x2 = sheet->invbox.y2 = -CSCH_COORD_MAX; + sheet->invbox_valid = 0; + } +} + +RND_INLINE void csch_cobj_redraw_unfreeze(csch_sheet_t *sheet) +{ + assert(sheet->redraw_inhibit > 0); + if (sheet->redraw_inhibit > 0) { + sheet->redraw_inhibit--; + if ((sheet->redraw_inhibit == 0) && sheet->invbox_valid) { + rnd_event(&sheet->hidlib, CSCH_EVENT_BOX_NEEDS_REDRAW, "p", &sheet->invbox); + sheet->invbox_valid = 0; + } + } +} + +int csch_cobj_has_fill_(csch_chdr_t *obj); +RND_INLINE int csch_cobj_has_fill(csch_chdr_t *obj) +{ + if (obj->type != CSCH_CTYPE_POLY) return 0; + return csch_cobj_has_fill_(obj); +} + + +RND_INLINE int csch_cobj_rtree_del(csch_sheet_t *sheet, csch_chdr_t *obj) +{ + if ((obj->dsply < 0) || (obj->dsply >= CSCH_DSPLY_max) || (csch_bbox_is_invalid(&obj->bbox))) + return -1; + + if (csch_cobj_has_fill(obj)) + csch_rtree_delete(&sheet->dsply_fill[obj->dsply], obj, &obj->bbox); + + return csch_rtree_delete(&sheet->dsply[obj->dsply], obj, &obj->bbox); +} + +RND_INLINE void csch_cobj_rtree_add(csch_sheet_t *sheet, csch_chdr_t *obj) +{ + if ((obj->dsply < 0) || (obj->dsply >= CSCH_DSPLY_max) || (csch_bbox_is_invalid(&obj->bbox)) || obj->indirect) + return; + if (csch_cobj_has_fill(obj)) + csch_rtree_insert(&sheet->dsply_fill[obj->dsply], obj, &obj->bbox); + csch_rtree_insert(&sheet->dsply[obj->dsply], obj, &obj->bbox); +} + + +RND_INLINE void csch_cobj_insert_(csch_chdr_t *dst, csch_sheet_t *sheet, csch_cgrp_t *parent, csch_oid_t oid) +{ + csch_cgrp_t *p; + + dst->oid = oid; + dst->parent = parent; + dst->sheet = sheet; + dst->dsply = csch_cobj_dsply(dst); + gdl_append(&sheet->active, dst, link); + if (dst->parent != NULL) + htip_set(&parent->id2obj, oid, dst); + + dst->indirect = 0; + for(p = parent; p != NULL; p = p->hdr.parent) { + if (p == &sheet->indirect) { + dst->indirect = 1; + break; + } + } +} + +RND_INLINE void csch_cobj_init(csch_chdr_t *dst, csch_sheet_t *sheet, csch_cgrp_t *parent, csch_oid_t oid, csch_ctype_t type) +{ + dst->type = type; + csch_cobj_insert_(dst, sheet, parent, oid); + csch_bbox_reset(&dst->bbox); +} + +RND_INLINE void csch_cobj_uninit(csch_chdr_t *dst) +{ + csch_chdr_t *o; + + if (dst->link.parent != NULL) + gdl_remove(dst->link.parent, dst, link); + csch_cobj_rtree_del(dst->sheet, dst); + + if ((dst->sheet != NULL) && (dst->parent != NULL)) { + o = htip_pop(&dst->parent->id2obj, dst->oid); + if (o != NULL) + assert(o == dst); + } + + vtp0_uninit(&dst->conn); +} + +RND_INLINE void csch_cobj_update_pen(csch_chdr_t *dst) +{ + csch_cobj_redraw(dst); + csch_stroke_(dst); + csch_fill_(dst); + if (dst->type == CSCH_CTYPE_TEXT) + csch_text_invalidate_font((csch_text_t *)dst); + csch_cobj_redraw(dst); +} + + +RND_INLINE int csch_grp_is_atomic(csch_sheet_t *sheet, csch_cgrp_t *grp) +{ + if ((grp == NULL) || (grp == &sheet->direct) || (grp == &sheet->indirect)) + return 0; + + switch(grp->role) { + case CSCH_ROLE_invalid: + case CSCH_ROLE_WIRE_NET: + return 0; + case CSCH_ROLE_empty: /* the user groupped it for this specific reason */ + case CSCH_ROLE_JUNCTION: + case CSCH_ROLE_BUS_NET: + case CSCH_ROLE_BUS_TERMINAL: + case CSCH_ROLE_HUB_POINT: + case CSCH_ROLE_TERMINAL: + return 1; + case CSCH_ROLE_SYMBOL: + return !sheet->loose_sym; + } + return 0; +} + +RND_INLINE int csch_cobj_is_explicit_locked(csch_chdr_t *obj) +{ + csch_chdr_t *o; + + /* if the object or any parent is locked, object is locked */ + for(o = obj; o != NULL; o = &o->parent->hdr) + if (o->lock) + return 1; + + return 0; +} + +RND_INLINE int csch_cobj_is_locked(csch_chdr_t *obj) +{ + /* group lock */ + if (csch_grp_is_atomic(obj->sheet, obj->parent) && !obj->floater) + return 1; + + return csch_cobj_is_explicit_locked(obj); +} + + +RND_INLINE csch_chdr_t *csch_cobj_first_unlocked(csch_chdr_t *obj) +{ + csch_chdr_t *o; + + /* obj not group locked */ + if (!obj->lock && (!csch_grp_is_atomic(obj->sheet, obj->parent) || obj->floater)) + return obj; + + /* find first unlocked parent */ + for(o = &obj->parent->hdr; ((o != NULL) && (o != &obj->sheet->direct.hdr)); o = &o->parent->hdr) + if (!o->lock && (!csch_grp_is_atomic(o->sheet, obj->parent) || o->floater)) + return o; + + return NULL; +} + + +RND_INLINE csch_chdr_t *csch_cobj_first_explicit_locked(csch_chdr_t *obj) +{ + csch_chdr_t *o; + + if (obj->lock) + return obj; + + /* find first unlocked parent */ + for(o = &obj->parent->hdr; ((o != NULL) && (o != &obj->sheet->direct.hdr)); o = &o->parent->hdr) + if (o->lock) + return o; + + return NULL; +} + +RND_INLINE unsigned csch_coord_hash(csch_coord_t crd) +{ + return crd; +} + +RND_INLINE unsigned csch_angle_hash(double angle) +{ + return floor(angle * 100.0); +} + +RND_INLINE unsigned csch_angle_eq(double angle1, double angle2) +{ + double diff = angle1 - angle2; + return ((diff >= -0.01) && (diff <= +0.01)); +} + +#endif + Index: tags/1.0.5/src/libcschem/cnc_pen.c =================================================================== --- tags/1.0.5/src/libcschem/cnc_pen.c (nonexistent) +++ tags/1.0.5/src/libcschem/cnc_pen.c (revision 10414) @@ -0,0 +1,482 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2018,2022,2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include "config.h" +#include +#include +#include +#include + +#include "event.h" +#include "concrete.h" +#include "cnc_obj.h" +#include "cnc_text.h" +#include "cnc_any_obj.h" +#include "cnc_pen.h" +#include "undo.h" +#include "op_common.h" + +csch_cpen_t csch_pen_default_unknown = { + {{0}, 0, CSCH_CTYPE_PEN, 0}, + {""}, + /* tip */ + CSCH_PSHP_ROUND, 1, + {0xF0, 0xC0, 0x00, 0x00, 0xF0C00000, 0.95, 0.8, 0, 0, "#F0C000"}, + 0, 0, + /* font */ + 3500, + NULL, NULL +}; + +static const char *pen_shape_names[] = {"round", "square"}; + +const char *csch_pen_shape_name(csch_pen_shape_t shape) +{ + if ((shape < 0) || (shape >= sizeof(pen_shape_names) / sizeof(pen_shape_names[0]))) + return "invalid"; + return pen_shape_names[shape]; +} + +csch_cpen_t *csch_pen_alloc(csch_sheet_t *sheet, csch_cgrp_t *parent, const char *name) +{ + csch_cpen_t *pen; + csch_oid_t oid; + + sheet->auto_oid--; + oid = sheet->auto_oid; + + pen = htip_get(&parent->id2obj, oid); + if (pen != NULL) + return NULL; + pen = calloc(sizeof(csch_cpen_t), 1); + + csch_cobj_init(&pen->hdr, sheet, parent, oid, CSCH_CTYPE_PEN); + pen->name = csch_comm_str(sheet, name, 1); + if (pen->name.str != NULL) + htsp_set(&parent->name2pen, (char *)pen->name.str, pen); + return pen; +} + +csch_cpen_t *csch_pen_dup2(csch_sheet_t *sheet, csch_cgrp_t *parent, const csch_cpen_t *src, const char *new_name) +{ + csch_cpen_t *dst = csch_pen_alloc(sheet, parent, new_name); + dst->shape = src->shape; + dst->size = src->size; + dst->color = src->color; + dst->dash = src->dash; + + dst->font_height = src->font_height; + dst->font_family = src->font_family == NULL ? NULL : rnd_strdup(src->font_family); + dst->font_style = src->font_style == NULL ? NULL : rnd_strdup(src->font_style); + + return dst; +} + +csch_cpen_t *csch_pen_dup(csch_sheet_t *sheet, csch_cgrp_t *parent, const csch_cpen_t *src) +{ + return csch_pen_dup2(sheet, parent, src, src->name.str); +} + +void (*csch_cb_pen_invalidate_font)(csch_sheet_t *sheet, csch_cpen_t *pen); + +RND_INLINE int csch_pen_same(csch_cpen_t *pen, csch_chdr_t *hdr, int is_fill) +{ + csch_comm_str_t *target; + + if (is_fill) + target = &hdr->stroke_name; + else + target = &hdr->fill_name; + + if (target->str == NULL) + return 0; + + /* it is safe to compare str pointers because they are from the same hash */ + return target->str == pen->name.str; +} + +/* Remove cached ->pen pointers that depend on the given pen from all + object headers that have it, recursively down from grp */ +static void csch_pen_invalidate_(csch_cpen_t *pen, csch_cgrp_t *grp, int tip, int font) +{ + htip_entry_t *e; + + for(e = htip_first(&grp->id2obj); e; e = htip_next(&grp->id2obj, e)) { + csch_chdr_t *hdr = e->value; + if ((hdr->stroke == pen) || csch_pen_same(pen, hdr, 0)) { + if (tip) + hdr->stroke = NULL; + if (hdr->type == CSCH_CTYPE_TEXT) + csch_text_invalidate_font((csch_text_t *)hdr); + } + + if (tip && ((hdr->fill == pen) || csch_pen_same(pen, hdr, 1))) + hdr->fill = NULL; + if (csch_obj_is_grp(hdr)) + csch_pen_invalidate_(pen, (csch_cgrp_t *)hdr, tip, font); + } +} + +void csch_pen_invalidate(csch_cpen_t *pen, int tip, int font, int remov) +{ + csch_sheet_t *sheet = pen->hdr.sheet; + htip_entry_t *e; + + if ((tip == 0) && (font == 0)) + return; + + if (sheet != NULL) + csch_pen_invalidate_(pen, pen->hdr.parent, tip, font); + + if (font && (csch_cb_pen_invalidate_font != NULL)) + csch_cb_pen_invalidate_font(pen->hdr.sheet, pen); + + if (remov && (pen->name.str != NULL)) { + htsp_popentry(&pen->hdr.parent->name2pen, pen->name.str); + + /* it's unlikely, but if another pen has the same name in the same group, we should fall back to that */ + for(e = htip_first(&pen->hdr.parent->id2obj); e; e = htip_next(&pen->hdr.parent->id2obj, e)) { + csch_cpen_t *p = e->value; + if ((p->hdr.type == CSCH_CTYPE_PEN) && (p != pen) && (p->name.str != NULL) && (p->name.str == pen->name.str)) { + htsp_set(&pen->hdr.parent->name2pen, (char *)p->name.str, p); + break; + } + } + } +} + +void csch_pen_free(csch_cpen_t *pen) +{ + /* remove cached pens from any object and pen from group */ + csch_pen_invalidate(pen, 1, 1, 1); + + free(pen->font_family); + free(pen->font_style); + csch_cobj_uninit(&pen->hdr); + free(pen); +} + + +csch_cpen_t *csch_pen_get(csch_sheet_t *sheet, csch_cgrp_t *grp, const char *name) +{ + csch_cpen_t *pen; + + if (name == NULL) + return NULL; + + pen = htsp_get(&grp->name2pen, name); + if ((pen != NULL) && (pen->hdr.type != CSCH_CTYPE_PEN)) + return NULL; + return pen; +} + +csch_cpen_t *csch_pen_resolve(csch_cgrp_t *grp, const char *pen_name) +{ + while((grp != NULL) && csch_obj_is_grp(&grp->hdr)) { + csch_cpen_t *pen = csch_pen_get(grp->hdr.sheet, grp, pen_name); + if (pen != NULL) + return pen; + grp = grp->hdr.parent; + } + return NULL; +} + + +static const char *pen_new_name(csch_cgrp_t *parent, char *tmp, int len) +{ + int n = 0; +#define PREFIX "new_pen" + + if (htsp_get(&parent->name2pen, PREFIX) == NULL) + return PREFIX; + + for(n = 2; n < 32766; n++) { + rnd_snprintf(tmp, len, PREFIX "_%d", n); + if (htsp_get(&parent->name2pen, tmp) == NULL) + return tmp; + } +#undef PREFIX + fprintf(stderr, "Failed to allocate new pen name - it's unlikely you have 2^15 new pens!\n"); + abort(); +} + +static csch_chdr_t *pen_create(csch_sheet_t *sheet, csch_cgrp_t *parent) +{ + char tmp[128]; + csch_cpen_t *pen = csch_pen_alloc(sheet, parent, pen_new_name(parent, tmp, sizeof(tmp))); + if (pen == NULL) return NULL; + return &pen->hdr; +} + +static void pen_remove_alloc(csch_undo_remove_t *slot) +{ +} + +static void pen_remove_redo(csch_undo_remove_t *slot) +{ + csch_pen_invalidate((csch_cpen_t *)slot->obj, 1, 1, 1); + csch_cnc_common_remove_redo(slot, CSCH_REM_FROM_RTREE | CSCH_REM_FROM_PARENT | CSCH_REM_DEL_EMPTY_PARENT); +} + +static void pen_remove_undo(csch_undo_remove_t *slot) +{ + csch_cpen_t *pen = (csch_cpen_t *)slot->obj; + + csch_cnc_common_remove_undo(slot, CSCH_REM_FROM_RTREE | CSCH_REM_FROM_PARENT | CSCH_REM_DEL_EMPTY_PARENT); + + if (pen->name.str != NULL) + htsp_set(&pen->hdr.parent->name2pen, (char *)pen->name.str, pen); +} + +static int pen_isc_with_box(csch_chdr_t *obj, csch_rtree_box_t *box) +{ + /* pens do not have bounding box */ + return 0; +} + +const csch_ops_t csch_ops_pen = { + pen_create, pen_remove_alloc, pen_remove_redo, pen_remove_undo, + pen_isc_with_box +}; + + +/*** hash ***/ + +unsigned csch_pen_hash(const csch_cpen_t *pen, csch_hash_ignore_t ignore) +{ + unsigned res = csch_chdr_hash(&pen->hdr); + + res ^= strhash(pen->name.str); + res ^= ((unsigned)pen->shape); + res ^= csch_coord_hash(pen->size); + res ^= (unsigned)pen->color.r << 16 | (unsigned)pen->color.g << 8 | (unsigned)pen->color.b; + res ^= ((unsigned)pen->dash) << 3; + res ^= csch_coord_hash(pen->dash_period); + return res; +} + +int csch_pen_keyeq(const csch_cpen_t *p1, const csch_cpen_t *p2, csch_hash_ignore_t ignore) +{ + if (!csch_chdr_eq(&p1->hdr, &p2->hdr)) return 0; + + if (p1->shape != p2->shape) return 0; + if (p1->size != p2->size) return 0; + if (p1->color.packed != p2->color.packed) return 0; + if (p1->dash != p2->dash) return 0; + if (p1->dash_period != p2->dash_period) return 0; + + if (p1->hdr.sheet == p2->hdr.sheet) { + if (p1->name.str != p2->name.str) return 0; + } + else { + if (strcmp(p1->name.str, p2->name.str) != 0) return 0; + } + + return 1; +} + + + +/*** Modify ***/ +typedef struct { + csch_cpen_t *pen; /* it is safe to save the object pointer because it is persistent (through the removed object list) */ + csch_pen_shape_t shape; + csch_coord_t size; + rnd_color_t color; + csch_comm_str_t name; + unsigned short dash; + csch_coord_t dash_period; + + unsigned copied_from_default:1; +} undo_pen_modify_tip_t; + + +static int undo_pen_modify_tip_swap(void *udata) +{ + undo_pen_modify_tip_t *u = udata; + csch_sheet_t *sheet = u->pen->hdr.sheet; + + if (u->name.str != u->pen->name.str) + csch_pen_invalidate(u->pen, 1, 1, 1); + else + csch_pen_invalidate(u->pen, 0, 1, 0); /* font color may depend on re-render */ + + rnd_swap(csch_pen_shape_t, u->shape, u->pen->shape); + rnd_swap(csch_coord_t, u->size, u->pen->size); + rnd_swap(rnd_color_t, u->color, u->pen->color); + rnd_swap(csch_comm_str_t, u->name, u->pen->name); + rnd_swap(unsigned short, u->dash, u->pen->dash); + rnd_swap(csch_coord_t, u->dash_period, u->pen->dash_period); + rnd_swap(int, u->copied_from_default, u->pen->copied_from_default); + + if (u->name.str != u->pen->name.str) + htsp_set(&u->pen->hdr.parent->name2pen, (char *)u->pen->name.str, u->pen); + + csch_pen_update_objs_for(sheet, &sheet->direct, u->pen); + + csch_sheet_set_changed(u->pen->hdr.sheet, 1); + + return 0; +} + +static void undo_pen_modify_tip_print(void *udata, char *dst, size_t dst_len) +{ + undo_pen_modify_tip_t *u = udata; + if (u->pen->name.str != u->name.str) + rnd_snprintf(dst, dst_len, "pen name change: %s <--> %s", u->pen->name.str, u->name.str); + else + rnd_snprintf(dst, dst_len, "pen tip modification (in %s)", u->pen->name.str); +} + +static const char core_cpen_cookie[] = "libcschem/core/cnc_pen.c"; + +static const uundo_oper_t undo_pen_modify_tip = { + core_cpen_cookie, + NULL, + undo_pen_modify_tip_swap, + undo_pen_modify_tip_swap, + undo_pen_modify_tip_print +}; + + +void csch_pen_modify_tip(csch_sheet_t *sheet, csch_cpen_t *pen, csch_pen_shape_t *shape, csch_coord_t *size, rnd_color_t *color, char **name, unsigned short *dash, csch_coord_t *dash_period, int undoable) +{ + undo_pen_modify_tip_t utmp, *u = &utmp; + + if (undoable) u = uundo_append(&sheet->undo, &undo_pen_modify_tip, sizeof(undo_pen_modify_tip_t)); + + u->pen = pen; + u->shape = CSCH_UNDO_MODIFY(pen, shape); + u->size = CSCH_UNDO_MODIFY(pen, size); + u->color = CSCH_UNDO_MODIFY(pen, color); + u->dash = CSCH_UNDO_MODIFY(pen, dash); + u->dash_period = CSCH_UNDO_MODIFY(pen, dash_period); + u->copied_from_default = 0; /* always reset */ + if (name == NULL) + u->name = pen->name; + else + u->name = csch_comm_str(sheet, *name, 1); + + csch_pen_update_objs_for(sheet, &sheet->direct, u->pen); + + undo_pen_modify_tip_swap(u); + if (undoable) csch_undo_inc_serial(sheet); +} + + +typedef struct { + csch_cpen_t *pen; /* it is safe to save the object pointer because it is persistent (through the removed object list) */ + + csch_coord_t font_height; + char *font_family; + char *font_style; + + unsigned copied_from_default:1; +} undo_pen_modify_font_t; + + +static int undo_pen_modify_font_swap(void *udata) +{ + undo_pen_modify_font_t *u = udata; + csch_sheet_t *sheet = u->pen->hdr.sheet; + + csch_pen_invalidate(u->pen, 0, 1, 0); + + rnd_swap(csch_coord_t, u->font_height, u->pen->font_height); + rnd_swap(char *, u->font_family, u->pen->font_family); + rnd_swap(char *, u->font_style, u->pen->font_style); + rnd_swap(int, u->copied_from_default, u->pen->copied_from_default); + + csch_pen_update_objs_for(sheet, &sheet->direct, u->pen); + + csch_sheet_set_changed(sheet, 1); + + return 0; +} + +static void undo_pen_modify_font_print(void *udata, char *dst, size_t dst_len) +{ + undo_pen_modify_font_t *u = udata; + rnd_snprintf(dst, dst_len, "pen font modification (in %s)", u->pen->name.str); +} + +static void undo_pen_modify_font_free(void *udata) +{ + undo_pen_modify_font_t *u = udata; + if (u->font_family != u->pen->font_family) + free(u->font_family); + if (u->font_style != u->pen->font_style) + free(u->font_style); +} + + +static const uundo_oper_t undo_pen_modify_font = { + core_cpen_cookie, + undo_pen_modify_font_free, + undo_pen_modify_font_swap, + undo_pen_modify_font_swap, + undo_pen_modify_font_print +}; + + +void csch_pen_modify_font(csch_sheet_t *sheet, csch_cpen_t *pen, csch_coord_t *font_height, char **font_family, char **font_style, int undoable) +{ + undo_pen_modify_font_t utmp, *u = &utmp; + + if (undoable) u = uundo_append(&sheet->undo, &undo_pen_modify_font, sizeof(undo_pen_modify_font_t)); + + u->pen = pen; + u->font_height = CSCH_UNDO_MODIFY(pen, font_height); + u->font_family = CSCH_UNDO_MODIFY(pen, font_family); + u->font_style = CSCH_UNDO_MODIFY(pen, font_style); + u->copied_from_default = 0; /* always reset */ + + undo_pen_modify_font_swap(u); + if (undoable) csch_undo_inc_serial(sheet); +} + + +void csch_pen_update_objs_for(csch_sheet_t *sheet, csch_cgrp_t *parent, csch_cpen_t *pen) +{ + htip_entry_t *e; + for(e = htip_first(&parent->id2obj); e != NULL; e = htip_next(&parent->id2obj, e)) { + csch_chdr_t *obj = e->value; + if (!csch_obj_is_grp(obj)) { + if (obj->stroke == pen) { + if (obj->type == CSCH_CTYPE_TEXT) { + ((csch_text_t *)obj)->bbox_calced = 0; + csch_cobj_update(sheet, obj, 0); + } + else + csch_cobj_update(sheet, obj, 1); /* have to redo xform for the new pen */ + } + } + else + csch_pen_update_objs_for(sheet, (csch_cgrp_t *)obj, pen); + } +} Index: tags/1.0.5/src/libcschem/cnc_pen.h =================================================================== --- tags/1.0.5/src/libcschem/cnc_pen.h (nonexistent) +++ tags/1.0.5/src/libcschem/cnc_pen.h (revision 10414) @@ -0,0 +1,160 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2018 Tibor 'Igor2' Palinkas + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + + +#ifndef CSCH_CONCRETE_PEN_H +#define CSCH_CONCRETE_PEN_H +#include "libcschem/concrete.h" +#include + +/* type=CSCH_CTYPE_PEN */ + +typedef enum csch_pen_shape_e { + CSCH_PSHP_ROUND, + CSCH_PSHP_SQUARE +} csch_pen_shape_t; + +struct csch_cpen_s { + csch_chdr_t hdr; + + csch_comm_str_t name; + + /* tip properties */ + csch_pen_shape_t shape; + csch_coord_t size; /* diameter or edge length */ + rnd_color_t color; + unsigned short dash; + csch_coord_t dash_period; + + /* font properties */ + csch_coord_t font_height; + char *font_family; + char *font_style; + + /* cache for the lib and io code */ + unsigned copied_from_default:1; /* set to 1 when a pen is copied from default sheet; reset on any change */ + + /* fields that can be used by the application */ + void *font_handle; + unsigned font_handle_valid:1; +}; + +/* the application is called back... (the application needs to load this) */ +extern void (*csch_cb_pen_invalidate_font)(csch_sheet_t *sheet, csch_cpen_t *pen); /* remove font cache */ + +const char *csch_pen_shape_name(csch_pen_shape_t shape); + + +csch_cpen_t *csch_pen_alloc(csch_sheet_t *sheet, csch_cgrp_t *parent, const char *name); +csch_cpen_t *csch_pen_dup(csch_sheet_t *sheet, csch_cgrp_t *parent, const csch_cpen_t *src); +csch_cpen_t *csch_pen_dup2(csch_sheet_t *sheet, csch_cgrp_t *parent, const csch_cpen_t *src, const char *new_name); +void csch_pen_free(csch_cpen_t *pen); +csch_cpen_t *csch_pen_get(csch_sheet_t *sheet, csch_cgrp_t *grp, const char *name); +void csch_pen_modify_tip(csch_sheet_t *sheet, csch_cpen_t *pen, csch_pen_shape_t *shape, csch_coord_t *size, rnd_color_t *color, char **name, unsigned short *dash, csch_coord_t *dash_period, int undoable); +void csch_pen_modify_font(csch_sheet_t *sheet, csch_cpen_t *pen, csch_coord_t *font_height, char **font_family, char **font_style, int undoable); + +unsigned csch_pen_hash(const csch_cpen_t *pen, csch_hash_ignore_t ignore); +int csch_pen_keyeq(const csch_cpen_t *p1, const csch_cpen_t *p2, csch_hash_ignore_t ignore); + + +extern csch_cpen_t csch_pen_default_unknown; + +/* Look up pen by name from within grp or NULL */ +csch_cpen_t *csch_pen_resolve(csch_cgrp_t *grp, const char *pen_name); + + +/* Return the object pen falling back to the "unknown pen" when not available */ +RND_INLINE csch_cpen_t *csch_stroke_(csch_chdr_t *hdr) +{ + if (hdr->stroke == NULL) { + csch_cgrp_t *grp = hdr->parent; + while((hdr->stroke == NULL) && (grp != NULL) && csch_obj_is_grp(&grp->hdr)) { + hdr->stroke = csch_pen_get(hdr->sheet, grp, hdr->stroke_name.str); + grp = grp->hdr.parent; + } + } + if (hdr->stroke == NULL) + return &csch_pen_default_unknown; + return hdr->stroke; +} +#define csch_stroke(sheet, obj) csch_stroke_(&(obj->hdr)) + +/* same as csch_stroke_() but with an option to use fallback pens from a group */ +RND_INLINE csch_cpen_t *csch_stroke_fallback_(csch_chdr_t *hdr, csch_cgrp_t *fallback) +{ + csch_cpen_t *res = csch_stroke_(hdr); + if ((res == &csch_pen_default_unknown) && (fallback != NULL)) { + csch_cpen_t *fb = csch_pen_get(hdr->sheet, fallback, hdr->stroke_name.str); + if (fb != NULL) + return fb; + } + return res; +} +#define csch_stroke_fallback(sheet, obj, fb) csch_stroke_fallback_(&(obj->hdr), fb) + +/* Return the object pen falling back to the "unknown pen" when not available */ +RND_INLINE csch_cpen_t *csch_fill_(csch_chdr_t *hdr) +{ + if (hdr->fill == NULL) { + csch_cgrp_t *grp = hdr->parent; + while((hdr->fill == NULL) && (grp != NULL) && csch_obj_is_grp(&grp->hdr)) { + hdr->fill = csch_pen_get(hdr->sheet, grp, hdr->fill_name.str); + grp = grp->hdr.parent; + } + } + if (hdr->fill == NULL) + return &csch_pen_default_unknown; + return hdr->fill; +} +#define csch_fill(sheet, obj) csch_fill_(&(obj->hdr)) + + +/* same as csch_stroke_() but with an option to use fallback pens from a group */ +RND_INLINE csch_cpen_t *csch_fill_fallback_(csch_chdr_t *hdr, csch_cgrp_t *fallback) +{ + csch_cpen_t *res = csch_fill_(hdr); + if ((res == &csch_pen_default_unknown) && (fallback != NULL)) { + csch_cpen_t *fb = csch_pen_get(hdr->sheet, fallback, hdr->fill_name.str); + if (fb != NULL) + return fb; + } + return res; +} +#define csch_fill_fallback(sheet, obj, fb) csch_fill_fallback_(&(obj->hdr), fb) + +/* If tip is non-zero: remove cached ->pen pointers that depend on the given + pen from all object headers that could have it, recursively down from pen's + parent group. + If remov is non-zero: the pen is also removed from the pen-name-hash (pen + is being removed or renamed). + If remov is non-zero: all text objects using this pen are font-invalidated */ +void csch_pen_invalidate(csch_cpen_t *pen, int tip, int font, int remov); + +/* Update all objects that has a specific pen as stroke; this recalculates obj + bbox assuming the pen change may have changed the object's size */ +void csch_pen_update_objs_for(csch_sheet_t *sheet, csch_cgrp_t *parent, csch_cpen_t *pen); + +#endif Index: tags/1.0.5/src/libcschem/cnc_poly.c =================================================================== --- tags/1.0.5/src/libcschem/cnc_poly.c (nonexistent) +++ tags/1.0.5/src/libcschem/cnc_poly.c (revision 10414) @@ -0,0 +1,642 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2018 Tibor 'Igor2' Palinkas + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + + +#include "config.h" + +#include +#include +#include +#include + +#include "event.h" +#include "concrete.h" +#include "cnc_obj.h" +#include "cnc_any_obj.h" +#include "cnc_arc.h" +#include "operation.h" +#include "op_common.h" +#include "gengeo2d/box.h" +#include "gengeo2d/xform.h" +#include "undo.h" +#include "rotate.h" + +#include "cnc_poly.h" + +csch_cpoly_t *csch_cpoly_alloc(csch_sheet_t *sheet, csch_cgrp_t *parent, csch_oid_t oid) +{ + csch_cpoly_t *poly; + + poly = htip_get(&parent->id2obj, oid); + if (poly != NULL) + return NULL; + poly = calloc(sizeof(csch_cpoly_t), 1); + + csch_cobj_init(&poly->hdr, sheet, parent, oid, CSCH_CTYPE_POLY); + return poly; +} + +csch_cpoly_t *csch_cpoly_dup(csch_sheet_t *sheet, csch_cgrp_t *parent, const csch_cpoly_t *src, int keep_id) +{ + csch_cpoly_t *dst = csch_cpoly_alloc(sheet, parent, CSCH_KEEP_OID(parent, src->hdr.oid)); + + dst->has_stroke = src->has_stroke; + dst->has_fill = src->has_fill; + + csch_chdr_copy_meta4dup(&dst->hdr, &src->hdr); + + csch_vtcoutline_enlarge(&dst->outline, src->outline.used); + memcpy(dst->outline.array, src->outline.array, src->outline.used * sizeof(csch_coutline_t)); + dst->outline.used = src->outline.used; + + return dst; +} + + +void csch_cpoly_free(csch_cpoly_t *poly) +{ + csch_cobj_uninit(&poly->hdr); + csch_vtcoutline_uninit(&poly->outline); + free(poly); +} + +csch_cpoly_t *csch_cpoly_get(csch_sheet_t *sheet, csch_cgrp_t *grp, csch_oid_t oid) +{ + csch_cpoly_t *poly = htip_get(&grp->id2obj, oid); + if ((poly != NULL) && (poly->hdr.type != CSCH_CTYPE_POLY)) + return NULL; + return poly; +} + +void csch_cpoly_center_bbox(csch_sheet_t *sheet, const csch_cpoly_t *poly, csch_rtree_box_t *dst) +{ + long n; + csch_coutline_t *o; + csch_rtree_box_t tmp; + + csch_bbox_reset(dst); + + for(n = 0, o = poly->outline.array; n < poly->outline.used; n++, o++) { + switch(o->hdr.type) { + case CSCH_CTYPE_LINE: csch_line_center_bbox(sheet, &o->line, &tmp); break; + case CSCH_CTYPE_ARC: csch_arc_center_bbox(sheet, &o->arc, &tmp); break; + default: break; /* already warned */ + } + csch_bbox_bump(dst, x, tmp.x1); + csch_bbox_bump(dst, x, tmp.x2); + csch_bbox_bump(dst, y, tmp.y1); + csch_bbox_bump(dst, y, tmp.y2); + } +} + +void csch_poly_update(csch_sheet_t *sheet, csch_cpoly_t *poly, int do_xform) +{ + long n; + csch_coutline_t *o; + + csch_cobj_update_pen(&poly->hdr); + + poly->area = -1; + + if (do_xform) { + for(n = 0, o = poly->outline.array; n < poly->outline.used; n++, o++) { + csch_ctype_t type_save = o->hdr.type; + o->hdr = poly->hdr; + o->hdr.type = type_save; + + switch(o->hdr.type) { + case CSCH_CTYPE_LINE: csch_line_update_xform(sheet, &o->line); break; + case CSCH_CTYPE_ARC: csch_arc_update_xform(sheet, &o->arc); break; + default: rnd_message(RND_MSG_ERROR, "Polygon #%ld contains an invalid object in its contour\n", poly->hdr.oid); break; + } + } + } + + csch_cobj_rtree_del(sheet, &poly->hdr); + + csch_obj_bbox_reset(poly); + for(n = 0, o = poly->outline.array; n < poly->outline.used; n++, o++) { + switch(o->hdr.type) { + case CSCH_CTYPE_LINE: csch_line_update_bbox(sheet, &o->line); break; + case CSCH_CTYPE_ARC: csch_arc_update_bbox(sheet, &o->arc); break; + default: break; /* already warned above */ + } + csch_bbox_bump(&poly->hdr.bbox, x, o->hdr.bbox.x1); + csch_bbox_bump(&poly->hdr.bbox, x, o->hdr.bbox.x2); + csch_bbox_bump(&poly->hdr.bbox, y, o->hdr.bbox.y1); + csch_bbox_bump(&poly->hdr.bbox, y, o->hdr.bbox.y2); + } + + csch_cobj_rtree_add(sheet, &poly->hdr); + + csch_cobj_bbox_changed(sheet, &poly->hdr); +} + +int csch_cpoly_has_fill(csch_cpoly_t *poly) +{ + return poly->has_fill; +} + +static csch_chdr_t *poly_create(csch_sheet_t *sheet, csch_cgrp_t *parent) +{ + csch_cpoly_t *poly = csch_cpoly_alloc(sheet, parent, csch_oid_new(sheet, parent)); + if (poly == NULL) return NULL; + return &poly->hdr; +} + +static void poly_remove_alloc(csch_undo_remove_t *slot) +{ +} + +static void poly_remove_redo(csch_undo_remove_t *slot) +{ + csch_cnc_common_remove_redo(slot, CSCH_REM_FROM_RTREE | CSCH_REM_FROM_PARENT | CSCH_REM_DEL_EMPTY_PARENT); +} + +static void poly_remove_undo(csch_undo_remove_t *slot) +{ + csch_cnc_common_remove_undo(slot, CSCH_REM_FROM_RTREE | CSCH_REM_FROM_PARENT | CSCH_REM_DEL_EMPTY_PARENT); +} + +/* obj_idx is at most 2 items long but can be NULL to skip the search */ +RND_INLINE int poly_isc_with_box_(csch_chdr_t *obj, csch_rtree_box_t *box, long *obj_idx) +{ + csch_cpoly_t *poly = (csch_cpoly_t *)obj; + g2d_box_t gbox, pbox, obox; + long n; + int found = 0; + csch_coutline_t *o; + + gbox.p1.x = box->x1; gbox.p1.y = box->y1; + gbox.p2.x = box->x2; gbox.p2.y = box->y2; + pbox.p1.x = poly->hdr.bbox.x1; pbox.p1.y = poly->hdr.bbox.y1; + pbox.p2.x = poly->hdr.bbox.x2; pbox.p2.y = poly->hdr.bbox.y2; + + /* poly fully within the box (cheapest) */ + if (g2d_box_in_box(&gbox, &pbox)) return 1; + + /* expect reasonably small polygons; typical use case ranges from triangle + to octagon. Linear search will be good enough for this */ + for(n = 0, o = poly->outline.array; n < poly->outline.used; n++, o++) { + + /* optimization: don't go and check the object if its bbox doesn't intersect with target bbox */ + obox.p1.x = o->hdr.bbox.x1; obox.p1.y = o->hdr.bbox.y1; + obox.p2.x = o->hdr.bbox.x2; obox.p2.y = o->hdr.bbox.y2; + if (!g2d_isc_box_box(&gbox, &obox)) + continue; + + if (csch_isc_with_box(&o->hdr, box)) { + if (obj_idx != NULL) { + obj_idx[found] = n; + found++; + if (found == 2) + return 2; + } + else + return 1; + } + } + + return found; +} + +static int poly_isc_with_box(csch_chdr_t *obj, csch_rtree_box_t *box) +{ + return poly_isc_with_box_(obj, box, NULL); +} + +int csch_poly_contour_objs_at(csch_cpoly_t *poly, csch_coord_t x, csch_coord_t y, csch_coord_t r, long out[2]) +{ + csch_rtree_box_t box; + long obj_idx[2]; + int len; + + box.x1 = x - r; box.y1 = y - r; + box.x2 = x + r; box.y2 = y + r; + len = poly_isc_with_box_(&poly->hdr, &box, obj_idx); + switch(len) { + case 0: + out[0] = out[1] = -1; + return 0; + case 1: + out[0] = obj_idx[0]; + out[1] = -1; + return 1; + case 2: + /* need to sort objects */ + if (obj_idx[1] == obj_idx[0]+1) { + out[0] = obj_idx[0]; + out[1] = obj_idx[1]; + return 2; + } + else if ((obj_idx[0] == 0) && (obj_idx[1] == poly->outline.used - 1)) { + out[0] = obj_idx[1]; + out[1] = obj_idx[0]; + return 2; + } + else { /* self-isect poly? */ + out[0] = obj_idx[0]; + out[1] = -1; + return 1; + } + break; + } + + assert(!"internal error poly_isc_with_box_()"); + return 0; +} + +int csch_poly_contour_obj_ends_at(csch_cpoly_t *poly, long idx, csch_coord_t x, csch_coord_t y) +{ + csch_coutline_t *o; + csch_coord_t ex, ey; + + if ((idx < 0) || (idx >= poly->outline.used)) + return 0; + + o = &poly->outline.array[idx]; + + switch(o->hdr.type) { + case CSCH_CTYPE_LINE: + if ((o->line.inst.c.p1.x == x) && (o->line.inst.c.p1.y == y)) return 1; + if ((o->line.inst.c.p2.x == x) && (o->line.inst.c.p2.y == y)) return 1; + return 0; + case CSCH_CTYPE_ARC: + if ((csch_arc_get_endxy(&o->arc, 0, &ex, &ey) == 0) && (ex == x) && (ey == y)) return 1; + if ((csch_arc_get_endxy(&o->arc, 1, &ex, &ey) == 0) && (ex == x) && (ey == y)) return 1; + return 0; + default: break; /* Invalid object in polygon, already warned on create/load */ + } + return 0; +} + +static void poly_outline_move(csch_vtcoutline_t *outline, csch_coord_t dx, csch_coord_t dy) +{ + csch_coutline_t *o; + long n; + + for(n = 0, o = outline->array; n < outline->used; n++,o++) { + switch(o->hdr.type) { + case CSCH_CTYPE_LINE: + o->line.spec.p1.x += dx; + o->line.spec.p1.y += dy; + o->line.spec.p2.x += dx; + o->line.spec.p2.y += dy; + break; + case CSCH_CTYPE_ARC: + o->arc.spec.c.x += dx; + o->arc.spec.c.y += dy; + break; + default: break; /* Invalid object in polygon, already warned on create/load */ + } + } +} + +static void poly_move(csch_sheet_t *sheet, csch_chdr_t *obj, csch_coord_t dx, csch_coord_t dy, int undoable) +{ + csch_cpoly_t *poly = (csch_cpoly_t *)obj; + csch_vtcoutline_t *outline; + void *cookie; + + outline = csch_cpoly_modify_geo_begin(sheet, poly, &cookie, undoable); + poly_outline_move(outline, dx, dy); + csch_cpoly_modify_geo_end(sheet, poly, &cookie); +} + +static void poly_copy(csch_sheet_t *sheet, csch_chdr_t *obj, csch_coord_t dx, csch_coord_t dy, int undoable) +{ + csch_cpoly_t *poly = csch_cpoly_dup(sheet, obj->parent, (csch_cpoly_t *)obj, 0); + if (poly != NULL) { + poly_outline_move(&poly->outline, dx, dy); + csch_poly_update(sheet, poly, 1); + csch_op_inserted(sheet, obj->parent, &poly->hdr); + } +} + +static void poly_outline_rotate(csch_vtcoutline_t *outline, csch_coord_t rcx, csch_coord_t rcy, double da) +{ + csch_coutline_t *o; + double rad = -da / RND_RAD_TO_DEG; + double cs = cos(rad), sn = sin(rad); + long n; + + for(n = 0, o = outline->array; n < outline->used; n++,o++) { + switch(o->hdr.type) { + case CSCH_CTYPE_LINE: + csch_rotate_pt(&o->line.spec.p1.x, &o->line.spec.p1.y, rcx, rcy, cs, sn); + csch_rotate_pt(&o->line.spec.p2.x, &o->line.spec.p2.y, rcx, rcy, cs, sn); + break; + case CSCH_CTYPE_ARC: + csch_arc_rotate_(&o->arc, rcx, rcy, da, cs, sn, &o->arc.spec.c.x, &o->arc.spec.c.y, &o->arc.spec.start); + break; + default: break; /* Invalid object in polygon, already warned on create/load */ + } + } +} + +static void poly_rotate(csch_sheet_t *sheet, csch_chdr_t *obj, csch_coord_t rcx, csch_coord_t rcy, double da, int undoable) +{ + csch_cpoly_t *poly = (csch_cpoly_t *)obj; + csch_vtcoutline_t *outline; + void *cookie; + + outline = csch_cpoly_modify_geo_begin(sheet, poly, &cookie, undoable); + poly_outline_rotate(outline, rcx, rcy, da); + csch_cpoly_modify_geo_end(sheet, poly, &cookie); +} + +static void poly_outline_rotate90(csch_vtcoutline_t *outline, csch_coord_t rcx, csch_coord_t rcy, int steps) +{ + csch_coutline_t *o; + long n; + + for(n = 0, o = outline->array; n < outline->used; n++,o++) { + switch(o->hdr.type) { + case CSCH_CTYPE_LINE: + csch_rotate90_pt(&o->line.spec.p1.x, &o->line.spec.p1.y, rcx, rcy, steps); + csch_rotate90_pt(&o->line.spec.p2.x, &o->line.spec.p2.y, rcx, rcy, steps); + break; + case CSCH_CTYPE_ARC: + csch_arc_rotate90_(&o->arc, rcx, rcy, steps, &o->arc.spec.c.x, &o->arc.spec.c.y, &o->arc.spec.start); + break; + default: break; /* Invalid object in polygon, already warned on create/load */ + } + } +} + +static void poly_rotate90(csch_sheet_t *sheet, csch_chdr_t *obj, csch_coord_t rcx, csch_coord_t rcy, int steps, int undoable) +{ + csch_cpoly_t *poly = (csch_cpoly_t *)obj; + csch_vtcoutline_t *outline; + void *cookie; + + outline = csch_cpoly_modify_geo_begin(sheet, poly, &cookie, undoable); + poly_outline_rotate90(outline, rcx, rcy, steps); + csch_cpoly_modify_geo_end(sheet, poly, &cookie); +} + + +static void poly_outline_mirror(csch_vtcoutline_t *outline, csch_coord_t mcx, csch_coord_t mcy, int mirx, int miry) +{ + csch_coutline_t *o; + long n; + + for(n = 0, o = outline->array; n < outline->used; n++,o++) { + switch(o->hdr.type) { + case CSCH_CTYPE_LINE: + csch_mirror_pt(&o->line.spec.p1.x, &o->line.spec.p1.y, mcx, mcy, mirx, miry); + csch_mirror_pt(&o->line.spec.p2.x, &o->line.spec.p2.y, mcx, mcy, mirx, miry); + break; + case CSCH_CTYPE_ARC: + csch_arc_mirror_(&o->arc, mcx, mcy, mirx, miry, &o->arc.spec.c.x, &o->arc.spec.c.y, &o->arc.spec.start, &o->arc.spec.delta); + break; + default: break; /* Invalid object in polygon, already warned on create/load */ + } + } +} + +static void poly_mirror(csch_sheet_t *sheet, csch_chdr_t *obj, csch_coord_t mcx, csch_coord_t mcy, int mirx, int miry, int undoable) +{ + csch_cpoly_t *poly = (csch_cpoly_t *)obj; + csch_vtcoutline_t *outline; + void *cookie; + + outline = csch_cpoly_modify_geo_begin(sheet, poly, &cookie, undoable); + poly_outline_mirror(outline, mcx, mcy, mirx, miry); + csch_cpoly_modify_geo_end(sheet, poly, &cookie); +} + +static void poly_outline_inst2spec(csch_sheet_t *sheet, csch_vtcoutline_t *dst, const csch_vtcoutline_t *src) +{ + const csch_coutline_t *s; + csch_coutline_t *d; + long n; + + for(n = 0, s = src->array, d = dst->array; n < src->used; n++,s++,d++) { + switch(s->hdr.type) { + case CSCH_CTYPE_LINE: + d->line.spec = s->line.inst.c; + break; + case CSCH_CTYPE_ARC: + d->arc.spec = s->arc.inst.c; + d->arc.svalid = d->arc.evalid = 0; + break; + default: break; /* Invalid object in polygon, already warned on create/load */ + } + } +} + +static void poly_inst2spec(csch_sheet_t *sheet, csch_chdr_t *obj, const csch_chdr_t *in, int undoable) +{ + csch_cpoly_t *dst = (csch_cpoly_t *)obj; + const csch_cpoly_t *src = (csch_cpoly_t *)in; + csch_vtcoutline_t *outline; + void *cookie; + + outline = csch_cpoly_modify_geo_begin(sheet, dst, &cookie, undoable); + poly_outline_inst2spec(sheet, outline, &src->outline); + csch_cpoly_modify_geo_end(sheet, dst, &cookie); +} + +const csch_ops_t csch_ops_poly = { + poly_create, poly_remove_alloc, poly_remove_redo, poly_remove_undo, + poly_isc_with_box, + poly_move, poly_copy, poly_rotate, poly_rotate90, poly_mirror, + poly_inst2spec +}; + +RND_INLINE unsigned csch_contour_hash(const csch_chdr_t *obj) +{ + switch(obj->type) { + case CSCH_CTYPE_LINE: return csch_line_hash_((const csch_line_t *)obj, 0, 1); + case CSCH_CTYPE_ARC: return csch_arc_hash_((const csch_arc_t *)obj, 0, 1); + default: break; + } + return 0; +} + +RND_INLINE int csch_contour_keyeq(const csch_chdr_t *p1, const csch_chdr_t *p2) +{ + if (p1->type != p2->type) return 0; + switch(p1->type) { + case CSCH_CTYPE_LINE: return csch_line_keyeq_((const csch_line_t *)p1, (const csch_line_t *)p2, 0, 1); + case CSCH_CTYPE_ARC: return csch_arc_keyeq_((const csch_arc_t *)p1, (const csch_arc_t *)p2, 0, 1); + default: break; + } + return 1; +} + +unsigned csch_cpoly_hash(const csch_cpoly_t *poly, csch_hash_ignore_t ignore) +{ + unsigned res = csch_chdr_hash(&poly->hdr); + long n; + + res ^= ((unsigned)poly->has_stroke) << 13; + res ^= ((unsigned)poly->has_fill) << 15; + res ^= ((unsigned)poly->outline.used) << 3; + + if (!(ignore & CSCH_HIGN_FLOATER_GEO) || !poly->hdr.floater) + for(n = 0; n < poly->outline.used; n++) + res ^= csch_contour_hash(&poly->outline.array[n].hdr); + + return res; +} + +int csch_cpoly_keyeq(const csch_cpoly_t *p1, const csch_cpoly_t *p2, csch_hash_ignore_t ignore) +{ + long n; + if (!csch_chdr_eq(&p1->hdr, &p2->hdr)) return 0; + if (p1->has_stroke != p2->has_stroke) return 0; + if (p1->has_fill != p2->has_fill) return 0; + if (p1->outline.used != p2->outline.used) return 0; + + if (!(ignore & CSCH_HIGN_FLOATER_GEO) || !p1->hdr.floater || !p2->hdr.floater) + for(n = 0; n < p1->outline.used; n++) + if (!csch_contour_keyeq(&p1->outline.array[n].hdr, &p2->outline.array[n].hdr)) + return 0; + + return 1; +} + +/*** Modify ***/ +typedef struct { + csch_cpoly_t *poly; /* it is safe to save the object pointer because it is persistent (through the removed object list) */ + csch_vtcoutline_t outline; + unsigned swap_outline:1; + unsigned has_stroke:1; + unsigned has_fill:1; + unsigned swap_has:1; +} undo_poly_modify_t; + + +static int undo_poly_modify_swap(void *udata) +{ + undo_poly_modify_t *u = udata; + + csch_cobj_redraw(u->poly); + + if (u->swap_has) { + csch_sheet_t *sheet = u->poly->hdr.sheet; + + /* if has_fill changes the fill layer rtree needs to be updated accordingly */ + if (u->poly->has_fill && !u->has_fill) + csch_rtree_delete(&sheet->dsply_fill[u->poly->hdr.dsply], &u->poly->hdr, &u->poly->hdr.bbox); + else if (!u->poly->has_fill && u->has_fill) + csch_rtree_insert(&sheet->dsply_fill[u->poly->hdr.dsply], &u->poly->hdr, &u->poly->hdr.bbox); + + rnd_swap(int, u->has_stroke, u->poly->has_stroke); + rnd_swap(int, u->has_fill, u->poly->has_fill); + + } + if (u->swap_outline) { + rnd_swap(csch_vtcoutline_t, u->outline, u->poly->outline); + csch_poly_update(u->poly->hdr.sheet, u->poly, 1); + } + csch_sheet_set_changed(u->poly->hdr.sheet, 1); + + csch_cobj_redraw(u->poly); + + return 0; +} + +static void undo_poly_modify_print(void *udata, char *dst, size_t dst_len) +{ + undo_poly_modify_t *u = udata; + rnd_snprintf(dst, dst_len, "poly modification has_stroke %d <-> %d, has_fill %d <-> %d", u->poly->has_stroke, u->has_stroke, u->poly->has_fill, u->has_fill); +} + +static const char core_cpoly_cookie[] = "libcschem/core/cnc_poly.c"; + +static const uundo_oper_t undo_poly_modify = { + core_cpoly_cookie, + NULL, + undo_poly_modify_swap, + undo_poly_modify_swap, + undo_poly_modify_print +}; + +void csch_cpoly_modify(csch_sheet_t *sheet, csch_cpoly_t *poly, int *has_stroke, int *has_fill, int undoable) +{ + undo_poly_modify_t utmp, *u = &utmp; + + if (undoable) u = uundo_append(&sheet->undo, &undo_poly_modify, sizeof(undo_poly_modify_t)); + + u->poly = poly; + u->has_stroke = CSCH_UNDO_MODIFY(poly, has_stroke); + u->has_fill = CSCH_UNDO_MODIFY(poly, has_fill); + u->swap_has = 1; + u->swap_outline = 0; + + undo_poly_modify_swap(u); + if (undoable) csch_undo_inc_serial(sheet); +} + + +static char not_undoable[] = "not undoable"; + +csch_vtcoutline_t *csch_cpoly_modify_geo_begin(csch_sheet_t *sheet, csch_cpoly_t *poly, void **cookie, int undoable) +{ + undo_poly_modify_t utmp, *u = &utmp; + long len; + + if (undoable) + u = uundo_append(&sheet->undo, &undo_poly_modify, sizeof(undo_poly_modify_t)); + + u->poly = poly; + u->swap_has = 0; + u->swap_outline = 1; + + if (undoable) { + /* clone the outline */ + u->outline.alloced = poly->outline.used; + u->outline.used = poly->outline.used; + len = sizeof(csch_coutline_t) * u->outline.alloced; + u->outline.array = malloc(len); + memcpy(u->outline.array, poly->outline.array, len); + *cookie = u; + return &u->outline; + } + + *cookie = (void *)not_undoable; + return &poly->outline; +} + + +void csch_cpoly_modify_geo_end(csch_sheet_t *sheet, csch_cpoly_t *poly, void **cookie) +{ + undo_poly_modify_t *u = *cookie; + + if (u == (void *)not_undoable) { + csch_poly_update(sheet, poly, 1); + csch_sheet_set_changed(sheet, 1); + } + else { + undo_poly_modify_swap(u); + csch_undo_inc_serial(sheet); + } + + *cookie = NULL; +} Index: tags/1.0.5/src/libcschem/cnc_poly.h =================================================================== --- tags/1.0.5/src/libcschem/cnc_poly.h (nonexistent) +++ tags/1.0.5/src/libcschem/cnc_poly.h (revision 10414) @@ -0,0 +1,83 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2018 Tibor 'Igor2' Palinkas + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + + +#ifndef CSCH_CONCRETE_POLY_H +#define CSCH_CONCRETE_POLY_H +#include "libcschem/concrete.h" +#include "libcschem/vtcoutline.h" + + /* type=CSCH_CTYPE_POLY */ + +typedef struct csch_cpoly_s { + csch_chdr_t hdr; + csch_vtcoutline_t outline; /* since it is made of lines and arcs, each object contains its spec and inst */ + unsigned has_stroke:1; /* draw outline with pen if 1 */ + unsigned has_fill:1; /* draw fill with solid color if 1 */ + + /*** cached ***/ + double area; /* for fill order; calculated by the app when needed, the lib sets it to -1 on any poly update */ +} csch_cpoly_t; + +csch_cpoly_t *csch_cpoly_alloc(csch_sheet_t *sheet, csch_cgrp_t *parent, csch_oid_t oid); +csch_cpoly_t *csch_cpoly_dup(csch_sheet_t *sheet, csch_cgrp_t *parent, const csch_cpoly_t *src, int keep_id); +void csch_cpoly_free(csch_cpoly_t *poly); +csch_cpoly_t *csch_cpoly_get(csch_sheet_t *sheet, csch_cgrp_t *grp, csch_oid_t oid); +void csch_poly_update(csch_sheet_t *sheet, csch_cpoly_t *poly, int do_xform); + +/* fill in dst with outline's centerline bounding box */ +void csch_cpoly_center_bbox(csch_sheet_t *sheet, const csch_cpoly_t *poly, csch_rtree_box_t *dst); + + +unsigned csch_cpoly_hash(const csch_cpoly_t *poly, csch_hash_ignore_t ignore); +int csch_cpoly_keyeq(const csch_cpoly_t *p1, const csch_cpoly_t *p2, csch_hash_ignore_t ignore); + +int csch_cpoly_has_fill(csch_cpoly_t *poly); + + +void csch_cpoly_modify(csch_sheet_t *sheet, csch_cpoly_t *poly, int *has_stroke, int *has_fill, int undoable); + +/* Call these to change poly outline in an undoable manner: + - call begin() and save cookie + - make modifications to the returned outline + - call end() with the same cookie to finalize the changes +*/ +csch_vtcoutline_t *csch_cpoly_modify_geo_begin(csch_sheet_t *sheet, csch_cpoly_t *poly, void **cookie, int undoable); +void csch_cpoly_modify_geo_end(csch_sheet_t *sheet, csch_cpoly_t *poly, void **cookie); + +/* Returns the contour object(s) near x;y with search "radius" r (really a + query box width). Returns: + - 0: no object found (x;y is within or outside of the poly) + - 1: obj_idx[0] loaded (x;y is on the middle of a contour object) + - 2: obj_idx[0] and obj_idx[1] loaded (x;y is near enough to a corner); + the corner point is at obj_idx[0] end while obj_idx[1] start point */ +int csch_poly_contour_objs_at(csch_cpoly_t *poly, csch_coord_t x, csch_coord_t y, csch_coord_t r, long obj_idx[2]); + +/* Returns whether x;y is an endpoint of poly's idxth contour object. If idx + is invalid, returns 0. */ +int csch_poly_contour_obj_ends_at(csch_cpoly_t *poly, long idx, csch_coord_t x, csch_coord_t y); + +#endif Index: tags/1.0.5/src/libcschem/cnc_text.c =================================================================== --- tags/1.0.5/src/libcschem/cnc_text.c (nonexistent) +++ tags/1.0.5/src/libcschem/cnc_text.c (revision 10414) @@ -0,0 +1,648 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2018,2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + + +#include "config.h" + +#include +#include +#include + +#include "event.h" +#include "concrete.h" +#include "cnc_text.h" +#include "cnc_obj.h" +#include "cnc_grp.h" +#include "cnc_grp_child.h" +#include "op_common.h" +#include "operation.h" +#include "undo.h" +#include "rotate.h" +#include "project.h" +#include "triangle.h" + +#include "gengeo2d/box.h" +#include "gengeo2d/xform.h" +#include "gengeo2d/cline.h" + +const char *csch_halign_names[] = { "start", "center", "end", "word_justify", "justify", NULL }; + +const char *csch_halign2str(csch_halign_t halign) +{ + if ((halign >= 0) && (halign < sizeof(csch_halign_names)/sizeof(char *))) + return csch_halign_names[halign]; + return ""; +} + +csch_halign_t csch_str2halign(const char *s) +{ + switch(*s) { + case 's': if (strcmp(s+1, "tart") == 0) return CSCH_HALIGN_START; break; + case 'c': if (strcmp(s+1, "enter") == 0) return CSCH_HALIGN_CENTER; break; + case 'e': if (strcmp(s+1, "nd") == 0) return CSCH_HALIGN_END; break; + case 'w': if (strcmp(s+1, "ord_justify") == 0) return CSCH_HALIGN_WORD_JUST; break; + case 'j': if (strcmp(s+1, "ustify") == 0) return CSCH_HALIGN_JUST; break; + } + return CSCH_HALIGN_invalid; +} + + +csch_text_t *csch_text_alloc(csch_sheet_t *sheet, csch_cgrp_t *parent, csch_oid_t oid) +{ + csch_text_t *text; + + text = htip_get(&parent->id2obj, oid); + if (text != NULL) + return NULL; + text = calloc(sizeof(csch_text_t), 1); + + csch_cobj_init(&text->hdr, sheet, parent, oid, CSCH_CTYPE_TEXT); + return text; +} + +/* Mirror and return rot_deg as mirx and miry directs */ +RND_INLINE double text_mirror_rot(const csch_text_t *text, double rot_deg, int mirx, int miry) +{ + double rot, sx, sy; + + if ((mirx == 0) && (miry == 0)) + return rot_deg; + + rot = rot_deg / RND_RAD_TO_DEG; + sx = cos(rot); sy = sin(rot); + if (mirx) sx = -sx; + if (miry) sy = -sy; + return atan2(sy, sx) * RND_RAD_TO_DEG; +} + +csch_text_t *csch_text_dup(csch_sheet_t *sheet, csch_cgrp_t *parent, const csch_text_t *src, int keep_id, int inst2spec) +{ + csch_text_t *dst = csch_text_alloc(sheet, parent, CSCH_KEEP_OID(parent, src->hdr.oid)); + + dst->has_bbox = src->has_bbox; + dst->halign = src->halign; + dst->text = rnd_strdup(src->text); + dst->dyntext = src->dyntext; + + + + if (inst2spec) { + g2d_xform_t mx; + g2d_vect_t v1 = src->inst1, v2 = src->inst2; + double ir; + + csch_cgrp_inverse_matrix(&mx, parent); + + /* undo the effect of text rotation on mirror; + Test the original bug: revert back to r7977, use + /work/manual_test/power.rs, select the right side circuit, drag&drop move + it one grid point to the right -> when using src->inst_rot instead of + ir, floater changes rotation by 180 deg */ + ir = text_mirror_rot(src, src->inst_rot, src->inst_mirx, src->inst_miry); + + dst->spec_rot = ir - parent->xform.rot; + dst->spec_mirx = src->inst_mirx ^ parent->xform.mirx; + dst->spec_miry = src->inst_miry ^ parent->xform.miry; + + v1 = g2d_xform_vect2vect(mx, v1); + v2 = g2d_xform_vect2vect(mx, v2); + dst->spec1 = v1; + dst->spec2 = v2; + csch_chdr_copy_meta4dup(&dst->hdr, &src->hdr); /* have to happen before update because of rtree (display layer change in this call) */ + csch_text_update(sheet, dst, 1); + } + else { + dst->spec1 = src->spec1; + dst->spec2 = src->spec2; + + dst->spec_rot = src->spec_rot; + dst->spec_mirx = src->spec_mirx; + dst->spec_miry = src->spec_miry; + dst->inst_rot = src->inst_rot; + dst->inst_raw_rot = src->inst_raw_rot; + dst->inst_mirx = src->inst_mirx; + dst->inst_miry = src->inst_miry; + + csch_chdr_copy_meta4dup(&dst->hdr, &src->hdr); + } + + return dst; +} + +void (*csch_cb_text_invalidate_font)(csch_sheet_t *sheet, csch_text_t *text) = NULL; +void (*csch_cb_text_calc_bbox)(csch_sheet_t *sheet, csch_text_t *text) = NULL; + +void csch_text_invalidate_font(csch_text_t *text) +{ + if (csch_cb_text_invalidate_font != NULL) + csch_cb_text_invalidate_font(text->hdr.sheet, text); +} + +void csch_text_invalidate_all_grp(csch_cgrp_t *grp, int dynonly) +{ + htip_entry_t *e; + for(e = htip_first(&grp->id2obj); e != NULL; e = htip_next(&grp->id2obj, e)) { + csch_chdr_t *obj = e->value; + if (obj->type == CSCH_CTYPE_TEXT) { + csch_text_t *text = (csch_text_t *)obj; + if (!dynonly || text->dyntext) { + if (dynonly) + csch_text_dyntext_inval(text); + csch_text_invalidate_font(text); + csch_cobj_redraw(text); + } + } + else if (csch_obj_is_grp(obj)) + csch_text_invalidate_all_grp((csch_cgrp_t *)obj, dynonly); + } +} + +void csch_text_invalidate_all_sheet(csch_sheet_t *sheet, int dynonly) +{ + csch_cobj_redraw_freeze(sheet); + csch_text_invalidate_all_grp(&sheet->direct, dynonly); + csch_cobj_redraw_unfreeze(sheet); +} + +void csch_text_invalidate_all_project(csch_project_t *prj, int dynonly) +{ + long n; + for(n = 0; n < prj->hdr.designs.used; n++) + csch_text_invalidate_all_sheet(prj->hdr.designs.array[n], dynonly); +} + + + +void csch_text_free(csch_text_t *text) +{ + csch_cobj_uninit(&text->hdr); + csch_text_invalidate_font(text); + free(text->rtext); + free(text->text); + free(text); +} + +csch_text_t *csch_text_get(csch_sheet_t *sheet, csch_cgrp_t *grp, csch_oid_t oid) +{ + csch_text_t *text = htip_get(&grp->id2obj, oid); + if ((text != NULL) && (text->hdr.type != CSCH_CTYPE_TEXT)) + return NULL; + return text; +} + +void csch_text_update_xform(csch_sheet_t *sheet, csch_text_t *text) +{ + if (text->hdr.parent != NULL) { + csch_child_xform_t *cx; + double cxrot, irot; + g2d_xform_t mx = csch_grp_ref_parent_mx(&text->hdr, &cx); + + text->inst1 = g2d_xform_vect2vect(mx, text->inst1); + text->inst2 = g2d_xform_vect2vect(mx, text->inst2); + text->inst15 = g2d_xform_vect2vect(mx, text->inst15); + text->inst25 = g2d_xform_vect2vect(mx, text->inst25); + text->inst_mirx = text->hdr.parent->xform.mirx ^ cx->mirx ^ text->spec_mirx; + text->inst_miry = text->hdr.parent->xform.miry ^ cx->miry ^ text->spec_miry; + + + if (text->inst_mirx ^ text->inst_miry) { + cxrot = -cx->rot; + irot = -text->inst_rot; + } + else { + cxrot = cx->rot; + irot = text->inst_rot; + } + + text->inst_raw_rot = irot + text->hdr.parent->xform.rot + cxrot; + text->inst_rot = text_mirror_rot(text, text->inst_rot + text->hdr.parent->xform.rot + cx->rot, text->inst_mirx, text->inst_miry); + } +} + +void csch_text_update_bbox(csch_sheet_t *sheet, csch_text_t *text) +{ + g2d_box_t bb = g2d_box_invalid(); + + g2d_box_bump_pt(&bb, text->inst1); + g2d_box_bump_pt(&bb, text->inst15); + g2d_box_bump_pt(&bb, text->inst2); + g2d_box_bump_pt(&bb, text->inst25); + + text->hdr.bbox.x1 = bb.p1.x; text->hdr.bbox.y1 = bb.p1.y; + text->hdr.bbox.x2 = bb.p2.x; text->hdr.bbox.y2 = bb.p2.y; +} + +void csch_text_update(csch_sheet_t *sheet, csch_text_t *text, int do_xform) +{ + if (!text->bbox_calcing) + csch_cobj_rtree_del(sheet, &text->hdr); + + if (!text->bbox_calcing) { + csch_cobj_redraw_freeze(sheet); + csch_cobj_update_pen(&text->hdr); + + if (!text->has_bbox && !text->bbox_calced) { + text->bbox_calcing = 1; + if (csch_cb_text_calc_bbox != NULL) + csch_cb_text_calc_bbox(sheet, text); + text->bbox_calced = 1; + text->bbox_calcing = 0; + } + csch_cobj_redraw_unfreeze(sheet); + } + + if (do_xform) { + text->spec15.x = text->spec2.x; text->spec15.y = text->spec1.y; + text->spec25.x = text->spec1.x; text->spec25.y = text->spec2.y; + + /* initial values of instance is copy of spec... */ + text->inst1 = text->spec1; + text->inst2 = text->spec2; + text->inst15 = text->spec15; + text->inst25 = text->spec25; + text->inst_rot = text->spec_rot; + text->inst_raw_rot = text->spec_rot; + text->inst_mirx = text->spec_mirx; + text->inst_miry = text->spec_miry; + + if (text->spec_mirx || text->spec_miry) { + csch_mirror_pt(&text->inst2.x, &text->inst2.y, text->inst1.x, text->inst1.y, text->spec_mirx, text->spec_miry); + csch_mirror_pt(&text->inst15.x, &text->inst15.y, text->inst1.x, text->inst1.y, text->spec_mirx, text->spec_miry); + csch_mirror_pt(&text->inst25.x, &text->inst25.y, text->inst1.x, text->inst1.y, text->spec_mirx, text->spec_miry); + } + + /* ... then add local text rotation keeping x1;y1 in place */ + if (text->inst_rot != 0) { + double cs, sn, rot = -fmod(text->inst_rot, 360.0) / RND_RAD_TO_DEG; + + if (text->spec_mirx ^ text->spec_miry) + rot = -rot; + + cs = cos(rot); sn = sin(rot); + csch_rotate_pt(&text->inst2.x, &text->inst2.y, text->inst1.x, text->inst1.y, cs, sn); + csch_rotate_pt(&text->inst15.x, &text->inst15.y, text->inst1.x, text->inst1.y, cs, sn); + csch_rotate_pt(&text->inst25.x, &text->inst25.y, text->inst1.x, text->inst1.y, cs, sn); + } + + /* ... and then parent transformation */ + csch_text_update_xform(sheet, text); + } + + csch_text_update_bbox(sheet, text); + + if (!text->bbox_calcing) { + csch_cobj_rtree_add(sheet, &text->hdr); + csch_cobj_bbox_changed(sheet, &text->hdr); + } +} + +int csch_text_invalid_chars(csch_text_t *txt) +{ + const char *s = csch_text_get_rtext(txt); + int ctr; + + if (s == NULL) + return 0; + + for(ctr = 0; *s != '\0'; s++) + if ((*s < 32) || (*s > 126)) + ctr++; + + return ctr; +} + +static csch_chdr_t *text_create(csch_sheet_t *sheet, csch_cgrp_t *parent) +{ + csch_text_t *text = csch_text_alloc(sheet, parent, csch_oid_new(sheet, parent)); + if (text == NULL) return NULL; + return &text->hdr; +} + +static void text_remove_alloc(csch_undo_remove_t *slot) +{ +} + +static void text_remove_redo(csch_undo_remove_t *slot) +{ + csch_cnc_common_remove_redo(slot, CSCH_REM_FROM_RTREE | CSCH_REM_FROM_PARENT | CSCH_REM_DEL_EMPTY_PARENT); +} + +static void text_remove_undo(csch_undo_remove_t *slot) +{ + csch_cnc_common_remove_undo(slot, CSCH_REM_FROM_RTREE | CSCH_REM_FROM_PARENT | CSCH_REM_DEL_EMPTY_PARENT); +} + +static int text_isc_with_box(csch_chdr_t *obj, csch_rtree_box_t *box) +{ + csch_text_t *text = (csch_text_t *)obj; + g2d_box_t gbox; + g2d_vect_t gbv[4]; + g2d_cline_t tedge[4]; + int n; + + /* (execute cheap tests first) */ + + gbox.p1.x = box->x1; gbox.p1.y = box->y1; + gbox.p2.x = box->x2; gbox.p2.y = box->y2; + + /* isc if any corner point of the text rectangle is within gbox */ + if (g2d_point_in_box(&gbox, text->inst1)) return 1; + if (g2d_point_in_box(&gbox, text->inst15)) return 1; + if (g2d_point_in_box(&gbox, text->inst2)) return 1; + if (g2d_point_in_box(&gbox, text->inst25)) return 1; + + + /* isc if any of the text rectangle edges are hit by any of the box edges */ + tedge[0].p1 = text->inst1; tedge[0].p2 = text->inst15; + tedge[1].p1 = text->inst15; tedge[1].p2 = text->inst2; + tedge[2].p1 = text->inst2; tedge[2].p2 = text->inst25; + tedge[3].p1 = text->inst25; tedge[3].p2 = text->inst1; + for(n = 0; n < 4; n++) { + if (g2d__iscp_cline_hcline(&tedge[n], box->y1, box->x1, box->x2, NULL, NULL)) return 1; + if (g2d__iscp_cline_hcline(&tedge[n], box->y2, box->x1, box->x2, NULL, NULL)) return 1; + if (g2d__iscp_cline_vcline(&tedge[n], box->x1, box->y1, box->y2, NULL, NULL)) return 1; + if (g2d__iscp_cline_vcline(&tedge[n], box->x2, box->y1, box->y2, NULL, NULL)) return 1; + } + + /* isc if any of the corner points of gbox is within the text; do this + by triangles of the text for efficiency */ + gbv[0].x = box->x1; gbv[0].y = box->y1; + gbv[1].x = box->x2; gbv[1].y = box->y1; + gbv[2].x = box->x2; gbv[2].y = box->y2; + gbv[3].x = box->x1; gbv[3].y = box->y2; + if (csch_any_point_in_triangle(text->inst1, text->inst15, text->inst2, gbv, 4)) return 1; + if (csch_any_point_in_triangle(text->inst1, text->inst25, text->inst2, gbv, 4)) return 1; + + return 0; +} + + +static void text_move(csch_sheet_t *sheet, csch_chdr_t *obj, csch_coord_t dx, csch_coord_t dy, int undoable) +{ + csch_text_t *text = (csch_text_t *)obj; + csch_text_modify(sheet, text, &dx, &dy, &dx, &dy, NULL, NULL, NULL, NULL, NULL, NULL, NULL, undoable, 1); +} + +static void text_copy(csch_sheet_t *sheet, csch_chdr_t *obj, csch_coord_t dx, csch_coord_t dy, int undoable) +{ + csch_text_t *text = csch_text_dup(sheet, obj->parent, (csch_text_t *)obj, 0, 0); + if (text != NULL) { + text->spec1.x += dx; text->spec1.y += dy; + text->spec2.x += dx; text->spec2.y += dy; + csch_text_update(sheet, text, 1); + csch_op_inserted(sheet, obj->parent, &text->hdr); + } +} + +static void text_rotate(csch_sheet_t *sheet, csch_chdr_t *obj, csch_coord_t rcx, csch_coord_t rcy, double da, int undoable) +{ + csch_text_t *text = (csch_text_t *)obj; + double rad, rot = fmod(text->spec_rot - da, 360.0); + csch_coord_t sx = text->spec2.x - text->spec1.x, sy = text->spec2.y - text->spec1.y; + csch_coord_t x1 = text->spec1.x, y1 = text->spec1.y, x2, y2; + + if (text->spec_mirx ^ text->spec_miry) + rot = -rot; + + rad = -rot / RND_RAD_TO_DEG; + + csch_rotate_pt(&x1, &y1, rcx, rcy, cos(rad), sin(rad)); + x2 = x1 + sx; y2 = y1 + sy; + + csch_text_modify(sheet, text, &x1, &y1, &x2, &y2, &rot, NULL, NULL, NULL, NULL, NULL, NULL, undoable, 0); +} + +static void text_rotate90(csch_sheet_t *sheet, csch_chdr_t *obj, csch_coord_t rcx, csch_coord_t rcy, int n, int undoable) +{ + csch_text_t *text = (csch_text_t *)obj; + double rot = fmod(text->spec_rot + (double)n * 90.0, 360.0); + csch_coord_t sx = text->spec2.x - text->spec1.x, sy = text->spec2.y - text->spec1.y; + csch_coord_t x1 = text->spec1.x, y1 = text->spec1.y, x2, y2; + + if (text->spec_mirx ^ text->spec_miry) + n = -n; + + csch_rotate90_pt(&x1, &y1, rcx, rcy, n); + x2 = x1 + sx; y2 = y1 + sy; + csch_text_modify(sheet, text, &x1, &y1, &x2, &y2, &rot, NULL, NULL, NULL, NULL, NULL, NULL, undoable, 0); +} + +static void text_mirror(csch_sheet_t *sheet, csch_chdr_t *obj, csch_coord_t mcx, csch_coord_t mcy, int mirx_in, int miry_in, int undoable) +{ + csch_text_t *text = (csch_text_t *)obj; + int mirx = text->spec_mirx, miry = text->spec_miry; + csch_coord_t x1 = text->spec1.x, y1 = text->spec1.y, x2 = text->spec2.x, y2 = text->spec2.y, w, h; + + if (!mirx_in && !miry_in) + return; + + if (mirx_in) + mirx = !mirx; + + if (miry_in) + miry = !miry; + + w = x2 - x1; h = y2 - y1; + csch_mirror_pt(&x1, &y1, mcx, mcy, mirx_in, miry_in); + x2 = x1 + w; y2 = y1 + h; + + csch_text_modify(sheet, text, &x1, &y1, &x2, &y2, NULL, &mirx, &miry, NULL, NULL, NULL, NULL, undoable, 0); +} + +static void text_inst2spec(csch_sheet_t *sheet, csch_chdr_t *obj, const csch_chdr_t *in, int undoable) +{ + csch_text_t *text = (csch_text_t *)in; + csch_coord_t x2, y2, sx, sy; + csch_coord_t x1 = text->inst1.x, y1 = text->inst1.y; + int mirx = text->inst_mirx, miry = text->inst_miry; + double rot = text->inst_raw_rot; + + if (mirx ^ miry) + rot = -rot; + + sx = text->spec2.x - text->spec1.x; if (sx < 0) sx = -sx; + sy = text->spec2.y - text->spec1.y; if (sy < 0) sy = -sy; + x2 = x1 + sx; + y2 = y1 + sy; + + csch_text_modify(sheet, (csch_text_t *)obj, &x1, &y1, &x2, &y2, &rot, &mirx, &miry, NULL, NULL, NULL, NULL, undoable, 0); +} + +const csch_ops_t csch_ops_text = { + text_create, text_remove_alloc, text_remove_redo, text_remove_undo, + text_isc_with_box, + text_move, text_copy, text_rotate, text_rotate90, text_mirror, + text_inst2spec +}; + +/*** hash ***/ + +unsigned csch_text_hash(const csch_text_t *text, csch_hash_ignore_t ignore) +{ + unsigned res = csch_chdr_hash(&text->hdr); + + if (!(ignore & CSCH_HIGN_FLOATER_GEO) || !text->hdr.floater) { + res ^= csch_coord_hash(text->spec1.x) + csch_coord_hash(text->spec1.y); + if (text->has_bbox) + res ^= csch_coord_hash(text->spec2.x) + csch_coord_hash(text->spec2.y); + res ^= csch_angle_hash(text->spec_rot); + res ^= ((unsigned)text->spec_mirx) << 7; + res ^= ((unsigned)text->spec_miry) << 8; + } + res ^= ((unsigned)text->has_bbox) << 3; + res ^= ((unsigned)text->halign); + res ^= ((unsigned)text->dyntext) << 5; + res ^= strhash(text->text); + + return res; +} + +int csch_text_keyeq(const csch_text_t *t1, const csch_text_t *t2, csch_hash_ignore_t ignore) +{ + if (!csch_chdr_eq(&t1->hdr, &t2->hdr)) return 0; + + if (!(ignore & CSCH_HIGN_FLOATER_GEO) || !t1->hdr.floater || !t2->hdr.floater) { + if (t1->spec1.x != t2->spec1.x) return 0; + if (t1->spec1.y != t2->spec1.y) return 0; + if (t1->has_bbox) { + if (t1->spec2.x != t2->spec2.x) return 0; + if (t1->spec2.y != t2->spec2.y) return 0; + } + if (t1->spec_rot != t2->spec_rot) return 0; + if (t1->spec_mirx != t2->spec_mirx) return 0; + if (t1->spec_miry != t2->spec_miry) return 0; + } + if (t1->has_bbox != t2->has_bbox) return 0; + if (t1->halign != t2->halign) return 0; + if (t1->dyntext != t2->dyntext) return 0; + if (strcmp(t1->text, t2->text) != 0) return 0; + return 1; +} + + +/*** Modify ***/ +typedef struct { + csch_text_t *texto; /* it is safe to save the object pointer because it is persistent (through the removed object list) */ + g2d_vect_t spec1, spec2; + double spec_rot; + csch_halign_t halign; + char *text; + unsigned spec_mirx:1; + unsigned spec_miry:1; + unsigned has_bbox:1; + unsigned dyntext:1; +} undo_text_modify_t; + + +static int undo_text_modify_swap(void *udata) +{ + undo_text_modify_t *u = udata; + + csch_cobj_redraw(u->texto); + + rnd_swap(g2d_vect_t, u->spec1, u->texto->spec1); + rnd_swap(g2d_vect_t, u->spec2, u->texto->spec2); + rnd_swap(double, u->spec_rot, u->texto->spec_rot); + rnd_swap(int, u->spec_mirx, u->texto->spec_mirx); + rnd_swap(int, u->spec_miry, u->texto->spec_miry); + rnd_swap(csch_halign_t, u->halign, u->texto->halign); + rnd_swap(char *, u->text, u->texto->text); + rnd_swap(int, u->has_bbox, u->texto->has_bbox); + rnd_swap(int, u->dyntext, u->texto->dyntext); + + csch_text_update(u->texto->hdr.sheet, u->texto, 1); + csch_sheet_set_changed(u->texto->hdr.sheet, 1); + csch_text_invalidate_font(u->texto); + csch_text_dyntext_inval(u->texto); + + csch_cobj_redraw(u->texto); + + return 0; +} + +static void undo_text_modify_print(void *udata, char *dst, size_t dst_len) +{ + undo_text_modify_t *u = udata; + + if (u->text == u->texto->text) + rnd_snprintf(dst, dst_len, "text change"); + else + rnd_snprintf(dst, dst_len, "text change (%s<->%s)", u->text, u->texto->text); +} + +static void undo_text_modify_free(void *udata) +{ + undo_text_modify_t *u = udata; + if (u->text != u->texto->text) + free(u->text); +} + +static const char core_text_cookie[] = "libcschem/core/cnc_text.c"; + +static const uundo_oper_t undo_text_modify = { + core_text_cookie, + undo_text_modify_free, + undo_text_modify_swap, + undo_text_modify_swap, + undo_text_modify_print +}; + + +void csch_text_modify(csch_sheet_t *sheet, csch_text_t *texto, + csch_coord_t *x1, csch_coord_t *y1, csch_coord_t *x2, csch_coord_t *y2, + double *spec_rot, int *spec_mirx, int *spec_miry, csch_halign_t *halign, + const char **text_, int *has_bbox, int *dyntext, int undoable, int relative) +{ + undo_text_modify_t utmp, *u = &utmp; + char **text = (char **)text_, *tmp; + + if (undoable) u = uundo_append(&sheet->undo, &undo_text_modify, sizeof(undo_text_modify_t)); + + if (text != NULL) { + tmp = rnd_strdup(*text); + text = &tmp; + } + + u->texto = texto; + u->spec1.x = (x1 == NULL) ? texto->spec1.x : (relative ? (texto->spec1.x + *x1) : *x1); + u->spec1.y = (y1 == NULL) ? texto->spec1.y : (relative ? (texto->spec1.y + *y1) : *y1); + u->spec2.x = (x2 == NULL) ? texto->spec2.x : (relative ? (texto->spec2.x + *x2) : *x2); + u->spec2.y = (y2 == NULL) ? texto->spec2.y : (relative ? (texto->spec2.y + *y2) : *y2); + u->spec_rot = CSCH_UNDO_RMODIFY(texto, spec_rot); + u->spec_mirx = CSCH_UNDO_MODIFY(texto, spec_mirx); + u->spec_miry = CSCH_UNDO_MODIFY(texto, spec_miry); + u->halign = CSCH_UNDO_MODIFY(texto, halign); + u->text = CSCH_UNDO_MODIFY(texto, text); + u->has_bbox = CSCH_UNDO_MODIFY(texto, has_bbox); + u->dyntext = CSCH_UNDO_MODIFY(texto, dyntext); + + undo_text_modify_swap(u); + if (undoable) csch_undo_inc_serial(sheet); + else undo_text_modify_free(u); +} + Index: tags/1.0.5/src/libcschem/cnc_text.h =================================================================== --- tags/1.0.5/src/libcschem/cnc_text.h (nonexistent) +++ tags/1.0.5/src/libcschem/cnc_text.h (revision 10414) @@ -0,0 +1,141 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + + +#ifndef CSCH_CONCRETE_TEXT_H +#define CSCH_CONCRETE_TEXT_H +#include "libcschem/concrete.h" +#include GENGEO2D_TYPECFG +#include "gengeo2d/prim.h" + +/* type=CSCH_CTYPE_TEXT */ + +typedef enum { + CSCH_HALIGN_START, + CSCH_HALIGN_CENTER, + CSCH_HALIGN_END, + CSCH_HALIGN_WORD_JUST, + CSCH_HALIGN_JUST, + CSCH_HALIGN_invalid +} csch_halign_t; + +const char *csch_halign2str(csch_halign_t halign); +csch_halign_t csch_str2halign(const char *s); +extern const char *csch_halign_names[]; /* NULL terminated */ + +typedef struct csch_text_s { + csch_chdr_t hdr; + g2d_vect_t spec1, spec2; /* x1,y1 and x2,y2 as specified */ + double spec_rot; /* rotation, as specified */ + double inst_rot; /* instance rotation (with all transformations) */ + csch_halign_t halign; + char *text; /* DO NOT USE: in case of dyntext this is only the template, see rtext below; call csch_text_get_rtext() instead */ + unsigned has_bbox:1; /* x2 and y2 are specified; when 0, spec2 is calculated and not saved */ + unsigned dyntext:1; + unsigned spec_mirx:1; + unsigned spec_miry:1; + + unsigned inst_mirx:1; + unsigned inst_miry:1; + double inst_raw_rot; + + /* cached */ + unsigned bbox_calced:1; /* when has_bbox==0, we need to get the app calculate spec2 - when this is 1, it is already calculated */ + unsigned bbox_calcing:1; /* the above calculation is taking palce, lock recursion */ + g2d_vect_t inst1, inst2; /* instance: as transformed from the spec */ + g2d_vect_t inst15, inst25; /* instance: the other two corners; order: inst1, inst15, inst2, inst25 */ + g2d_vect_t spec15, spec25; + char *rtext; /* rendered text; in case of dyntext it differs from ->text, this one is the substituted version */ + + /* the application may use these fields to store a rendered font info */ + void *pixmap; + long pix_sx, pix_sy; + csch_coord_t crd_sx, crd_sy, net_sx, net_sy, off_x, off_y, extra_spc, extra_glyph; + double scale; + + /* the application may use these fields to store temporary data e.g. while loading a file */ + union { + long l; + void *p; + } tmp[4]; +} csch_text_t; + +#include + +/* the application is called back... (the application needs to load this) */ +extern void (*csch_cb_text_invalidate_font)(csch_sheet_t *sheet, csch_text_t *text); /* remove font pixmap/cache */ +extern void (*csch_cb_text_calc_bbox)(csch_sheet_t *sheet, csch_text_t *text); /* calculate bounding box for a text that doesn't have ->has_bbox set */ + +csch_text_t *csch_text_alloc(csch_sheet_t *sheet, csch_cgrp_t *parent, csch_oid_t oid); +csch_text_t *csch_text_dup(csch_sheet_t *sheet, csch_cgrp_t *parent, const csch_text_t *src, int keep_id, int inst2spec); +void csch_text_free(csch_text_t *text); +csch_text_t *csch_text_get(csch_sheet_t *sheet, csch_cgrp_t *grp, csch_oid_t oid); +void csch_text_update(csch_sheet_t *sheet, csch_text_t *text, int do_xform); + +/* if text is not NULL, it's strdup'd */ +void csch_text_modify(csch_sheet_t *sheet, csch_text_t *texto, + csch_coord_t *x1, csch_coord_t *y1, csch_coord_t *x2, csch_coord_t *y2, + double *rot, int *mirx, int *miry, csch_halign_t *halign, const char **text, + int *has_bbox, int *dyntext, int undoable, int relative); + +unsigned csch_text_hash(const csch_text_t *text, csch_hash_ignore_t ignore); +int csch_text_keyeq(const csch_text_t *t1, const csch_text_t *t2, csch_hash_ignore_t ignore); + +/* non-standard calls */ + +/* Force application to re-render the text (drop render cache) */ +void csch_text_invalidate_font(csch_text_t *text); + +/* Invalidate and redraw all text objects; if dynonly is 1, do this only + on text objects marked as dyntext but also make sure their render-text are + re-generated too */ +void csch_text_invalidate_all_grp(csch_cgrp_t *grp, int dynonly); +void csch_text_invalidate_all_sheet(csch_sheet_t *sheet, int dynonly); +void csch_text_invalidate_all_project(csch_project_t *prj, int dynonly); + +/* Return rendered text; never returns NULL. */ +RND_INLINE const char *csch_text_get_rtext(csch_text_t *text); + +/* Return the number of non-7-bit-ASCII-printable characters in rendered + txt string */ +int csch_text_invalid_chars(csch_text_t *txt); + + +/*** Implementation ***/ +RND_INLINE const char *csch_text_get_rtext(csch_text_t *text) +{ + if (text->rtext == NULL) + csch_text_dyntext_render(text); + + if (text->rtext == NULL) + return ""; + + return text->rtext; +} + +#endif Index: tags/1.0.5/src/libcschem/cnc_text_dyn.c =================================================================== --- tags/1.0.5/src/libcschem/cnc_text_dyn.c (nonexistent) +++ tags/1.0.5/src/libcschem/cnc_text_dyn.c (revision 10414) @@ -0,0 +1,228 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2018,2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/* Dynamic text (dyntext) management/render */ + +#include "config.h" + +#include +#include +#include +#include + +#include "abstract.h" +#include "cnc_text.h" +#include "cnc_grp.h" +#include "cnc_text_dyn.h" +#include "project.h" + +RND_INLINE const csch_chdr_t *get_attrib_obj(char **path, const csch_text_t *text) +{ + const csch_chdr_t *hdr = &text->hdr; + for(;;) { + if (((*path)[0] == '.') && ((*path)[1] == '.') && ((*path)[2] == '/')) { + if (hdr->parent != NULL) + hdr = &hdr->parent->hdr; + *path += 3; + } + else break; + } + return hdr; +} + +static const char *get_filename(csch_sheet_t *sheet) +{ + const char *sep, *fn = sheet->hidlib.fullpath; + + if (fn == NULL) + return ""; + + sep = strrchr(fn, '/'); + if (sep != NULL) + return sep+1; /* basename */ + + return fn; +} + +static const char *prj_name(const char *fullpath) +{ + static char res[1024], *d; + const char *s; + + for(s = rnd_parent_dir_name(fullpath), d = res; *s != '/'; s++, d++) { + if ((d - res) > sizeof(res)-2) + break; + *d = *s; + } + *d = '\0'; + return res; +} + +static const char *get_prjname(csch_sheet_t *sheet) +{ + const char *fn = sheet->hidlib.loadname; + csch_project_t *prj = NULL; + htsp_entry_t *e; + + if ((fn == NULL) || (fn[0] == '<')) + return " (save sheet!)"; + + prj = (csch_project_t *)sheet->hidlib.project; + if (prj == NULL) + return " (no project)"; + + if (prj->hdr.fullpath != NULL) + return prj_name(prj->hdr.fullpath); + + for(e = htsp_first(&rnd_projects); e != NULL; e = htsp_next(&rnd_projects, e)) + if (prj == e->value) + return prj_name(e->key); + + return " (unnamed prj)"; +} + +static const char *dyntext_get_attr_val(const csch_attribs_t *attrs, const char *key) +{ + const char *val = csch_attrib_get_str(attrs, key); + if (val == NULL) { + const vts0_t *arr = csch_attrib_get_arr(attrs, key); + if (arr != NULL) { + if (arr->used == 1) + val = arr->array[0]; + else + val = ""; + } + } + return val; +} + + +static int csch_text_render_str_cb(void *ctx, gds_t *s, const char **input) +{ + const csch_text_t *text = ctx; + const csch_attribs_t *attrs = NULL; + const csch_chdr_t *agrp; + char *end, key[128], *path; + const char *val = NULL; + size_t len; + + end = strchr(*input, '%'); + len = end - *input; + if (len > sizeof(key)-1) + return -1; + + strncpy(key, *input, len); + key[len] = '\0'; + *input += len+1; + + if (strcmp(key, "filename") == 0) { + val = get_filename(text->hdr.sheet); + goto append; + } + if (strcmp(key, "project.name") == 0) { + val = get_prjname(text->hdr.sheet); + goto append; + } + if (strncmp(key, "stance.", 7) == 0) { + val = csch_stance_get(key+7); + goto append; + } + if (strncmp(key, "view.", 5) == 0) { + val = csch_view_get_prop((csch_project_t *)text->hdr.sheet->hidlib.project, -1, key+5); + goto append; + } + + + path = key; + agrp = get_attrib_obj(&path, text); + if ((path[0] == 'A') && (path[1] == '.')) { + if (agrp != NULL) { + csch_cgrp_t *g = (csch_cgrp_t *)agrp; + attrs = &g->attr; + } + path+=2; + if (attrs != NULL) { + val = dyntext_get_attr_val(attrs, path); + goto append; + } + } + else if ((path[0] == 'a') && (path[1] == '.')) { + int hier_idx = 0; + csch_ahdr_t *a = NULL; + + path+=2; + TODO("hierarchic: provide a spinbox next to the view name for selecting hier_idx here instead of hardwiring 0"); + if (agrp != NULL) { + assert(csch_obj_is_grp(agrp)); + a = csch_cgrp_get_abstract(text->hdr.sheet, (const csch_cgrp_t *)agrp, hier_idx); + } + if (a != NULL) + attrs = &a->attr; + if (attrs != NULL) { + val = dyntext_get_attr_val(attrs, path); + goto append; + } + } + return 0; + + append:; + if (val != NULL) + gds_append_str(s, val); + return 0; +} + + +void csch_text_dyntext_inval(csch_text_t *text) +{ + free(text->rtext); + text->rtext = NULL; +} + +void csch_text_dyntext_render(csch_text_t *text) +{ + const char *empty = "\001"; + csch_text_dyntext_inval(text); + + if (text->dyntext) { + gds_t tmp = {0}; + rnd_subst_append(&tmp, text->text, csch_text_render_str_cb, (void *)text, RND_SUBST_PERCENT | RND_SUBST_CONF, 0); + if ((tmp.array == NULL) || (*tmp.array == '\0')) { + text->rtext = rnd_strdup(empty); + gds_uninit(&tmp); + } + else + text->rtext = tmp.array; + } + else { + if ((text->text == NULL) || (*text->text == '\0')) + text->rtext = rnd_strdup(empty); + else + text->rtext = rnd_strdup(text->text); + } +} + Index: tags/1.0.5/src/libcschem/cnc_text_dyn.h =================================================================== --- tags/1.0.5/src/libcschem/cnc_text_dyn.h (nonexistent) +++ tags/1.0.5/src/libcschem/cnc_text_dyn.h (revision 10414) @@ -0,0 +1,43 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/* Dynamic text (dyntext) management/render */ + + +#ifndef CSCH_CONCRETE_TEXT_DYN_H +#define CSCH_CONCRETE_TEXT_DYN_H + +#include + +/* Render text->rtext (may allocate it) */ +void csch_text_dyntext_render(csch_text_t *text); + +/* Free text->rtext and make it NULL */ +void csch_text_dyntext_inval(csch_text_t *text); + +#endif Index: tags/1.0.5/src/libcschem/common_types.h =================================================================== --- tags/1.0.5/src/libcschem/common_types.h (nonexistent) +++ tags/1.0.5/src/libcschem/common_types.h (revision 10414) @@ -0,0 +1,33 @@ +#ifndef CSCH_COMMON_TYPES_H +#define CSCH_COMMON_TYPES_H + +#include "libcschem/config.h" + +typedef struct csch_chdr_s csch_chdr_t; + +typedef csch_sint32_t csch_oid_t; +#define CSCH_INVALID_OID ((csch_oid_t)(0)) +#define CSCH_MAX_OID ((csch_oid_t)0x7FFFFFFF) + +#define CSCH_COORD_MIN ((csch_coord_t)(-((1UL<<31)-1))) +#define CSCH_COORD_MAX ((csch_coord_t)(+((1UL<<31)-1))) +#define CSCH_COORD_INV CSCH_COORD_MAX + +/* from concrete.h */ +typedef struct csch_cpen_s csch_cpen_t; +typedef struct csch_sheet_s csch_sheet_t; +typedef struct csch_cgrp_s csch_cgrp_t; + +/* from abstract.h */ +typedef struct csch_abstract_s csch_abstract_t; +typedef struct csch_ahdr_s csch_ahdr_t; + +/* project/view */ +typedef struct csch_project_s csch_project_t; +typedef struct csch_view_s csch_view_t; +typedef struct csch_view_eng_s csch_view_eng_t; + +/* for non-graphical sheets (non_graphical.h) */ +typedef struct csch_non_graphical_impl_s csch_non_graphical_impl_t; + +#endif Index: tags/1.0.5/src/libcschem/compile.c =================================================================== --- tags/1.0.5/src/libcschem/compile.c (nonexistent) +++ tags/1.0.5/src/libcschem/compile.c (revision 10414) @@ -0,0 +1,1019 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2018,2019,2022..2024 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022, Entrust in 2023) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include "config.h" + +#include + +#include + +#include "abstract.h" +#include "actions_csch.h" +#include "concrete.h" +#include "event.h" +#include "cnc_line.h" +#include "cnc_arc.h" +#include "cnc_poly.h" +#include "cnc_text.h" +#include "cnc_bitmap.h" +#include "cnc_conn.h" +#include "cnc_grp.h" +#include "cnc_pen.h" +#include "cnc_obj.h" +#include "engine.h" +#include "project.h" +#include "util_compile.h" +#include "util_project.h" +#include "libcschem.h" +#include "non_graphical.h" +#include "hierarchy.h" + +#include "compile.h" + +int csch_compile_attribute(csch_ahdr_t *dst, const char *dstkey, const csch_attrib_t *srca, csch_source_arg_t *src, const char *err1, const char *err2, int referee, int append, csch_attrib_t **dsta_out) +{ + csch_attrib_t *dsta = NULL; + const char *key = (dstkey == NULL ? srca->key : dstkey); + const char *sval, *dval; + + if (key[0] == '-') { + if (dsta_out != NULL) *dsta_out = NULL; + csch_attr_src_free(src); + return 0; + } + + if (key[0] == '+') { + key++; + append = 1; + } + + dsta = csch_attrib_get(&dst->attr, key); + if (dsta_out != NULL) *dsta_out = dsta; + + sval = srca == NULL ? NULL : srca->val; + dval = dsta == NULL ? NULL : dsta->val; + + /* Hierarchic special casing: remove hierarchic prefix from the name + attribute so it doesn't cause conflicts, e.g. when a v/foo is merged with + a matching ^/foo */ + if ((key[0] == 'n') || (key[1] == 'a') || (key[2] == 'm') || (key[3] == 'e') || (key[4] == '\0')) { + if (sval != NULL) + csch_split_name_scope(&sval); + if (dval != NULL) + csch_split_name_scope(&dval); + } + + /* attribute merging logic */ + if (sval != NULL) { + if (append) + return csch_attrib_append_val(&dst->attr, srca->prio, key, srca, src); + if (dsta != NULL) { + if (dval != NULL) { + if (strcmp(sval, dval) == 0) { + /* both set, same value, remember lowest prio */ + if (srca->prio >= dsta->prio) { + csch_attrib_append_src(dsta, srca->prio, src, 1); + csch_attr_src_free(src); + return 0; /* ignore new */ + } + } + else { + /* different values, look at prios */ + if (srca->prio > dsta->prio) { + csch_attrib_append_src(dsta, srca->prio, src, 1); + csch_attr_src_free(src); + return 0; /* lower prio, ignore */ + } + if (srca->prio == dsta->prio) { + if (!referee) /* it's okay if a group ref's referee had it - we are overwriting it from the group ref */ + rnd_message(RND_MSG_ERROR, "compile_attributes(): %s %s: attribute collision for '%s'\n", err1, err2, srca->key); + csch_attr_src_free(src); + return -1; + } + /* else set */ + } + } + } + csch_attrib_set(&dst->attr, srca->prio, key, sval, src, dsta_out); + } + else { + if (append) { + if ((dsta != NULL) && (dval != NULL)) { + csch_attr_src_free(src); + rnd_message(RND_MSG_ERROR, "compile_attributes(): %s %s: can not append to destination attribute '%s', it is a string not an array\n", err1, err2, key); + return -1; + } + return csch_attrib_append_val(&dst->attr, srca->prio, key, srca, src); + } + else + csch_attrib_set_arr(&dst->attr, srca->prio, key, &srca->arr, src, dsta_out); + } + + return 0; +} + +/* Copy all sources from srca in front of the sources in dst */ +static void compile_attribute_copy_srcs_front(csch_attrib_t *dst, const csch_attrib_t *srca) +{ + long n; + + if (srca->source.used <= 0) + return; + + vts0_alloc_insert(&dst->source, 0, srca->source.used); + for(n = 0; n < srca->source.used; n++) + dst->source.array[n] = rnd_strdup(srca->source.array[n]); +} + +static int compile_attributes(csch_ahdr_t *dst, const csch_attribs_t *src, csch_cgrp_t *cgrp, const char *err1, const char *err2, int referee) +{ + htsp_entry_t *e; + int res = 0, r1; + + for(e = htsp_first(src); e; e = htsp_next(src, e)) { + const csch_attrib_t *srca = e->value; + csch_source_arg_t *src = csch_attrib_src_ac(&cgrp->hdr, srca->key, "compile_attributes()"); + csch_attrib_t *dsta; + + r1 = csch_compile_attribute(dst, NULL, srca, src, err1, err2, referee, 0, &dsta); + + if ((r1 == 0) && (dsta != NULL)) + compile_attribute_copy_srcs_front(dsta, srca); + + res |= r1; + } + + TODO("this should return res"); + return 0; +} + +static int compile_wire_net(csch_abstract_t *dst, int viewid, csch_hier_path_t *hpath, const csch_sheet_t *sheet, csch_cgrp_t *src) +{ + char tmpname[128]; + const char *orig_name; + char *name_glob = NULL, *name_loc = NULL; + const csch_attrib_t *aname; + csch_anet_t *net; + int no_uname = 0; + csch_ascope_t scope; + + aname = csch_attrib_get(&src->attr, "name"); + dst->ucnt.wirenet++; + if ((aname == NULL) || (aname->key == NULL) || (*aname->key == '\0')) { + sprintf(tmpname, "anon_net_%ld", dst->ucnt.wirenet); + orig_name = tmpname; + no_uname = 1; + } + else + orig_name = aname->val; + + scope = csch_split_name_scope(&orig_name); + + /* Translate name, including hierarchical address prefixes */ + csch_eng_call_namemod((csch_project_t *)sheet->hidlib.project, viewid, hpath, CSCH_ENGHK_WIRENET_NAME_TO_NET_NAME, + &name_glob, &name_loc, orig_name, FGW_COBJ, src, FGW_HPATH, hpath, FGW_INVALID); + + if (name_glob == NULL) { + rnd_message(RND_MSG_ERROR, "Internal error: failed to perform wire_net name translation\n"); + return -1; + } + + net = csch_anet_get_at(dst, hpath->hlev, scope, name_loc); + if (net == NULL) { + net = csch_anet_new(dst, hpath->hlev, scope, name_glob, name_loc, no_uname); + if (net == NULL) { + csch_eng_free_namemod(&name_glob, &name_loc); + return -1; + } + } + csch_eng_free_namemod(&name_glob, &name_loc); + + csch_compile_add_source(src, &net->hdr); + return compile_attributes(&net->hdr, &src->attr, src, "net", orig_name, 0); +} + +static csch_aport_t *compile_port(csch_abstract_t *dst, int viewid, csch_hier_path_t *hpath, const csch_sheet_t *sheet, csch_acomp_t *comp, csch_cgrp_t *t, int hier_down) +{ + char tmpname[128]; + const csch_attrib_t *trole, *tname; + const char *orig_name; + char *name_glob = NULL, *name_loc = NULL; + csch_aport_t *port = NULL; + + if ((t->hdr.type != CSCH_CTYPE_GRP) && (t->hdr.type != CSCH_CTYPE_GRP_REF)) + return NULL; + + if (t->hdr.type == CSCH_CTYPE_GRP_REF) + trole = csch_cgrp_ref_get_attr(t, "role"); + else + trole = csch_attrib_get(&t->attr, "role"); + if ((trole == NULL) || (trole->val == NULL) || (strcmp(trole->val, "terminal") != 0)) + return NULL; + + if (t->hdr.type == CSCH_CTYPE_GRP_REF) + tname = csch_cgrp_ref_get_attr(t, "name"); + else + tname = csch_attrib_get(&t->attr, "name"); + + dst->ucnt.port++; + + if ((tname == NULL) || (tname->key == NULL) || (*tname->key == '\0')) { + sprintf(tmpname, "anon_%ld", dst->ucnt.port); + orig_name = tmpname; + } + else + orig_name = tname->val; + + csch_eng_call_namemod((csch_project_t *)sheet->hidlib.project, viewid, hpath, CSCH_ENGHK_TERMINAL_NAME_TO_PORT_NAME, + &name_glob, &name_loc, orig_name, FGW_AOBJ, comp, FGW_COBJ, t, FGW_HPATH, hpath, FGW_INVALID); + + if (name_glob == NULL) { + rnd_message(RND_MSG_ERROR, "Internal error: failed to perform port name translation\n"); + return NULL; + } + + port = csch_aport_get(dst, comp, name_glob, 1); + if (port == NULL) + return NULL; + + port->parent = comp; + csch_compile_add_source(t, &port->hdr); + + compile_attributes(&port->hdr, &t->attr, t, "port", orig_name, 0); + + csch_eng_free_namemod(&name_glob, &name_loc); + + return port; +} + +/* Compile a normal (non-sheet-ref) symbol into a component; */ +static int compile_symbol_to_component(csch_abstract_t *dst, int viewid, csch_hier_path_t *hpath, csch_ascope_t scope, const csch_sheet_t *sheet, csch_cgrp_t *src, char *name_glob, char *name_loc, const char *orig_name) +{ + htip_entry_t *e; + csch_acomp_t *comp; + int res = 0; + + /* don't compile if it had no name - note: at the moment this can't happen (because of anon_comp_%ld) */ + if (orig_name == NULL) + return 0; + + comp = csch_acomp_get_at(dst, hpath->hlev, scope, name_loc); + if (comp == NULL) + comp = csch_acomp_new(dst, hpath->hlev, scope, name_glob, name_loc); + + if (comp == NULL) + return -1; + + csch_compile_add_source(src, &comp->hdr); + + res |= compile_attributes(&comp->hdr, &src->attr, src, "component", orig_name, 0); + if ((src->hdr.type == CSCH_CTYPE_GRP_REF) && (src->data.ref.grp != NULL)) + res |= compile_attributes(&comp->hdr, &src->data.ref.grp->attr, src->data.ref.grp, "component", orig_name, 1); + + csch_eng_call((csch_project_t *)sheet->hidlib.project, viewid, hpath, CSCH_ENGHK_SYMBOL_JOINED_COMPONENT, + FGW_COBJ, src, FGW_AOBJ, comp, FGW_HPATH, hpath, FGW_INVALID); + + /* compile ports */ + for(e = htip_first(&src->id2obj); e != NULL; e = htip_next(&src->id2obj, e)) + compile_port(dst, viewid, hpath, sheet, comp, e->value, 0); + + return res; +} + +/* Return is grp is directly on the sheet and not within a symbol on any level */ +static int is_grp_a_sheet_port(const csch_sheet_t *sheet, csch_cgrp_t *grp) +{ + csch_cgrp_t *g; + + for(g = grp->hdr.parent; g != NULL; g = g->hdr.parent) { + if (g == &sheet->direct) + return 1; + if (g->role == CSCH_ROLE_SYMBOL) + return 0; + } + + return 1; +} + +/* Hierarchic: search child sheet terminals and return the abstract port that + has a matching port name (or NULL if not found) */ +static csch_aport_t *find_subsheet_port(csch_abstract_t *dst, csch_sheet_t *child, const char *port_name) +{ + csch_chdr_t *h; + + for(h = gdl_first(&child->active); h != NULL; h = gdl_next(&child->active, h)) { + csch_cgrp_t *grp = (csch_cgrp_t *)h; + + if (h->indirect) + continue; + + if ((h->type != CSCH_CTYPE_GRP) && (h->type != CSCH_CTYPE_GRP_REF)) + continue; + + /* can use enum role here because role attribute overwrite is handled in csch_cgrp_ref_render() */ + if (grp->role == CSCH_ROLE_TERMINAL) { + if (is_grp_a_sheet_port(child, grp)) { + long n; + for(n = 0; n < grp->aid.used; n++) { + csch_aport_t *aport = htip_get(&dst->aid2obj, grp->aid.array[n]); + if ((aport != NULL) && (aport->hdr.type == CSCH_ATYPE_PORT)) { + if (strcmp(aport->name, port_name) == 0) + return aport; + } + } + } + } + } + + return NULL; +} + +/* Returns whether a sheet ref sym has parameter pass-down attributes */ +static int srs_has_params(csch_cgrp_t *srs) +{ + htsp_entry_t *e; + + for(e = htsp_first(&srs->attr); e != NULL; e = htsp_next(&srs->attr, e)) + if (strncmp(e->key, "cschem/param/", 13) == 0) + return 1; + + return 0; +} + +int csch_compile_descend(csch_abstract_t *dst, int viewid, csch_hier_path_t *hpath, csch_cgrp_t *srs, char *name_loc, csch_sheet_t *child) +{ + int res, restore_attrs = 0; + csch_hier_temp_t htmp; + csch_attribs_t aorig; + + /* pass down parameters by temporary switching child to a new attribute hash */ + if (srs_has_params(srs)) { + htsp_entry_t *e, *old; + + /* clone orig attrs */ + memcpy(&aorig, &child->direct.attr, sizeof(csch_attribs_t)); + csch_attrib_init(&child->direct.attr); + csch_attrib_copy_all(&child->direct.attr, &aorig); + restore_attrs = 1; + + /* copy the new ones */ + for(e = htsp_first(&srs->attr); e != NULL; e = htsp_next(&srs->attr, e)) { + if (strncmp(e->key, "cschem/param/", 13) == 0) { + const char *new_key = e->key+13; + csch_attrib_t *a = csch_attrib_dup_rename(e->value, new_key); + + old = htsp_popentry(&child->direct.attr, new_key); + if (old != NULL) + csch_attr_free(e->value); + + htsp_set(&child->direct.attr, a->key, a); + } + } + } + + res = csch_hier_enter(hpath, &htmp, srs, name_loc); + if (res != 0) return -1; + res = csch_compile_sheet_(dst, viewid, hpath, child); + csch_hier_leave(hpath, &htmp); + + /* restore child's old attribute hash (undo parameter passing) */ + if (restore_attrs) { + csch_attrib_uninit(&child->direct.attr); + memcpy(&child->direct.attr, &aorig, sizeof(csch_attribs_t)); + } + + return res; +} + +/* Compile a normal (non-sheet-ref) symbol into a component; use name_tmp + if available, else use name_ */ +static int compile_symbol_child_sheet(csch_abstract_t *dst, int viewid, csch_hier_path_t *hpath, csch_ascope_t scope, const csch_sheet_t *sheet, csch_cgrp_t *src, char *name_glob, char *name_loc, const char *orig_name, csch_sheet_t *child) +{ + int res; + csch_acomp_t *comp; + htip_entry_t *e; + + if (orig_name == NULL) { + rnd_message(RND_MSG_ERROR, "Sheet reference symbol in hierarchic design must have a name\n"); + return -1; /* comp has no name -> error - can't happen because of anon_comp_%ld */ + } + + comp = csch_acomp_get(dst, name_glob); + if (comp == NULL) { + comp = csch_acomp_new(dst, hpath->hlev, CSCH_ASCOPE_SHEET_LOCAL, name_glob, name_loc); + + res = csch_compile_descend(dst, viewid, hpath, src, name_loc, child); + + comp->child_sheet = child; + comp->hdr.omit = 1; + } + else + res = 0; + + /* Bind sheet ref sym terminals to child sheet terminals */ + for(e = htip_first(&src->id2obj); e != NULL; e = htip_next(&src->id2obj, e)) { + csch_aport_t *sym_port; + const char *sym_port_api_name; + + sym_port = compile_port(dst, viewid, hpath, sheet, comp, e->value, 1); + + if (sym_port != NULL) { + sym_port_api_name = sym_port->name; + sym_port->subsheet_port = find_subsheet_port(dst, child, sym_port_api_name); + if (sym_port->subsheet_port == NULL) { + rnd_message(RND_MSG_ERROR, + "Hierarchy error: sheet %s doesn't have terminal %s for symbol port %s:%s\n", + child->hidlib.loadname, sym_port_api_name, comp->name, sym_port_api_name); + res = -1; + } + else + sym_port->subsheet_port->referer = comp; + sym_port->hdr.omit = 1; + } + } + + return res; +} + +static int compile_symbol(csch_abstract_t *dst, int viewid, csch_hier_path_t *hpath, const csch_sheet_t *sheet, csch_cgrp_t *src, rnd_bool do_sheet_ref_syms) +{ + char tmpname[128]; + const char *orig_name; + char *name_glob = NULL, *name_loc = NULL; + const csch_attrib_t *aname = NULL; + csch_sheet_t *child = NULL; + int hres, cres; + csch_ascope_t scope = CSCH_ASCOPE_unknown; + + hres = csch_hier_find_sym_child(sheet, src, &child, 0); + if (hres < 0) + return hres; + + /* we are called in two passes, first doing non-sheet-refs then sheet refs */ + if ((hres == 0) && do_sheet_ref_syms) + return 0; + if ((hres == 1) && !do_sheet_ref_syms) + return 0; + + if (src->hdr.type == CSCH_CTYPE_GRP_REF) + aname = csch_cgrp_ref_get_attr(src, "name"); + else + aname = csch_attrib_get(&src->attr, "name"); + + + dst->ucnt.comp++; + if ((aname == NULL) || (aname->key == NULL) || (*aname->key == '\0')) { + sprintf(tmpname, "anon_comp_%ld", dst->ucnt.comp); + orig_name = tmpname; + } + else { + orig_name = aname->val; + scope = csch_split_name_scope(&orig_name); + } + + csch_eng_call_namemod((csch_project_t *)sheet->hidlib.project, viewid, hpath, CSCH_ENGHK_SYMBOL_NAME_TO_COMPONENT_NAME, + &name_glob, &name_loc, orig_name, FGW_COBJ, src, FGW_HPATH, hpath, FGW_INVALID); + + if (name_glob == NULL) { + csch_eng_free_namemod(&name_glob, &name_loc); + rnd_message(RND_MSG_ERROR, "Internal error: failed to perform symbol name translation\n"); + return -1; + } + + + if (hres == 1) + cres = compile_symbol_child_sheet(dst, viewid, hpath, scope, sheet, src, name_glob, name_loc, orig_name, child); + else + cres = compile_symbol_to_component(dst, viewid, hpath, scope, sheet, src, name_glob, name_loc, orig_name); + + csch_eng_free_namemod(&name_glob, &name_loc); + + return cres; +} + +int csch_compile_connect_net_to(csch_anet_t **net, csch_ahdr_t *a, int allow_reconn) +{ + if (a->type == CSCH_ATYPE_PORT) { + csch_aport_t *ap = (csch_aport_t *)a; + csch_anet_t *new_net; + + if (ap->sheet_port) { +/* rnd_trace(" conn sheet port '%s' to net '%s'!\n", ap->name, (*net)->name);*/ + ap->hdr.omit = 1; + /* go on so that sheet local connections are made */ + } + + if ((ap->parent != NULL) && (ap->parent->child_sheet != NULL)) { +/* rnd_trace(" conn ref sym port '%s' to net '%s'!\n", ap->name, (*net)->name);*/ + if ((ap->subsheet_port != NULL) && (ap->subsheet_port->conn.net)) { +/* rnd_trace(" connect to subsheet port's net %s\n", ap->subsheet_port->conn.net->name);*/ + new_net = csch_cmp_merge_nets(*net, ap->subsheet_port->conn.net); + if (new_net == NULL) { + rnd_message(RND_MSG_ERROR, "csch_compile_connect_net_to(): failed to merge nets %s and %s at port %s:%s for hierarchic connection down\n", (*net)->name, ap->subsheet_port->conn.net->name, ap->parent->name, ap->name); + return -1; + } + *net = new_net; + } + /* go on so that sheet local connections are made */ + } + + if (ap->conn.net != NULL) { + int allowed = 0; + + /* special case: resistor term overlap with vcc term and a wire is + also connected; this means we have a term-term net and a wirenet + and this shouldn't be considered as a reconn because the + term-term connection is really invisible */ + if (ap->conn.net->term_term || (*net)->term_term) + allowed = 1; + + if (!allow_reconn && !allowed) { + rnd_message(RND_MSG_ERROR, "csch_compile_connect_net_to(): port %s:%s already connected\n(This error is generated because multiport_net_merge is disabled in the config)\n", ap->parent->name, ap->name); + return -1; + } + new_net = csch_cmp_merge_nets(*net, ap->conn.net); + if (new_net == NULL) { + rnd_message(RND_MSG_ERROR, "csch_compile_connect_net_to(): failed to merge nets %s and %s at port %s:%s\n", (*net)->name, ap->conn.net->name, ap->parent->name, ap->name); + return -1; + } + *net = new_net; + } + ap->conn.net = *net; + + TODO("bus: do the same for buses and bus ports? Or do we put nets in buses?"); + vtp0_append(&(*net)->conns, a); + return 0; + } + + rnd_message(RND_MSG_ERROR, "csch_compile_connect_net_to(): unsupported object type\n"); + return -1; +} + +int csch_compile_disconnect(csch_ahdr_t *a) +{ + if (a->type == CSCH_ATYPE_PORT) { + csch_aport_t *ap = (csch_aport_t *)a; + csch_anet_t *net = ap->conn.net; + long n; + + if (net == NULL) + return 0; /* already disconnected */ + + ap->conn.net = NULL; + for(n = 0; n < net->conns.used; n++) { + if (net->conns.array[n] == ap) { + vtp0_remove(&net->conns, n, 1); + break; + } + } + + return 0; + } + rnd_message(RND_MSG_ERROR, "csch_compile_disconnect(): unsupported object type\n"); + return -1; +} + + +static int compile_conn(csch_abstract_t *dst, const csch_sheet_t *sheet, csch_hier_path_t *hpath, const csch_conn_t *src) +{ + long n; + csch_anet_t *net = NULL; + + if (src->conn.used < 2) { + rnd_msg_error("Ignoring conn object with %d connection(s) - needs at least 2\n", src->conn.used); + return -1; + } + + + /* first pass: find the net */ + for(n = 0; n < src->conn.used; n++) { + const csch_chdr_t *obj = src->conn.array[n]; + const csch_cgrp_t *grp = obj->parent; + csch_ahdr_t *a; + + TODO("remove this:"); + if (grp == NULL) continue; + + if ((grp->hdr.type != CSCH_CTYPE_GRP) && (grp->hdr.type != CSCH_CTYPE_GRP_REF)) + continue; + + if (grp->aid.used < 1) { + rnd_msg_error("Invalid object on the conn list (empty); conn id: #%ld\n", src->hdr.oid); + return -1; + } + + a = htip_get(&dst->aid2obj, grp->aid.array[0]); + if (a == NULL) { + rnd_msg_error("Invalid object on the conn list (NULL); conn id: #%ld\n", src->hdr.oid); + return -1; + } + switch(a->type) { + case CSCH_ATYPE_NET: + if ((net != NULL) && (&net->hdr != a)) { + TODO("figure how to handle network collisions"); + rnd_msg_error("Network collision\n"); + return -1; + } + net = (csch_anet_t *)a; + break; + case CSCH_ATYPE_PORT: + break; + default: + rnd_msg_error("Invalid object on the conn list (%s)\n", csch_atype_name(a->type)); + return -1; + } + } + + /* create an anon net if there was no wirenet in the conn list; this happens + in a term-term connection */ + if (net == NULL) { + char tmpname[128]; + + sprintf(tmpname, "anon_net_%ld", ++dst->ucnt.wirenet); + net = csch_anet_new(dst, NULL, CSCH_ASCOPE_GLOBAL, tmpname, tmpname, 1); + if (net == NULL) { + rnd_msg_error("failed to create anon net for terminal-terminal connection\n"); + return -1; + } + net->term_term = 1; + net->hdepth = hpath->hdepth; + net->hlev = hpath->hlev; /* even tho it won't be referenced because it's a globally unique name... */ + } + + /* second pass: make the connections */ + for(n = 0; n < src->conn.used; n++) { + const csch_chdr_t *obj = src->conn.array[n]; + const csch_cgrp_t *grp = obj->parent; + csch_ahdr_t *a; + + TODO("remove this:"); + if (grp == NULL) continue; + + if ((grp->hdr.type != CSCH_CTYPE_GRP) && (grp->hdr.type != CSCH_CTYPE_GRP_REF)) + continue; + + if (grp->aid.used < 1) + continue; + + a = htip_get(&dst->aid2obj, grp->aid.array[0]); + if (a == &net->hdr) + continue; + + if (csch_compile_connect_net_to(&net, a, CSCH_CFG(multiport_net_merge, 0)) != 0) + return -1; + } + return 0; +} + +static void compile_reset_abstract(csch_abstract_t *dst) +{ + /* reset uniq name counters */ + dst->ucnt.wirenet = 0; + dst->ucnt.comp = 0; + dst->ucnt.port = 0; + dst->ucnt.target_tmp = 0; +} + +static void csch_reset_sheet_aids(const csch_sheet_t *src) +{ + const csch_chdr_t *h; + + for(h = gdl_first(&src->active); h != NULL; h = gdl_next(&src->active, h)) { + if (csch_obj_is_grp(h)) { + csch_cgrp_t *grp = (csch_cgrp_t *)h; + grp->aid.used = 0; + } + } +} + + +int csch_compile_sheet_(csch_abstract_t *dst, int viewid, csch_hier_path_t *hpath, const csch_sheet_t *src) +{ + int res = 0; + const csch_chdr_t *h; + + if (src->non_graphical) { + if ((src->non_graphical_impl == NULL) || (src->non_graphical_impl->compile_sheet == NULL)) { + rnd_message(RND_MSG_ERROR, "Don't know how to compile non-graphical sheet %s\n", src->hidlib.fullpath); + return -1; + } + return src->non_graphical_impl->compile_sheet(dst, viewid, hpath, src); + } + + csch_reset_sheet_aids(src); + + /* compile nets and non-sheet-ref components */ + for(h = gdl_first(&src->active); h != NULL; h = gdl_next(&src->active, h)) { + csch_cgrp_t *grp = (csch_cgrp_t *)h; + + if (h->indirect) + continue; + + if ((h->type != CSCH_CTYPE_GRP) && (h->type != CSCH_CTYPE_GRP_REF)) + continue; + + /* can use enum role here because role attribute overwrite is handled in csch_cgrp_ref_render() */ + switch(grp->role) { + case CSCH_ROLE_WIRE_NET: res |= compile_wire_net(dst, viewid, hpath, src, grp); break; + case CSCH_ROLE_SYMBOL: res |= compile_symbol(dst, viewid, hpath, src, grp, 0); break; + + case CSCH_ROLE_TERMINAL: + if (is_grp_a_sheet_port(src, grp)) { + csch_aport_t *aport = compile_port(dst, viewid, hpath, src, NULL, grp, 0); + csch_eng_call((csch_project_t *)src->hidlib.project, viewid, hpath, CSCH_ENGHK_COMPILE_PORT, FGW_AOBJ, aport, FGW_HPATH, hpath, FGW_INVALID); + aport->sheet_port = 1; +/* rnd_trace("Sheet port: prefix='%s' name='%s'\n", hpath->prefix.array, aport->name);*/ + } + break; + + case CSCH_ROLE_invalid: + case CSCH_ROLE_empty: + case CSCH_ROLE_BUS_NET: + case CSCH_ROLE_BUS_TERMINAL: + case CSCH_ROLE_HUB_POINT: + case CSCH_ROLE_JUNCTION: + break; + } + } + + /* compile sheet-ref components */ + for(h = gdl_first(&src->active); h != NULL; h = gdl_next(&src->active, h)) { + csch_cgrp_t *grp = (csch_cgrp_t *)h; + + if (h->indirect) + continue; + + if ((h->type != CSCH_CTYPE_GRP) && (h->type != CSCH_CTYPE_GRP_REF)) + continue; + + if (grp->role == CSCH_ROLE_SYMBOL) + res |= compile_symbol(dst, viewid, hpath, src, grp, 1); + } + + csch_eng_call((csch_project_t *)src->hidlib.project, viewid, hpath, CSCH_ENGHK_CONNS_BEFORE, + FGW_PTR, dst, FGW_HPATH, hpath, FGW_INVALID); + + /* compile connections between nets and components (the "netlist" part) */ + for(h = gdl_first(&src->active); h != NULL; h = gdl_next(&src->active, h)) { + const csch_conn_t *conn = (const csch_conn_t *)h; + + if (h->indirect) + continue; + + if (h->type != CSCH_CTYPE_CONN) + continue; + res |= compile_conn(dst, src, hpath, conn); + } + + csch_eng_call((csch_project_t *)src->hidlib.project, viewid, hpath, CSCH_ENGHK_CONNS_AFTER, + FGW_PTR, dst, FGW_HPATH, hpath, FGW_INVALID); + + + return res; +} + +int csch_compile_sheet(csch_abstract_t *dst, int viewid, const csch_sheet_t *src) +{ + int res; + csch_hier_path_t hpath; + + csch_hier_path_init(&hpath, dst); + + compile_reset_abstract(dst); + + res = csch_compile_sheet_(dst, viewid, &hpath, src); + + csch_hier_path_free(&hpath); + return res; +} + +/* Returns whether the loop should be restarted because of new components added */ +RND_INLINE int csch_compile_post_port(csch_project_t *proj, int viewid, csch_hier_path_t *hpath, csch_abstract_t *dst, csch_aport_t *port) +{ + if (port->hdr.compiled) return 0; + port->hdr.compiled = 1; + + csch_eng_call(proj, viewid, hpath, CSCH_ENGHK_COMPILE_PORT, FGW_AOBJ, port, FGW_INVALID); + + return dst->new_ports; +} + + +/* Returns whether the loop should be restarted because of new components added */ +RND_INLINE int csch_compile_post_comp(csch_project_t *proj, int viewid, csch_hier_path_t *hpath, csch_abstract_t *dst, csch_acomp_t *comp) +{ + htsp_entry_t *p; + + if (comp->hdr.compiled) return 0; + comp->hdr.compiled = 1; + + csch_eng_call(proj, viewid, hpath, CSCH_ENGHK_COMPILE_COMPONENT0, FGW_AOBJ, comp, FGW_INVALID); + csch_compile_update_obj_cache(&comp->hdr); + csch_eng_call(proj, viewid, hpath, CSCH_ENGHK_COMPILE_COMPONENT1, FGW_AOBJ, comp, FGW_INVALID); + csch_compile_update_obj_cache(&comp->hdr); + + restart_port:; + dst->new_ports = 0; + for(p = htsp_first(&comp->ports); p != NULL; p = htsp_next(&comp->ports, p)) + if (csch_compile_post_port(proj, viewid, hpath, dst, p->value)) + goto restart_port; /* if new components are created restart the loop because genht gets confused */ + + csch_eng_call(proj, viewid, hpath, CSCH_ENGHK_COMPILE_COMPONENT2, FGW_AOBJ, comp, FGW_INVALID); + return dst->new_comps; +} + +/* Returns whether the loop should be restarted because of new components added */ +RND_INLINE int csch_compile_post_net(csch_project_t *proj, int viewid, csch_hier_path_t *hpath, csch_abstract_t *dst, csch_anet_t *net) +{ + if (net->hdr.compiled) return 0; + net->hdr.compiled = 1; + + csch_eng_call(proj, viewid, hpath, CSCH_ENGHK_COMPILE_NET, FGW_AOBJ, net, FGW_INVALID); + + return dst->new_nets; +} + +RND_INLINE void csch_compile_post_update_cache_(csch_ahdr_t *obj) +{ + const char *val; + + val = csch_attrib_get_str(&obj->attr, "display/dnp"); + if ((val != NULL) && (*val != '\0')) + obj->dnp = 1; + + val = csch_attrib_get_str(&obj->attr, "display/omit"); + if ((val != NULL) && (*val != '\0')) + obj->omit = 1; +} + +void csch_compile_update_obj_cache(csch_ahdr_t *obj) +{ + csch_compile_post_update_cache_(obj); +} + + +/* Calculate all caches in the abstract model after the compilation has finished */ +RND_INLINE void csch_compile_post_update_cache(csch_project_t *proj, int viewid, csch_abstract_t *abst) +{ + htsp_entry_t *n, *c, *p; + + for(n = htsp_first(&abst->nets); n != NULL; n = htsp_next(&abst->nets, n)) { + csch_anet_t *net = n->value; + csch_compile_post_update_cache_(&net->hdr); + } + + + for(c = htsp_first(&abst->comps); c != NULL; c = htsp_next(&abst->comps, c)) { + csch_acomp_t *comp = c->value; + csch_compile_post_update_cache_(&comp->hdr); + for(p = htsp_first(&comp->ports); p != NULL; p = htsp_next(&comp->ports, p)) { + csch_aport_t *port = p->value; + csch_compile_post_update_cache_(&port->hdr); + } + } +} + +static int cmp_comp_hdepth(const void *C1, const void *C2) +{ + const csch_acomp_t **c1 = (const csch_acomp_t **)C1; + const csch_acomp_t **c2 = (const csch_acomp_t **)C2; + + if ((*c1)->hdepth > (*c2)->hdepth) return 1; + return -1; +} + +int csch_compile_post(csch_project_t *proj, int viewid, csch_abstract_t *dst) +{ + htsp_entry_t *e; + csch_sheet_t *sheet; + csch_hier_path_t *hpath = NULL; /* we have no path after compilation */ + vtp0_t lst = {0}; + long n; + + /* NOTE: have to sort objects and go from top to bottom in hierarchy to + make surethe top end of a v/foo reference is created before the bottom + end ^/foo (or just foo) is found */ + + restart_comp:; + lst.used = 0; + dst->new_comps = 0; + for(e = htsp_first(&dst->comps); e != NULL; e = htsp_next(&dst->comps, e)) { + csch_acomp_t *acomp = e->value; + if (!acomp->postprocessed) + vtp0_append(&lst, acomp); + } + + if (lst.used > 0) { + qsort(lst.array, lst.used, sizeof(void *), cmp_comp_hdepth); + + for(n = 0; n < lst.used; n++) { + csch_acomp_t *acomp = lst.array[n]; + acomp->postprocessed = 1; + csch_compile_post_comp(proj, viewid, hpath, dst, acomp); + } + + if (dst->new_comps) + goto restart_comp; + } + + lst.used = 0; + + + restart_net:; + dst->new_nets = 0; + for(e = htsp_first(&dst->nets); e != NULL; e = htsp_next(&dst->nets, e)) + if (csch_compile_post_net(proj, viewid, hpath, dst, e->value)) + goto restart_net; /* if new components are created restart the loop because genht gets confused */ + + vtp0_uninit(&lst); + + csch_text_invalidate_all_project(proj, 1); + + csch_eng_call(proj, viewid, NULL, CSCH_ENGHK_PROJECT_AFTER, + FGW_PTR, dst, FGW_PTR, proj, FGW_INVALID); + + csch_compile_post_update_cache(proj, viewid, dst); + + sheet = *vtp0_get(&proj->hdr.designs, 0, 0); + rnd_event(&sheet->hidlib, CSCH_EVENT_PRJ_COMPILED, NULL); + + return 0; +} + +int csch_compile_project(csch_project_t *prj, int viewid, csch_abstract_t *dst, int quiet) +{ + int res = 0, r; + long n; + htpp_entry_t *e; + + compile_reset_abstract(dst); + htpp_init(&dst->eng_transient, ptrhash, ptrkeyeq); + dst->view_id = viewid; + dst->prj = prj; + + if (csch_project_is_partial(prj)) + rnd_message(RND_MSG_ERROR, "*** PARTIAL PROJECT ***\nNot all root sheets are loaded, the resulting abstract model\nwill be partial too.\n"); + + csch_eng_call(prj, viewid, NULL, CSCH_ENGHK_PROJECT_BEFORE, + FGW_PTR, dst, FGW_PTR, prj, FGW_INVALID); + + for(n = 0; n < vtp0_len(&prj->hdr.designs); n++) { + csch_sheet_t *sheet = *vtp0_get(&prj->hdr.designs, n, 0); + + /* hierarchy: start from root sheets only, skip aux sheets; unlisted/unknown are rather compiled so no-project-file works */ + if ((sheet->stype == CSCH_SHTY_AUX) || (sheet->stype == CSCH_SHTY_EXTERNAL)) continue; + if ((sheet->stype == CSCH_SHTY_UNLISTED) || (sheet->stype == CSCH_SHTY_unknown)) { + if (prj->num_root_sheets != 0) { + rnd_message(RND_MSG_WARNING, "Compile: not compiling sheet %s: unlisted file in a project with explicit sheet list in project file\n", sheet->hidlib.loadname); + if (!sheet->non_graphical) + csch_reset_sheet_aids(sheet); + continue; + } + else { + /* implicit project file, accept and compile unlisted sheets */ + } + } + + { + csch_hier_path_t hpath; + csch_hier_path_init(&hpath, dst); + r = csch_compile_sheet_(dst, viewid, &hpath, sheet); + csch_hier_path_free(&hpath); + } + if (r != 0) + rnd_message(RND_MSG_ERROR, "sheet #%d (%s) compilation failed: %d\n", n, sheet->hidlib.fullpath, r); + res |= r; + } + csch_compile_post(prj, viewid, dst); + + for(e = htpp_first(&dst->eng_transient); e != NULL; e = htpp_next(&dst->eng_transient, e)) + rnd_message(RND_MSG_ERROR, "csch_compile_project(): engine transient leftover: %s (memory leak)\n", e->key); + htpp_uninit(&dst->eng_transient); + dst->prj = NULL; + return res; +} Index: tags/1.0.5/src/libcschem/compile.h =================================================================== --- tags/1.0.5/src/libcschem/compile.h (nonexistent) +++ tags/1.0.5/src/libcschem/compile.h (revision 10414) @@ -0,0 +1,79 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2019 Tibor 'Igor2' Palinkas + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#ifndef CSCH_COMPILE_H +#define CSCH_COMPILE_H + +#include +#include +#include + +int csch_compile_sheet(csch_abstract_t *dst, int viewid, const csch_sheet_t *src); +int csch_compile_post(csch_project_t *proj, int viewid, csch_abstract_t *dst); + +int csch_compile_project(csch_project_t *prj, int viewid, csch_abstract_t *dst, int quiet); + + +/*** utility for plugins ***/ + +/* Compile attribute src of cgrp into dst. If dstkey is NULL, srca's + key is used. src is used for history and is always freed. + Err1 and err2 are two strings printed in error messages + for location, with space in between. If referee is 1, src is a group + ref. If append is 1, append src array to dst array (fails if either + src or dst attrib is not an array). If append is 0, but src key starts + with '+', append is set to 1 internally. If dsta_out is not NULL, + destination attribute (abstract model) is returned there. + Returns 0 on success. */ +int csch_compile_attribute(csch_ahdr_t *dst, const char *dstkey, const csch_attrib_t *srca, csch_source_arg_t *src, const char *err1, const char *err2, int referee, int append, csch_attrib_t **dsta_out); + + +/* For compiler hooks in plugins */ +int csch_compile_connect_net_to(csch_anet_t **net, csch_ahdr_t *a, int allow_reconn); +int csch_compile_disconnect(csch_ahdr_t *a); + +/* Updates hdr cache fields, e.g. dnp and omit, from attributes; useful after + setting such an attribute or before depending on such an attribute */ +void csch_compile_update_obj_cache(csch_ahdr_t *obj); + + +/* Descend in hierarchy to compile the child sheet for dst; srs is the sheet + ref symbol, name_loc is the short name of the srs that is going to be + used as the next segment in the hierarchic path. Returns 0 on success. */ +int csch_compile_descend(csch_abstract_t *dst, int viewid, csch_hier_path_t *hpath, csch_cgrp_t *srs, char *name_loc, csch_sheet_t *child); + + +/*** for lib itnernal use ***/ + +RND_INLINE void csch_compile_add_source(csch_cgrp_t *src, csch_ahdr_t *abst) +{ + vtl0_append(&src->aid, abst->aid); + vtp0_append(&abst->srcs, src); +} + +int csch_compile_sheet_(csch_abstract_t *dst, int viewid, csch_hier_path_t *hpath, const csch_sheet_t *src); + +#endif Index: tags/1.0.5/src/libcschem/concrete.c =================================================================== --- tags/1.0.5/src/libcschem/concrete.c (nonexistent) +++ tags/1.0.5/src/libcschem/concrete.c (revision 10414) @@ -0,0 +1,271 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2018,2023 Tibor 'Igor2' Palinkas + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + + +#include +#include +#include +#include +#include +#include +#include "concrete.h" +#include "event.h" +#include "cnc_obj.h" +#include "cnc_grp.h" +#include "non_graphical.h" +#include "project.h" +#include "plug_library.h" + +static const char *dsply_names[CSCH_DSPLY_max] = { + "background", + "wire", + "bus", + "symbol decoration", + "hub & terminal", + "sheet decoration", + "symbol", + "connections", + "symbol meta", + "text meta" +}; + +int csch_layer_vis[CSCH_DSPLY_max] = {1, 1, 1, 1, 1, 1, 1, 1, 0, 0}; +int csch_export_layer_vis[CSCH_DSPLY_max] = {1, 1, 1, 1, 1, 1, 1, 0, 0, 0}; + +const char *csch_dsply_name(csch_displayer_t dsply) +{ + if ((dsply < 0) || (dsply >= CSCH_DSPLY_max)) + return ""; + return dsply_names[dsply]; +} + +csch_rtree_t *csch_rtree_lookup_by_name(csch_sheet_t *sheet, const char *name) +{ + int n; + + for(n = 0; n < CSCH_DSPLY_max; n++) { + int len; + + len = strlen(dsply_names[n]); + if (strncmp(name, dsply_names[n], len) == 0) { + name += len; + goto found; + } + } + return NULL; + + found:; + while(isspace(*name) || (*name == '-') || (*name == '_') || (*name == '/')) name++; + if (*name == '\0') return &sheet->dsply[n]; + if (strcmp(name, "fill") == 0) return &sheet->dsply_fill[n]; + if (strcmp(name, "stroke") == 0) return &sheet->dsply[n]; + return NULL; +} + + +static const char *ctype_names[CSCH_CTYPE_max] = { "invalid", "line", "arc", "polygon", "text", "bitmap", "connection", "grp", "grp_ref", "pen" }; +const char *csch_ctype_name(csch_ctype_t typ) +{ + if ((typ < 0) || (typ >= CSCH_CTYPE_max)) + return ""; + return ctype_names[typ]; +} + +static long next_uid; + +csch_sheet_t *csch_sheet_init(csch_sheet_t *sheet, csch_project_t *parent) +{ + int n; + + if (sheet == NULL) + return NULL; + + if (parent != NULL) + rnd_project_append_design(&parent->hdr, &sheet->hidlib); + + sheet->uid = next_uid++; + htsp_init(&sheet->comm_str, strhash, strkeyeq); + + sheet->util_wirenet.recalc_inhibit = 0; + htpi_init(&sheet->util_wirenet.recalc_wn, ptrhash, ptrkeyeq); + + for(n = 0; n < CSCH_DSPLY_max; n++) { + csch_rtree_init(&sheet->dsply[n]); + csch_rtree_init(&sheet->dsply_fill[n]); + } + + csch_cgrp_init(sheet, &sheet->direct, NULL, CSCH_TOP_OID_DIRECT); + csch_cgrp_init(sheet, &sheet->indirect, NULL, CSCH_TOP_OID_INDIRECT); + + csch_bbox_invalidate(&sheet->bbox); + sheet->junction_pen_name = csch_comm_str(sheet, "junction", 1); + + uundo_list_init(&sheet->undo); + + return sheet; +} + +csch_sheet_t *csch_sheet_alloc(csch_project_t *parent) +{ + + return csch_sheet_init(calloc(sizeof(csch_sheet_t), 1), parent); +} + +void csch_sheet_uninit(csch_sheet_t *sheet) +{ + int n; + + if (sheet->non_graphical && (sheet->non_graphical_impl != NULL) && (sheet->non_graphical_impl->free_sheet != NULL)) { + sheet->non_graphical_impl->free_sheet(sheet); + sheet->non_graphical_data = NULL; + sheet->non_graphical_impl = NULL; + } + + htpi_uninit(&sheet->util_wirenet.recalc_wn); + + csch_lib_free_sheet_local_libs(sheet); + csch_lib_free_sheet_libs(sheet); + + uundo_list_uninit(&sheet->undo); + + csch_cgrp_uninit(&sheet->direct); + csch_cgrp_uninit(&sheet->indirect); + + TODO("free all objects in the hash"); + for(n = 0; n < CSCH_DSPLY_max; n++) { + csch_rtree_uninit(&sheet->dsply[n]); + csch_rtree_uninit(&sheet->dsply_fill[n]); + } + + genht_uninit_deep(htsp, &sheet->comm_str, { + free(htent->key); + }); + + free(sheet->newname); + sheet->newname = NULL; + free(sheet->hidlib.loadname); + sheet->hidlib.loadname = NULL; + free(sheet->hidlib.fullpath); + sheet->hidlib.fullpath = NULL; + free(sheet->loadfmt); + sheet->loadfmt = NULL; + free(sheet->design_dir); + sheet->design_dir = NULL; + +} + +void csch_sheet_free(csch_sheet_t *sheet) +{ + rnd_event(&sheet->hidlib, CSCH_EVENT_SHEET_PREUNLOAD, NULL); + if (sheet->hidlib.project != NULL) + rnd_project_remove_design(sheet->hidlib.project, &sheet->hidlib); + if (sheet->hidlib.link.parent != NULL) /* NULL for buffers */ + rnd_conf_state_del_design(&sheet->hidlib); /* also removes curr from rnd_designs */ + csch_sheet_uninit(sheet); + free(sheet); +} + +void csch_sheet_bbox_update(csch_sheet_t *sheet) +{ + csch_cgrp_bbox_update(sheet, &sheet->direct); + sheet->bbox = sheet->direct.bbox_flt; +} + +csch_oid_t csch_oid_new(csch_sheet_t *sheet, csch_cgrp_t *grp) +{ + if (grp->data.grp.next_id == 0) + grp->data.grp.next_id = 1; + + assert(grp->hdr.type == CSCH_CTYPE_GRP); + assert(grp->data.grp.next_id < CSCH_MAX_OID); + return grp->data.grp.next_id++; +} + +void csch_chdr_copy_meta4dup(csch_chdr_t *dst, const csch_chdr_t *src) +{ + if (dst->sheet != src->sheet) { + /* cross-sheet copy: need to use dst sheet's pen name hash */ + dst->stroke_name = csch_comm_str(dst->sheet, src->stroke_name.str, 1); + dst->fill_name = csch_comm_str(dst->sheet, src->fill_name.str, 1); + } + else { + /* cheap: copy within a sheet means names are from the same hash */ + dst->stroke_name = src->stroke_name; + dst->fill_name = src->fill_name; + } + + dst->dsply = src->dsply; + dst->lock = src->lock; + dst->floater = src->floater; +} + +char *csch_chdr_to_oidpath_str(const csch_chdr_t *chdr) +{ + csch_oidpath_t oidp; + char *res; + + memset(&oidp, 0, sizeof(oidp)); + csch_oidpath_from_obj(&oidp, chdr); + res = csch_oidpath_to_str(&oidp); + csch_oidpath_free(&oidp); + return res; +} + +csch_comm_str_t csch_comm_str(csch_sheet_t *sheet, const char *str, int alloc) +{ + csch_comm_str_t res; + + if (str != NULL) { + htsp_entry_t *e = htsp_getentry(&sheet->comm_str, str); + if (e != NULL) { + res.str = e->key; + return res; + } + + if (alloc) { + res.str = rnd_strdup(str); + htsp_set(&sheet->comm_str, (char *)res.str, NULL); + return res; + } + } + + /* allocate the standard NULL string for "not found but not allocated" */ + res.str = NULL; + return res; +} + +void csch_sheet_set_changed(csch_sheet_t *sheet, int new_val) +{ + int old = sheet->changed; + + sheet->changed = new_val; + + if (old != new_val) + rnd_event(&sheet->hidlib, RND_EVENT_DESIGN_META_CHANGED, NULL); + + if (new_val) + rnd_event(&sheet->hidlib, CSCH_EVENT_SHEET_EDITED, NULL); +} Index: tags/1.0.5/src/libcschem/concrete.h =================================================================== --- tags/1.0.5/src/libcschem/concrete.h (nonexistent) +++ tags/1.0.5/src/libcschem/concrete.h (revision 10414) @@ -0,0 +1,365 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2018, 2022, 2024 Tibor 'Igor2' Palinkas + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + + +#ifndef CSCH_CONCRETE_H +#define CSCH_CONCRETE_H + +#include +#include +#include + +#include + +#include "libcschem/common_types.h" +#include "libcschem/rtree.h" +#include "libcschem/attrib.h" +#include "libcschem/oidpath.h" +#include +#include +#include +#include +#include +#include +#include +#include GENGEO2D_TYPECFG +#include + +/* the two top level sheet groups have hardwired OIDs by the spec */ +#define CSCH_TOP_OID_INDIRECT 1 +#define CSCH_TOP_OID_DIRECT 2 + +typedef enum csch_displayer_e { + CSCH_DSPLY_BACKGROUND, /* bottom: decoration */ + CSCH_DSPLY_WIRE, /* wiring: wires, hubs, anything non-bus */ + CSCH_DSPLY_BUS, /* buses only */ + CSCH_DSPLY_SYMBOL, /* symbol graphics that are not in HUBTERM */ + CSCH_DSPLY_HUBTERM, /* non-in-symbol hubs, terminals (overrides symbol so symbol terminals are included) */ + CSCH_DSPLY_DECORATION, /* text, annotations, titleblocks */ + CSCH_DSPLY_SYMBOL_GRP, /* symbol groups and group refs */ + CSCH_DSPLY_CONN, /* connections or missing connections */ + CSCH_DSPLY_SYMBOL_META, /* symbol bbox and loclib info */ + CSCH_DSPLY_TEXT_META, /* text bbox and orientation */ + CSCH_DSPLY_max, + CSCH_DSPLY_invalid = -1 +} csch_displayer_t; + +extern int csch_layer_vis[CSCH_DSPLY_max]; +extern int csch_export_layer_vis[CSCH_DSPLY_max]; + +typedef enum csch_ctype_s { + CSCH_CTYPE_invalid = 0, + CSCH_CTYPE_LINE, + CSCH_CTYPE_ARC, + CSCH_CTYPE_POLY, + CSCH_CTYPE_TEXT, + CSCH_CTYPE_BITMAP, + CSCH_CTYPE_CONN, + CSCH_CTYPE_GRP, + CSCH_CTYPE_GRP_REF, + CSCH_CTYPE_PEN, + CSCH_CTYPE_max +} csch_ctype_t; + +typedef enum csch_cmask_s { + CSCH_CMASK_LINE = (1 << CSCH_CTYPE_LINE), + CSCH_CMASK_ARC = (1 << CSCH_CTYPE_ARC), + CSCH_CMASK_POLY = (1 << CSCH_CTYPE_POLY), + CSCH_CMASK_TEXT = (1 << CSCH_CTYPE_TEXT), + CSCH_CMASK_BITMAP = (1 << CSCH_CTYPE_BITMAP), + CSCH_CMASK_CONN = (1 << CSCH_CTYPE_CONN), + CSCH_CMASK_GRP = (1 << CSCH_CTYPE_GRP), + CSCH_CMASK_GRP_REF = (1 << CSCH_CTYPE_GRP_REF), + CSCH_CMASK_PEN = (1 << CSCH_CTYPE_PEN), + + /* composites */ + CSCH_CMASK_ANY_GRP = CSCH_CMASK_GRP | CSCH_CMASK_GRP_REF, + CSCH_CMASK_ANY_ATOM = CSCH_CMASK_LINE | CSCH_CMASK_ARC | CSCH_CMASK_POLY | CSCH_CMASK_TEXT | CSCH_CMASK_BITMAP, + CSCH_CMASK_ANY = 65535 +} csch_cmask_t; + +typedef enum csch_role_s { + CSCH_ROLE_invalid, + CSCH_ROLE_empty, + CSCH_ROLE_BUS_NET, + CSCH_ROLE_BUS_TERMINAL, + CSCH_ROLE_HUB_POINT, + CSCH_ROLE_SYMBOL, + CSCH_ROLE_TERMINAL, + CSCH_ROLE_WIRE_NET, + CSCH_ROLE_JUNCTION +} csch_role_t; + +typedef struct csch_comm_str_s { + const char *str; /* sheet comm_str hash key */ +} csch_comm_str_t; + +struct csch_chdr_s { + csch_rtree_box_t bbox; /* CACHE: first field to easy rtree handling */ + + csch_oid_t oid; + csch_ctype_t type; + csch_cgrp_t *parent; + csch_comm_str_t stroke_name, fill_name; /* used to resolve pen */ + gdl_elem_t link; /* sheet's active or removed list */ + + /* common properties (as per {des3:81}) */ + unsigned int lock:1; /* deduced from the lock attribute */ + unsigned int floater:1; /* deduced from the floater attribute */ + + /*** cached ***/ + csch_cpen_t *stroke, *fill; + csch_sheet_t *sheet; + csch_displayer_t dsply; + vtp0_t conn; /* in which connections the current object participates */ + struct { + csch_cgrp_t *g; /* grp_ref that hosts transformations for this object */ + long idx; /* transformation index within grpref's child_xform array */ + } grp_ref_xform; + + unsigned int indirect:1; + + /*** gui states (not saved) ***/ + unsigned int selected:1; + unsigned int hilight:1; + + /** for integrity check and other sync plugins ***/ + unsigned mark:1; + unsigned visit:1; + void *mark_ptr; +}; + +struct csch_cgrp_s { /* type=CSCH_CTYPE_GRP || CSCH_CTYPE_GRP_REF */ + csch_chdr_t hdr; + minuid_bin_t uuid; /* instance (changes on dup/copy) */ + htsp_t attr; + htip_t id2obj; /* members (memb): id -> object pointer (primary storage); also acts as a list of active children objects */ + htsp_t name2pen; /* all pen directly under this group; key: pen->name; value: pen */ + char *loclib_name; /* name used in the local library only */ + + union { + struct { /* type=CSCH_CTYPE_GRP */ + csch_oid_t next_id; + minuid_bin_t src_uuid; /* initial/source uuid (filled in on initial allocation, preserved on dup/copy) */ + } grp; + struct { /* type=CSCH_CTYPE_GRP_REF */ + char *ref_str; /* xorcache: will be NULL once ->grp is resolved */ + csch_cgrp_t *grp; /* xorcache: NULL only when ref_str is not NULL */ + vtp0_t child_xform; /* an array of child transformations (csch_child_xform_t) */ + } ref; + } data; + + double spec_rot; + csch_coord_t x, y; + unsigned mirx:1, miry:1; + + /* cache */ + const char *srole; /* string version of the role: points into the attributes */ + csch_role_t role; /* symbolic version, resolved once when the string is changed */ + struct { /* accumulated transformations: parent's + local offset/rot/mirror */ + g2d_xform_t mx; /* resulting matrix for quick coord transformations */ + double rot; + csch_coord_t x, y; + unsigned mirx:1, miry:1; + } xform; + unsigned wirenet_recalc_lock:1; + unsigned wirenet_split_lock:1; + unsigned sym_prefer_loclib:1; /* this group is a symbol that should be put in the local lib and converted to a group ref if global config permits */ + vtl0_t aid; /* link to the abstract objects compiled from this group; zero or one in flat design but can be more in hierarchic */ + char *file_name; /* hint: trace file name from which the group was loaded, if available */ + csch_rtree_box_t bbox_flt; /* bounding box with floaters included (e.g. for sheet size) */ +}; + +typedef enum csch_sheet_type_e { + CSCH_SHTY_unknown, + CSCH_SHTY_UNLISTED, /* not explicitly listen in the project file, just happens to be in the same dir */ + CSCH_SHTY_ROOT, /* explicitly listed in project file as a root sheet */ + CSCH_SHTY_AUX, /* explicitly listed in project file as an aux sheet */ + CSCH_SHTY_EXTERNAL /* not explicitly listen in the project file, loaded during compilation, for hierarchy */ +} csch_sheet_type_t; + +struct csch_sheet_s { + rnd_design_t hidlib; + long uid; + + csch_rtree_t dsply[CSCH_DSPLY_max]; /* object strokes to draw per display layer */ + csch_rtree_t dsply_fill[CSCH_DSPLY_max]; /* fills to draw per display layer */ + csch_cgrp_t direct, indirect; /* a sheet is really made of groups to keep the code simple */ + /* (sheet attributes are in the direct, the indirect group is for the "local library") */ + + char *newname; /* special case: if a new sheet is created, loadname will be NULL but we need to remember what we loaded for new sheet for revert to work; for non-new-sheets this is NULL but ->hidlib.loadname is non-NULL */ + char *loadfmt; /* format request used at original load */ + csch_rtree_box_t bbox; + unsigned bbox_changed:1; /* set when bbox changed (bumped) by object editing; used and reset by the GUI */ + + unsigned non_graphical:1; /* sheet specified by data, not drawing */ + + void *non_graphical_data; /* filled in and used by the plugin dealing with the non-graphical format when ->non_graphical==1 */ + csch_non_graphical_impl_t *non_graphical_impl; + + /* list of all objects ever allocated for the sheet */ + gdl_list_t active, deleted; + + csch_comm_str_t junction_pen_name; /* the caller may change this; used whenever junction needs to be placed in wirenet recalc */ + + /* caches and temporary storage */ + uundo_list_t undo; + htsp_t comm_str; /* common strings, like pen names, stored only once; key=strdup(str), val=NULL; referenceed as csch_comm_str_t */ + csch_oid_t auto_oid; /* negative oids for objects that have automatically assigned oid; decrease first, use after */ + vtp0_t libs; /* indexed by csch_lib_master_t->uid, resolves to (csch_lib_root_t *); each sheet needs an own set because of local configuration may differ */ + vtp0_t local_libs; /* same as libs but operates on sheet->indirect */ + csch_chdr_t *currobj; /* for propset @ */ + + csch_rtree_box_t invbox; /* an application may keep track on redraw bbox here - maintained by libcschem*/ + long redraw_inhibit; /* when >0 do not draw but collect invalidated box - maintained by libcschem */ + unsigned invbox_valid:1; /* whether invbox is a valid box that could be drawn */ + unsigned saving:1; /* set to 1 while the sheet is being saved (helps inhibiting some change indications on the UI) */ + unsigned warned_too_large:1; /* whether a sheet-too-large warning has already been generated for this sheet */ + + struct { + int recalc_inhibit; + htpi_t recalc_wn; + } util_wirenet; + + unsigned load_pending:1; /* when set, the sheet has not yet been loaded (but got referenced from the project file) */ + unsigned loose_sym:1; /* allow editing symbol part objects, bypassing the symbol lock */ + unsigned is_symbol:1; /* if 1: we are in symbol editing mode */ + unsigned changed:1; /* whether data has been edited since last save */ + csch_sheet_type_t stype; /* sheet type/role within the project */ + + char *design_dir; /* for rc.paths.desgin */ + + /* Autocomp timer */ + long acp_remain; /* remaining time in milisec; 0 means not started */ + long acp_starting; /* starting time in milisec; used to update the progress bar */ + + /* plugins */ + double infobar_last_date; +}; + +/* Standard low level object operations; when int, return 0 for success */ +typedef struct csch_cop_s { + csch_chdr_t *(*remove)(csch_sheet_t *dst, csch_chdr_t *obj); + csch_chdr_t *(*dup)(csch_chdr_t *obj); + csch_chdr_t *(*move)(csch_chdr_t *obj, csch_coord_t dx, csch_coord_t dy); + csch_chdr_t *(*move_to)(csch_sheet_t *dst, csch_chdr_t *obj); + csch_chdr_t *(*rotate90)(csch_chdr_t *obj, csch_coord_t dx, csch_coord_t dy, int steps); + csch_chdr_t *(*rotate)(csch_chdr_t *obj, csch_coord_t dx, csch_coord_t dy, double ang, double cosx, double sinx); + csch_chdr_t *(*mirrorx)(csch_chdr_t *obj, csch_coord_t ox); /* mirror x coordinates (around the y axis) */ + csch_chdr_t *(*mirrory)(csch_chdr_t *obj, csch_coord_t oy); /* mirror y coordinates (around the x axis) */ +} csch_cop_t; + +typedef enum csch_hash_ignore_u { /* bitfield: which properties to ignore in objects hashing */ + CSCH_HIGN_FLOATER_GEO = 1, /* recursively ignore floater geometry (position, transformations) */ + CSCH_HIGN_GRP_ATTRIB = 2, /* ignore root group's attributes */ + CSCH_HIGN_GRP_PLACEMENT = 4 /* ignore root group's placement */ +} csch_hash_ignore_t; + +csch_sheet_t *csch_sheet_init(csch_sheet_t *sheet, csch_project_t *parent); +void csch_sheet_uninit(csch_sheet_t *sheet); + +csch_sheet_t *csch_sheet_alloc(csch_project_t *parent); +void csch_sheet_free(csch_sheet_t *); +RND_INLINE const csch_rtree_box_t *csch_sheet_bbox(csch_sheet_t *sheet); +void csch_sheet_bbox_update(csch_sheet_t *sheet); + +csch_oid_t csch_oid_new(csch_sheet_t *sheet, csch_cgrp_t *grp); + +/* Return the human readable name of a display layer, or "" */ +const char *csch_dsply_name(csch_displayer_t dsply); + +/* Return the sheet's rtree for a name; the name may be suffixed with + -fill or -stroke for selecting the appropriate rtree. If not suffixed, + the stroke rtree is returned. */ +csch_rtree_t *csch_rtree_lookup_by_name(csch_sheet_t *sheet, const char *name); + +/* Return the human readable name of concrete object type, or "" */ +const char *csch_ctype_name(csch_ctype_t typ); + +/* Copy header metadata (like display layer and pen OID) while dupping + an object */ +void csch_chdr_copy_meta4dup(csch_chdr_t *dst, const csch_chdr_t *src); + +/* Return the full oidpath of chdr renderd in text; caller needs to free + the returned string */ +char *csch_chdr_to_oidpath_str(const csch_chdr_t *chdr); + +/* An object is selected if it is ->selected or if any of its parents is ->selected */ +RND_INLINE int csch_chdr_is_selected(csch_chdr_t *obj); + +/* An object is selected if it is ->selected or if any of its parents is ->selected */ +RND_INLINE int csch_chdr_any_parent_selected(csch_chdr_t *obj); + +/* Return common string for str; if not already allocated and alloc != 0, + strup and insert str to common strings. If str is NULL or not found/allocated, + returns a comm_str with NULL str */ +csch_comm_str_t csch_comm_str(csch_sheet_t *sheet, const char *str, int alloc); + + +/*** implementation ***/ +RND_INLINE const csch_rtree_box_t *csch_sheet_bbox(csch_sheet_t *sheet) +{ + if (csch_bbox_is_invalid(&sheet->bbox)) + csch_sheet_bbox_update(sheet); + return &sheet->bbox; +} + +RND_INLINE int csch_chdr_is_selected(csch_chdr_t *obj) +{ + for(;obj != NULL; obj = &obj->parent->hdr) + if (obj->selected) + return 1; + + return 0; +} + +RND_INLINE int csch_chdr_any_parent_selected(csch_chdr_t *obj) +{ + return csch_chdr_is_selected(&obj->parent->hdr); +} + + +/* Returns 1 if obj is a group or group ref, 0 for other objects */ +RND_INLINE int csch_obj_is_grp(const csch_chdr_t *obj) +{ + return ((obj != NULL) && ((obj->type == CSCH_CTYPE_GRP) || (obj->type == CSCH_CTYPE_GRP_REF))); +} + +/* Returns 1 if obj is deleted (not part of the active objects of the sheet) */ +RND_INLINE int csch_obj_is_deleted(const csch_chdr_t *obj) +{ + return (obj->link.parent == &obj->sheet->deleted); +} + +#define csch_ctype_in_cmask(type, mask) (!!((1 << (type)) & (mask))) + +#define CSCH_ACT_SHEET ((csch_sheet_t *)argv[0].val.argv0.user_call_ctx) + +/* Call with new_val=1 after any sheet edit */ +void csch_sheet_set_changed(csch_sheet_t *sheet, int new_val); + + +#endif Index: tags/1.0.5/src/libcschem/config.h.in =================================================================== --- tags/1.0.5/src/libcschem/config.h.in (nonexistent) +++ tags/1.0.5/src/libcschem/config.h.in (revision 10414) @@ -0,0 +1,35 @@ +print [@ +#ifndef CSCH_CONFIG_H +#define CSCH_CONFIG_H + +#define RND_APP_PREFIX(x) csch_ ## x + +#include + +@sys/types/size/includes@ + +typedef @sys/types/size/4_u_int@ csch_uint32_t; +typedef @sys/types/size/4_s_int@ csch_sint32_t; +@] + +# coordinates and gengeo2d config +print [@ +/* set to long temporarily; we'll need a local typecfg_csch_coord_t_double */ +/*typedef csch_sint32_t csch_coord_t;*/ +typedef long csch_coord_t; +#define GENGEO2D_TYPECFG "gengeo2d/typecfg_long_double.h" +#define G2D_INLINE RND_INLINE +@] + +print [@ + +/* the dot-dir: where to save user config under ther user's home; it's used + as ~/DOT_SCH_RND/ */ +#define DOT_SCH_RND "@/local/csch/dot_sch_rnd@" + +/* Version number of package */ +#define CSCH_VERSION "@/local/version@" +#define CSCH_REVISION "@/local/revision@" + +#endif +@] Index: tags/1.0.5/src/libcschem/config.sh.in =================================================================== --- tags/1.0.5/src/libcschem/config.sh.in (nonexistent) +++ tags/1.0.5/src/libcschem/config.sh.in (revision 10414) @@ -0,0 +1,6 @@ +print [@ +# *** Autogenerated by scconfig *** DO NOT EDIT *** +# cschem config for shell scripts +librnd_root=@/local/csch/librnd_prefix@ +librnd_libdir=$librnd_root/lib/librnd4 +@] Index: tags/1.0.5/src/libcschem/csch_printf.c =================================================================== --- tags/1.0.5/src/libcschem/csch_printf.c (nonexistent) +++ tags/1.0.5/src/libcschem/csch_printf.c (revision 10414) @@ -0,0 +1,81 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include "config.h" + +#include +#include +#include + +#include "csch_printf.h" + +rnd_aft_ret_t RND_AFT_csch_coord = RND_AFT_error; + +rnd_aft_ret_t csch_printf_app_format(gds_t *string, gds_t *spec, const char **fmt, rnd_unit_allow_t mask, rnd_unit_suffix_t suffix, rnd_aft_arg_t *arg, rnd_aft_arg_t *cookie) +{ + csch_coord_t c; + rnd_coord_t rc; + + if (RND_AFT_csch_coord == RND_AFT_error) { + if (sizeof(int)== sizeof(csch_coord_t)) + RND_AFT_csch_coord = RND_AFT_INT; + else if (sizeof(long) == sizeof(csch_coord_t)) + RND_AFT_csch_coord = RND_AFT_LONG; + else { + rnd_message(RND_MSG_ERROR, "Can't find matching integer type for sizeof(csch_coord_t)\n"); + return RND_AFT_error; + } + } + + switch(**fmt) { + case 'r': + if (arg == NULL) return RND_AFT_csch_coord; + rc = (RND_AFT_csch_coord == RND_AFT_INT) ? arg->i : arg->l; + c = rc >> 10; + goto print_coord; + + case 'c': + if (arg == NULL) return RND_AFT_csch_coord; + c = (RND_AFT_csch_coord == RND_AFT_INT) ? arg->i : arg->l; + print_coord:; + if ((suffix != RND_UNIT_NO_SUFFIX) && ((c % 1000) == 0)) { + c /= 1000; + switch(suffix) { + case RND_UNIT_NO_SUFFIX: break; + case RND_UNIT_SUFFIX: gds_append_str(spec, "ld k"); break; + case RND_UNIT_FILE_MODE: gds_append_str(spec, "ldk"); break; + } + } + else + gds_append_str(spec, "ld"); + + if (rnd_append_printf(string, spec->array, (long)c) < 0) + return RND_AFT_error; + + return RND_AFT_csch_coord; + } + return RND_AFT_error; +} Index: tags/1.0.5/src/libcschem/csch_printf.h =================================================================== --- tags/1.0.5/src/libcschem/csch_printf.h (nonexistent) +++ tags/1.0.5/src/libcschem/csch_printf.h (revision 10414) @@ -0,0 +1,10 @@ +#include + +/* Extra formats: + %rc prints csch_coord_t; no suffix is printed + %$rc prints csch_coord_t; if round (divisible by 1000) use the 'k' suffix form + %$$rc prints csch_coord_t; same as %$rc but no space between num and unit + %rr prints rnd_coord_t; same as %rc but scales down the value by 2^10 first +*/ +rnd_aft_ret_t csch_printf_app_format(gds_t *string, gds_t *spec, const char **fmt, rnd_unit_allow_t mask, rnd_unit_suffix_t suffix, rnd_aft_arg_t *arg, rnd_aft_arg_t *cookie); + Index: tags/1.0.5/src/libcschem/drc.c =================================================================== --- tags/1.0.5/src/libcschem/drc.c (nonexistent) +++ tags/1.0.5/src/libcschem/drc.c (revision 10414) @@ -0,0 +1,210 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem: design rule checker + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust Fund in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include "config.h" + +#include +#include + +#include "actions_csch.h" +#include "drc.h" +#include "event.h" + +static const char drc_cookie[] = "libcschem/drc"; + +csch_drc_abst_ref_t *csch_drc_abst_ref_alloc(void) +{ + return calloc(sizeof(csch_drc_abst_ref_t), 1); +} + +csch_drc_abst_ref_t *csch_drc_abst_ref_alloc_append(csch_drc_violation_t *v) +{ + csch_drc_abst_ref_t *r = csch_drc_abst_ref_alloc(); + vtp0_append(&v->ref, r); + return r; +} + +void csch_drc_abst_ref_free(csch_drc_abst_ref_t *ref) +{ + free(ref->net_name); + free(ref->comp_name); + free(ref->port_name); + free(ref->attr_key); + free(ref); +} + +csch_drc_violation_t *csch_drc_violation_alloc(void) +{ + csch_drc_violation_t *v = calloc(sizeof(csch_drc_violation_t), 1); + return v; +} + +csch_drc_violation_t *csch_drc_violation_alloc_append(csch_drc_t *ctx) +{ + csch_drc_violation_t *v = csch_drc_violation_alloc(); + vtp0_append(&ctx->violations, v); + return v; +} + +void csch_drc_violation_free(csch_drc_violation_t *v) +{ + long n; + for(n = 0; n < v->ref.used; n++) + csch_drc_abst_ref_free(v->ref.array[n]); + vtp0_uninit(&v->ref); + free(v->title); + free(v->desc); + free(v); +} + + +void csch_drc_uninit(csch_drc_t *ctx) +{ + long n; + + ctx->ran = 0; + for(n = 0; n < ctx->violations.used; n++) + csch_drc_violation_free(ctx->violations.array[n]); + vtp0_uninit(&ctx->violations); +} + + +long csch_drc_project(csch_drc_t *ctx, csch_sheet_t *sheet) +{ + ctx->ran = 0; + vtp0_init(&ctx->violations); + + rnd_event(&sheet->hidlib, CSCH_EVENT_DRC_RUN, "p", ctx); + if (ctx->ran == 0) + rnd_message(RND_MSG_ERROR, "No DRC tests ran. Is any DRC capable plugin compiled? Are they disabled? Are all rules disabled? Maybe need to compile the project first?\n"); + + return ctx->violations.used; +} + +static void csch_drc_print(csch_drc_t *ctx, FILE *f) +{ + long n, m; + for(n = 0; n < ctx->violations.used; n++) { + csch_drc_violation_t *v = ctx->violations.array[n]; + fprintf(f, "%s\n", v->title); + fprintf(f, " %s\n", v->desc); + for(m = 0; m < v->ref.used; m++) { + csch_drc_abst_ref_t *r = v->ref.array[m]; + if (r->net_name != NULL) + fprintf(f, " net %s\n", r->net_name); + if (r->comp_name != NULL) + fprintf(f, " component %s\n", r->comp_name); + if (r->port_name != NULL) + fprintf(f, " port %s\n", r->port_name); + if (r->attr_key != NULL) + fprintf(f, " attribute %s\n", r->attr_key); + } + printf("\n"); + } +} + +static void csch_drc_log(csch_drc_t *ctx) +{ + long n, m; + for(n = 0; n < ctx->violations.used; n++) { + csch_drc_violation_t *v = ctx->violations.array[n]; + rnd_message(RND_MSG_ERROR, "%s\n", v->title); + rnd_message(RND_MSG_ERROR, " %s\n", v->desc); + for(m = 0; m < v->ref.used; m++) { + csch_drc_abst_ref_t *r = v->ref.array[m]; + if (r->net_name != NULL) + rnd_message(RND_MSG_ERROR, " net %s\n", r->net_name); + if (r->comp_name != NULL) + rnd_message(RND_MSG_ERROR, " component %s\n", r->comp_name); + if (r->port_name != NULL) + rnd_message(RND_MSG_ERROR, " port %s\n", r->port_name); + if (r->attr_key != NULL) + rnd_message(RND_MSG_ERROR, " attribute %s\n", r->attr_key); + } + printf("\n"); + } +} + + + + + +static const char csch_acts_DRC[] = "DRC([list|print|log])"; +static const char csch_acth_DRC[] = "Invoke the DRC check. Results are presented as the argument requests."; +static fgw_error_t csch_act_DRC(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + csch_sheet_t *sheet = CSCH_ACT_SHEET; + csch_drc_t ctx; + const char *dlg_type = "log"; + + RND_ACT_MAY_CONVARG(1, FGW_STR, DRC, dlg_type = argv[1].val.str); + + csch_drc_project(&ctx, sheet); + + if (strcmp(dlg_type, "print") == 0) { + if (ctx.violations.used > 0) { + printf("\n=== DRC violations ===\n"); + csch_drc_print(&ctx, stdout); + printf("\n"); + } + else + printf("(no DRC violations)\n"); + csch_drc_uninit(&ctx); + } + else if (strcmp(dlg_type, "log") == 0) { + if (ctx.violations.used > 0) { + rnd_message(RND_MSG_ERROR, "\n=== DRC violations ===\n"); + csch_drc_log(&ctx); + rnd_message(RND_MSG_ERROR, "\n"); + } + else + rnd_message(RND_MSG_INFO, "No DRC violations\n"); + csch_drc_uninit(&ctx); + } + else { + rnd_message(RND_MSG_ERROR, "Invalid first argument for DRC()\n"); + RND_ACT_IRES(-1); + } + + return 0; +} + +static rnd_action_t csch_drc_act_list[] = { + {"DRC", csch_act_DRC, csch_acth_DRC, csch_acts_DRC} +}; + +void csch_drc_act_init(void) +{ + RND_REGISTER_ACTIONS(csch_drc_act_list, drc_cookie); +} + +void csch_drc_act_uninit(void) +{ + rnd_remove_actions_by_cookie(drc_cookie); +} + Index: tags/1.0.5/src/libcschem/drc.h =================================================================== --- tags/1.0.5/src/libcschem/drc.h (nonexistent) +++ tags/1.0.5/src/libcschem/drc.h (revision 10414) @@ -0,0 +1,85 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem: design rule checker + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust Fund in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#ifndef CSCH_DRC_H +#define CSCH_DRC_H + +#include + +/* Referencing a violation can not be done using an abstract object ID because + those IDs get invalidated upon compilation and the typical use case of + DRC is keeping a list open while fixing violations. Rather reference + things by name. Any field may be NULL. */ +typedef struct csch_drc_abst_ref_s { + char *net_name; + char *comp_name; + char *port_name; + char *attr_key; +} csch_drc_abst_ref_t; + +/* A single violation (part of a list generated for a drc) */ +typedef struct csch_drc_violation_s { + char *title; /* short title for sorting by, in form of topic/title; strdup'd */ + char *desc; /* long explanation; strdup'd */ + vtp0_t ref; /* of (csch_drc_abst_ref_t *) indicating where the violation is */ +} csch_drc_violation_t; + +typedef struct csch_drc_s { + int ran; + vtp0_t violations; /* of (csch_drc_violation_t *) */ +} csch_drc_t; + +/*** For DRC implementations ***/ + + +/* Allocate and free violation */ +csch_drc_violation_t *csch_drc_violation_alloc(void); +csch_drc_violation_t *csch_drc_violation_alloc_append(csch_drc_t *ctx); +void csch_drc_violation_free(csch_drc_violation_t *v); + +/* Allocate and free reference used in violations */ +csch_drc_abst_ref_t *csch_drc_abst_ref_alloc(void); +csch_drc_abst_ref_t *csch_drc_abst_ref_alloc_append(csch_drc_violation_t *v); +void csch_drc_abst_ref_free(csch_drc_abst_ref_t *ref); + + +/*** Internal ***/ + +/* Run all DRCs on the project that sheet is part of. Returns the number of + DRC violations. Results are stored in ctx, the caller needs to call + csch_drc_uninit(ctx) after the results are processed. */ +long csch_drc_project(csch_drc_t *ctx, csch_sheet_t *sheet); + +/* Free all fields of ctx (but not ctx itself) */ +void csch_drc_uninit(csch_drc_t *ctx); + +/* (Un)register drc related actions */ +void csch_drc_act_init(void); +void csch_drc_act_uninit(void); + +#endif Index: tags/1.0.5/src/libcschem/engine.c =================================================================== --- tags/1.0.5/src/libcschem/engine.c (nonexistent) +++ tags/1.0.5/src/libcschem/engine.c (revision 10414) @@ -0,0 +1,281 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2019 Tibor 'Igor2' Palinkas + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include "config.h" + +#include +#include +#include + +#include "actions_csch.h" +#include +#include "project.h" + +#include "engine.h" + +#define MAX_ARGS 16 + +const char *csch_enghk_names[CSCH_ENGHK_max] = { + "terminal_name_to_port_name", + "wirenet_name_to_net_name", + "attrib_net_name_to_net_name", + "symbol_name_to_component_name", + "symbol_joined_component", + "compile_component0", + "compile_component1", + "compile_component2", + "compile_port", + "compile_net", + "compile_conns_before", + "compile_conns_after", + "compile_project_before", + "compile_project_after" +}; + +TODO("fungw: remove this in favor of fgws_c_call_script() in fungwbind (make sure it is installed)") +fgw_error_t csch_c_call_script(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + fgw_error_t rv; + fgw_func_t *fnc = argv[0].val.func; + rv = fnc->func(res, argc, argv); + fgw_argv_free(fnc->obj->parent, argc, argv); + return rv; +} + +csch_view_eng_t *csch_eng_alloc(csch_view_t *view, const char *user_name, const char *eng_name, const char *options) +{ + csch_view_eng_t *eng; + fgw_obj_t *obj; + csch_eng_hook_t i; + + eng = calloc(sizeof(csch_view_eng_t), 1); + obj = fgw_obj_new2(&view->fgw_ctx, user_name, eng_name, options, NULL, eng); + if (obj == NULL) { + free(eng); + return NULL; + } + + eng->obj = obj; + if (options != NULL) + eng->options = rnd_strdup(options); + + for(i = 0; i < CSCH_ENGHK_max; i++) + eng->hook[i] = fgw_func_lookup_in(obj, csch_enghk_names[i]); + + return eng; +} + +void csch_eng_free(csch_view_t *view, csch_view_eng_t *eng) +{ + fgw_obj_unreg(&view->fgw_ctx, eng->obj); + free(eng->options); + free(eng); +} +/*** calls ***/ + +/* returns argc or -1 on error; arguments are packed starting from skip_first+1, + making room for caller supplied arguments before argv[1] if skip_first > 0 */ +static int eng_load_args(csch_hook_call_ctx_t *cctx, fgw_arg_t *argv, int max_argc, va_list ap, int skip_first) +{ + int argc; + + argv[0].type = FGW_FUNC; + argv[0].val.argv0.user_call_ctx = cctx; + + for(argc = 1 + skip_first;;argc++) { + fgw_type_t type = va_arg(ap, fgw_type_t); + if (argc >= max_argc) + return -1; + if (type == FGW_INVALID) + break; + + argv[argc].type = type; + type = type & 0x3FF; + if ((argv[argc].type) & FGW_PTR) + argv[argc].val.ptr_void = va_arg(ap, void *); + else switch((int)type) { + case FGW_CHAR: argv[argc].val.nat_char = va_arg(ap, int); break; + case FGW_UCHAR: argv[argc].val.nat_uchar = va_arg(ap, int); break; + case FGW_SCHAR: argv[argc].val.nat_schar = va_arg(ap, int); break; + case FGW_SHORT: argv[argc].val.nat_short = va_arg(ap, int); break; + case FGW_USHORT: argv[argc].val.nat_ushort = va_arg(ap, int); break; + case FGW_INT: argv[argc].val.nat_int = va_arg(ap, int); break; + case FGW_UINT: argv[argc].val.nat_uint = va_arg(ap, unsigned int); break; + case FGW_LONG: argv[argc].val.nat_long = va_arg(ap, long); break; + case FGW_ULONG: argv[argc].val.nat_ulong = va_arg(ap, unsigned long); break; + case FGW_SIZE_T: argv[argc].val.nat_size_t = va_arg(ap, size_t); break; + case FGW_FLOAT: argv[argc].val.nat_float = va_arg(ap, double); break; + case FGW_DOUBLE: argv[argc].val.nat_double = va_arg(ap, double); break; + case FGW_AOBJ: + case FGW_COBJ: + case FGW_HPATH: + argv[argc].val.ptr_void = va_arg(ap, void *); + break; + default: + assert(!"invalid fungw type"); + } + } + return argc; +} + +void csch_eng_call_namemod(csch_project_t *proj, int viewid, csch_hier_path_t *hpath, csch_eng_hook_t hkid, char **res_glob, char **res_loc, const char *defval, ...) +{ + va_list ap; + csch_view_t *view; + void **v; + int argc; + long n; + char *sres_glob = NULL, *sres_loc = NULL; + fgw_arg_t argv[MAX_ARGS], ares; + csch_hook_call_ctx_t cctx; + + if (viewid < 0) + viewid = proj->curr; + + v = vtp0_get(&proj->views, viewid, 0); + if (v == NULL) + goto error; + view = *v; + + va_start(ap, defval); + argc = eng_load_args(&cctx, argv, (sizeof(argv)/sizeof(argv[0])), ap, 1); + va_end(ap); + if (argc < 0) + goto error; + + argv[1].type = 0; /* avoid invalid memory handling in corner case */ + + sres_glob = rnd_strdup(defval); + sres_loc = rnd_strdup(defval); + cctx.project = proj; + cctx.view_id = viewid; + cctx.hpath = hpath; + + for(n = 0; n < view->engines.used; n++) { + csch_view_eng_t *eng = view->engines.array[n]; + fgw_func_t *hk = eng->hook[hkid]; + if (hk == NULL) + continue; + + cctx.view_eng = eng; + ares.type = FGW_INT; + ares.val.nat_int = 0; + argv[0].type = FGW_FUNC; + argv[0].val.argv0.func = hk; + argv[1].type = FGW_STR; + argv[1].val.cstr = defval; + if (hk->func(&ares, argc, argv) == 0) { + if ((ares.type & FGW_STR) == FGW_STR) { + char *names, *new_glob, *new_loc; + + /* sort out allocation of returned string */ + if (ares.type & FGW_DYN) { /* steal allocated string */ + names = ares.val.str; + ares.val.str = NULL; + } + else /* need to dup static string */ + names = rnd_strdup(ares.val.str); + + new_glob = names; + new_loc = strpbrk(new_glob, "\n\r"); + if (new_loc != NULL) { + *new_loc = '\0'; + new_loc++; + while((*new_loc == '\n') || (*new_loc == '\r')) new_loc++; + } + + /* override sres_glob with new value */ + if (sres_glob != defval) + free(sres_glob); + sres_glob = new_glob; + + if (new_loc != NULL) { + if (sres_loc != defval) + free(sres_loc); + sres_loc = rnd_strdup(new_loc); /* it's part of the new_glob allocation, need to reallocate */ + } + + } + fgw_arg_free(&view->fgw_ctx, &ares); + } + } + + fgw_argv_free(&view->fgw_ctx, argc, argv); + + *res_glob = sres_glob; + *res_loc = sres_loc; + return; + error:; + free(sres_glob); + free(sres_loc); + *res_glob = *res_loc = NULL; +} + +int csch_eng_call(csch_project_t *proj, int viewid, csch_hier_path_t *hpath, csch_eng_hook_t hkid, ...) +{ + va_list ap; + csch_view_t *view; + void **v; + int argc; + long n; + fgw_arg_t argv[MAX_ARGS], ares; + csch_hook_call_ctx_t cctx; + + if (viewid < 0) + viewid = proj->curr; + + v = vtp0_get(&proj->views, viewid, 0); + if (v == NULL) + return -1; + view = *v; + + va_start(ap, hkid); + argc = eng_load_args(&cctx, argv, (sizeof(argv)/sizeof(argv[0])), ap, 0); + va_end(ap); + if (argc < 0) + return -1; + + cctx.project = proj; + cctx.view_id = viewid; + cctx.hpath = hpath; + + for(n = 0; n < view->engines.used; n++) { + csch_view_eng_t *eng = view->engines.array[n]; + fgw_func_t *hk = eng->hook[hkid]; + if (hk == NULL) + continue; + + cctx.view_eng = eng; + ares.type = FGW_INT; + ares.val.nat_int = 0; + argv[0].val.argv0.func = hk; + hk->func(&ares, argc, argv); + fgw_arg_free(&view->fgw_ctx, &ares); + } + + fgw_argv_free(&view->fgw_ctx, argc, argv); + return 0; +} Index: tags/1.0.5/src/libcschem/engine.h =================================================================== --- tags/1.0.5/src/libcschem/engine.h (nonexistent) +++ tags/1.0.5/src/libcschem/engine.h (revision 10414) @@ -0,0 +1,101 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2019 Tibor 'Igor2' Palinkas + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + + +#ifndef CSCH_ENGINE_H +#define CSCH_ENGINE_H + +#include +#include +#include +#include +#include + +typedef enum { + CSCH_ENGHK_TERMINAL_NAME_TO_PORT_NAME, + CSCH_ENGHK_WIRENET_NAME_TO_NET_NAME, + CSCH_ENGHK_ATTRIB_NET_NAME_TO_NET_NAME, + CSCH_ENGHK_SYMBOL_NAME_TO_COMPONENT_NAME, + CSCH_ENGHK_SYMBOL_JOINED_COMPONENT, + CSCH_ENGHK_COMPILE_COMPONENT0, /* called once per component, after all symbol merges, before port processing; should set component attributes but should not have any other side effect (e.g. making connections) */ + CSCH_ENGHK_COMPILE_COMPONENT1, /* same as component0, but can have side effects */ + CSCH_ENGHK_COMPILE_COMPONENT2, /* called once per component, after port merges finished */ + CSCH_ENGHK_COMPILE_PORT, + CSCH_ENGHK_COMPILE_NET, + CSCH_ENGHK_CONNS_BEFORE, /* called once per sheet, before starting to compile connection objects */ + CSCH_ENGHK_CONNS_AFTER, /* called once per sheet, after finished compiling connection objects */ + CSCH_ENGHK_PROJECT_BEFORE, /* called once before starting to compile the project */ + CSCH_ENGHK_PROJECT_AFTER, /* called once after finished compiling the project */ + CSCH_ENGHK_max +} csch_eng_hook_t; + +struct csch_view_eng_s { + fgw_obj_t *obj; + htss_t cfg; + + /* cache */ + fgw_func_t *hook[CSCH_ENGHK_max]; /* look up all hooks once after load so calls don't have to go trhough */ + void *cfg_cache; /* optional: compiled by the engine */ + short int eprio; /* engine priority; final attribute priority should be (CSCH_PRI_PLUGIN_* + eprio) */ + char *options; /* parameter (e.g. script file name) specified on creation */ +}; + +typedef struct csch_hook_call_ctx_s { + csch_project_t *project; + const csch_view_eng_t *view_eng; + int view_id; + csch_hier_path_t *hpath; +} csch_hook_call_ctx_t; + +csch_view_eng_t *csch_eng_alloc(csch_view_t *view, const char *user_name, const char *eng_name, const char *options); +void csch_eng_free(csch_view_t *view, csch_view_eng_t *eng); + +/* temporary until fungw C binding installation is sorted out */ +fgw_error_t csch_c_call_script(fgw_arg_t *res, int argc, fgw_arg_t *argv); + +/*** calls ***/ + +/* Call hooks, expect no reply; returns 0 on success, -1 on view or + argument error */ +int csch_eng_call(csch_project_t *proj, int viewid, csch_hier_path_t *hpath, csch_eng_hook_t hkid, ...); + +/* Call hooks to modify a name. Result is in *res_glob and *res_loc after + the call are strdup'd and can be freed using csch_eng_call_namemod(). If + any of these are NULL, there was an internal error. */ +void csch_eng_call_namemod(csch_project_t *proj, int viewid, csch_hier_path_t *hpath, csch_eng_hook_t hook, char **res_glob, char **res_loc, const char *defval, ...); + +/* Clean up after csch_eng_call_namemod(). */ +RND_INLINE void csch_eng_free_namemod(char **res_glob, char **res_loc); + + +/*** implementation ***/ +RND_INLINE void csch_eng_free_namemod(char **res_glob, char **res_loc) +{ + free(*res_glob); res_glob = NULL; + free(*res_loc); res_loc = NULL; +} + +#endif Index: tags/1.0.5/src/libcschem/event.c =================================================================== --- tags/1.0.5/src/libcschem/event.c (nonexistent) +++ tags/1.0.5/src/libcschem/event.c (revision 10414) @@ -0,0 +1,56 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2020 Tibor 'Igor2' Palinkas + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + + +#include +#include "event.h" + +static const char *csch_evnames[] = { + "cschev_layervis_changed", + "cschev_undo_post", + "cschev_sheet_edit", + "cschev_sheet_preunload", + "cschev_sheet_postunload", + "cschev_sheet_postload", + "cschev_sheet_postsave", + "cschev_obj_needs_redraw", + "cschev_obj_attr_edited", + "cschev_prj_compiled", + "cschev_prj_views_changed", + "cschev_prj_view_activated", + "cschev_prj_stance_changed", + "cschev_library_changed", + "cschev_selection_changed", + "cschev_drc_run", + + "cschev_buffer_copy_custom", + "cschev_buffer_paste_custom" +}; + +void csch_event_init_app(void) +{ + rnd_event_app_reg(CSCH_EVENT_last, csch_evnames, sizeof(csch_evnames)); +} Index: tags/1.0.5/src/libcschem/event.h =================================================================== --- tags/1.0.5/src/libcschem/event.h (nonexistent) +++ tags/1.0.5/src/libcschem/event.h (revision 10414) @@ -0,0 +1,64 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2020 Tibor 'Igor2' Palinkas + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#ifndef CSCH_EVENT_H +#define CSCH_EVENT_H + +#include + +/* Prefix: + [d]: per-design: generated for a specific rnd_design_t + [a]: per-app: generated once, not targeted or specific for a rnd_design_t +*/ +enum { + CSCH_EVENT_LAYERVIS_CHANGED= RND_EVENT_app, /* [d] called after the visibility of layers has changed */ + CSCH_EVENT_UNDO_POST, /* [d] called after undo */ + CSCH_EVENT_SHEET_EDITED, /* [d] called after any sheet edit */ + CSCH_EVENT_SHEET_PREUNLOAD, /* [d] called before sheet is unloaded, arg: none (sheet is accessible in hidlib) */ + CSCH_EVENT_SHEET_POSTUNLOAD, /* [d] called after sheet is unloaded, arg: none (hidlib in the next sheet we are switching to) */ + CSCH_EVENT_SHEET_POSTLOAD, /* [d] called after sheet is loaded, so that the app can do postprocessing; arg: none (sheet is accessible in hidlib) */ + CSCH_EVENT_SHEET_POSTSAVE, /* [d] called after sheet is saved; arg: none (sheet is accessible in hidlib) */ + CSCH_EVENT_BOX_NEEDS_REDRAW, /* [d] called an area of a sheet needs redraw, with the affected box passed; arg: (csch_rtree_box_t *) */ + CSCH_EVENT_OBJ_ATTR_EDITED, /* [d] called after object attributes got edited arg: (csch_chdr_t *) */ + CSCH_EVENT_PRJ_COMPILED, /* [d] called after the project has been compiled (abstract model changed); no args (project can be retrieved from hidlib -> sheet) */ + CSCH_EVENT_PRJ_VIEWS_CHANGED, /* [d] called after project view configuration changed; no args (project can be retrieved from hidlib -> sheet) */ + CSCH_EVENT_PRJ_VIEW_ACTIVATED, /* [d] called after a new view is set active in a project (project can be retrieved from hidlib -> sheet) */ + CSCH_EVENT_PRJ_STANCE_CHANGED, /* [d] called after any project stance changed */ + CSCH_EVENT_LIBRARY_CHANGED, /* [d] called after a new entry is added to the library so that any open library window can be updated on the GUI; no args (sheet can be retrieved from hidlib) */ + CSCH_EVENT_SELECTION_CHANGED, /* [d] called after object selection changed (sleected/unselected objects) */ + + CSCH_EVENT_DRC_RUN, /* [d] called from core to run all configured DRCs (implemented in plugins). Args: (csch_drc_t *ctx). Each DRC plugin shall increase ctx->ran if it did any check */ + + /* generated by the app, not libcschem */ + CSCH_EVENT_BUFFER_COPY_CUSTOM, /* [d] called before an object is duplicated from sheet to buffer; args: (csch_chdr_t **obj, csch_sheet_t *buffer); *obj is the current object, initially the source object on the sheet; destination buffer the second arg */ + CSCH_EVENT_BUFFER_PASTE_CUSTOM, /* [d] called before an object is duplicated from buffer to sheet; args: (csch_chdr_t **obj); *obj is the current object, initially the source object in the buffer; destination sheet is in the hidlib arg */ + + CSCH_EVENT_last /* not a real event */ +}; + +void csch_event_init_app(void); + +#endif Index: tags/1.0.5/src/libcschem/hierarchy.c =================================================================== --- tags/1.0.5/src/libcschem/hierarchy.c (nonexistent) +++ tags/1.0.5/src/libcschem/hierarchy.c (revision 10414) @@ -0,0 +1,383 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2024 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust Fund in 2024) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include + +#include "concrete.h" +#include "cnc_grp.h" +#include "project.h" +#include "plug_library.h" + +#include "hierarchy.h" + +#define HSEP '/' +#define MAX_DEPTH 32 + +csch_sheet_t *(*csch_app_load_sheet_cb)(csch_project_t *proj, const char *path) = NULL; + + +csch_sheet_t *csch_hier_find_by_uuid(const csch_sheet_t *sheet, const char *uuid, int add_to_prj_as_aux) +{ + rnd_message(RND_MSG_ERROR, "cschem/child/uuid not yet implemented"); + TODO("hierarchical: implement me\n"); + return NULL; +} + +/* sname is sheet's loadname (short name), name:nlen is the requested name and its strlen() */ +RND_INLINE int sheet_name_eq(const char *sname, const char *name, long nlen) +{ + long slen = strlen(sname); + + if (slen < nlen) return 0; /* sheet name too short, can't match */ + + if (strcmp(sname+slen-nlen, name) == 0) { + if (slen == nlen) + return 1; + if ((slen > nlen) && (sname[slen-nlen-1] == '/')) /* avoid suffix match */ + return 1; + } + + /* ignore .rs ending */ + if ((slen >= nlen+3) && (strcmp(sname+slen-3, ".rs") == 0)) { + if (strncmp(sname+slen-nlen-3, name, nlen) == 0) { + if ((slen-3 > nlen) && (sname[slen-nlen-3-1] == '/')) /* avoid suffix match */ + return 1; + if (slen-3 == nlen) + return 1; /* full length match */ + } + } + + /* ignore .lht/sch ending for historic reasons */ + if ((slen >= nlen+4) && ((strcmp(sname+slen-4, ".lht") == 0) || (strcmp(sname+slen-4, ".sch") == 0))) { + if (strncmp(sname+slen-nlen-4, name, nlen) == 0) { + if ((slen-4 > nlen) && (sname[slen-nlen-4-1] == '/')) /* avoid suffix match */ + return 1; + if (slen-4 == nlen) + return 1; /* full length match */ + } + } + + return 0; +} + +csch_sheet_t *sch_rnd_multi_load(const char *fn, const char *fmt, int *is_project); + +static csch_sheet_t *hlib_find_by_name(csch_project_t *proj, csch_lib_t *lib, const char *name, long nlen, int add_to_prj_as_aux) +{ + long n; + + if (lib == NULL) + return NULL; + + switch(lib->type) { + case CSCH_SLIB_STATIC: + if (sheet_name_eq(lib->name, name, nlen)) { + csch_sheet_t *res; + + rnd_message(RND_MSG_INFO, "Attempting to load '%s' for sheet named '%s'...\n", lib->realpath, name); + res = csch_app_load_sheet_cb(proj, lib->realpath); + return res; + } + break; + + case CSCH_SLIB_PARAMETRIC: + case CSCH_SLIB_invalid: + return NULL; + + case CSCH_SLIB_DIR: + for(n = 0; n < lib->children.used; n++) { + csch_sheet_t *res = hlib_find_by_name(proj, lib->children.array[n], name, nlen, add_to_prj_as_aux); + if (res != NULL) + return res; + } + break; + } + + return NULL; +} + +csch_sheet_t *csch_hier_find_by_name(const csch_sheet_t *sheet, const char *name, int add_to_prj_as_aux) +{ + csch_project_t *prj = (csch_project_t *)sheet->hidlib.project; + long n, nlen = strlen(name); + csch_lib_master_t *master; + htsp_entry_t *e; + + /* search in project first */ + for(n = 0; n < prj->hdr.designs.used; n++) { + csch_sheet_t *sheet = prj->hdr.designs.array[n]; + if (sheet_name_eq(sheet->hidlib.loadname, name, nlen)) + return sheet; + } + + rnd_message(RND_MSG_INFO, "Hirearchic: sheet named '%s' not found in the project, searching the hlibrary...\n", name); + + /* search the hlibrary */ + if (csch_app_load_sheet_cb == NULL) + return NULL; + master = csch_lib_get_master("hlibrary", 0); + if (master == NULL) + return NULL; + + for(e = htsp_first(&master->roots); e != NULL; e = htsp_next(&master->roots, e)) { + csch_sheet_t *res = hlib_find_by_name((csch_project_t *)sheet->hidlib.project, e->value, name, nlen, add_to_prj_as_aux); + if (res != NULL) + return res; + } + + return NULL; +} + +csch_sheet_t *csch_hier_find_by_path(const csch_sheet_t *sheet, const char *path, int add_to_prj_as_aux) +{ + csch_project_t *prj = (csch_project_t *)sheet->hidlib.project; + csch_sheet_t *res = NULL; + char *dirname, *new_path, *nr_path; + long n; + + /* refuse invalid and absolute path */ + if ((path == NULL) || (path[0] == '/')) + return NULL; + + dirname = rnd_dirname_real(sheet->hidlib.fullpath); + new_path = rnd_concat(dirname, "/", path, NULL); + free(dirname); + nr_path = rnd_lrealpath(new_path); + + if (nr_path == NULL) { + rnd_message(RND_MSG_ERROR, "Hirearchic: sheet with path '%s' not found on the file system...\n", new_path); + free(new_path); + goto done; + } + free(new_path); + + /* search in project first */ + for(n = 0; n < prj->hdr.designs.used; n++) { + csch_sheet_t *sh = prj->hdr.designs.array[n]; + if (strcmp(sh->hidlib.fullpath, nr_path) == 0) { + res = sh; + goto done; + } + } + + rnd_message(RND_MSG_INFO, "Hirearchic: sheet with path '%s' not found in the project, loading from the file system...\n", path); + res = csch_app_load_sheet_cb(prj, nr_path); + + done:; + free(nr_path); + return res; +} + +RND_INLINE const char *get_sym_attr(csch_cgrp_t *sym, const char *key) +{ + const csch_attrib_t *aname; + + if (sym->hdr.type == CSCH_CTYPE_GRP_REF) + aname = csch_cgrp_ref_get_attr(sym, key); + else + aname = csch_attrib_get(&sym->attr, key); + + if (aname == NULL) + return NULL; + + return aname->val; +} + +int csch_hier_find_sym_child(const csch_sheet_t *sheet, csch_cgrp_t *sym, csch_sheet_t **child_out, int add_to_prj_as_aux) +{ + const char *type, *val; + csch_sheet_t *child = NULL; + + val = get_sym_attr(sym, "cschem/child/uuid"); + if (val != NULL) { + child = csch_hier_find_by_uuid(sheet, val, add_to_prj_as_aux); + type = "uid"; + goto yes; + } + + val = get_sym_attr(sym, "cschem/child/name"); + if (val != NULL) { + child = csch_hier_find_by_name(sheet, val, add_to_prj_as_aux); + type = "name"; + goto yes; + } + + val = get_sym_attr(sym, "cschem/child/path"); + if (val != NULL) { + child = csch_hier_find_by_path(sheet, val, add_to_prj_as_aux); + type = "path"; + goto yes; + } + + /* no (known) cschem/child/ attribute */ + return 0; + + yes:; + if (child == NULL) { + rnd_message(RND_MSG_ERROR, "Failed to find hierarchic child-sheet referenced by %s '%s'\n", type, val); + return -1; + } + *child_out = child; + return 1; +} + +int csch_hier_find_child(const csch_sheet_t *sheet, const char *chuuid, const char *chname, const char *chpath, csch_sheet_t **child_out, int add_to_prj_as_aux) +{ + const char *type, *val; + csch_sheet_t *child = NULL; + + if (chuuid != NULL) { + child = csch_hier_find_by_uuid(sheet, chuuid, add_to_prj_as_aux); + type = "uid"; + val = chuuid; + goto yes; + } + + if (chname != NULL) { + child = csch_hier_find_by_name(sheet, chname, add_to_prj_as_aux); + type = "name"; + val = chname; + goto yes; + } + + if (chpath != NULL) { + child = csch_hier_find_by_path(sheet, chpath, add_to_prj_as_aux); + type = "path"; + val = chpath; + goto yes; + } + + /* no (known) cschem/child/ attribute */ + return 0; + + yes:; + if (child == NULL) { + rnd_message(RND_MSG_ERROR, "Failed to find hierarchic child-sheet referenced by %s '%s'\n", type, val); + return -1; + } + *child_out = child; + return 1; +} + + +void csch_hier_path_free(csch_hier_path_t *hpath) +{ + gds_uninit(&hpath->prefix); + hpath->hlev = NULL; + hpath->hdepth = -1; +} + +void csch_hier_path_init(csch_hier_path_t *hpath, csch_abstract_t *abst) +{ + memset(hpath, 0, sizeof(csch_hier_path_t)); + hpath->hlev = abst->hroot; +} + + +csch_hlevel_t *csch_hlevel_new(csch_hlevel_t *parent, csch_cgrp_t *sym, const char *name) +{ + csch_hlevel_t *hlev = calloc(sizeof(csch_hlevel_t), 1); + if (parent != NULL) { + hlev->parent = parent; + gdl_append(&parent->children, hlev, link); + } + htsp_init(&hlev->nets, strhash, strkeyeq); + htsp_init(&hlev->comps, strhash, strkeyeq); + hlev->name = (name == NULL) ? NULL : rnd_strdup(name); + hlev->hdepth = (parent == NULL) ? 0 : parent->hdepth+1; + return hlev; +} + + +void csch_hlevel_free_tree(csch_hlevel_t *hlev) +{ + csch_hlevel_t *f; + for(f = gdl_first(&hlev->children); f != NULL; f = gdl_first(&hlev->children)) { + gdl_remove(&hlev->children, f, link); + csch_hlevel_free_tree(f); + } + htsp_uninit(&hlev->nets); + htsp_uninit(&hlev->comps); + free(hlev->name); + free(hlev); +} + + +int csch_hier_enter(csch_hier_path_t *hpath, csch_hier_temp_t *tmp, csch_cgrp_t *sym, const char *name) +{ + if (hpath->hdepth > MAX_DEPTH) { + rnd_message(RND_MSG_ERROR, "Hierarchy recursion too deep (%ld)\n(The hierarchy graph shall not contain loops)\n", hpath->hdepth); + return -1; + } + + if (hpath->prefix.used > MAX_DEPTH*8) { + rnd_message(RND_MSG_ERROR, "Hierarchy recursion too deep, prefix too long (%ld)\n(The hierarchy graph shall not contain loops)\n", hpath->prefix.used); + return -1; + } + + tmp->prefix_len = hpath->prefix.used; + gds_append_str(&hpath->prefix, name); + gds_append(&hpath->prefix, HSEP); +/* rnd_trace("HIER: enter [%d '%s']\n", hpath->path.used+1, hpath->prefix.array);*/ + + hpath->hlev = csch_hlevel_new(hpath->hlev, sym, name); + hpath->hdepth++; + + return 0; +} + +void csch_hier_leave(csch_hier_path_t *hpath, csch_hier_temp_t *tmp) +{ +/* rnd_trace("HIER: leave [%d '%s']\n", hpath->path.used, hpath->prefix.array);*/ + hpath->hlev = hpath->hlev->parent; + hpath->hdepth--; + hpath->prefix.used = tmp->prefix_len; + hpath->prefix.array[hpath->prefix.used] = '\0'; + assert(hpath->hdepth >= 0); +} + + +void csch_hier_build_path(gds_t *prefix, csch_hlevel_t *hlev) +{ + if ((hlev == NULL) || (hlev->parent == NULL)) + return; /* root path is empty */ + + while((hlev != NULL) && (hlev->name != NULL)) { + gds_insert_len(prefix, 0, "/", 1); + gds_insert_len(prefix, 0, hlev->name, strlen(hlev->name)); + hlev = hlev->parent; + } +} + Index: tags/1.0.5/src/libcschem/hierarchy.h =================================================================== --- tags/1.0.5/src/libcschem/hierarchy.h (nonexistent) +++ tags/1.0.5/src/libcschem/hierarchy.h (revision 10414) @@ -0,0 +1,75 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2024 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust Fund in 2024) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#ifndef CSCH_HIERARCHY_H +#define CSCH_HIERARCHY_H + +#include +#include +#include + +/* describes the current path while descending a hierarchic design */ +struct csch_hier_path_s { + gds_t prefix; /* path prefix string (cache) */ + csch_hlevel_t *hlev; /* subtree we are in at the moment */ + long hdepth; +}; + +/* used for enter/leave to store some temporary data on the caller's stack; + caller should declare it as csch_hier_temp_t htmp and pass it as &htmp */ +typedef struct csch_hier_temp_s { + int prefix_len; +} csch_hier_temp_t; + +/* Return 1 if sheet:sym is a subsheet reference, 0 otherwise. If a subsheet ref, + look up the child subsheet and load *child_out with it. If a sheet needs to + be loaded from the hlibrary, it is added to the in-memory project; normally + this means adding it as an external file. If add_to_prj_as_aux is + not 0, the new sheet is added to the project file as an aux sheet. + Returns -1 on error (lookup failure) */ +int csch_hier_find_sym_child(const csch_sheet_t *sheet, csch_cgrp_t *sym, csch_sheet_t **child_out, int add_to_prj_as_aux); + +/* same but with user provided ref strings (in case source is not a concrete + model symbol, e.g. non-graphical sheets */ +int csch_hier_find_child(const csch_sheet_t *sheet, const char *chuuid, const char *chname, const char *chpath, csch_sheet_t **child_out, int add_to_prj_as_aux); + + +void csch_hier_path_init(csch_hier_path_t *hpath, csch_abstract_t *abst); +void csch_hier_path_free(csch_hier_path_t *hpath); + +int csch_hier_enter(csch_hier_path_t *hpath, csch_hier_temp_t *tmp, csch_cgrp_t *sym, const char *name); +void csch_hier_leave(csch_hier_path_t *hpath, csch_hier_temp_t *tmp); +csch_hlevel_t *csch_hlevel_new(csch_hlevel_t *parent, csch_cgrp_t *sym, const char *name); +void csch_hlevel_free_tree(csch_hlevel_t *hlev); + +void csch_hier_build_path(gds_t *prefix, csch_hlevel_t *hlev); + +/* The app needs to provide this call */ +extern csch_sheet_t *(*csch_app_load_sheet_cb)(csch_project_t *proj, const char *path); + +#endif Index: tags/1.0.5/src/libcschem/htPo.c =================================================================== --- tags/1.0.5/src/libcschem/htPo.c (nonexistent) +++ tags/1.0.5/src/libcschem/htPo.c (revision 10414) @@ -0,0 +1,18 @@ +#include "htPo.h" +#define HT(x) htPo_ ## x +static htPo_value_t invalid; +#define HT_INVALID_VALUE invalid +#include +#include + +int htPo_keyeq(htPo_key_t a, htPo_key_t b) +{ + return (a.x == b.x) && (a.y == b.y); +} + +unsigned int htPo_keyhash(htPo_key_t a) +{ + return longhash(a.x) ^ longhash(a.y); +} + +#undef HT Index: tags/1.0.5/src/libcschem/htPo.h =================================================================== --- tags/1.0.5/src/libcschem/htPo.h (nonexistent) +++ tags/1.0.5/src/libcschem/htPo.h (revision 10414) @@ -0,0 +1,25 @@ +#ifndef GENHT_HTPO_H +#define GENHT_HTPO_H + +#include "config.h" +#include GENGEO2D_TYPECFG +#include "gengeo2d/prim.h" + +typedef struct { + g2d_coord_t x, y; +} htPo_key_t; + +typedef struct { + void *ptr; + long i; + void *wire; +} htPo_value_t; + +#define HT(x) htPo_ ## x +#include +#undef HT + +int htPo_keyeq(htPo_key_t a, htPo_key_t b); +unsigned int htPo_keyhash(htPo_key_t a); + +#endif Index: tags/1.0.5/src/libcschem/htepu.c =================================================================== --- tags/1.0.5/src/libcschem/htepu.c (nonexistent) +++ tags/1.0.5/src/libcschem/htepu.c (revision 10414) @@ -0,0 +1,28 @@ +#include "htepu.h" +#define HT(x) htepu_ ## x +static htepu_value_t invalid; +#define HT_INVALID_VALUE invalid +#include +#include + +int htepu_keyeq(htepu_key_t a, htepu_key_t b) +{ + return (a.obj == b.obj) && (a.epi == b.epi) && (a.x == b.x) && (a.y == b.y); +} + +unsigned int htepu_keyhash(htepu_key_t a) +{ + return ptrhash(a.obj) ^ longhash(a.epi) ^ longhash(a.x) ^ longhash(a.y); +} + +int htepu_keyeq_xy(htepu_key_t a, htepu_key_t b) +{ + return (a.x == b.x) && (a.y == b.y); +} + +unsigned int htepu_keyhash_xy(htepu_key_t a) +{ + return longhash(a.x) ^ longhash(a.y); +} + +#undef HT Index: tags/1.0.5/src/libcschem/htepu.h =================================================================== --- tags/1.0.5/src/libcschem/htepu.h (nonexistent) +++ tags/1.0.5/src/libcschem/htepu.h (revision 10414) @@ -0,0 +1,44 @@ +#ifndef GENHT_HTEPU_H +#define GENHT_HTEPU_H + +#include "config.h" + +#include "concrete.h" + +/* Endpoint to user data hash */ + +typedef enum csch_endpoint_idx_e { /* bitfield */ + CSCH_EPI_invalid = 0, + CSCH_EPI_START = 1, + CSCH_EPI_END = 2, + CSCH_EPI_MID = 4, + CSCH_EPI_ALL = 0xff /* both START and END and everything in between (e.g. 0 length obj) */ +} csch_endpoint_idx_t; + +typedef struct { + csch_chdr_t *obj; + csch_coord_t x, y; + csch_endpoint_idx_t epi; +} htepu_key_t; + +typedef struct htepu_value_s { + csch_coord_t newx, newy; + union { + csch_coord_t crd; + long l; + double d; + void *p; + } data[4]; +} htepu_value_t; + + +#define HT(x) htepu_ ## x +#include +#undef HT + +int htepu_keyeq(htepu_key_t a, htepu_key_t b); +int htepu_keyeq_xy(htepu_key_t a, htepu_key_t b); /* consider x;y only */ +unsigned int htepu_keyhash(htepu_key_t a); +unsigned int htepu_keyhash_xy(htepu_key_t a); /* consider x;y only */ + +#endif Index: tags/1.0.5/src/libcschem/integrity.c =================================================================== --- tags/1.0.5/src/libcschem/integrity.c (nonexistent) +++ tags/1.0.5/src/libcschem/integrity.c (revision 10414) @@ -0,0 +1,350 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/* Data integrity check */ + +#include "config.h" + +#include + +#include "project.h" +#include "cnc_any_obj.h" +#include "cnc_conn.h" +#include "intersect.h" + +#include "integrity.h" + +int csch_integrity_auto = 1; + +static void igy_brk() {} + +#define ASSERT1(expr, reason, arg1) \ + do { \ + if (!(expr)) { \ + const char *sheetname = sheet->hidlib.loadname; \ + rnd_message(RND_MSG_ERROR, "Integrity violation: " reason, arg1); \ + rnd_message(RND_MSG_ERROR, " (" #expr ") at " CSCH_IGY_LOC ", sheet: %s; called from: %s\n", sheetname, called_from); \ + igy_brk(); \ + res |= 1; \ + } \ + } while(0) + +#define ASSERT(expr, reason) ASSERT1(expr, reason, NULL) + +RND_INLINE int igy_cnc_grp(void *parent, csch_cgrp_t *grp, const char *called_from); + +RND_INLINE int igy_cnc_conn(void *parent, csch_conn_t *c, const char *called_from) +{ + int res = 0, had_two_grps = 0; + csch_sheet_t *sheet = c->hdr.sheet; + csch_cgrp_t *first = NULL; + long n; + + if (c->conn_path.used != 0) + csch_conn_text2ptr(sheet, c); + + ASSERT(c->conn.used != 0, "Can't resolve connections"); + ASSERT(c->conn.used != 1, "Connection object with a single object ref"); + + /* require each object to be in a wirenet or symbol */ + for(n = 0; n < c->conn.used; n++) { + csch_chdr_t *obj = c->conn.array[n]; + + ASSERT(obj != NULL, "Connection object with invalid ref"); + if (obj != NULL) { + + /* count if we have two differnet parent groups */ + if (first == NULL) + first = obj->parent; + else if (first != obj->parent) + had_two_grps = 1; + + ASSERT((obj->parent != NULL), "conn with no parent"); + if (obj->parent != NULL) + ASSERT((obj->parent->role == CSCH_ROLE_TERMINAL) || (obj->parent->role == CSCH_ROLE_WIRE_NET), "unusual parent group for connection referee"); + } + } + + ASSERT(had_two_grps, "Connection's all ref'd objects are of the same parent group"); + + return res; +} + +RND_INLINE int igy_cnc_obj(csch_cgrp_t *parent, csch_chdr_t *obj, const char *called_from) +{ + int res = 0; + csch_sheet_t *sheet = obj->sheet; + + if (parent != NULL) + ASSERT(parent == obj->parent, "broken object parent"); + + switch(obj->type) { + case CSCH_CTYPE_LINE: + case CSCH_CTYPE_TEXT: + case CSCH_CTYPE_ARC: + case CSCH_CTYPE_POLY: + case CSCH_CTYPE_BITMAP: + case CSCH_CTYPE_PEN: + break; + + case CSCH_CTYPE_CONN: + res |= igy_cnc_conn(NULL, (csch_conn_t *)obj, called_from); + break; + + case CSCH_CTYPE_GRP: + case CSCH_CTYPE_GRP_REF: + res |= igy_cnc_grp(NULL, (csch_cgrp_t *)obj, called_from); + break; + + case CSCH_CTYPE_invalid: + case CSCH_CTYPE_max: + ASSERT(0, "invalid object type"); + } + + return res; +} + +/* Recursive intersection search: set ->mark on any object that is in the + same group and on the CSCH_DSPLY_WIRE layer that are reachable through + intersections from obj */ +RND_INLINE void igy_wirenet_find_segs_from(csch_chdr_t *obj) +{ + csch_chdr_t *pair; + csch_rtree_it_t it; + + /* collect all relevant intersections and mark them and schedule them for visit */ + for(pair = csch_rtree_first(&it, &obj->sheet->dsply[CSCH_DSPLY_WIRE], &obj->bbox); pair != NULL; pair = csch_rtree_next(&it)) { + csch_chdr_t *po = (csch_chdr_t *)pair; + if (!po->mark && (po->parent == obj->parent)) { + if (csch_obj_intersect_obj(obj->sheet, obj, po, NULL, 0)) { + po->mark = 1; + po->visit = 1; + } + } + } + + /* execute scheduled visits (recursion) */ + for(pair = csch_rtree_first(&it, &obj->sheet->dsply[CSCH_DSPLY_WIRE], &obj->bbox); pair != NULL; pair = csch_rtree_next(&it)) { + csch_chdr_t *po = (csch_chdr_t *)pair; + if (po->visit) { + po->visit = 0; + igy_wirenet_find_segs_from(po); + } + } +} + +RND_INLINE int igy_wirenet(void *parent, csch_cgrp_t *wn, const char *called_from) +{ + int res = 0; + long wnlen = htip_length(&wn->id2obj); + csch_sheet_t *sheet = wn->hdr.sheet; + + if (wnlen > 1) { + htip_entry_t *e; + csch_chdr_t *obj; + + for(e = htip_first(&wn->id2obj); e != NULL; e = htip_next(&wn->id2obj, e)) { + csch_chdr_t *obj = e->value; + obj->mark = obj->visit = 0; + } + + /* find the first non-floater to start from */ + obj = NULL; + for(e = htip_first(&wn->id2obj); e != NULL; e = htip_next(&wn->id2obj, e)) { + csch_chdr_t *o = e->value; + if (!o->floater) { + obj = o; + break; + } + } + + if (obj != NULL) { + obj->mark = 1; + + igy_wirenet_find_segs_from(obj); + + for(e = htip_first(&wn->id2obj); e != NULL; e = htip_next(&wn->id2obj, e)) { + csch_chdr_t *obj = e->value; + if (!obj->floater) + ASSERT(obj->mark, "Disjoint wirenet"); + obj->mark = obj->visit = 0; + } + } + else { + ASSERT1(0, "wirenet #%ld conists of floaters only", wn->hdr.oid); + } + } + else if (wnlen == 1) { + htip_entry_t *e = htip_first(&wn->id2obj); + csch_chdr_t *o = e->value; + ASSERT1(!o->floater, "wirenet #%ld conists of floaters only", wn->hdr.oid); + } + else if (wnlen < 1) + ASSERT(parent == wn->hdr.parent, "empty wirenet (invisible ghost group)"); + + return res; +} + +RND_INLINE int igy_cnc_grp(void *parent, csch_cgrp_t *grp, const char *called_from) +{ + int res = 0, sym_mode_direct; + htip_entry_t *e; + csch_sheet_t *sheet = grp->hdr.sheet; + + if (parent != NULL) + ASSERT(parent == grp->hdr.parent, "broken group parent"); + + if (grp->role == CSCH_ROLE_WIRE_NET) + res |= igy_wirenet(parent, grp, called_from); + + if (grp->loclib_name != NULL) + ASSERT(csch_cobj_is_indirect(&grp->hdr), "group with loclib_name set shall be under the indirect subtree"); + + /* check each child object's integrity */ + for(e = htip_first(&grp->id2obj); e != NULL; e = htip_next(&grp->id2obj, e)) { + csch_chdr_t *obj = e->value; + ASSERT(obj->oid == e->key, "wrong ID in hash"); + res |= igy_cnc_obj(grp, obj, called_from); + } + + if (grp->hdr.type == CSCH_CTYPE_GRP_REF) { + ASSERT((grp->data.ref.grp != NULL) || (grp->data.ref.ref_str != NULL), "grp_ref with no referee"); + if (grp->data.ref.grp != NULL) + ASSERT(grp->data.ref.grp->hdr.sheet == grp->hdr.sheet, "grp_ref referee is on another sheet"); + } + + /* in symbol edit mode the sheet is a dummy sheet so does not have an uuid */ + sym_mode_direct = sheet->is_symbol && (grp == &grp->hdr.sheet->direct); + + if (grp != &grp->hdr.sheet->indirect && !sym_mode_direct) + ASSERT(!minuid_is_nil(grp->uuid), "grp without (instance) UUID"); + + return res; +} + +RND_INLINE int igy_cnc_direct(csch_cgrp_t *grp, const char *called_from) +{ + int res = 0; + csch_sheet_t *sheet = grp->hdr.sheet; + + ASSERT(grp->spec_rot == 0, "sheet's direct group must not be rotated"); + ASSERT(grp->x == 0, "sheet's direct group must not be translated (x)"); + ASSERT(grp->y == 0, "sheet's direct group must not be translated (y)"); + ASSERT(grp->mirx == 0, "sheet's direct group must not be mirrored (x)"); + ASSERT(grp->miry == 0, "sheet's direct group must not be mirrored (y)"); + + return res; +} + +RND_INLINE int igy_cnc_rtree(csch_sheet_t *sheet, csch_rtree_t *rtree, const char *called_from) +{ + csch_rtree_it_t it; + csch_chdr_t *o; + int res = 0; + + for(o = csch_rtree_all_first(&it, rtree); o != NULL; o = csch_rtree_all_next(&it)) { + ASSERT(!csch_obj_is_deleted(o), "Ghost object: presents in rtree but has been deleted"); + } + + return res; +} + +RND_INLINE int igy_cnc_rtrees(csch_sheet_t *sheet, const char *called_from) +{ + int n, res = 0; + for(n = 0; n < CSCH_DSPLY_max; n++) { + res |= igy_cnc_rtree(sheet, &sheet->dsply[n], called_from); + res |= igy_cnc_rtree(sheet, &sheet->dsply_fill[n], called_from); + } + return res; +} + +RND_INLINE int igy_sheet(csch_project_t *proj, csch_sheet_t *sheet, const char *called_from) +{ + int res = 0; + + if (sheet->non_graphical) + return 0; /* don't check them for now */ + + if (proj != NULL) + ASSERT(proj == (csch_project_t *)sheet->hidlib.project, "broken sheet parent"); + + ASSERT(sheet->direct.hdr.parent == NULL, "broken direct grp parent"); + ASSERT(sheet->indirect.hdr.parent == NULL, "broken indirect grp parent"); + + res |= igy_cnc_direct(&sheet->direct, called_from); + + res |= igy_cnc_grp(NULL, &sheet->direct, called_from); + res |= igy_cnc_grp(NULL, &sheet->indirect, called_from); + res |= igy_cnc_rtrees(sheet, called_from); + + return res; +} + +int csch_integrity_sheet(csch_sheet_t *sheet, const char *called_from) +{ + return igy_sheet(NULL, sheet, called_from); +} + +int csch_integrity_project(csch_project_t *proj, const char *called_from) +{ + long n; + int res = 0; + + for(n = 0; n < proj->hdr.designs.used; n++) + res |= igy_sheet(proj, proj->hdr.designs.array[n], called_from); + + + return res; +} + +static const char integrity_cookie[] = "libcschem/integrity.c"; + +static const char csch_acts_Integrity[] = "Integrity()"; +static const char csch_acth_Integrity[] = "Run data integrity checks on current sheet."; +fgw_error_t csch_act_Integrity(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + csch_sheet_t *sheet = CSCH_ACT_SHEET; + RND_ACT_IRES(csch_integrity_sheet(sheet, "Integrity() action")); + return 0; +} + +static rnd_action_t csch_integrity_act_list[] = { + {"Integrity", csch_act_Integrity, csch_acth_Integrity, csch_acts_Integrity} +}; + +void csch_integrity_act_init(void) +{ + RND_REGISTER_ACTIONS(csch_integrity_act_list, integrity_cookie); +} + +void csch_integrity_act_uninit(void) +{ + rnd_remove_actions_by_cookie(integrity_cookie); +} + Index: tags/1.0.5/src/libcschem/integrity.h =================================================================== --- tags/1.0.5/src/libcschem/integrity.h (nonexistent) +++ tags/1.0.5/src/libcschem/integrity.h (revision 10414) @@ -0,0 +1,48 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include "concrete.h" + +/* Do not run automatic integrity checks if 0 */ +extern int csch_integrity_auto; + +int csch_integrity_project(csch_project_t *proj, const char *called_from); +int csch_integrity_sheet(csch_sheet_t *sheet, const char *called_from); + + +#define CSCH_IGY_LOC__(func, line) func ":" #line +#define CSCH_IGY_LOC_(func, line) CSCH_IGY_LOC__(func, line) +#define CSCH_IGY_LOC CSCH_IGY_LOC_(__FILE__, __LINE__) +#define CSCH_IGY_AUTO(igy) (csch_integrity_auto ? (igy) : 0) + +#define CSCH_INTEGRITY_SHEET(sheet) csch_integrity_sheet(sheet, CSCH_IGY_LOC) +#define CSCH_INTEGRITY_SHEET_AUTO(sheet) CSCH_IGY_AUTO(CSCH_INTEGRITY_SHEET(sheet)) + + +void csch_integrity_act_init(void); +void csch_integrity_act_uninit(void); Index: tags/1.0.5/src/libcschem/intersect.c =================================================================== --- tags/1.0.5/src/libcschem/intersect.c (nonexistent) +++ tags/1.0.5/src/libcschem/intersect.c (revision 10414) @@ -0,0 +1,213 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include "config.h" + +#include "concrete.h" +#include "cnc_line.h" +#include "cnc_arc.h" +#include "cnc_poly.h" +#include "cnc_grp.h" + +#include +#include +#include + +#include "intersect.h" + +static long csch_obj_intersect_obj_(csch_chdr_t *o1, csch_chdr_t *o2, g2d_vect_t **iscp, long *iscp_len); + +RND_INLINE void isc_append(g2d_vect_t **dst, long *dst_len, g2d_vect_t *src, long src_len) +{ + long n; + + for(n = 0; n < src_len; n++) { + if (*dst_len == 0) + return; + **dst = *src; + (*dst)++; + (*dst_len)--; + src++; + } +} + +RND_INLINE long isc_ll(csch_line_t *l1, csch_line_t *l2, g2d_vect_t **iscp, long *iscp_len) +{ + if (*iscp != NULL) { + g2d_vect_t ip[2]; + int res = g2d_iscp_cline_cline(&l1->inst.c, &l2->inst.c, ip, NULL); + isc_append(iscp, iscp_len, ip, res); + return res; + } + else + return g2d_isc_sline_sline(&l1->inst, &l2->inst); +} + +RND_INLINE long isc_la(csch_line_t *l, csch_arc_t *a, g2d_vect_t **iscp, long *iscp_len) +{ + if (*iscp != NULL) { + g2d_vect_t ip[2]; + int res = g2d_iscp_cline_carc(&l->inst.c, &a->inst.c, ip, NULL, 0); + isc_append(iscp, iscp_len, ip, res); + return 0; + } + else + return g2d_isc_sline_sarc(&l->inst, &a->inst); +} + +RND_INLINE long isc_aa(csch_arc_t *a1, csch_arc_t *a2, g2d_vect_t **iscp, long *iscp_len) +{ + TODO("g2d needs arc-arc intersection calculations"); + return 0; +} + +RND_INLINE long isc_po(csch_cpoly_t *p, csch_chdr_t *o, g2d_vect_t **iscp, long *iscp_len) +{ + long n, res = 0; + for(n = 0; n < p->outline.used; n++) { + csch_chdr_t *po = &p->outline.array[n].hdr; + res += csch_obj_intersect_obj_(po, o, iscp, iscp_len); + } + return res; +} + +RND_INLINE long isc_pp(csch_cpoly_t *p1, csch_cpoly_t *p2, g2d_vect_t **iscp, long *iscp_len) +{ + long n, res = 0; + for(n = 0; n < p1->outline.used; n++) { + csch_chdr_t *po = &p1->outline.array[n].hdr; + res += isc_po(p2, po, iscp, iscp_len); + } + return res; +} + +RND_INLINE long isc_go(csch_cgrp_t *g, csch_chdr_t *o, g2d_vect_t **iscp, long *iscp_len) +{ + long res = 0; + htip_entry_t *e; + for(e = htip_first(&g->id2obj); e != NULL; e = htip_next(&g->id2obj, e)) { + csch_chdr_t *go = e->value; + res += csch_obj_intersect_obj_(go, o, iscp, iscp_len); + } + return res; +} + +RND_INLINE long isc_gg(csch_cgrp_t *g1, csch_cgrp_t *g2, g2d_vect_t **iscp, long *iscp_len) +{ + long res = 0; + htip_entry_t *e; + for(e = htip_first(&g1->id2obj); e != NULL; e = htip_next(&g1->id2obj, e)) { + csch_chdr_t *go = e->value; + res += isc_go(g2, go, iscp, iscp_len); + } + return res; +} + + + +static long csch_obj_intersect_obj_(csch_chdr_t *o1, csch_chdr_t *o2, g2d_vect_t **iscp, long *iscp_len) +{ + switch(o1->type) { + case CSCH_CTYPE_LINE: + switch(o2->type) { + case CSCH_CTYPE_LINE: return isc_ll((csch_line_t *)o1, (csch_line_t *)o2, iscp, iscp_len); + case CSCH_CTYPE_ARC: return isc_la((csch_line_t *)o1, (csch_arc_t *)o2, iscp, iscp_len); + case CSCH_CTYPE_POLY: return isc_po((csch_cpoly_t *)o2, o1, iscp, iscp_len); + case CSCH_CTYPE_GRP: /* intentional fall-through */ + case CSCH_CTYPE_GRP_REF: return isc_go((csch_cgrp_t *)o2, o1, iscp, iscp_len); + case CSCH_CTYPE_TEXT: return 0; + case CSCH_CTYPE_BITMAP: return 0; + case CSCH_CTYPE_CONN: return 0; + case CSCH_CTYPE_PEN: return 0; + case CSCH_CTYPE_invalid: return 0; + case CSCH_CTYPE_max: return 0; + } + return 0; + case CSCH_CTYPE_ARC: + switch(o2->type) { + case CSCH_CTYPE_LINE: return isc_la((csch_line_t *)o2, (csch_arc_t *)o1, iscp, iscp_len); + case CSCH_CTYPE_ARC: return isc_aa((csch_arc_t *)o2, (csch_arc_t *)o1, iscp, iscp_len); + case CSCH_CTYPE_POLY: return isc_po((csch_cpoly_t *)o2, o1, iscp, iscp_len); + case CSCH_CTYPE_GRP: /* intentional fall-through */ + case CSCH_CTYPE_GRP_REF: return isc_go((csch_cgrp_t *)o2, o1, iscp, iscp_len); + case CSCH_CTYPE_TEXT: return 0; + case CSCH_CTYPE_BITMAP: return 0; + case CSCH_CTYPE_CONN: return 0; + case CSCH_CTYPE_PEN: return 0; + case CSCH_CTYPE_invalid: return 0; + case CSCH_CTYPE_max: return 0; + } + return 0; + case CSCH_CTYPE_POLY: + switch(o2->type) { + case CSCH_CTYPE_LINE: /* intentional fall-through */ + case CSCH_CTYPE_ARC: return isc_po((csch_cpoly_t *)o1, o2, iscp, iscp_len); + case CSCH_CTYPE_POLY: return isc_pp((csch_cpoly_t *)o1, (csch_cpoly_t *)o2, iscp, iscp_len); + case CSCH_CTYPE_GRP: /* intentional fall-through */ + case CSCH_CTYPE_GRP_REF: return isc_go((csch_cgrp_t *)o2, o1, iscp, iscp_len); + case CSCH_CTYPE_TEXT: return 0; + case CSCH_CTYPE_BITMAP: return 0; + case CSCH_CTYPE_CONN: return 0; + case CSCH_CTYPE_PEN: return 0; + case CSCH_CTYPE_invalid: return 0; + case CSCH_CTYPE_max: return 0; + } + return 0; + case CSCH_CTYPE_GRP: + case CSCH_CTYPE_GRP_REF: + switch(o2->type) { + case CSCH_CTYPE_LINE: /* intentional fall-through */ + case CSCH_CTYPE_ARC: /* intentional fall-through */ + case CSCH_CTYPE_POLY: return isc_go((csch_cgrp_t *)o1, o2, iscp, iscp_len); + case CSCH_CTYPE_GRP: /* intentional fall-through */ + case CSCH_CTYPE_GRP_REF: return isc_gg((csch_cgrp_t *)o1, (csch_cgrp_t *)o2, iscp, iscp_len); + case CSCH_CTYPE_TEXT: return 0; + case CSCH_CTYPE_BITMAP: return 0; + case CSCH_CTYPE_CONN: return 0; + case CSCH_CTYPE_PEN: return 0; + case CSCH_CTYPE_invalid: return 0; + case CSCH_CTYPE_max: return 0; + } + return 0; + + case CSCH_CTYPE_TEXT: + case CSCH_CTYPE_BITMAP: + case CSCH_CTYPE_CONN: + case CSCH_CTYPE_PEN: + case CSCH_CTYPE_invalid: + case CSCH_CTYPE_max: + return 0; + } + return 0; +} + +long csch_obj_intersect_obj(csch_sheet_t *sheet, csch_chdr_t *o1, csch_chdr_t *o2, g2d_vect_t *iscp, long iscp_len) +{ + return csch_obj_intersect_obj_(o1, o2, &iscp, &iscp_len); + +} Index: tags/1.0.5/src/libcschem/intersect.h =================================================================== --- tags/1.0.5/src/libcschem/intersect.h (nonexistent) +++ tags/1.0.5/src/libcschem/intersect.h (revision 10414) @@ -0,0 +1,38 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include + +/* Return number of intersections between o1 and o2; optionally loads iscp + with intersection points, up to iscp_len. If iscp is NULL, precise + intersection caclulation is done usign thickness of objects and the number + of different object-object intersections is returned. If iscp is not NULL, + only centerline-intersections are considered and iscp coords are all on + object centerlines (number of total centerline iscs returned, may be + larger than iscp_len) */ +long csch_obj_intersect_obj(csch_sheet_t *sheet, csch_chdr_t *o1, csch_chdr_t *o2, g2d_vect_t *iscp, long iscp_len); Index: tags/1.0.5/src/libcschem/libcschem.c =================================================================== --- tags/1.0.5/src/libcschem/libcschem.c (nonexistent) +++ tags/1.0.5/src/libcschem/libcschem.c (revision 10414) @@ -0,0 +1,110 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2018 Tibor 'Igor2' Palinkas + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include "config.h" + +#include +#include +#include +#include +#include + +#include "libcschem.h" +#include "buildin.h" +#include "project_act.h" +#include "project.h" +#include "project_p4.h" +#include "plug_library.h" +#include "plug_io.h" +#include "integrity.h" +#include "undo.h" +#include "actions_csch.h" +#include "drc.h" + +const int *csch_cfg_multiport_net_merge = NULL; +const int *csch_cfg_hier_net_allow_rename = NULL; +const int *csch_cfg_hier_net_rename_prefer_top = NULL; + +minuid_session_t csch_minuid; + + +int csch_init(void) +{ + minuid_init(&csch_minuid); +#ifdef __WIN32__ +#error need to get some good random source +#endif + csch_plug_library_init(); + return 0; +} + +void csch_uninit(void) +{ + csch_project_uninit(); + csch_project_act_uninit(); + csch_integrity_act_uninit(); + csch_drc_act_uninit(); + csch_undo_act_uninit(); + csch_plug_library_uninit(); +} + +void csch_uninit_last(void) +{ + csch_p4_uninit(); + csch_plug_io_uninit(); +} + +int csch_init_actions() +{ + csch_actions_init(&rnd_fgw); /* custom fgw types */ + csch_project_act_init(); + csch_integrity_act_init(); + csch_drc_act_init(); + csch_undo_act_init(); + csch_project_init(); + return 0; +} + +static rnd_unit_t csch_unit_tbl[] = { + {"k", 'c', 1.0/1024000.0, 0, 0, 3, 0}, + {"", 0, 1.0/1024, 0, 0, 3, 0}, /* csch_coord_t no-unit (when an integer coord is provided without a suffix) */ + {"cschem", 0, 1.0/1024, 0, 0, 3, 1} /* csch_coord_t */ +}; + +rnd_unit_t *csch_unit_k, * csch_unit_base; + +unsigned long csch_unit_k_allow, csch_unit_family_cschem; + +int csch_init_units(void) +{ + csch_unit_family_cschem = rnd_unit_reg_family(); + rnd_unit_reg_units(csch_unit_tbl, 3, csch_unit_family_cschem); + rnd_get_value_default_unit = "cschem"; + csch_unit_k_allow = csch_unit_tbl[0].allow; + csch_unit_k = &csch_unit_tbl[0]; + csch_unit_base = &csch_unit_tbl[1]; + return 0; +} Index: tags/1.0.5/src/libcschem/libcschem.h =================================================================== --- tags/1.0.5/src/libcschem/libcschem.h (nonexistent) +++ tags/1.0.5/src/libcschem/libcschem.h (revision 10414) @@ -0,0 +1,93 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2018 Tibor 'Igor2' Palinkas + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#ifndef CSCH_LIBCSHEM_H +#define CSCH_LIBCSHEM_H + +#include +#include + +typedef enum { + CSCH_PRI_HARDWIRED = 0, + CSCH_PRI_USER_GRPREF_HIGH = 1, + CSCH_PRI_USER_GRP_HIGH = 101, + CSCH_PRI_USER_GRPREF_NORMAL = 201, + CSCH_PRI_USER_GRP_NORMAL = 301, + CSCH_PRI_USER_GRPREF_LOW = 401, + CSCH_PRI_USER_GRP_LOW = 501, + CSCH_PRI_PLUGIN_HIGH = 1001, + CSCH_PRI_PLUGIN_NORMAL = 11001, + CSCH_PRI_PLUGIN_LOW = 21001, + CSCH_PRI_USER_LOW = 31001, + + /* maximum values */ + CSCH_PRIMAX_PLUGIN = 1000 /* can not have more plugins than this, because of priority overlaps */ +} csch_pri_t; + +int csch_init(void); +void csch_uninit(void); +void csch_uninit_last(void); /* call this after fungw uninit */ + +/* Insert all core actions to the global action hash */ +int csch_init_actions(void); + +/* Insert cschem-specific types; call after rnd_hidlib_init2() */ +int csch_init_units(void); + +/* cschem-unit bits */ +extern unsigned long csch_unit_k_allow, csch_unit_family_cschem; + +extern rnd_unit_t *csch_unit_k; /* the standard cschem 'k' suffix unit (csch_coord_t * 1000) */ +extern rnd_unit_t *csch_unit_base; /* csch_coord_t, no suffix */ + +/*** Config system ***/ +/* We have no access to the app's conf_core from the lib so we present + this API with pointers that the app can bind to native conf values */ + +/* when multiple ports with the same component:port name connect to different + nets: if true, allow merging those nets, else throw an error */ +extern const int *csch_cfg_multiport_net_merge; + +/* If zero: throw an error if a network is named on both parent and child + side of a hierarchic descend; else use *csch_cfg_hier_net_rename_prefer_top to + decide which name to keep */ +extern const int *csch_cfg_hier_net_allow_rename; + +/* If *csch_cfg_hier_net_allow_rename==1, this decides whether to use parent + (top) sheet's net name (1) or child (bottom) sheet's net name (0) */ +extern const int *csch_cfg_hier_net_rename_prefer_top; + + +#define CSCH_CFG_(name, defval) (name == NULL ? defval : *name) +#define CSCH_CFG(name, defval) CSCH_CFG_((csch_cfg_ ## name), (defval)) + +extern minuid_session_t csch_minuid; + +/* Further app-side configuration defined in other headers: + - csch_app_load_sheet_cb() +*/ + +#endif Index: tags/1.0.5/src/libcschem/non_graphical.c =================================================================== --- tags/1.0.5/src/libcschem/non_graphical.c (nonexistent) +++ tags/1.0.5/src/libcschem/non_graphical.c (revision 10414) @@ -0,0 +1,45 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - sch-rnd (executable) + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust in 2023) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include "config.h" + +#include "concrete.h" +#include "non_graphical.h" + +void csch_non_graphical_impl_pre_unload(csch_non_graphical_impl_t *impl) +{ + rnd_design_t *curr; + for(curr = gdl_first(&rnd_designs); curr != NULL; curr = gdl_next(&rnd_designs, curr)) { + csch_sheet_t *sheet = (csch_sheet_t *)curr; + if (sheet->non_graphical && (sheet->non_graphical_impl == impl) && (impl->free_sheet != NULL)) { + impl->free_sheet(sheet); + sheet->non_graphical_impl = NULL; + sheet->non_graphical_data = NULL; + } + } +} Index: tags/1.0.5/src/libcschem/non_graphical.h =================================================================== --- tags/1.0.5/src/libcschem/non_graphical.h (nonexistent) +++ tags/1.0.5/src/libcschem/non_graphical.h (revision 10414) @@ -0,0 +1,44 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - sch-rnd (executable) + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust in 2023) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include + +/* callbacks that implement a non-graphical sheet format */ +struct csch_non_graphical_impl_s { + int (*reload)(csch_sheet_t *sheet); + int (*compile_sheet)(csch_abstract_t *dst, int viewid, csch_hier_path_t *hpath, const csch_sheet_t *src); + void (*free_sheet)(csch_sheet_t *sheet); + char *(*draw_getline)(csch_sheet_t *sheet, long *cnt, void **cookie); /* call to draw next line; *cnt and *cookie are both 0 on initial call and are handled by the callee; return NULL on eof */ +}; + + +/* Iterate over all sheets and call ->free_sheet() if the sheet is handled + by impl. This should be called before a plugin that implements + non_graphical sheets is unloaded so the callbacks are not left behind */ +void csch_non_graphical_impl_pre_unload(csch_non_graphical_impl_t *impl); + Index: tags/1.0.5/src/libcschem/oidpath.c =================================================================== --- tags/1.0.5/src/libcschem/oidpath.c (nonexistent) +++ tags/1.0.5/src/libcschem/oidpath.c (revision 10414) @@ -0,0 +1,166 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2019 Tibor 'Igor2' Palinkas + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include "config.h" +#include + +#define TDL_DONT_UNDEF +#include "oidpath.h" +#include +#undef TDL_DONT_UNDEF +#include + +#include "concrete.h" + +int csch_oidpath_parse_relative(csch_oidpath_t *dst, const char *src) +{ + const char *curr; + char *next; + + dst->vt.used = 0; + for(curr = src; curr != NULL; curr = next) { + long oid = strtol(curr, &next, 10); + + if (*next == '\0') next = NULL; + else if (*next == '/') next++; + else return -1; + + csch_vtoid_append(&dst->vt, oid); + } + return 0; +} + +int csch_oidpath_parse(csch_oidpath_t *dst, const char *src) +{ + if (*src != '/') + return -1; + src++; + return csch_oidpath_parse_relative(dst, src); +} + +RND_INLINE csch_chdr_t *csch_oidpath_resolve_in_(csch_cgrp_t *curr, const csch_oidpath_t *path, long start_idx) +{ + int n; + + for(n = start_idx; n < path->vt.used; n++) { + if (!csch_obj_is_grp(&curr->hdr)) + return NULL; + + curr = htip_get(&curr->id2obj, path->vt.array[n]); + if (curr == NULL) + return NULL; + } + + return &curr->hdr; +} + +csch_chdr_t *csch_oidpath_resolve_in(csch_cgrp_t *grp, const csch_oidpath_t *path) +{ + return csch_oidpath_resolve_in_(grp, path, 0); +} + + +csch_chdr_t *csch_oidpath_resolve(csch_sheet_t *sheet, const csch_oidpath_t *path) +{ + csch_chdr_t *curr; + + if (path->vt.used < 1) + return NULL; + + /* Note: resolves absolute paths only */ + + /* first oid must be 1 or 2 for the top group */ + if (path->vt.array[0] == CSCH_TOP_OID_DIRECT) + curr = &sheet->direct.hdr; + else if (path->vt.array[0] == CSCH_TOP_OID_INDIRECT) + curr = &sheet->indirect.hdr; + else + return NULL; + + return csch_oidpath_resolve_in_((csch_cgrp_t *)curr, path, 1); +} + +void csch_oidpath_free(csch_oidpath_t *path) +{ + csch_vtoid_truncate(&path->vt, 0); +} + + +int csch_oidpath_to_str_append(gds_t *dst, const csch_oidpath_t *path) +{ + int n; + for(n = 0; n < path->vt.used; n++) { + char tmp[64]; + int len = sprintf(tmp, "/%ld", (long)path->vt.array[n]); + gds_append_len(dst, tmp, len); + } + return path->vt.used; +} + +char *csch_oidpath_to_str(const csch_oidpath_t *path) +{ + gds_t tmp; + gds_init(&tmp); + csch_oidpath_to_str_append(&tmp, path); + return tmp.array; +} + + +void csch_oidpath_from_obj(csch_oidpath_t *dst, const csch_chdr_t *src) +{ + const csch_chdr_t *o; + long len = 0; + + dst->vt.used = 0; + for(o = src; o != NULL; o = (const csch_chdr_t *)o->parent) len++; + for(o = src; o != NULL; o = (const csch_chdr_t *)o->parent) + csch_vtoid_set(&dst->vt, --len, o->oid); +} + + +void csch_oidpath_list_clear(csch_oidpath_list_t *lst) +{ + csch_oidpath_t *i, *next; + for(i = csch_oidpath_list_first(lst); i != NULL; i = next) { + next = csch_oidpath_list_next(i); + csch_oidpath_free(i); + free(i); + } +} + + +int csch_oidpath_eq(const csch_oidpath_t *p1, const csch_oidpath_t *p2) +{ + long n; + + if (p1->vt.used != p2->vt.used) return 0; + + for(n = 0; n < p1->vt.used; n++) + if (p1->vt.array[n] != p2->vt.array[n]) + return 0; + + return 1; +} Index: tags/1.0.5/src/libcschem/oidpath.h =================================================================== --- tags/1.0.5/src/libcschem/oidpath.h (nonexistent) +++ tags/1.0.5/src/libcschem/oidpath.h (revision 10414) @@ -0,0 +1,82 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2019 Tibor 'Igor2' Palinkas + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#ifndef CSCH_OIDPATH_H +#define CSCH_OIDPATH_H + +#include +#include +#include "libcschem/vtoid.h" +#include "libcschem/common_types.h" + +typedef struct { + csch_vtoid_t vt; + gdl_elem_t link; /* may be part of an idpath list */ +} csch_oidpath_t; + +void csch_oidpath_from_obj(csch_oidpath_t *dst, const csch_chdr_t *src); + +/* Convert a slash separated list of integers into an oidpath array; + Normally the path must start with a slash, the relative variant + allows starting with a number */ +int csch_oidpath_parse(csch_oidpath_t *dst, const char *src); +int csch_oidpath_parse_relative(csch_oidpath_t *dst, const char *src); + +csch_chdr_t *csch_oidpath_resolve(csch_sheet_t *sheet, const csch_oidpath_t *path); +csch_chdr_t *csch_oidpath_resolve_in(csch_cgrp_t *grp, const csch_oidpath_t *path); +void csch_oidpath_free(csch_oidpath_t *path); + +/* Append the textual representation of path to dst */ +int csch_oidpath_to_str_append(gds_t *dst, const csch_oidpath_t *path); + +/* Return newly allocated string holding the textual representation of path */ +char *csch_oidpath_to_str(const csch_oidpath_t *path); + +/* Returns wheter p1 has the same path as p2; returns 1 on match, 0 on mismatch */ +int csch_oidpath_eq(const csch_oidpath_t *p1, const csch_oidpath_t *p2); + +RND_INLINE int csch_oidpath_is_empty(const csch_oidpath_t *path) +{ + return path->vt.used == 0; +} + +/* oidpath lists */ +#define TDL(x) csch_oidpath_list_ ## x +#define TDL_LIST_T csch_oidpath_list_t +#define TDL_ITEM_T csch_oidpath_t +#define TDL_FIELD link +#define TDL_SIZE_T size_t +#define TDL_FUNC + +#define csch_oidpath_list_foreach(list, iterator, loop_elem) \ + gdl_foreach_((&((list)->lst)), (iterator), (loop_elem)) + +#include +#include + +void csch_oidpath_list_clear(csch_oidpath_list_t *lst); + +#endif Index: tags/1.0.5/src/libcschem/op_common.c =================================================================== --- tags/1.0.5/src/libcschem/op_common.c (nonexistent) +++ tags/1.0.5/src/libcschem/op_common.c (revision 10414) @@ -0,0 +1,205 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/* Low level operation implementations that are common to multiple objects */ + +#include "config.h" + +#include + +#include "event.h" +#include "cnc_obj.h" +#include "operation.h" +#include "cnc_conn.h" +#include "undo.h" +#include "util_wirenet.h" + +#include "op_common.h" + +static const char csch_operation_cookie[] = "libcschem/op_common.c"; + +/*** Remove ***/ + +static int undo_remove_undo(void *udata) +{ + csch_undo_remove_t *u = udata; + csch_chdr_t *obj = u->obj; + const csch_ops_t *ops = csch_op_get(obj->type); + assert(ops->remove_undo != NULL); + ops->remove_undo(u); + csch_sheet_set_changed(obj->sheet, 1); + return 0; +} + +static int undo_remove_redo(void *udata) +{ + csch_undo_remove_t *u = udata; + csch_chdr_t *obj = u->obj; + const csch_ops_t *ops = csch_op_get(obj->type); + assert(ops->remove_redo != NULL); + + ops->remove_redo(u); + csch_sheet_set_changed(obj->sheet, 1); + return 0; +} + +static void undo_crem_print(void *udata, char *dst, size_t dst_len, const char *op) +{ + csch_undo_remove_t *u = udata; + csch_oidpath_t oidp = {0}; + char *path; + const char *st = ""; + int len; + + csch_oidpath_from_obj(&oidp, u->obj); + path = csch_oidpath_to_str(&oidp); + + if (u->obj->link.parent == &u->sheet->active) st = "active"; + else if (u->obj->link.parent == &u->sheet->deleted) st = "deleted"; + + len = rnd_snprintf(dst, dst_len, "%s: %s %s (%s)", op, csch_ctype_name(u->obj->type), path, st); + if (csch_obj_is_grp(u->obj)) { + csch_cgrp_t *grp = (csch_cgrp_t *)u->obj; + const char *role = csch_attrib_get_str(&grp->attr, "role"); + const char *name = csch_attrib_get_str(&grp->attr, "name"); + + if (role != NULL) { + dst_len -= len; + dst += len; + rnd_snprintf(dst, dst_len, " role=%s", role); + } + if (name != NULL) { + dst_len -= len; + dst += len; + rnd_snprintf(dst, dst_len, " name=%s", name); + } + } + + csch_oidpath_free(&oidp); + free(path); +} + + +static void undo_remove_print(void *udata, char *dst, size_t dst_len) +{ + undo_crem_print(udata, dst, dst_len, "remove"); +} + +static const uundo_oper_t undo_remove = { + csch_operation_cookie, + NULL, /* free */ + undo_remove_undo, + undo_remove_redo, + undo_remove_print +}; + +csch_undo_remove_t *csch_op_remove_alloc_undo(csch_sheet_t *sheet) +{ + return uundo_append(&sheet->undo, &undo_remove, sizeof(csch_undo_remove_t)); +} + + +csch_chdr_t *csch_cnc_common_remove_redo(csch_undo_remove_t *u, csch_cnc_common_remove_t how) +{ + csch_chdr_t *obj = u->obj; + + if (how & CSCH_REM_FROM_RTREE) + csch_cobj_rtree_del(obj->sheet, obj); + + if ((how & CSCH_REM_FROM_PARENT) && (obj != &obj->sheet->direct.hdr) && (obj != &obj->sheet->indirect.hdr)) { + assert(obj->parent != NULL); + u->parent = obj->parent; + htip_pop(&obj->parent->id2obj, obj->oid); + gdl_remove(&u->sheet->active, obj, link); + gdl_append(&u->sheet->deleted, obj, link); + obj->parent = NULL; + } + + csch_cobj_redraw(obj); + + return obj; +} + +csch_chdr_t *csch_cnc_common_remove_undo(csch_undo_remove_t *u, csch_cnc_common_remove_t how) +{ + csch_chdr_t *obj = u->obj; + + if (how & CSCH_REM_FROM_PARENT) { + obj->parent = u->parent; + assert(obj->parent != NULL); + htip_insert(&obj->parent->id2obj, obj->oid, obj); + gdl_remove(&u->sheet->deleted, obj, link); + gdl_append(&u->sheet->active, obj, link); + } + + if (how & CSCH_REM_FROM_RTREE) + csch_cobj_rtree_add(obj->sheet, obj); + + csch_cobj_redraw(obj); + + return obj; +} + + +/*** Create ***/ + +static void undo_create_print(void *udata, char *dst, size_t dst_len) +{ + undo_crem_print(udata, dst, dst_len, "create"); +} + + +static const uundo_oper_t undo_create = { + csch_operation_cookie, + NULL, /* free */ + undo_remove_redo, /* swapped: create is reverse order remove */ + undo_remove_undo, /* swapped: create is reverse order remove */ + undo_create_print +}; + + +/*** MISC ***/ + +csch_chdr_t *csch_op_inserted(csch_sheet_t *sheet, csch_cgrp_t *parent, csch_chdr_t *obj) +{ + csch_undo_create_t *u = uundo_append(&sheet->undo, &undo_create, sizeof(csch_undo_create_t)); + u->sheet = sheet; + u->obj = obj; + u->parent = obj->parent; + u->side_effects = 0; + + if (csch_obj_is_grp(obj)) /* e.g. terminal or symbol moved/added in user op */ + csch_conn_auto_recalc(sheet, obj); + + if (obj->parent->role == CSCH_ROLE_WIRE_NET) /* new wire added in a wirenet */ + csch_wirenet_recalc_obj_conn(sheet, obj); + + csch_undo_inc_serial(sheet); + csch_cobj_redraw(obj); + return obj; +} Index: tags/1.0.5/src/libcschem/op_common.h =================================================================== --- tags/1.0.5/src/libcschem/op_common.h (nonexistent) +++ tags/1.0.5/src/libcschem/op_common.h (revision 10414) @@ -0,0 +1,58 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#ifndef CSCH_OP_COMMON_H +#define CSCH_OP_COMMON_H + +#include "operation.h" + +typedef enum csch_cnc_common_remove_e { /* bitfield flags controlling what the common object removal should remove */ + CSCH_REM_UNDOABLE = 1, /* allocate undo slot; this is on by default when called from an object's handler */ + CSCH_REM_FROM_RTREE = 2, + CSCH_REM_FROM_PARENT = 4, + CSCH_REM_DEL_EMPTY_PARENT = 8 +} csch_cnc_common_remove_t; + + +/* Modular redo implementation for any object */ +csch_chdr_t *csch_cnc_common_remove_redo(csch_undo_remove_t *u, csch_cnc_common_remove_t how); +csch_chdr_t *csch_cnc_common_remove_undo(csch_undo_remove_t *u, csch_cnc_common_remove_t how); + + +/* Allocate an undo slot for removing an object */ +csch_undo_remove_t *csch_op_remove_alloc_undo(csch_sheet_t *sheet); + +/* Call this (centrally) after a new object has been inserted into sheet; will + do the undo administration. */ +csch_chdr_t *csch_op_inserted(csch_sheet_t *sheet, csch_cgrp_t *parent, csch_chdr_t *obj); + +/* either keep orig_oid or allocate a new oid, depending on the keep_id arg */ +#define CSCH_KEEP_OID(parent, orig_oid) \ + (keep_id ? orig_oid : csch_oid_new(sheet, parent)) + +#endif Index: tags/1.0.5/src/libcschem/operation.c =================================================================== --- tags/1.0.5/src/libcschem/operation.c (nonexistent) +++ tags/1.0.5/src/libcschem/operation.c (revision 10414) @@ -0,0 +1,404 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2020,2022,2024 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + + +#include "config.h" + +#include +#include + +#include "concrete.h" +#include + +#include "event.h" +#include "cnc_obj.h" +#include "cnc_grp.h" +#include "cnc_grp_child.h" +#include "cnc_conn.h" +#include "cnc_any_obj.h" +#include "operation.h" +#include "search.h" +#include "op_common.h" +#include "undo.h" +#include "util_wirenet.h" + +extern const csch_ops_t csch_ops_line; +extern const csch_ops_t csch_ops_arc; +extern const csch_ops_t csch_ops_poly; +extern const csch_ops_t csch_ops_text; +extern const csch_ops_t csch_ops_conn; +extern const csch_ops_t csch_ops_cgrp; +extern const csch_ops_t csch_ops_cgrp_ref; +extern const csch_ops_t csch_ops_pen; + +static const csch_ops_t *ops[CSCH_CTYPE_max] = { + NULL, /* invalid */ + &csch_ops_line, + &csch_ops_arc, + &csch_ops_poly, + &csch_ops_text, + NULL, /* CSCH_CTYPE_BITMAP */ + &csch_ops_conn, + &csch_ops_cgrp, + &csch_ops_cgrp_ref, + &csch_ops_pen +}; + + +const csch_ops_t *csch_op_get(csch_ctype_t type) +{ + if ((type < 0) || (type >= CSCH_CTYPE_max)) + return NULL; + return ops[type]; +} + +RND_INLINE csch_chdr_t *csch_cnc_remove_(csch_sheet_t *sheet, csch_chdr_t *obj, csch_cnc_common_remove_t how) +{ + const csch_ops_t *ops = csch_op_get(obj->type); + csch_undo_remove_t *u, utmp; + csch_cgrp_t *parent = obj->parent; + + assert(ops != NULL); + assert(ops->remove_redo != NULL); + + if (how & CSCH_REM_UNDOABLE) + u = csch_op_remove_alloc_undo(sheet); + else + u = &utmp; + + u->obj = obj; + u->sheet = sheet; + + uundo_freeze_serial(&sheet->undo); /* remove_alloc() may have side effects: undoable changes to other related objects; bundle them */ + ops->remove_alloc(u); + + u->side_effects = 1; + ops->remove_redo(u); + u->side_effects = 0; + + if (how & CSCH_REM_UNDOABLE) + csch_conn_auto_recalc(sheet, obj); + + if ((parent != NULL) && (parent->role == CSCH_ROLE_WIRE_NET)) + csch_wirenet_post_remove_checks(sheet, parent, (how & CSCH_REM_UNDOABLE)); + + if ((how & CSCH_REM_DEL_EMPTY_PARENT) && (parent != NULL) && (parent->id2obj.used == 0) && (!csch_obj_is_deleted(&parent->hdr))) + csch_cnc_remove_(sheet, &parent->hdr, how); + + uundo_unfreeze_serial(&sheet->undo); + csch_undo_inc_serial(sheet); + + csch_sheet_set_changed(sheet, 1); + + return obj; +} + +csch_chdr_t *csch_op_remove(csch_sheet_t *sheet, csch_chdr_t *obj) +{ + return csch_cnc_remove_(sheet, obj, CSCH_REM_FROM_RTREE | CSCH_REM_FROM_PARENT | CSCH_REM_UNDOABLE | CSCH_REM_DEL_EMPTY_PARENT); +} + +csch_chdr_t *csch_cnc_remove(csch_sheet_t *sheet, csch_chdr_t *obj) +{ + return csch_cnc_remove_(sheet, obj, CSCH_REM_FROM_RTREE | CSCH_REM_FROM_PARENT); +} + +csch_chdr_t *csch_op_create(csch_sheet_t *sheet, csch_cgrp_t *parent, csch_ctype_t type) +{ + const csch_ops_t *op = csch_op_get(type); + csch_chdr_t *obj; + + if ((op == NULL) || (op->create == NULL)) + return NULL; + + obj = op->create(sheet, parent); + if (obj != NULL) + csch_op_inserted(sheet, parent, obj); + + return obj; +} + + +csch_chdr_t *csch_op_copy_into(csch_sheet_t *sheet, csch_cgrp_t *dst, csch_chdr_t *src) +{ + csch_chdr_t *newo; + +TODO("undo problem: dup doesn't preserve oid and that may need to be undone"); + newo = csch_cobj_dup(sheet, dst, src, 0, 1); + csch_cobj_update(sheet, newo, 0); + csch_op_inserted(sheet, dst, newo); + return newo; +} + +csch_chdr_t *csch_op_move_into(csch_sheet_t *sheet, csch_cgrp_t *dst, csch_chdr_t *src, int restore_conns, int undoable_conns) +{ + csch_chdr_t *newo = NULL; + vtp0_t conn_save; + long n; + + /* save original connections before removing the object */ + if (restore_conns) { + conn_save = src->conn; + src->conn.used = src->conn.alloced = 0; + src->conn.array = NULL; + } + + csch_op_remove(sheet, src); + +TODO("undo problem: dup doesn't preserve oid and that may need to be undone"); + newo = csch_cobj_dup(sheet, dst, src, 0, 1); + csch_cobj_update(sheet, newo, 0); + csch_op_inserted(sheet, dst, newo); + + /* restore connections: remove old object and add new object to the same conns */ + if (restore_conns) { + + for(n = 0; n < conn_save.used; n++) { + csch_conn_t *orig_conn = conn_save.array[n]; + csch_conn_t *existing = csch_conn_find_mergable(sheet, orig_conn, newo); + + if (existing) { + /* corer case: removing the wire from orig_conn may have oprhaned + orig_conn; this call takes care of removing that conn in an + undoable manner */ + csch_conn_auto_del_obj(sheet, orig_conn, src); + + /* if there is an existing "overlapping" conn in dst group, reuse that + instead of our original conn; this happens when a wire from wirenet A + is moved into wirenet B and the wire creates a new connection to + a terminal that wirenet B already connected. In this case the wire + should be removed from its own connection (orig_conn) and should be + added to the existing connection of wirenet B. */ + csch_conn_add_obj(sheet, existing, newo, undoable_conns); + } + else { + /* replace object in conn: remove old object (src) and add new + object (newo); this won't change the number of objects in orig_conn, + it can't get orphaned */ + csch_conn_del_obj(sheet, orig_conn, src, undoable_conns); + csch_conn_add_obj(sheet, orig_conn, newo, undoable_conns); + } + } + vtp0_uninit(&conn_save); + } + return newo; +} + +void csch_op_merge_into(csch_sheet_t *sheet, csch_cgrp_t *dst, csch_cgrp_t *src) +{ + htip_entry_t *e; + + /* always move the first, don't rely on htip_next() as items are being removed from src */ + for(e = htip_first(&src->id2obj); e != NULL; e = htip_first(&src->id2obj)) + csch_op_move_into(sheet, dst, e->value, 1, 1); + + csch_attrib_copy_all_undoable(sheet, dst, &dst->attr, &src->attr, 1); +} + +void csch_op_merge_into_remember(csch_sheet_t *sheet, csch_cgrp_t *dst, csch_cgrp_t *src, vtp0_t *dst_news) +{ + htip_entry_t *e; + + /* always move the first, don't rely on htip_next() as items are being removed from src */ + for(e = htip_first(&src->id2obj); e != NULL; e = htip_first(&src->id2obj)) { + void *newo = csch_op_move_into(sheet, dst, e->value, 1, 1); + if (newo != NULL) + vtp0_append(dst_news, newo); + } + + csch_attrib_copy_all_undoable(sheet, dst, &dst->attr, &src->attr, 1); +} + + +int csch_isc_with_box(csch_chdr_t *obj, csch_rtree_box_t *box) +{ + const csch_ops_t *op = csch_op_get(obj->type); + if ((op == NULL) || (op->isc_with_box == NULL)) + return 0; + return op->isc_with_box(obj, box); +} + +/* When moving or copying a floater: change dx and dy from sheet coords to + parent group coords */ +static void move_copy_floater_inverse(const csch_chdr_t *obj, csch_coord_t *dx, csch_coord_t *dy) +{ + g2d_xform_t mx; + g2d_vect_t v; + + /* optimization: noop on top objects */ + if (obj->parent == &obj->sheet->direct) + return; + + /* if there's no parent, there's no transformation possible (when copying to buffer) */ + if (obj->parent == NULL) + return; + + v.x = *dx; v.y = *dy; + csch_cgrp_inverse_matrix(&mx, obj->parent); + + mx.v[2] = mx.v[5] = 0; /* drop translation, we are interested only in mirror/rot */ + + v = g2d_xform_vect2vect(mx, v); + *dx = v.x; *dy = v.y; +} + +void csch_move(csch_sheet_t *sheet, csch_chdr_t *obj, csch_coord_t dx, csch_coord_t dy, int undoable) +{ + if ((dx != 0) || (dy != 0)) { + const csch_ops_t *op = csch_op_get(obj->type); + if ((op != NULL) && (op->move != NULL)) { + uundo_freeze_serial(&sheet->undo); + move_copy_floater_inverse(obj, &dx, &dy); + + if (!csch_grp_ref_child_moved(sheet, obj, dx, dy, undoable)) + op->move(sheet, obj, dx, dy, undoable); + + if (undoable) { + csch_conn_auto_recalc(sheet, obj); + if (csch_obj_is_grp(obj)) { + csch_cgrp_t *grp = (csch_cgrp_t *)obj; + if (grp->role == CSCH_ROLE_WIRE_NET) + csch_wirenet_recalc_junctions(sheet, grp); + } + } + uundo_unfreeze_serial(&sheet->undo); + uundo_inc_serial(&sheet->undo); + + + if (undoable) + csch_sheet_set_changed(sheet, 1); + } + } +} + +void csch_inst2spec(csch_sheet_t *sheet, csch_chdr_t *obj, const csch_chdr_t *inst_from, int undoable) +{ + const csch_ops_t *op = csch_op_get(obj->type); + if ((op != NULL) && (op->inst2spec != NULL)) { + uundo_freeze_serial(&sheet->undo); + op->inst2spec(sheet, obj, inst_from, undoable); + if (undoable) + csch_conn_auto_recalc(sheet, obj); + uundo_unfreeze_serial(&sheet->undo); + uundo_inc_serial(&sheet->undo); + } +} + + +void csch_copy(csch_sheet_t *sheet, csch_chdr_t *obj, csch_coord_t dx, csch_coord_t dy, int undoable) +{ + if ((dx != 0) || (dy != 0)) { + const csch_ops_t *op = csch_op_get(obj->type); + if ((op != NULL) && (op->copy != NULL)) { +/* csch_cobj_t *newo;*/ + + if (csch_obj_is_grp_ref_child(sheet, obj)) { + rnd_message(RND_MSG_ERROR, "Can't copy group ref children (would change the referenced group)\n"); + return; + } + + uundo_freeze_serial(&sheet->undo); + move_copy_floater_inverse(obj, &dx, &dy); +/* newo = */ + op->copy(sheet, obj, dx, dy, undoable); +/* if (undoable && (newo != NULL)) + csch_conn_auto_recalc(sheet, newo);*/ + uundo_unfreeze_serial(&sheet->undo); + uundo_inc_serial(&sheet->undo); + } + } +} + +static void floater_origin(const csch_chdr_t *obj, csch_coord_t *x, csch_coord_t *y) +{ + g2d_xform_t mx; + g2d_vect_t v; + + /* optimization: noop on top objects */ + if (obj->parent == &obj->sheet->direct) + return; + + v.x = *x; v.y = *y; + csch_cgrp_inverse_matrix(&mx, obj->parent); + v = g2d_xform_vect2vect(mx, v); + *x = v.x; *y = v.y; +} + +void csch_rotate(csch_sheet_t *sheet, csch_chdr_t *obj, csch_coord_t rcx, csch_coord_t rcy, double da, int undoable) +{ + da = fmod(da, 360); + if (da != 0) { + const csch_ops_t *op = csch_op_get(obj->type); + if ((op != NULL) && (op->rotate != NULL)) { + uundo_freeze_serial(&sheet->undo); + floater_origin(obj, &rcx, &rcy); + if (!csch_grp_ref_child_rotated(sheet, obj, rcx, rcy, da, undoable)) + op->rotate(sheet, obj, rcx, rcy, da, undoable); + if (undoable) + csch_conn_auto_recalc(sheet, obj); + uundo_unfreeze_serial(&sheet->undo); + uundo_inc_serial(&sheet->undo); + } + } +} + +void csch_rotate90(csch_sheet_t *sheet, csch_chdr_t *obj, csch_coord_t rcx, csch_coord_t rcy, int n, int undoable) +{ + n = n & 0x3; + if (n != 0) { + const csch_ops_t *op = csch_op_get(obj->type); + if ((op != NULL) && (op->rotate90 != NULL)) { + uundo_freeze_serial(&sheet->undo); + floater_origin(obj, &rcx, &rcy); + if (!csch_grp_ref_child_rotated90(sheet, obj, rcx, rcy, n, undoable)) + op->rotate90(sheet, obj, rcx, rcy, n, undoable); + if (undoable) + csch_conn_auto_recalc(sheet, obj); + uundo_unfreeze_serial(&sheet->undo); + uundo_inc_serial(&sheet->undo); + } + } +} + +void csch_mirror(csch_sheet_t *sheet, csch_chdr_t *obj, csch_coord_t mcx, csch_coord_t mcy, int mirx, int miry, int undoable) +{ + if (mirx || miry) { + const csch_ops_t *op = csch_op_get(obj->type); + if ((op != NULL) && (op->mirror != NULL)) { + uundo_freeze_serial(&sheet->undo); + floater_origin(obj, &mcx, &mcy); + if (!csch_grp_ref_child_mirrored(sheet, obj, mcx, mcy, mirx, miry, undoable)) + op->mirror(sheet, obj, mcx, mcy, mirx, miry, undoable); + if (undoable) + csch_conn_auto_recalc(sheet, obj); + uundo_unfreeze_serial(&sheet->undo); + uundo_inc_serial(&sheet->undo); + } + } +} + Index: tags/1.0.5/src/libcschem/operation.h =================================================================== --- tags/1.0.5/src/libcschem/operation.h (nonexistent) +++ tags/1.0.5/src/libcschem/operation.h (revision 10414) @@ -0,0 +1,98 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2020,2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + + +#ifndef CSCH_OPERATIONS_H +#define CSCH_OPERATIONS_H + +#include "concrete.h" + +typedef struct csch_undo_remove_s { + csch_chdr_t *obj; + csch_cgrp_t *parent; + csch_sheet_t *sheet; + unsigned side_effects:1; /* whether side effects should be performed */ +} csch_undo_remove_t; + +typedef struct csch_undo_remove_s csch_undo_create_t; + +typedef struct { + csch_chdr_t *(*create)(csch_sheet_t *sheet, csch_cgrp_t *parent); + void (*remove_alloc)(csch_undo_remove_t *slot); + void (*remove_redo)(csch_undo_remove_t *slot); + void (*remove_undo)(csch_undo_remove_t *slot); + int (*isc_with_box)(csch_chdr_t *obj, csch_rtree_box_t *box); + void (*move)(csch_sheet_t *sheet, csch_chdr_t *obj, csch_coord_t dx, csch_coord_t dy, int undoable); + void (*copy)(csch_sheet_t *sheet, csch_chdr_t *obj, csch_coord_t dx, csch_coord_t dy, int undoable); + void (*rotate)(csch_sheet_t *sheet, csch_chdr_t *obj, csch_coord_t rcx, csch_coord_t rcy, double da, int undoable); + void (*rotate90)(csch_sheet_t *sheet, csch_chdr_t *obj, csch_coord_t rcx, csch_coord_t rcy, int n, int undoable); + void (*mirror)(csch_sheet_t *sheet, csch_chdr_t *obj, csch_coord_t mcx, csch_coord_t mcy, int mirx, int miry, int undoable); + void (*inst2spec)(csch_sheet_t *sheet, csch_chdr_t *obj, const csch_chdr_t *in, int undoable); +} csch_ops_t; + + +csch_chdr_t *csch_op_create(csch_sheet_t *sheet, csch_cgrp_t *parent, csch_ctype_t type); +csch_chdr_t *csch_op_remove(csch_sheet_t *sheet, csch_chdr_t *obj); + +/* non-undoable object remove (e.g. for buffer) */ +csch_chdr_t *csch_cnc_remove(csch_sheet_t *sheet, csch_chdr_t *obj); + + +/* migrate all objects from src to dst, leaving src empty (always undoable); + the remember variant appends all new object pointers to dst_news */ +void csch_op_merge_into(csch_sheet_t *sheet, csch_cgrp_t *dst, csch_cgrp_t *src); +void csch_op_merge_into_remember(csch_sheet_t *sheet, csch_cgrp_t *dst, csch_cgrp_t *src, vtp0_t *dst_news); + +int csch_isc_with_box(csch_chdr_t *obj, csch_rtree_box_t *box); + +/* Undoably move/copy object by dx;dy; the original spec is moved/copied */ +void csch_move(csch_sheet_t *sheet, csch_chdr_t *obj, csch_coord_t dx, csch_coord_t dy, int undoable); +void csch_copy(csch_sheet_t *sheet, csch_chdr_t *obj, csch_coord_t dx, csch_coord_t dy, int undoable); + +/* Copy inst (current final transformation) of inst_from to spec of obj; this + can be used in a transformed group breakup to get all ex-member objects stay in place. */ +void csch_inst2spec(csch_sheet_t *sheet, csch_chdr_t *obj, const csch_chdr_t *inst_from, int undoable); + +/* Undoably rotate object by da degrees around rcx;rcy; the original spec is moved */ +void csch_rotate(csch_sheet_t *sheet, csch_chdr_t *obj, csch_coord_t rcx, csch_coord_t rcy, double da, int undoable); + +/* Same as rotate but works in n*90 degree angles and guarantees to avoid + rounding errors */ +void csch_rotate90(csch_sheet_t *sheet, csch_chdr_t *obj, csch_coord_t rcx, csch_coord_t rcy, int n, int undoable); + +/* Mirror object's x or y coords (mirx or miry) around mcx;mcy */ +void csch_mirror(csch_sheet_t *sheet, csch_chdr_t *obj, csch_coord_t mcx, csch_coord_t mcy, int mirx, int miry, int undoable); + +/* Copy or move src into the dst group; always undoable */ +csch_chdr_t *csch_op_copy_into(csch_sheet_t *sheet, csch_cgrp_t *dst, csch_chdr_t *src); +csch_chdr_t *csch_op_move_into(csch_sheet_t *sheet, csch_cgrp_t *dst, csch_chdr_t *src, int restore_conns, int undoable_conns); + + +const csch_ops_t *csch_op_get(csch_ctype_t type); + +#endif Index: tags/1.0.5/src/libcschem/plug_io.c =================================================================== --- tags/1.0.5/src/libcschem/plug_io.c (nonexistent) +++ tags/1.0.5/src/libcschem/plug_io.c (revision 10414) @@ -0,0 +1,763 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2018,2019,2023 Tibor 'Igor2' Palinkas + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + + +#include "config.h" +#include +#include +#include +#include "cnc_grp.h" +#include "cnc_obj.h" +#include "cnc_any_obj.h" +#include "plug_io.h" +#include +#include +#include "project.h" +#include "integrity.h" +#include +#include + +vtp0_t csch_ios; + +void csch_plug_io_register(const csch_plug_io_t *io) +{ + vtp0_append(&csch_ios, (void *)io); +} + +void csch_plug_io_unregister(const csch_plug_io_t *io) +{ + long n; + for(n = 0; n < csch_ios.used; n++) + if (csch_ios.array[n] == io) + csch_ios.array[n] = NULL; +} + +void csch_plug_io_uninit(void) +{ + vtp0_uninit(&csch_ios); +} + +typedef struct { + int prio; + csch_plug_io_t *io; +} prio_t; +#define GVT(x) vtpr_ ## x +#define GVT_ELEM_TYPE prio_t +#define GVT_SIZE_TYPE int +#define GVT_DOUBLING_THRS 32 +#define GVT_START_SIZE 8 +#define GVT_FUNC +#define GVT_SET_NEW_BYTES_TO 0 +#include +#define GVT_REALLOC(vect, ptr, size) realloc(ptr, size) +#define GVT_FREE(vect, ptr) free(ptr) +#include + +static int prio_cmp(const void *d1, const void *d2) +{ + const prio_t *p1 = d1, *p2 = d2; + if (p1->prio <= p2->prio) return 1; + return -1; +} + +typedef enum { + LIST_LOAD, + LIST_SAVE, + LIST_EXPORT +} io_list_dir_t; + +static void csch_plug_io_list(vtpr_t *res, const char *fn, const char *fmt, csch_plug_io_type_t type, io_list_dir_t dir) +{ + int n, p; + prio_t *pr; + + for(n = 0; n < vtp0_len(&csch_ios); n++) { + csch_plug_io_t *io = csch_ios.array[n]; + if (io == NULL) continue; + switch(dir) { + case LIST_LOAD: + if (io->load_prio == NULL) continue; + p = io->load_prio(fn, fmt, type); + break; + case LIST_SAVE: + if (io->save_prio == NULL) continue; + p = io->save_prio(fn, fmt, type); + break; + case LIST_EXPORT: + if (io->export_prio == NULL) continue; + p = io->export_prio(fn, fmt, type); + break; + } + + if (p > 0) { + pr = vtpr_alloc_append(res, 1); + pr->prio = p; + pr->io = io; + } + } + qsort(res->array, vtpr_len(res), sizeof(prio_t), prio_cmp); +} + +static int load_postproc_sheet(csch_sheet_t *sheet) +{ + if (sheet->direct.hdr.oid != CSCH_TOP_OID_DIRECT) { + rnd_msg_error("Load error: top group 'direct' doesn't have the correct OID (has %d, expected %d\n", sheet->direct.hdr.oid, CSCH_TOP_OID_DIRECT); + return -1; + } + if (sheet->indirect.hdr.oid != CSCH_TOP_OID_INDIRECT) { + rnd_msg_error("Load error: top group 'indirect' doesn't have the correct OID (has %d, expected %d\n", sheet->indirect.hdr.oid, CSCH_TOP_OID_INDIRECT); + return -1; + } + csch_cobj_redraw_freeze(sheet); + csch_cgrp_render_all(sheet, &sheet->direct); + csch_cobj_update(sheet, &sheet->direct.hdr, 1); + csch_cobj_redraw_unfreeze(sheet); + return 0; +} + +/* if proj is not NULL and sheet is NULL, allocate a new sheet */ +csch_sheet_t *csch_load_sheet_io(csch_project_t *proj, csch_sheet_t *sheet, const char *load_fn, const char *real_fn, const char *fmt, int is_buffer, FILE *optf) +{ + int n; + vtpr_t prios; + FILE *f; + + if (optf == NULL) { + f = rnd_fopen(NULL, real_fn, "r"); + if (f == NULL) { + TODO("error reporting"); + return NULL; + } + } + else + f = optf; + + vtpr_init(&prios); + csch_plug_io_list(&prios, real_fn, fmt, (is_buffer ? CSCH_IOTYP_BUFFER : CSCH_IOTYP_SHEET), LIST_LOAD); + +#if 0 + for(n = 0; n < vtpr_len(&prios); n++) { + prio_t *pr = &prios.array[n]; + rnd_trace("*** %d %s\n", pr->prio, pr->io->name); + } +#endif + + for(n = 0; n < vtpr_len(&prios); n++) { + prio_t *pr = &prios.array[n]; + int alloced = 0, load_res; + + rewind(f); + if (pr->io->test_parse != NULL) { + if (pr->io->test_parse(f, real_fn, fmt, (is_buffer ? CSCH_IOTYP_BUFFER : CSCH_IOTYP_SHEET)) != 0) + continue; + rewind(f); + } + + if ((proj != NULL) && (sheet == NULL) && (!is_buffer)) { + sheet = csch_sheet_alloc(proj); + alloced = 1; + } + if (sheet == NULL) + break; + + csch_cobj_redraw_freeze(sheet); + if (is_buffer) { + load_res = pr->io->load_buffer(f, real_fn, fmt, sheet); + } + else if (pr->io->load_sheet == NULL) + load_res = -1; + else { + rnd_event(&sheet->hidlib, RND_EVENT_LOAD_PRE, "s", real_fn); + load_res = pr->io->load_sheet(f, real_fn, fmt, sheet); + if (load_res != 0) { + sheet->non_graphical = 0; + sheet->non_graphical_impl = NULL; + sheet->non_graphical_data = NULL; + } + rnd_event(&sheet->hidlib, RND_EVENT_LOAD_POST, "si", real_fn, load_res); + } + csch_cobj_redraw_unfreeze(sheet); + + if (load_res == 0) { + free(sheet->hidlib.fullpath); + sheet->hidlib.fullpath = rnd_strdup(real_fn); + free(sheet->hidlib.loadname); + sheet->hidlib.loadname = rnd_strdup(load_fn); + free(sheet->loadfmt); + sheet->loadfmt = (fmt == NULL ? NULL : rnd_strdup(fmt)); + sheet->load_pending = 0; + load_postproc_sheet(sheet); + break; + } + if (alloced) { + csch_sheet_free(sheet); + sheet = NULL; + } + else + csch_sheet_uninit(sheet); + } + vtpr_uninit(&prios); + + if (optf == NULL) + fclose(f); + + return sheet; +} + +int csch_test_parse_file(rnd_design_t *hl, FILE *f, const char *real_fn, csch_plug_io_type_t type) +{ + long n; + int res = 0; + + for(n = 0; n < vtp0_len(&csch_ios); n++) { + csch_plug_io_t *io = csch_ios.array[n]; + + rewind(f); + if ((io->test_parse != NULL) && (io->test_parse(f, real_fn, NULL, type) == 0)) { + res = 1; + break; + } + } + + return res; +} + +int csch_test_parse_fn(rnd_design_t *hl, const char *fn, csch_plug_io_type_t type) +{ + int res; + FILE *f; + + f = rnd_fopen(hl, fn, "r"); + if (f == NULL) + return -1; + + res = csch_test_parse_file(hl, f, fn, type); + + fclose(f); + return res; +} + +void *csch_test_parse_bundled(rnd_design_t *hl, const char *real_fn, csch_plug_io_type_t type, FILE **f_out, void **io_out) +{ + long n; + FILE *f = NULL; + void *cookie = NULL; + + *io_out = NULL; + + for(n = 0; n < vtp0_len(&csch_ios); n++) { + csch_plug_io_t *io = csch_ios.array[n]; + + if (io->test_parse_bundled == NULL) + continue; + + if (f == NULL) { + f = rnd_fopen(hl, real_fn, "r"); + if (f == NULL) + return NULL; + } + else + rewind(f); + + cookie = io->test_parse_bundled(f, real_fn, NULL, type); + if (cookie != NULL) { + *io_out = io; + break; + } + } + + *f_out = f; + return cookie; +} + +static int load_postproc_project(csch_project_t *proj) +{ + return 0; +} + +csch_sheet_t *csch_load_bundled_sheets(void *cookie, void *io_, FILE *f, const char *fn, void (*post_load_cb)(csch_sheet_t *)) +{ + csch_plug_io_t *io = io_; + csch_project_t *prj; + csch_sheet_t *res = NULL; + + prj = csch_project_alloc(); + prj->hdr.loadname = rnd_strdup(fn); + load_postproc_project(prj); + + for(;;) { + int r; + csch_sheet_t *sheet = csch_sheet_alloc(prj); + rnd_conf_state_t *ncs; + + rnd_conf_multi_pre_new_design(&ncs); + rnd_conf_reset(RND_CFR_DESIGN, fn); + rnd_conf_merge_all(NULL); /* get the conf tree filled in - some io plugins depend on config for the load/parse */ + + csch_cobj_redraw_freeze(sheet); + r = io->load_sheet_bundled(cookie, f, fn, sheet); + csch_cobj_redraw_unfreeze(sheet); + + if (r >= 0) { + rnd_project_append_design(&prj->hdr, &sheet->hidlib); + if (res == NULL) + res = sheet; /* return first sheet loaded */ + } + + rnd_conf_multi_post_new_design(&ncs, &sheet->hidlib); + rnd_conf_state_new_design(&sheet->hidlib); + rnd_conf_merge_all(NULL); /* to get the project file applied */ + + post_load_cb(sheet); + rnd_conf_state_save(sheet->hidlib.saved_rnd_conf); + + if (r != 0) /* stop iteration on error or eof */ + break; + } + + io->end_bundled(cookie, fn); + + return res; +} + + +csch_sheet_t *csch_load_sheet(csch_project_t *proj, const char *load_fn, const char *fmt, int *already_in_proj, FILE *optf) +{ + int n; + csch_sheet_t *sheet = NULL; + char *real_fn; + + if ((fmt != NULL) && (*fmt == '\0')) fmt = NULL; /* reduce the number of cases */ + + if (already_in_proj != NULL) + *already_in_proj = 0; + + real_fn = rnd_lrealpath(load_fn); + if (real_fn == NULL) { + TODO("error reporting: already loaded"); + return NULL; + } + for(n = 0; n < proj->hdr.designs.used; n++) { + csch_sheet_t *sh = proj->hdr.designs.array[n]; + if (sh->hidlib.fullpath == NULL) continue; + if (strcmp(sh->hidlib.fullpath, real_fn) == 0) { + if (already_in_proj != NULL) + *already_in_proj = 1; + if (!sh->load_pending) { + free(real_fn); + return sh; + } + sheet = sh; + break; + } + } + + sheet = csch_load_sheet_io(proj, sheet, load_fn, real_fn, fmt, 0, optf); + if ((sheet != NULL) && (sheet->hidlib.project != NULL) && (already_in_proj != NULL)) + *already_in_proj = 1; + + free(real_fn); + if (sheet != NULL) + CSCH_INTEGRITY_SHEET_AUTO(sheet); + return sheet; +} + +void csch_revert_sheet(csch_sheet_t *sheet, csch_sheet_t *(*sheet_new)(csch_sheet_t *)) +{ + csch_sheet_t *orig_sheet = sheet; + char *orig_fmt = sheet->loadfmt; + char *orig_real_fn = sheet->hidlib.fullpath; + char *orig_load_fn = sheet->hidlib.loadname; + csch_project_t *proj = (csch_project_t *)sheet->hidlib.project; + int defsheet = 0, newed = 0; + + if (orig_real_fn == NULL) { + /* this happens on a "new sheet", when default sheet is loaded; revert should load that */ + orig_real_fn = rnd_strdup_null(orig_load_fn == NULL ? sheet->newname : orig_load_fn); + orig_load_fn = rnd_strdup_null(orig_real_fn); + defsheet = 1; + } + + rnd_event(&sheet->hidlib, CSCH_EVENT_SHEET_PREUNLOAD, NULL); + sheet->hidlib.loadname = NULL; + sheet->loadfmt = NULL; + sheet->hidlib.fullpath = NULL; + csch_sheet_uninit(sheet); + csch_sheet_init(sheet, proj); + + sheet = csch_load_sheet_io(NULL, orig_sheet, orig_load_fn, orig_real_fn, orig_fmt, 0, NULL); + if (sheet == NULL) { + sheet = sheet_new(orig_sheet); + newed = 1; + } + free(orig_fmt); + free(orig_real_fn); + free(orig_load_fn); + + if (defsheet) { + free(sheet->hidlib.fullpath); + sheet->hidlib.fullpath = NULL; + sheet->newname = sheet->hidlib.loadname; + sheet->hidlib.loadname = NULL; + } + + if (!newed) + rnd_event(&sheet->hidlib, CSCH_EVENT_SHEET_POSTLOAD, NULL); + rnd_event(&sheet->hidlib, RND_EVENT_LOAD_POST, NULL); +} + + + +csch_project_t *csch_load_project(const char *load_fn, const char *fmt, int with_sheets) +{ + vtpr_t prios; + int n; + FILE *f; + csch_project_t *proj = NULL; + char *real_fn; + + if ((fmt != NULL) && (*fmt == '\0')) fmt = NULL; /* reduce the number of cases */ + + real_fn = rnd_lrealpath(load_fn); + if (real_fn == NULL) { + TODO("error reporting"); + return NULL; + } + f = rnd_fopen(NULL, real_fn, "r"); + if (f == NULL) { + TODO("error reporting"); + free(real_fn); + return NULL; + } + + vtpr_init(&prios); + csch_plug_io_list(&prios, real_fn, fmt, CSCH_IOTYP_PROJECT, LIST_LOAD); + for(n = 0; n < vtpr_len(&prios); n++) { + prio_t *pr = &prios.array[n]; + + rewind(f); + if ((pr->io->test_parse != NULL) && (pr->io->test_parse(f, real_fn, fmt, CSCH_IOTYP_PROJECT) != 0)) + continue; + + proj = csch_project_alloc(); + if (pr->io->load_project(f, real_fn, fmt, proj, with_sheets) == 0) { + free(proj->hdr.fullpath); + proj->hdr.fullpath = real_fn; + real_fn = NULL; + free(proj->hdr.loadname); + proj->hdr.loadname = rnd_strdup(load_fn); + load_postproc_project(proj); + break; + } + csch_project_free(proj); + proj = NULL; + } + vtpr_uninit(&prios); + free(real_fn); + fclose(f); + return proj; +} + +static int csch_save_sheet_as_sym(prio_t *pr, const char *fn, const char *fmt, const csch_sheet_t *sheet) +{ + return pr->io->save_grp(fn, fmt, &sheet->direct, 0); +} + +typedef enum { SS_SAVE_SHEET, SS_SAVE_SHEET_BACKUP, SS_EXPORT_SHEET, SS_SAVE_BUFFER, SS_SAVE_SHEET_AS_SYM } save_sheet_t; +static int csch_export_or_save_sheet(csch_sheet_t *sheet, const char *fn_, const char *fmt, save_sheet_t stype, int preserve_changed) +{ + vtpr_t prios; + int n, ret = -1, len, preserve_name = 0; + char *fn, *ext = NULL; + + if ((fmt == NULL) || (*fmt == '\0')) + return -1; + + if (stype == SS_SAVE_SHEET_BACKUP) + preserve_name = 1; + + if (sheet->is_symbol && ((stype == SS_SAVE_SHEET) || (stype == SS_SAVE_SHEET_BACKUP))) + stype = SS_SAVE_SHEET_AS_SYM; + + len = strlen(fn_); + fn = malloc(len+1); + memcpy(fn, fn_, len+1); + if (fn[len-1] == '*') + ext = fn + len - 1; + + vtpr_init(&prios); + csch_plug_io_list(&prios, fn, fmt, CSCH_IOTYP_SHEET, ((stype == SS_EXPORT_SHEET) ? LIST_EXPORT : LIST_SAVE)); + for(n = 0; n < vtpr_len(&prios); n++) { + prio_t *pr = &prios.array[n]; + if (ext != NULL) { + switch(stype) { + case SS_EXPORT_SHEET: + if (pr->io->ext_export_sheet != NULL) + strcpy(ext, pr->io->ext_export_sheet); + else + *ext = '\0'; + break; + case SS_SAVE_SHEET: + case SS_SAVE_SHEET_BACKUP: + if (pr->io->ext_save_sheet != NULL) + strcpy(ext, pr->io->ext_save_sheet); + else + *ext = '\0'; + break; + case SS_SAVE_SHEET_AS_SYM: + if (pr->io->ext_save_grp != NULL) + strcpy(ext, pr->io->ext_save_grp); + else + *ext = '\0'; + break; + case SS_SAVE_BUFFER: + if (pr->io->ext_save_buffer != NULL) + strcpy(ext, pr->io->ext_save_buffer); + else + *ext = '\0'; + break; + } + } + + + switch(stype) { + case SS_EXPORT_SHEET: + ret = pr->io->export_sheet(fn, fmt, sheet); + break; + case SS_SAVE_SHEET: + case SS_SAVE_SHEET_BACKUP: + case SS_SAVE_SHEET_AS_SYM: + sheet->saving = 1; + rnd_event(&sheet->hidlib, RND_EVENT_SAVE_PRE, "s", fmt); + + if (stype == SS_SAVE_SHEET_AS_SYM) + ret = csch_save_sheet_as_sym(pr, fn, fmt, sheet); + else + ret = pr->io->save_sheet(fn, fmt, sheet); + + if (!preserve_name && ((stype == SS_SAVE_SHEET) || (stype == SS_SAVE_SHEET_AS_SYM))) { + char *newname = rnd_lrealpath(fn); + if (newname == NULL) { + rnd_message(RND_MSG_ERROR, "Failed to realpath(%s)\nMight be write permission problems\n", fn); + ret = -1; + goto error; + } + if ((sheet->hidlib.fullpath == NULL) || (strcmp(sheet->hidlib.fullpath, newname) != 0)) { + free(sheet->hidlib.fullpath); + sheet->hidlib.fullpath = newname; + free(sheet->hidlib.loadname); + sheet->hidlib.loadname = rnd_strdup(rnd_basename(newname)); + } + else + free(newname); + } + if (preserve_changed == 0) + rnd_event(&sheet->hidlib, CSCH_EVENT_SHEET_POSTSAVE, NULL); /* updates the info bar */ + sheet->saving = 0; + rnd_event(&sheet->hidlib, RND_EVENT_SAVE_POST, "si", fmt, ret); + if ((ret == 0) && !preserve_changed) + csch_sheet_set_changed(sheet, 0); + break; + + case SS_SAVE_BUFFER: + ret = pr->io->save_buffer(fn, fmt, sheet); + break; + } + + if (ret == 0) + break; + } + + error:; + free(fn); + vtpr_uninit(&prios); + return ret; +} + +int csch_export_sheet(csch_sheet_t *sheet, const char *fn, const char *fmt) +{ + return csch_export_or_save_sheet(sheet, fn, fmt, SS_EXPORT_SHEET, 0); +} + +int csch_save_sheet(csch_sheet_t *sheet, const char *fn, const char *fmt) +{ + return csch_export_or_save_sheet(sheet, fn, fmt, SS_SAVE_SHEET, 0); +} + +int csch_save_sheet_backup(csch_sheet_t *sheet, const char *fn, const char *fmt) +{ + return csch_export_or_save_sheet(sheet, fn, fmt, SS_SAVE_SHEET_BACKUP, 1); +} + + +int csch_export_project_abst(csch_abstract_t *abs, const char *fn_, const char *fmt, rnd_hid_attr_val_t *options) +{ + vtpr_t prios; + int n, ret = -1, len; + char *fn, *ext = NULL; + + if ((fmt == NULL) || (*fmt == '\0')) + return -1; + + len = strlen(fn_); + fn = malloc(len+256); /* leave "enoguh room" for the extension */ + memcpy(fn, fn_, len+1); /* copy \0 as well */ + if (fn[len-1] == '*') + ext = fn + len - 1; + + vtpr_init(&prios); + csch_plug_io_list(&prios, fn, fmt, CSCH_IOTYP_NETLIST, LIST_EXPORT); + for(n = 0; n < vtpr_len(&prios); n++) { + prio_t *pr = &prios.array[n]; + if (ext != NULL) { + if (pr->io->ext_export_project != NULL) + strcpy(ext, pr->io->ext_export_project); + else + *ext = '\0'; + } + ret = pr->io->export_project_abst(fn, fmt, abs, options); + if (ret == 0) + break; + } + + free(fn); + vtpr_uninit(&prios); + return ret; +} + +int csch_save_grp(csch_cgrp_t *grp, const char *fn_, const char *fmt, int inhibit_uuid) +{ + vtpr_t prios; + int n, ret = -1, len; + char *fn, *ext = NULL; + + if ((fmt == NULL) || (*fmt == '\0')) + return -1; + + len = strlen(fn_); + fn = malloc(len+1); + memcpy(fn, fn_, len+1); + if (fn[len-1] == '*') + ext = fn + len - 1; + + vtpr_init(&prios); + csch_plug_io_list(&prios, fn, fmt, CSCH_IOTYP_SHEET, LIST_SAVE); + for(n = 0; n < vtpr_len(&prios); n++) { + prio_t *pr = &prios.array[n]; + if (ext != NULL) { + if (pr->io->ext_save_grp != NULL) + strcpy(ext, pr->io->ext_save_grp); + else + *ext = '\0'; + } + ret = pr->io->save_grp(fn, fmt, grp, inhibit_uuid); + if (ret == 0) + break; + } + + free(fn); + vtpr_uninit(&prios); + return ret; +} + +csch_cgrp_t *csch_load_grp(csch_sheet_t *dst, const char *load_fn, const char *fmt) +{ + vtpr_t prios; + int n; + FILE *f; + char *real_fn; + csch_cgrp_t *res = NULL; + + if ((fmt != NULL) && (*fmt == '\0')) fmt = NULL; /* reduce the number of cases */ + + real_fn = rnd_lrealpath(load_fn); + if (real_fn == NULL) { + TODO("error reporting: not found"); + return NULL; + } + + f = rnd_fopen(NULL, real_fn, "r"); + if (f == NULL) { + TODO("error reporting"); + free(real_fn); + return NULL; + } + + vtpr_init(&prios); + csch_plug_io_list(&prios, real_fn, fmt, CSCH_IOTYP_SHEET, LIST_LOAD); + +#if 0 + for(n = 0; n < vtpr_len(&prios); n++) { + prio_t *pr = &prios.array[n]; + rnd_trace("*** %d %s\n", pr->prio, pr->io->name); + } +#endif + + for(n = 0; n < vtpr_len(&prios); n++) { + prio_t *pr = &prios.array[n]; + + if (pr->io->load_grp == NULL) + continue; + + rewind(f); + if ((pr->io->test_parse != NULL) && (pr->io->test_parse(f, real_fn, fmt, CSCH_IOTYP_GROUP) != 0)) + continue; + + rewind(f); + res = pr->io->load_grp(f, real_fn, fmt, dst); + } + vtpr_uninit(&prios); + free(real_fn); + fclose(f); + + if (res != NULL) + res->file_name = rnd_strdup(load_fn); + + return res; +} + +int csch_load_buffer(csch_sheet_t *buffer, const char *load_fn, const char *fmt) +{ + csch_sheet_t *rsheet; + char *real_fn; + + if ((fmt != NULL) && (*fmt == '\0')) fmt = NULL; /* reduce the number of cases */ + + real_fn = rnd_lrealpath(load_fn); + if (real_fn == NULL) { + rnd_message(RND_MSG_ERROR, "csch_load_buffer(): can't find real path for '%s'\n", load_fn); + return -1; + } + + rsheet = csch_load_sheet_io(NULL, buffer, load_fn, real_fn, fmt, 1, NULL); + free(real_fn); + return (rsheet == NULL) ? -1 : 0; +} + +int csch_save_buffer(csch_sheet_t *buffer, const char *fn, const char *fmt) +{ + return csch_export_or_save_sheet(buffer, fn, fmt, SS_SAVE_BUFFER, 0); +} Index: tags/1.0.5/src/libcschem/plug_io.h =================================================================== --- tags/1.0.5/src/libcschem/plug_io.h (nonexistent) +++ tags/1.0.5/src/libcschem/plug_io.h (revision 10414) @@ -0,0 +1,139 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2018,2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust in 2023) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + + +#ifndef CSCH_PLUG_IO_H +#define CSCH_PLUG_IO_H + +#include +#include +#include +#include + +typedef enum csch_plug_io_type_s { /* bitfield so multiple detections (e.g. sheet-or-project) can be handled */ + CSCH_IOTYP_PROJECT = 1, + CSCH_IOTYP_SHEET = 2, + CSCH_IOTYP_BUFFER = 4, /* whole buffer (direct & indirect; similar to sheet) */ + CSCH_IOTYP_GROUP = 8, /* a single group (e.g. symbol) */ + CSCH_IOTYP_NETLIST = 16 +} csch_plug_io_type_t; + +typedef struct csch_plug_io_s { + const char *name; + + int (*load_prio)(const char *fn, const char *fmt, csch_plug_io_type_t type); + int (*save_prio)(const char *fn, const char *fmt, csch_plug_io_type_t type); + int (*test_parse)(FILE *f, const char *fn, const char *fmt, csch_plug_io_type_t type); + + int (*load_sheet)(FILE *f, const char *fn, const char *fmt, csch_sheet_t *dst); + int (*save_sheet)(const char *fn, const char *fmt, const csch_sheet_t *dst); + int (*load_project)(FILE *f, const char *fn, const char *fmt, csch_project_t *dst, int with_sheets); + + int (*load_buffer)(FILE *f, const char *fn, const char *fmt, csch_sheet_t *dst); + int (*save_buffer)(const char *fn, const char *fmt, const csch_sheet_t *dst); + + /* useful for saving/loading symbols */ + csch_cgrp_t *(*load_grp)(FILE *f, const char *fn, const char *fmt, csch_sheet_t *sheet); + int (*save_grp)(const char *fn, const char *fmt, const csch_cgrp_t *src, int inhibit_uuid); + + int (*export_prio)(const char *fn, const char *fmt, csch_plug_io_type_t type); + int (*export_sheet)(const char *fn, const char *fmt, csch_sheet_t *dst); + int (*export_project_abst)(const char *fn, const char *fmt, csch_abstract_t *abs, rnd_hid_attr_val_t *options); + + /* Bundled files contain multiple sheets or symbols. For sheets, they + act as a project file. test_parse_bundled() is called before + test_parse; if it returns non-NULL, the file is considered + bundled and the _bundled() loader is called with the cookie + set to the intially returned value, in an iteration. If the + bundled() loader returns a positive value, the iteration stops. + Negative return means error (iteration stops). Return zero when the next + item was loaded succesfully. end_bundled() is called after the iteration. + + WARNING: config is not available in test_parse_bundled(), only in + load_sheet_bundled(). + */ + void *(*test_parse_bundled)(FILE *f, const char *fn, const char *fmt, csch_plug_io_type_t type); + int (*load_sheet_bundled)(void *cookie, FILE *f, const char *fn, csch_sheet_t *dst); + /* TODO: load_grp_bundled() */ + void (*end_bundled)(void *cookie, const char *fn); + + const char *ext_export_sheet; /* default extension for exporting sheets */ + const char *ext_save_sheet; /* default extension for saving sheets */ + const char *ext_save_buffer; /* default extension for saving buffers */ + const char *ext_save_grp; /* default extension for saving groups */ + const char *ext_export_project; /* default extension for exporting the whole project (e.g. abstract model for netlist or bundled export of concrete model) */ +} csch_plug_io_t; + +void csch_plug_io_register(const csch_plug_io_t *io); +void csch_plug_io_unregister(const csch_plug_io_t *io); + +/* Load a sheet. If optf is NULL, use fopen()/fclose() using fn. optf + is not closed but seeked/rewound. */ +csch_sheet_t *csch_load_sheet(csch_project_t *proj, const char *fn, const char *fmt, int *already_in_proj, FILE *optf); + +csch_project_t *csch_load_project(const char *fn, const char *fmt, int with_sheets); +csch_cgrp_t *csch_load_grp(csch_sheet_t *dst, const char *load_fn, const char *fmt); + +int csch_save_sheet(csch_sheet_t *sheet, const char *fn, const char *fmt); +int csch_save_sheet_backup(csch_sheet_t *sheet, const char *fn, const char *fmt); /* does not make the sheet look saved */ +int csch_save_grp(csch_cgrp_t *grp, const char *fn_, const char *fmt, int inhibit_uuid); + +int csch_load_buffer(csch_sheet_t *buffer, const char *fn, const char *fmt); +int csch_save_buffer(csch_sheet_t *buffer, const char *fn, const char *fmt); + + +int csch_export_sheet(csch_sheet_t *sheet, const char *fn, const char *fmt); +int csch_export_project_abst(csch_abstract_t *abs, const char *fn, const char *fmt, rnd_hid_attr_val_t *options); + +void csch_revert_sheet(csch_sheet_t *sheet, csch_sheet_t *(*sheet_new)(csch_sheet_t *)); + +/* Test-parse the file for type using all available io plugin in random + order. Return -1 on error (e.g. file can not be open for read), 0 if + no plugin accepted the file or 1 if a plugin accepted it. Rewind()s + the file multiple times. */ +int csch_test_parse_fn(rnd_design_t *hl, const char *fn, csch_plug_io_type_t type); + +/* Same as csch_test_parse_fn() but takes FILE *f already open from the caller */ +int csch_test_parse_file(rnd_design_t *hl, FILE *f, const char *real_fn, csch_plug_io_type_t type); + +/* low level sheet loader. If optf is NULL, use fopen()/fclose() using real_fn. + optf is not closed but seeked/rewound. */ +csch_sheet_t *csch_load_sheet_io(csch_project_t *proj, csch_sheet_t *sheet, const char *load_fn, const char *real_fn, const char *fmt, int is_buffer, FILE *optf); + + +void *csch_test_parse_bundled(rnd_design_t *hl, const char *real_fn, csch_plug_io_type_t type, FILE **f_out, void **io_out); +csch_sheet_t *csch_load_bundled_sheets(void *cookie, void *io, FILE *f, const char *prj_fn, void (*post_load_cb)(csch_sheet_t *)); + + +void csch_plug_io_uninit(void); + +/* List of all IO plugins */ +extern vtp0_t csch_ios; + + +#endif Index: tags/1.0.5/src/libcschem/plug_library.c =================================================================== --- tags/1.0.5/src/libcschem/plug_library.c (nonexistent) +++ tags/1.0.5/src/libcschem/plug_library.c (revision 10414) @@ -0,0 +1,507 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "concrete.h" +#include "cnc_obj.h" + +#include "plug_library.h" + +static htsp_t lib_masters; +static int master_uids = 0; + + +TODO("librnd: Use libualloc") +csch_lib_t *csch_lib_alloc_append(const csch_lib_backend_t *be, csch_lib_t *parent, char *name, csch_lib_type_t type) +{ + csch_lib_t *sl = calloc(sizeof(csch_lib_t), 1); + sl->backend = be; + sl->parent = parent; + sl->name = name; + sl->type = type; + if (parent != NULL) + vtp0_append(&parent->children, sl); + return sl; +} + +RND_INLINE void csch_lib_uninit(csch_lib_t *sl) +{ + long n; + + for(n = 0; n < sl->children.used; n++) { + csch_lib_uninit(sl->children.array[n]); + free(sl->children.array[n]); + } + + if ((sl->backend != NULL) && (sl->backend->free != NULL)) + sl->backend->free(sl); + if (sl->realpath != sl->name) + free(sl->realpath); + free(sl->name); + + vtp0_uninit(&sl->children); +} + +void csch_lib_free(csch_lib_t *slib) +{ + csch_lib_uninit(slib); + free(slib); +} + +void csch_lib_remove(csch_lib_t *l) +{ + long n, end = l->parent->children.used; + int removing = 0; + + for(n = 0; n < end; n++) { + if (l->parent->children.array[n] == l) { + removing++; + end--; + } + if (removing && (n < end)) + l->parent->children.array[n] = l->parent->children.array[n+removing]; + } + l->parent->children.used -= removing; + + csch_lib_free(l); +} + + + +RND_INLINE char *slib_find_realpath(rnd_design_t *hl, csch_lib_master_t *master, const char *path, const csch_lib_backend_t **be_out) +{ + long n; + + for(n = 0; n < master->backends.used; n++) { + const csch_lib_backend_t *be = master->backends.array[n]; + char *rp; + + if (be->realpath == NULL) + continue; + + rp = be->realpath(hl, path); + if (rp != NULL) { + *be_out = be; + return rp; + } + } + return NULL; +} + +int slib_sort_cmp(const void *l1_, const void *l2_) +{ + csch_lib_t * const *l1 = l1_; + csch_lib_t * const *l2 = l2_; + return strcmp((*l1)->name, (*l2)->name); +} + +/* recursively sort a lib dir */ +RND_INLINE void csch_lib_sort(rnd_design_t *hl, csch_lib_t *l) +{ + long n; + + qsort(l->children.array, l->children.used, sizeof(csch_lib_t *), slib_sort_cmp); + for(n = 0; n < l->children.used; n++) { + csch_lib_t *c = l->children.array[n]; + if (c->type == CSCH_SLIB_DIR) + csch_lib_sort(hl, c); + } +} + +RND_INLINE csch_lib_t *csch_lib_map(rnd_design_t *hl, csch_lib_master_t *master, const csch_lib_backend_t *be, char *path, char *real_path) +{ + csch_lib_t *res; + + res = csch_lib_alloc_append(be, NULL, path, CSCH_SLIB_DIR); + res->realpath = real_path; + htsp_set(&master->roots, real_path, res); + + /* keep it in the hash so it doesn't get re-mapped */ + if (be->map(hl, res) != 0) { + res->error = "plugin mapping error"; + if (*path == '?') + res->hide = 1; + } + else + csch_lib_sort(hl, res); + + return res; +} + +int csch_lib_add(csch_sheet_t *sheet, csch_lib_master_t *master, char *path, int append, int do_rehash, int skip_just_mapped) +{ + rnd_design_t *hl = &sheet->hidlib; + csch_lib_root_t *libroot; + csch_lib_t *root; + const csch_lib_backend_t *be_new; + char *real_path = slib_find_realpath(hl, master, path, &be_new); + int optional = (*path == '?'); + + if (real_path == NULL) { + if (optional) { + free(path); path = NULL; + return 0; + } + rnd_message(RND_MSG_ERROR, "%s library mapping error: no plugin to handle '%s' (or plugin failed to map it, e.g. path does not exist)\n", master->name, path); + free(path); path = NULL; + return -1; + } + + root = htsp_get(&master->roots, real_path); + if ((root != NULL) && skip_just_mapped && root->just_mapped) + do_rehash = 0; + + if (root == NULL) { + /* need to map be_new */ + root = csch_lib_map(hl, master, be_new, path, real_path); + if (root == NULL) { + fprintf(stderr, "Internal error: symlib map returns NULL\n"); + abort(); /* at the moment this shouldn't happen */ +#if 0 + if (real_path != path) free(real_path); + rnd_message(RND_MSG_ERROR, "%s library mapping error: %s failed to map '%s'\n", master->name, be_new->name, path); + free(path); path = NULL; + return -1; +#endif + } + root->just_mapped = 1; + } + else { /* matching real_path: reuse */ + TODO("TODO#41: sharing root pointers may not be a good idea: they will not have unique names; see the other TODO#41"); + if (real_path != path) free(real_path); + free(path); path = NULL;/* we are going to use the existing one in root */ + if (root->backend != be_new) { + if (optional) + return 0; + rnd_message(RND_MSG_ERROR, "%s library mapping error: different plugins claim to handle '%s'\n", master->name, root->name); + return -1; + } + if (do_rehash) { + if (csch_lib_rehash(sheet, master, root) != 0) { + rnd_message(RND_MSG_ERROR, "%s library mapping error: failed to re-scan library '%s'\n", master->name, root->name); + root->just_mapped = 1; + } + else + append = 0; /* do not add orig_root, rehash has replaced it */ + } + } + + if (sheet->libs.used <= master->uid) + vtp0_enlarge(&sheet->libs, master->uid); + + if (sheet->libs.array[master->uid] == NULL) + sheet->libs.array[master->uid] = calloc(sizeof(csch_lib_root_t), 1); + + if (append) { + long n, found = 0; + + libroot = sheet->libs.array[master->uid]; + for(n = 0; n < libroot->roots.used; n++) { + if (libroot->roots.array[n] == root) { + found = 1; + break; + } + } + if (!found) + vtp0_append(&libroot->roots, root); + } + return 0; +} + + +static void csch_lib_root_uninit(csch_lib_root_t *root) +{ + long n; + for(n = 0; n < root->roots.used; n++) + if (root->roots.array[n] != NULL) + csch_lib_free(root->roots.array[n]); + vtp0_uninit(&root->roots); +} + +static void csch_lib_root_free(csch_lib_root_t *root) +{ + csch_lib_root_uninit(root); + free(root); +} + +void csch_lib_free_sheet_local_libs(csch_sheet_t *sheet) +{ + long n; + for(n = 0; n < sheet->local_libs.used; n++) + if (sheet->local_libs.array[n] != NULL) + csch_lib_root_free(sheet->local_libs.array[n]); + vtp0_uninit(&sheet->local_libs); +} + +void csch_lib_clear_sheet_lib(csch_sheet_t *sheet, int master_uid) +{ + if (master_uid < sheet->libs.used) { + csch_lib_root_t *libroot = sheet->libs.array[master_uid]; + vtp0_uninit(&libroot->roots); + } +} + +void csch_lib_free_sheet_libs(csch_sheet_t *sheet) +{ + long n; + /* do not uninit vector entries because they are shared among sheets */ + for(n = 0; n < sheet->libs.used; n++) { + csch_lib_root_t *libroot = sheet->libs.array[n]; + if (libroot != NULL) { + vtp0_uninit(&libroot->roots); + free(libroot); + } + } + vtp0_uninit(&sheet->libs); +} + +int csch_lib_add_local(csch_sheet_t *sheet, csch_lib_master_t *master) +{ + rnd_design_t *hl = &sheet->hidlib; + csch_lib_root_t *libroot; + csch_lib_t *root; + long n; + + if (sheet->local_libs.used <= master->uid) + vtp0_enlarge(&sheet->local_libs, master->uid); + + /* need to have a local libroot for master (library type) uid */ + if (sheet->local_libs.array[master->uid] == NULL) + sheet->local_libs.array[master->uid] = calloc(sizeof(csch_lib_root_t), 1); + libroot = sheet->local_libs.array[master->uid]; + + /* ensure exactly one root, */ + if (libroot->roots.used < 1) + vtp0_enlarge(&libroot->roots, 1); + if (libroot->roots.array[0] == NULL) + libroot->roots.array[0] = csch_lib_alloc_append(NULL, NULL, rnd_strdup(""), CSCH_SLIB_DIR); + root = libroot->roots.array[0]; + + + TODO("flush old local libs under libroot->roots.array[0]"); + + for(n = 0; n < master->backends.used; n++) { + const csch_lib_backend_t *be = master->backends.array[n]; + if (be->map_local == NULL) continue; + be->map_local(hl, root, &sheet->indirect); + } + + return 0; +} + +/* Replace orig_root with new_root in a sheet's lib */ +static void lib_rehash_update_root_in_all_sheets(csch_sheet_t *sheet, csch_lib_master_t *master, csch_lib_t *orig_root, csch_lib_t *new_root) +{ + long n; + csch_lib_root_t *libroot = sheet->libs.array[master->uid]; + + assert(libroot != NULL); /* csch_lib_add() created it */ + for(n = 0; n < libroot->roots.used; n++) + if (libroot->roots.array[n] == orig_root) + libroot->roots.array[n] = new_root; +} + +int csch_lib_rehash(csch_sheet_t *sheet, csch_lib_master_t *master, csch_lib_t *node) +{ + csch_lib_t *root = node, *orig_root, *new_root; + rnd_design_t *dsg; + long n; + + while(root->parent != NULL) root = root->parent; + + if (root->realpath == NULL) { + rnd_message(RND_MSG_ERROR, "csch_lib_rehash(): library tree does not have a realpath, can not be refreshed\n"); + return -1; + } + orig_root = htsp_pop(&master->roots, root->realpath); + if (orig_root == NULL) { + rnd_message(RND_MSG_ERROR, "csch_lib_rehash(): failed to find original root\n"); + return -1; + } + if (csch_lib_add(sheet, master, rnd_strdup(root->name), 0, 1, 0) != 0) { + rnd_message(RND_MSG_ERROR, "csch_lib_rehash(): failed to rehash %s\nDid it disappear meanwhile?\n", root->realpath); + htsp_set(&master->roots, root->realpath, orig_root); + return -1; + } + + /* got a new one */ + new_root = htsp_get(&master->roots, root->realpath); + assert(new_root != NULL); /* csch_lib_add() created it */ + + TODO("TODO#41: sharing root pointers may not be a good idea: they will not have unique names; see the other TODO#41"); + + /* have to fix up aliases - in all open sheets because of shared roots! */ + for(dsg = gdl_first(&rnd_designs); dsg != NULL; dsg = dsg->link.next) + lib_rehash_update_root_in_all_sheets((csch_sheet_t *)dsg, master, orig_root, new_root); + + csch_lib_free(orig_root); + return 0; +} + +void csch_lib_add_all(csch_sheet_t *sheet, csch_lib_master_t *master, const rnd_conflist_t *searchpath, int do_rehash) +{ + rnd_conf_listitem_t *ci; + + /* clear the just_mapped bit so that csch_lib_add() can set it */ + for(ci = rnd_conflist_first((rnd_conflist_t *)searchpath); ci != NULL; ci = rnd_conflist_next(ci)) { + const char *p = ci->val.string[0]; + const csch_lib_backend_t *be_new; + char *real_path = slib_find_realpath(&sheet->hidlib, master, p, &be_new); + if (real_path != NULL) { + csch_lib_t *root = htsp_get(&master->roots, real_path); + if (root != NULL) + root->just_mapped = 0; + free(real_path); + } + } + + /* (re)load each, but make sure everything is scanned only once */ + for(ci = rnd_conflist_first((rnd_conflist_t *)searchpath); ci != NULL; ci = rnd_conflist_next(ci)) { + const char *p = ci->val.string[0]; + csch_lib_add(sheet, master, rnd_strdup(p), 1, do_rehash, 1); + } +} + + +void csch_lib_backend_reg(csch_lib_master_t *master, const csch_lib_backend_t *be) +{ + vtp0_append(&master->backends, (void *)be); +} + +static void csch_lib_uninit_master(csch_lib_master_t *master) +{ + free(master->name); + vtp0_uninit(&master->backends); + genht_uninit_deep(htsp, &master->roots, { + csch_lib_uninit(htent->value); + free(htent->value); + }); +} + +csch_lib_master_t *csch_lib_get_master(const char *name, int alloc) +{ + csch_lib_master_t *res = htsp_get(&lib_masters, name); + + if (res != NULL) + return res; + + if (!alloc) + return NULL; + + res = calloc(sizeof(csch_lib_master_t), 1); + res->name = rnd_strdup(name); + res->uid = master_uids++; + htsp_init(&res->roots, strhash, strkeyeq); + htsp_set(&lib_masters, res->name, res); + return res; +} + +int csch_lib_load(csch_sheet_t *sheet, void *dst, csch_lib_t *src, const char *params) +{ + int res; + if ((src == NULL) || (src->backend == NULL) || (src->backend->load == NULL)) + return -1; + + csch_cobj_redraw_freeze(sheet); + res = src->backend->load(sheet, dst, src, params); + csch_cobj_redraw_unfreeze(sheet); + + return res; +} + +csch_lib_t *csch_lib_search_(csch_lib_t *node, const char *name, csch_lib_type_t mask) +{ + if (node == NULL) + return NULL; + + /* check for direct match */ + if ((node->type & mask) && (strcmp(node->name, name) == 0)) + return node; + + /* recurse */ + if (node->type == CSCH_SLIB_DIR) { + long n; + for(n = 0; n < node->children.used; n++) { + csch_lib_t *res = csch_lib_search_(node->children.array[n], name, mask); + if (res != NULL) + return res; + } + } + + return NULL; +} + +csch_lib_t *csch_lib_search(csch_lib_root_t *lib, const char *name, csch_lib_type_t mask) +{ + long n; + for(n = 0; n < lib->roots.used; n++) { + csch_lib_t *res = csch_lib_search_(lib->roots.array[n], name, mask); + if (res != NULL) + return res; + } + return NULL; +} + +csch_lib_t *csch_lib_search_master(csch_lib_master_t *master, const char *name, csch_lib_type_t mask) +{ + htsp_entry_t *e; + for(e = htsp_first(&master->roots); e != NULL; e = htsp_next(&master->roots, e)) { + csch_lib_t *res = csch_lib_search_(e->value, name, mask); + if (res != NULL) + return res; + } + return NULL; +} + + +void csch_plug_library_init(void) +{ + htsp_init(&lib_masters, strhash, strkeyeq); + csch_lib_get_master("symbol", 1); + csch_lib_get_master("hlibrary", 1); + + /* backends is all-zero already */ +} + +void csch_plug_library_uninit(void) +{ + genht_uninit_deep(htsp, &lib_masters, { + csch_lib_uninit_master(htent->value); + free(htent->value); + }); +} Index: tags/1.0.5/src/libcschem/plug_library.h =================================================================== --- tags/1.0.5/src/libcschem/plug_library.h (nonexistent) +++ tags/1.0.5/src/libcschem/plug_library.h (revision 10414) @@ -0,0 +1,171 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#ifndef CSCH_SYMLIB_H +#define CSCH_SYMLIB_H + +#include +#include +#include + +#include + +typedef enum { /* bitfield so that it can be OR'd for mask */ + CSCH_SLIB_invalid = 0, + CSCH_SLIB_STATIC = 1, + CSCH_SLIB_PARAMETRIC = 2, + CSCH_SLIB_DIR = 4 +} csch_lib_type_t; + +typedef struct csch_lib_s csch_lib_t; +typedef struct csch_lib_backend_s csch_lib_backend_t; + + +struct csch_lib_backend_s { + const char *name; + + /* called with a path to a resource; returns root or realpath(3) of root if applicable */ + char *(*realpath)(rnd_design_t *hl, const char *root); + + /* called with a path to a resource; map and build the slib tree under + root_dir. Return 0 on success. Do not add anything to the tree on error. + Not being able to map a few sub-resources is not considered an error. */ + int (*map)(rnd_design_t *hl, csch_lib_t *root_dir); + int (*map_local)(rnd_design_t *hl, csch_lib_t *root_dir, const csch_cgrp_t *indirect); + + /* load an slib entry into a new group.1 under empty sheet */ + int (*load)(csch_sheet_t *sheet, void *dst, csch_lib_t *src, const char *params); + + /* optional: generate textual preview for the library window; return value + will be free()'d */ + char *(*preview_text)(csch_sheet_t *sheet, csch_lib_t *src, const char *parametric); + + /* free backend data in src; called on entries when they are removed from + the lib and roots on library/sheet removal. In the latter case first + it is called on the root then on all children recursively. */ + void (*free)(csch_lib_t *src); + + /*** helpers for local library entries (any may be NULL) ***/ + /* Refresh local lib copy within sheet from the external lib (if available) */ + int (*loc_refresh_from_ext)(csch_sheet_t *sheet, csch_lib_t *src); + + /* Count and list users of a given local lib entry on the sheet */ + int (*loc_list)(csch_sheet_t *sheet, csch_lib_t *src); + + /* Remove from local lib and tune references in sheet */ + int (*loc_del)(csch_sheet_t *sheet, csch_lib_t *src); + + /* Invoke interactive editor for an entry */ + int (*loc_edit)(csch_sheet_t *sheet, csch_lib_t *src); +}; + +struct csch_lib_s { + char *name; + char *realpath; /* NULL if parent is not NULL; may point to name; on the filesystem it's the real-path so relative names like ./sym of different projects are different */ + csch_lib_type_t type; + + const csch_lib_backend_t *backend; + struct { + void *ptr[8]; + long lng[8]; + } backend_data; + + const char *error; /* if not NULL, there was an error accessing this node */ + unsigned int hide:1; /* hide from the UI */ + unsigned just_mapped:1; /* in root: set right after mapping/scanning a root from disk */ + + csch_lib_t *parent; /* NULL in the first level of root dirs */ + vtp0_t children; +}; + +typedef struct csch_lib_root_s { + csch_sheet_t *sheet; /* sheet this lib set is for; NULL for the master (all-known) set */ + vtp0_t roots; /* ordered list of (csch_lib_t *) root dirs as configured */ +} csch_lib_root_t; + +typedef struct csch_lib_master_s { + char *name; + int uid; + htsp_t roots; /* realpath -> (csch_lib_t *) root dir */ + vtp0_t backends; /* list of (csch_lib_backend_t *) as registered */ +} csch_lib_master_t; + + + + +/*** calls for lib users ***/ + +/* call csch_lib_add() for all configured lib paths in sheet; re-scan + existing libs only if do_rehash is non-zero; new libraries found + that were not present previously are always scanned */ +void csch_lib_add_all(csch_sheet_t *sheet, csch_lib_master_t *master, const rnd_conflist_t *searchpath, int do_rehash); + +/* Re-map the root of an existing node */ +int csch_lib_rehash(csch_sheet_t *sheet, csch_lib_master_t *master, csch_lib_t *node); + +/* Remove all roots from a library within sheet; useful before rehashing the + whole library for that sheet:master combo */ +void csch_lib_clear_sheet_lib(csch_sheet_t *sheet, int master_uid); + +csch_lib_master_t *csch_lib_get_master(const char *name, int alloc); + +int csch_lib_load(csch_sheet_t *sheet, void *dst, csch_lib_t *src, const char *params); + +/* Linear search of a footprint by name within the libraries; returns first match */ +csch_lib_t *csch_lib_search(csch_lib_root_t *lib, const char *name, csch_lib_type_t mask); +csch_lib_t *csch_lib_search_master(csch_lib_master_t *master, const char *name, csch_lib_type_t mask); + +void csch_lib_free_sheet_local_libs(csch_sheet_t *sheet); +void csch_lib_free_sheet_libs(csch_sheet_t *sheet); + +/* Removes l from its parent and frees it */ +void csch_lib_remove(csch_lib_t *l); + +/*** calls for symlib_ plugins ***/ + +/* Append a new child under parent; name is not strdup()'d, caller has to + dup it or otherwise make it permament. On csch_lib_free() this field + will be free()'d. */ +csch_lib_t *csch_lib_alloc_append(const csch_lib_backend_t *be, csch_lib_t *parent, char *name, csch_lib_type_t type); + +void csch_lib_backend_reg(csch_lib_master_t *master, const csch_lib_backend_t *be); + +/*** calls for internal use ***/ +/* Rehash (re-scan) existing libraries only if do_rehash is non-zero; new + libraries just added are always scanned. skip_just_mapped is used by + csch_lib_add_all() to avoid redundant mapping. path needs to be strdup'd by + the caller, csch_lib_add() will take ownership of it. */ +int csch_lib_add(csch_sheet_t *sheet, csch_lib_master_t *master, char *path, int append, int do_rehash, int skip_just_mapped); + +int csch_lib_add_local(csch_sheet_t *sheet, csch_lib_master_t *master); +void csch_lib_free(csch_lib_t *slib); /* doesn't remove from parent! */ +void csch_plug_symlib_init(void); +void csch_plug_library_init(void); +void csch_plug_library_uninit(void); + +#endif Index: tags/1.0.5/src/libcschem/project.c =================================================================== --- tags/1.0.5/src/libcschem/project.c (nonexistent) +++ tags/1.0.5/src/libcschem/project.c (revision 10414) @@ -0,0 +1,465 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2018,2023 Tibor 'Igor2' Palinkas + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include "config.h" + +#include +#include "project.h" +#include "libcschem.h" +#include +#include +#include +#include +#include +#include "plug_io.h" +#include "event.h" +#include "project_p4.h" + +static const char project_cookie[] = "libcschem/project"; + +csch_project_t *csch_project_alloc(void) +{ + csch_project_t *prj; + + prj = calloc(sizeof(csch_project_t), 1); + /* no need to init fields because of calloc() */ + + rnd_conf_load_as(RND_CFR_PROJECT, NULL, 0); + + prj->dummy = 1; /* until it's loaded or saved */ + prj->view_conf_rev = -1; + csch_p4_call_project_init(prj); + return prj; +} + +void csch_project_free(csch_project_t *prj) +{ + int n; + + if (prj->abst != NULL) { + csch_abstract_uninit(prj->abst); + free(prj->abst); + } + + for(n = 0; n < vtp0_len(&prj->hdr.designs); n++) + csch_sheet_free(prj->hdr.designs.array[n]); + prj->hdr.designs.used = 0; /* rnd_project_uninit() will iterate */ + + csch_p4_call_project_uninit(prj); + vtp0_uninit(&prj->p4data); + + for(n = 0; n < vtp0_len(&prj->views); n++) + csch_view_free(prj->views.array[n]); + vtp0_uninit(&prj->views); + + rnd_project_uninit(&prj->hdr); + free(prj); +} + +csch_view_t *csch_view_create(csch_project_t *prj, const char *name) +{ + csch_view_t *view = calloc(sizeof(csch_view_t), 1); + + fgw_init(&view->fgw_ctx, name); + view->parent = prj; + + vtp0_append(&prj->views, view); + return view; +} + +void csch_view_free(csch_view_t *view) +{ + long n; + + for(n = 0; n < vtp0_len(&view->engines); n++) + csch_eng_free(view, view->engines.array[n]); + vtp0_uninit(&view->engines); + + fgw_uninit(&view->fgw_ctx); + free(view); +} + +void csch_view_remove_all(csch_project_t *prj) +{ + long n; + for(n = 0; n < prj->views.used; n++) + csch_view_free(prj->views.array[n]); + prj->views.used = 0; +} + +int csch_view_get_id(csch_project_t *prj, const char *name) +{ + int n; + for(n = 0; n < prj->views.used; n++) { + csch_view_t *v = prj->views.array[n]; + if ((v != NULL) && (strcmp(v->fgw_ctx.name, name) == 0)) + return n; + } + return -1; +} + +csch_view_t *csch_view_get(csch_project_t *prj, const char *name) +{ + int view_id = csch_view_get_id(prj, name); + if (view_id < 0) + return NULL; + return prj->views.array[view_id]; +} + + +void csch_view_renum(csch_view_t *view) +{ + int n, prio; + for(n = 0, prio = (view->engines.used - 1) * 20; n < view->engines.used; n++,prio-=20) { + csch_view_eng_t *eng = view->engines.array[n]; + eng->eprio = prio; + } +} + +int csch_view_eng_append(csch_view_t *view, const char *user_name, const char *eng_name, const char *file_name) +{ + csch_view_eng_t *eng; + + if (view->engines.used >= CSCH_PRIMAX_PLUGIN/2) return -1; + + eng = csch_eng_alloc(view, user_name, eng_name, file_name); + if (eng == NULL) return -1; + + vtp0_append(&view->engines, eng); + csch_view_renum(view); + return 0; +} + + +int csch_view_eng_insert_before(csch_view_t *view, const char *user_name, const char *eng_name, const char *file_name, int idx) +{ + csch_view_eng_t *eng; + + if (view->engines.used >= CSCH_PRIMAX_PLUGIN) return -1; + if ((idx < 0) || (idx > view->engines.used)) return -1; + + eng = csch_eng_alloc(view, user_name, eng_name, file_name); + if (eng == NULL) return -1; + + vtp0_insert_len(&view->engines, idx, (void *)eng, 1); + csch_view_renum(view); + return 0; +} + + +int csch_proj_sheet_update_filename(csch_project_t *prj, csch_sheet_t *sheet) +{ + gds_t tmp; + char *realfn; + + if (rnd_is_path_abs(sheet->hidlib.loadname)) { + free(sheet->hidlib.fullpath); + sheet->hidlib.fullpath = rnd_strdup(sheet->hidlib.loadname); + rnd_event(&sheet->hidlib, RND_EVENT_DESIGN_FN_CHANGED, NULL); + return 0; + } + + if (prj->hdr.fullpath == NULL) + return -1; + + gds_init(&tmp); + gds_append_str(&tmp, prj->hdr.prjdir); + gds_append(&tmp, '/'); + gds_append_str(&tmp, sheet->hidlib.loadname); + realfn = rnd_lrealpath(tmp.array); + gds_uninit(&tmp); + if (realfn == NULL) + return -1; + + free(sheet->hidlib.fullpath); + sheet->hidlib.fullpath = realfn; + rnd_event(&sheet->hidlib, RND_EVENT_DESIGN_FN_CHANGED, NULL); + return 0; +} + +int csch_proj_update_filename(csch_project_t *prj) +{ + return rnd_project_update_filename(&prj->hdr); +} + +int csch_project_load_sheet(csch_project_t *prj, const char *fn, const char *fmt, csch_sheet_t **sheet_out, rnd_bool quiet, FILE *optf) +{ + int ain; + csch_sheet_t *sheet = csch_load_sheet(prj, fn, fmt, &ain, optf); + + if (sheet_out != NULL) + *sheet_out = sheet; + + if (sheet == NULL) { + if (!quiet) { + if (fmt != NULL) + rnd_message(RND_MSG_ERROR, "Failed to load %s (with requested format %s)\n", fn, fmt); + else + rnd_message(RND_MSG_ERROR, "Failed to load %s\n", fn); + } + return -1; + } + + if (!ain) + return rnd_project_append_design(&prj->hdr, &sheet->hidlib); + + return 0; +} + +int csch_project_remove_sheet(csch_project_t *prj, csch_sheet_t *sheet) +{ + return rnd_project_remove_design(&prj->hdr, &sheet->hidlib); +} + +void csch_project_flush(void) +{ + csch_sheet_t *sheet = (csch_sheet_t *)rnd_multi_get_current(); + + rnd_conf_makedirty(RND_CFR_PROJECT); + rnd_conf_save_file(&sheet->hidlib, NULL, sheet->hidlib.loadname, RND_CFR_PROJECT, NULL); +} + +csch_project_t *csch_load_project_by_sheet_name(const char *sheet_fn, int with_sheets, rnd_bool quiet) +{ + const char *try; + const char *project_fn = rnd_conf_get_project_conf_name(NULL, sheet_fn, &try); + csch_project_t *prj = csch_load_project(project_fn, "lht", with_sheets); + + if (prj == NULL) { + if (!quiet) { + if (project_fn == NULL) + rnd_message(RND_MSG_INFO, "Failed to load project file for %s; assuming implicit project\n", sheet_fn); + else + rnd_message(RND_MSG_WARNING, "Failed to load project file %s; creating a dummy project in memory and assuming implicit project\n", project_fn); + } + prj = csch_project_alloc(); + if (project_fn != NULL) + prj->hdr.loadname = rnd_strdup(project_fn); + } + else + prj->dummy = 0; + + return prj; +} + +void csch_project_clean_views(csch_project_t *prj) +{ + long n; + for(n = 0; n < prj->views.used; n++) + csch_view_free(prj->views.array[n]); + prj->views.used = 0; +} + +void csch_views_changed(csch_project_t *prj) +{ + long n; + + for(n = 0; n < prj->hdr.designs.used; n++) { + if (prj->hdr.designs.array[n] != NULL) { + csch_sheet_t *sheet = prj->hdr.designs.array[n]; + rnd_event(&sheet->hidlib, CSCH_EVENT_PRJ_VIEWS_CHANGED, NULL); + return; + } + } +} + +int csch_view_activate(csch_project_t *prj, int view_id) +{ + long n; + + if ((view_id < 0) || (view_id >= prj->views.used)) + return -1; + + if (prj->curr == view_id) + return 0; + + prj->curr = view_id; + + /* call with the first sheet */ + for(n = 0; n < prj->hdr.designs.used; n++) { + if (prj->hdr.designs.array[n] != NULL) { + csch_sheet_t *sheet = prj->hdr.designs.array[n]; + rnd_event(&sheet->hidlib, CSCH_EVENT_PRJ_VIEW_ACTIVATED, NULL); + return 0; + } + } + + return 0; +} + + +static void csch_project_conf_saved(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + int role = argv[2].d.i; + + if (role == RND_CFR_PROJECT) { + csch_sheet_t *sheet = (csch_sheet_t *)hidlib; + csch_project_t *prj = (csch_project_t *)sheet->hidlib.project; + + prj->dummy = 0; + } +} + +const char *csch_view_get_prop(csch_project_t *prj, int viewid, const char *name) +{ + csch_view_t *view; + + if (viewid < 0) + viewid = prj->curr; + + if ((viewid < 0) || (viewid >= prj->views.used)) + return NULL; + + view = prj->views.array[viewid]; + if (view == NULL) + return NULL; + + if (strcmp(name, "name") == 0) return view->fgw_ctx.name; + + return NULL; + +} + +static gds_t stance_path = {0}; +const char *csch_stance_get(const char *name) +{ + int save; + rnd_conf_native_t *nat; + + if (stance_path.used == 0) gds_append_str(&stance_path, "stance/"); + + save = stance_path.used; + gds_append_str(&stance_path, name); + nat = rnd_conf_get_field(stance_path.array); + stance_path.used = save; + + if ((nat == NULL) || (nat->type != RND_CFN_STRING)) + return NULL; + + return (nat->val.string[0] == NULL) ? "" : nat->val.string[0]; +} + +extern lht_doc_t *rnd_conf_main_root[RND_CFR_max_alloc]; +static rnd_conf_role_t get_role(lht_node_t *nd) +{ + rnd_conf_role_t n; + + if (nd == NULL) + return RND_CFR_invalid; + + for(n = 0; n < RND_CFR_max_alloc; n++) + if (nd->doc == rnd_conf_main_root[n]) + return n; + return RND_CFR_invalid; +} + +static void stance_flush(rnd_conf_role_t role) +{ + if (role == RND_CFR_PROJECT) + csch_project_flush(); +} + +int csch_stance_add_to_values(const char *name, const char *val) +{ + rnd_conf_native_t *nat, *nat_scalar; + rnd_conf_role_t role; + int save, idx; + rnd_conf_listitem_t *item_li; + const char *item_str; + lht_node_t *nd, *src; + + if (stance_path.used == 0) gds_append_str(&stance_path, "stance/"); + save = stance_path.used; + gds_append_str(&stance_path, name); + nat_scalar = rnd_conf_get_field(stance_path.array); + gds_append_str(&stance_path, "_values"); + nat = rnd_conf_get_field(stance_path.array); + stance_path.used = save; + + if ((nat == NULL) || (nat_scalar == NULL) || (nat->type != RND_CFN_LIST)) + return -1; + + role = get_role(nat_scalar->prop[0].src); + if (role == RND_CFR_invalid) + role = RND_CFR_PROJECT; + + + /* check if value already exists */ + rnd_conf_loop_list_str(nat->val.list, item_li, item_str, idx) { + if (strcmp(val, item_str) == 0) + return 0; + } + + src = rnd_conf_lht_get_at(role, nat->hash_path, 1); + nd = lht_dom_node_alloc(LHT_TEXT, NULL); + lht_dom_list_append(src, nd); + nd->data.text.value = rnd_strdup(val); + rnd_conf_update(nat->hash_path, -1); + + stance_flush(role); + + return -1; +} + + +int csch_stance_set(const char *name, const char *val) +{ + int save, res; + rnd_conf_native_t *nat; + rnd_conf_role_t role; + + if (stance_path.used == 0) gds_append_str(&stance_path, "stance/"); + save = stance_path.used; + gds_append_str(&stance_path, name); + nat = rnd_conf_get_field(stance_path.array); + stance_path.used = save; + + if ((nat == NULL) || (nat->type != RND_CFN_STRING)) + return -1; + + role = get_role(nat->prop[0].src); + if (role == RND_CFR_invalid) + role = RND_CFR_PROJECT; + + res = rnd_conf_set(role, nat->hash_path, -1, val, RND_POL_OVERWRITE); + + stance_flush(role); + + return res; +} + + +void csch_project_init(void) +{ + rnd_event_bind(RND_EVENT_CONF_FILE_SAVE_POST, csch_project_conf_saved, NULL, project_cookie); +} + +void csch_project_uninit(void) +{ + rnd_event_unbind_allcookie(project_cookie); + gds_uninit(&stance_path); +} + Index: tags/1.0.5/src/libcschem/project.h =================================================================== --- tags/1.0.5/src/libcschem/project.h (nonexistent) +++ tags/1.0.5/src/libcschem/project.h (revision 10414) @@ -0,0 +1,163 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2018,2019,2023 Tibor 'Igor2' Palinkas + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + + +#ifndef CSCH_PROJECT_H +#define CSCH_PROJECT_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* use currently active view of the project */ +#define CSCH_VIEW_DEFAULT -1 + +struct csch_view_s { + fgw_ctx_t fgw_ctx; /* name of the view is the name of the context */ + vtp0_t engines; /* priority-ordered list of (csch_view_eng_t *); highest prio (lowest numer) is at the end */ + csch_project_t *parent; +}; + +struct csch_project_s { + rnd_project_t hdr; + vtp0_t views; /* of (csch_view_t *) */ + vtp0_t p4data; /* per-plugin-per-project data indexed by csch_p4id_t registered by the plugin */ + + long view_conf_rev; + + /* cached */ + csch_abstract_t *abst; /* compiled for display attributes */ + int curr; /* index of currently active view */ + long num_root_sheets; /* cached from conf prj/root_sheets; filled in by the app */ + long num_aux_sheets; /* cached from conf prj/aux_sheets; filled in by the app */ + unsigned dummy:1; /* 1 when there's no real project but a dummy one is allocated */ +}; + +csch_project_t *csch_project_alloc(void); +void csch_project_free(csch_project_t *prj); + +/* Write out the project file */ +void csch_project_flush(void); + +/* Remove every view from prj */ +void csch_project_clean_views(csch_project_t *prj); + +/* Create a new view, returns the index; returns -1 on error */ +csch_view_t *csch_view_create(csch_project_t *prj, const char *name); + +/* Returns current view or NULL */ +RND_INLINE csch_view_t *csch_view_get_current(csch_project_t *prj); + +/* Returns view by name using linear search (there'd be only a few views) */ +csch_view_t *csch_view_get(csch_project_t *prj, const char *name); +int csch_view_get_id(csch_project_t *prj, const char *name); + +/* free all fields and view itself (but do not remove from parent!) */ +void csch_view_free(csch_view_t *view); + +/* Activate view by integer ID; returns 0 on success */ +int csch_view_activate(csch_project_t *prj, int view_id); + + +/* Generate an event to get the GUI updated */ +void csch_views_changed(csch_project_t *prj); + + +/* Create a new engine in a view, reassign priorities of other engines in + the view as needed. On success return the index of the new engine (from 0); + on failure return -1; + user_name, eng_name and file_name are as specified for fgw_obj_new() */ +int csch_view_eng_append(csch_view_t *view, const char *user_name, const char *eng_name, const char *file_name); +int csch_view_eng_insert_before(csch_view_t *view, const char *user_name, const char *eng_name, const char *file_name, int idx); + +/* Remove a sheet from a project; returns the number of removals done, + ideally 1. If it returns 0, sheet was not in the project, if >1, + sheet was added multiple times (shouldn't happen) */ +int csch_project_remove_sheet(csch_project_t *prj, csch_sheet_t *sheet); + + +/* Recalculate the ->hdr.fullpath and ->hdr.prjdir of prj using its + ->hdr.loadname field */ +int csch_proj_update_filename(csch_project_t *prj); + +/* recalculate the filename (real, full path) of sheet, using prj's filename + for CWD in case of relative path */ +int csch_proj_sheet_update_filename(csch_project_t *prj, csch_sheet_t *sheet); + +/* Remove and free all views of a project */ +void csch_view_remove_all(csch_project_t *prj); + +/* Renumber engine priorities, useful after a manual modification to the engine list */ +void csch_view_renum(csch_view_t *view); + +/* Return the stance value for a given stance name (config lookup) */ +const char *csch_stance_get(const char *name); + +/* Set the value of a named stance on the same config role the value is + already set on, or on project level if stance was not defined */ +int csch_stance_set(const char *name, const char *val); + +/* Append val to the list of values for a named stance, if val is not + already on the list. Operates on the same config role the stance value + (not the list!) is on or on project level if stance was not defined */ +int csch_stance_add_to_values(const char *name, const char *val); + + +/* Return a property of view prj:viewid, e.g. its "name"; returns NULL on + error (or empty or not found) */ +const char *csch_view_get_prop(csch_project_t *prj, int viewid, const char *name); + + +/*** loaders ***/ +/* does not emit sheet post load event */ +int csch_project_load_sheet(csch_project_t *prj, const char *fn, const char *fmt, csch_sheet_t **sheet_out, rnd_bool quiet, FILE *optf); +csch_project_t *csch_load_project_by_sheet_name(const char *sheet_load_fn, int with_sheets, rnd_bool quiet); + + +/*** implementation ***/ +RND_INLINE csch_view_t *csch_view_get_current(csch_project_t *prj) +{ + if ((prj->curr < 0) || (prj->curr >= prj->views.used)) + return NULL; + + return prj->views.array[prj->curr]; +} + + +/*** lib internal ***/ + +/* called by cschem_init() */ +void csch_project_init(void); +void csch_project_uninit(void); + +#endif Index: tags/1.0.5/src/libcschem/project_act.c =================================================================== --- tags/1.0.5/src/libcschem/project_act.c (nonexistent) +++ tags/1.0.5/src/libcschem/project_act.c (revision 10414) @@ -0,0 +1,106 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include "config.h" + +#include + +#include +#include +#include "event.h" +#include "project.h" +#include "compile.h" + +#include "project_act.h" + +static const char *project_cookie = "project_act"; + +static const char csch_acts_CompileProject[] = "CompileProject([view_name])"; +static const char csch_acth_CompileProject[] = "Compile the abstract model of the current project, using the current view (or the view named)"; +fgw_error_t csch_act_CompileProject(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_design_t *hidlib = RND_ACT_DESIGN; + csch_sheet_t *sheet = (csch_sheet_t *)hidlib; + csch_project_t *prj = (csch_project_t *)sheet->hidlib.project; + int rv, view_id = CSCH_VIEW_DEFAULT; + const char *view_name = NULL; + + RND_ACT_MAY_CONVARG(1, FGW_STR, CompileProject, view_name = argv[1].val.str); + + if (view_name != NULL) { + view_id = csch_view_get_id(prj, view_name); + if (view_id < 0) { + rnd_message(RND_MSG_ERROR, "Invalid view name: '%s'\n", view_name); + return FGW_ERR_ARG_CONV; + } + } + + if (prj->abst == NULL) + prj->abst = calloc(sizeof(csch_abstract_t), 1); + else + csch_abstract_uninit(prj->abst); + + csch_abstract_init(prj->abst); + rv = csch_compile_project(prj, view_id, prj->abst, 0); + + RND_ACT_IRES(rv); + return 0; +} + + +static const char csch_acts_DiscardAbstract[] = "CompileProject()"; +static const char csch_acth_DiscardAbstract[] = "Free the abstract model of the current project."; +fgw_error_t csch_act_DiscardAbstract(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_design_t *hidlib = RND_ACT_DESIGN; + csch_sheet_t *sheet = (csch_sheet_t *)hidlib; + csch_project_t *prj = (csch_project_t *)sheet->hidlib.project; + + if (prj->abst != NULL) { + csch_abstract_uninit(prj->abst); + free(prj->abst); + prj->abst = NULL; + } + + RND_ACT_IRES(0); + return 0; +} + +static rnd_action_t csch_project_act_list[] = { + {"CompileProject", csch_act_CompileProject, csch_acth_CompileProject, csch_acts_CompileProject}, + {"DiscardAbstract", csch_act_DiscardAbstract, csch_acth_DiscardAbstract, csch_acts_DiscardAbstract} +}; + +void csch_project_act_init(void) +{ + RND_REGISTER_ACTIONS(csch_project_act_list, project_cookie); +} + +void csch_project_act_uninit(void) +{ + rnd_remove_actions_by_cookie(project_cookie); +} + Index: tags/1.0.5/src/libcschem/project_act.h =================================================================== --- tags/1.0.5/src/libcschem/project_act.h (nonexistent) +++ tags/1.0.5/src/libcschem/project_act.h (revision 10414) @@ -0,0 +1,2 @@ +void csch_project_act_init(void); +void csch_project_act_uninit(void); Index: tags/1.0.5/src/libcschem/project_p4.c =================================================================== --- tags/1.0.5/src/libcschem/project_p4.c (nonexistent) +++ tags/1.0.5/src/libcschem/project_p4.c (revision 10414) @@ -0,0 +1,118 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust Fund in 2023) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include "project_p4.h" +#include + +/* all currently active plugin configs; NULL means plugin got unregistered */ +static vtp0_t p4cfgs; + +static csch_p4id_t p4id_find_unused(void) +{ + csch_p4id_t n; + for(n = 0; n < p4cfgs.used; n++) + if (p4cfgs.array[n] == NULL) + return n; + return -1; +} + +void csch_p4_reg_plugin(csch_p4cfg_t *cfg) +{ + csch_p4id_t id; + + /* figure the ID, store cfg */ + id = p4id_find_unused(); + if (id < 0) { + id = p4cfgs.used; + vtp0_append(&p4cfgs, cfg); + } + else + p4cfgs.array[id] = cfg; + cfg->id = id; + + if (cfg->project_init != NULL) { + htsp_entry_t *e; + for(e = htsp_first(&rnd_projects); e != NULL; e = htsp_next(&rnd_projects, e)) { + csch_project_t *prj = e->value; + cfg->project_init(cfg, prj); + } + } +} + +void csch_p4_unreg_plugin(csch_p4cfg_t *cfg) +{ + htsp_entry_t *e; + assert(cfg->id >= 0); + assert(cfg->id < p4cfgs.used); + + for(e = htsp_first(&rnd_projects); e != NULL; e = htsp_next(&rnd_projects, e)) { + csch_project_t *prj = e->value; + if (cfg->project_uninit != NULL) + cfg->project_uninit(cfg, prj); + if (prj->p4data.used > cfg->id) + prj->p4data.array[cfg->id] = NULL; + } + + p4cfgs.array[cfg->id] = NULL; + cfg->id = -1; +} + + +void csch_p4_set_by_project(csch_p4cfg_t *cfg, csch_project_t *prj, void *data) +{ + assert(cfg->id >= 0); + assert(cfg->id < p4cfgs.used); + vtp0_set(&prj->p4data, cfg->id, data); +} + +void csch_p4_call_project_init(csch_project_t *prj) +{ + csch_p4id_t n; + for(n = 0; n < p4cfgs.used; n++) { + csch_p4cfg_t *cfg = p4cfgs.array[n]; + if (cfg->project_init != NULL) + cfg->project_init(cfg, prj); + } +} + +void csch_p4_call_project_uninit(csch_project_t *prj) +{ + csch_p4id_t n; + for(n = 0; n < p4cfgs.used; n++) { + csch_p4cfg_t *cfg = p4cfgs.array[n]; + if (cfg->project_uninit != NULL) + cfg->project_uninit(cfg, prj); + if (prj->p4data.used > cfg->id) + prj->p4data.array[cfg->id] = NULL; + } +} + +void csch_p4_uninit(void) +{ + vtp0_uninit(&p4cfgs); +} Index: tags/1.0.5/src/libcschem/project_p4.h =================================================================== --- tags/1.0.5/src/libcschem/project_p4.h (nonexistent) +++ tags/1.0.5/src/libcschem/project_p4.h (revision 10414) @@ -0,0 +1,107 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust Fund in 2023) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + + +#ifndef CSCH_PROJECT_P4_H +#define CSCH_PROJECT_P4_H + +/* Per Plugin Per Project (p4) data */ + +#include + +typedef long csch_p4id_t; /* used internally for indexing project->p4data */ + +typedef struct csch_p4cfg_s csch_p4cfg_t; +struct csch_p4cfg_s { + + /* called early in project creation; plugin should allocate + p4 data and store it in the project. prj fields are not initialized + yet. Also called on csch_p4_reg_plugin() for all projects */ + void (*project_init)(csch_p4cfg_t *p4, csch_project_t *prj); + + /* called while a project is discarded (no sheet loaded anymore); plugin + should free p4 data still stored in the project. Also called on + csch_p4_unreg_plugin() for all projects. Libcschem sets project's p4 + data to NULL after this call. */ + void (*project_uninit)(csch_p4cfg_t *p4, csch_project_t *prj); + + /* as assigned on registration, filled in by libcschem; used for + indexing project->p4data */ + csch_p4id_t id; + + /* opqaue data for the registration (not plugin-specific); only the + plugin uses this */ + void *plugin_data; +}; + +/* Register a plugin by its p4cfg; id is filled in here; cfg->project_init + is called for all existing projects */ +void csch_p4_reg_plugin(csch_p4cfg_t *cfg); + +/* Unregister a plugin by its p4cfg; id is reset to -1; cfg->project_uninit + is called for all existing projects */ +void csch_p4_unreg_plugin(csch_p4cfg_t *cfg); + +/* Store p4 data in a project, overwriting previous data. p4 data + is a void * allocated by the plugin. It's typically allocated and + stored in the ->project_init() callback and free'd in the + ->project_uninit() callback */ +void csch_p4_set_by_project(csch_p4cfg_t *cfg, csch_project_t *prj, void *data); + + +/* Return the plugin's p4 data for a project or a sheet (or NULL if not + available). When not NULL, data had been previously registered by the + plugin using csch_p4_set_(). */ +RND_INLINE void *csch_p4_get_by_project(csch_p4cfg_t *cfg, csch_project_t *prj); +RND_INLINE void *csch_p4_get_by_sheet(csch_p4cfg_t *cfg, csch_sheet_t *sheet); + +/*** Internal calls for libcschem ***/ + +/* Call all p4 ->project_init or ->project_uninit of all p4 plugins */ +void csch_p4_call_project_init(csch_project_t *prj); +void csch_p4_call_project_uninit(csch_project_t *prj); + +/*** Implementation ***/ + +RND_INLINE void *csch_p4_get_by_project(csch_p4cfg_t *cfg, csch_project_t *prj) +{ + if ((cfg->id < 0) || (cfg->id >= prj->p4data.used)) + return NULL; + + return prj->p4data.array[cfg->id]; +} + +RND_INLINE void *csch_p4_get_by_sheet(csch_p4cfg_t *cfg, csch_sheet_t *sheet) +{ + return csch_p4_get_by_project(cfg, (csch_project_t *)sheet->hidlib.project); +} + +/*** For internal use ***/ +void csch_p4_uninit(void); + +#endif Index: tags/1.0.5/src/libcschem/rotate.h =================================================================== --- tags/1.0.5/src/libcschem/rotate.h (nonexistent) +++ tags/1.0.5/src/libcschem/rotate.h (revision 10414) @@ -0,0 +1,61 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#ifndef CSCH_ROTATE_H +#define CSCH_ROTATE_H + +#include +#include + +RND_INLINE void csch_rotate90_pt(csch_coord_t *x, csch_coord_t *y, csch_coord_t cx, csch_coord_t cy, int n) +{ + csch_coord_t dx = *x - cx, dy = *y - cy; + switch(n & 0x3) { + case 3: *x = cx + dy; *y = cy - dx; break; + case 2: *x = cx - dx; *y = cy - dy; break; + case 1: *x = cx - dy; *y = cy + dx; break; + } +} + +RND_INLINE void csch_rotate_pt(csch_coord_t *x, csch_coord_t *y, csch_coord_t cx, csch_coord_t cy, double cosa, double sina) +{ + csch_coord_t px = *x - cx, py = *y - cy; + + *x = rnd_round(px * cosa + py * sina + cx); + *y = rnd_round(py * cosa - px * sina + cy); +} + +RND_INLINE void csch_mirror_pt(csch_coord_t *x, csch_coord_t *y, csch_coord_t mcx, csch_coord_t mcy, int mirx, int miry) +{ + if (mirx) + *x = 2*mcx - *x; + if (miry) + *y = 2*mcy - *y; +} + +#endif Index: tags/1.0.5/src/libcschem/rtree.c =================================================================== --- tags/1.0.5/src/libcschem/rtree.c (nonexistent) +++ tags/1.0.5/src/libcschem/rtree.c (revision 10414) @@ -0,0 +1,10 @@ +#include +#include +#include + +#include "rtree.h" + +#include +#include +#include +#include Index: tags/1.0.5/src/libcschem/rtree.h =================================================================== --- tags/1.0.5/src/libcschem/rtree.h (nonexistent) +++ tags/1.0.5/src/libcschem/rtree.h (revision 10414) @@ -0,0 +1,32 @@ +#ifndef CSCH_RTREE_H +#define CSCH_RTREE_H + +#include "libcschem/common_types.h" + +typedef long csch_rtree_cardinal_t; +typedef csch_coord_t csch_rtree_coord_t; + +#define RTR(n) csch_rtree_ ## n +#define RTRU(n) csch_RTREE_ ## n +#define csch_rtree_privfunc static +#define csch_rtree_size 6 +#define csch_rtree_stack_max 1024 + +#include + +#define csch_bbox_invalidate(bbox) (bbox)->x1 = CSCH_COORD_INV +#define csch_bbox_is_invalid(bbox) ((bbox)->x1 == CSCH_COORD_INV) + +#define csch_bbox_reset(bbox) \ +do { \ + (bbox)->x1 = (bbox)->y1 = CSCH_COORD_MAX; \ + (bbox)->x2 = (bbox)->y2 = CSCH_COORD_MIN; \ +} while(0) + +#define csch_bbox_bump(bbox, coord, value) \ +do { \ + if (value < (bbox)->coord ## 1) { (bbox)->coord ## 1 = value; } \ + if (value > (bbox)->coord ## 2) { (bbox)->coord ## 2 = value; } \ +} while(0) + +#endif /* CSCH_RTREE2_H */ Index: tags/1.0.5/src/libcschem/search.c =================================================================== --- tags/1.0.5/src/libcschem/search.c (nonexistent) +++ tags/1.0.5/src/libcschem/search.c (revision 10414) @@ -0,0 +1,228 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - sch-rnd (executable) + * Copyright (C) 2020 Tibor 'Igor2' Palinkas + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include "config.h" +#include "operation.h" +#include "search.h" +#include "cnc_obj.h" + +typedef struct { + csch_rtree_box_t *query; + csch_rtree_cb_t *found_obj; + void *found_ctx; + int find_grp_bbox; /* when 1 any overlap with the group's bbox is enough for a match, else require an object overlap */ +} search_ctx_t; + +static csch_rtree_dir_t search_obj(void *ctx_, void *obj_, const csch_rtree_box_t *box) +{ + search_ctx_t *ctx = ctx_; +/* csch_chdr_t *obj = obj_;*/ + + TODO("detailed check for intersection"); + return ctx->found_obj(ctx->found_ctx, obj_, box); + return csch_RTREE_DIR_NOT_FOUND_CONT; +} + +csch_rtree_dir_t csch_search(csch_sheet_t *sheet, csch_rtree_box_t *query, csch_rtree_cb_t *found_obj, void *ctx) +{ + int n; + csch_rtree_dir_t res, state = 0; + search_ctx_t sctx; + + sctx.query = query; + sctx.found_obj = found_obj; + sctx.found_ctx = ctx; + + for(n = CSCH_DSPLY_max-1; n >= 0; n--) { + if (!csch_layer_vis[n]) + continue; + sctx.find_grp_bbox = (n >= CSCH_DSPLY_SYMBOL); + res = csch_rtree_search_obj(&sheet->dsply[n], query, search_obj, &sctx); + state |= res; + if (res & csch_RTREE_DIR_STOP) + break; + } + + return state; +} + +csch_rtree_dir_t csch_search_obj_first_cb(void *ctx_, void *obj_, const csch_rtree_box_t *box) +{ + csch_chdr_t *obj = obj_; + csch_search_obj_first_t *ctx = ctx_; + long score = 1, locked; + + if (!csch_isc_with_box(obj, ctx->query)) + return csch_RTREE_DIR_NOT_FOUND_CONT; + + if ((ctx->mask != 0) && !csch_ctype_in_cmask(obj->type, ctx->mask)) + return csch_RTREE_DIR_NOT_FOUND_CONT; + + if (ctx->ignore_wirenet_grp && csch_obj_is_grp(obj)) { + csch_cgrp_t *grp = (csch_cgrp_t *)obj; + if (grp->role == CSCH_ROLE_WIRE_NET) + return csch_RTREE_DIR_NOT_FOUND_CONT; + } + + if ((ctx->ignore != NULL) && (ctx->ignore(ctx, obj))) + return csch_RTREE_DIR_NOT_FOUND_CONT; + + switch(obj->type) { + case CSCH_CTYPE_GRP: score = 1000; break; + case CSCH_CTYPE_GRP_REF: score = 1000; break; + case CSCH_CTYPE_POLY: score = 2000; break; + case CSCH_CTYPE_BITMAP: score = 3000; break; + case CSCH_CTYPE_TEXT: score = 4000; break; + case CSCH_CTYPE_LINE: score = 5000*16; break; /* *16 means even a floater text won't win over a line, e.g. in a terminal */ + case CSCH_CTYPE_ARC: score = 5000*16; break; + + case CSCH_CTYPE_CONN: + case CSCH_CTYPE_PEN: + case CSCH_CTYPE_invalid: + case CSCH_CTYPE_max: + return csch_RTREE_DIR_NOT_FOUND_CONT; + } + + if (ctx->explicitly_locked_only) { + locked = csch_cobj_is_explicit_locked(obj); + if (!locked) + return csch_RTREE_DIR_NOT_FOUND_CONT; + obj = csch_cobj_first_explicit_locked(obj); + if (obj == NULL) + return csch_RTREE_DIR_NOT_FOUND_CONT; + } + else { + locked = csch_cobj_is_locked(obj); + if (!locked) + score = score * 2; + + if (locked) { + if (ctx->allow_term) { + if (obj->parent->role == CSCH_ROLE_TERMINAL) { + ctx->res = &obj->parent->hdr; + ctx->score = score * 2; /* win over wirenet */ + return csch_RTREE_DIR_FOUND_CONT; + } + } + + /* clicked on something locked, parent wants to find the first unlocked parent */ + obj = csch_cobj_first_unlocked(obj); + if (obj == NULL) + return csch_RTREE_DIR_NOT_FOUND_CONT; + } + } + + if (obj->floater) + score = score * 2; + + if (score > ctx->score) { + ctx->res = obj; + ctx->score = score; + } + return csch_RTREE_DIR_FOUND_CONT; +} + +csch_chdr_t *csch_search_first_mask(csch_sheet_t *sheet, csch_rtree_box_t *query, csch_cmask_t mask) +{ + csch_search_obj_first_t ctx = {0}; + ctx.query = query; + ctx.mask = mask; + csch_search(sheet, query, csch_search_obj_first_cb, &ctx); + return ctx.res; +} + +csch_chdr_t *csch_search_first_gui_filter(csch_sheet_t *sheet, csch_rtree_box_t *query, csch_search_obj_ignore_cb_t ignore) +{ + csch_search_obj_first_t ctx = {0}; + ctx.query = query; + ctx.ignore_wirenet_grp = 1; + ctx.ignore = ignore; + csch_search(sheet, query, csch_search_obj_first_cb, &ctx); + return ctx.res; +} + +csch_chdr_t *csch_search_first_gui(csch_sheet_t *sheet, csch_rtree_box_t *query) +{ + return csch_search_first_gui_filter(sheet, query, NULL); +} + + +csch_chdr_t *csch_search_first_gui_inspect_filter(csch_sheet_t *sheet, csch_rtree_box_t *query, csch_search_obj_ignore_cb_t ignore) +{ + csch_search_obj_first_t ctx = {0}; + ctx.query = query; + ctx.allow_term = 1; + ctx.ignore_wirenet_grp = 1; + ctx.ignore = ignore; + csch_search(sheet, query, csch_search_obj_first_cb, &ctx); + return ctx.res; +} + +csch_chdr_t *csch_search_first_gui_inspect(csch_sheet_t *sheet, csch_rtree_box_t *query) +{ + return csch_search_first_gui_inspect_filter(sheet, query, NULL); +} + + +csch_chdr_t *csch_search_first_locked(csch_sheet_t *sheet, csch_rtree_box_t *query) +{ + csch_search_obj_first_t ctx = {0}; + ctx.query = query; + ctx.explicitly_locked_only = 1; + csch_search(sheet, query, csch_search_obj_first_cb, &ctx); + return ctx.res; +} + +csch_chdr_t *csch_search_first_locked_gui(csch_sheet_t *sheet, csch_rtree_box_t *query) +{ + csch_chdr_t *res = csch_search_first_locked(sheet, query); + if (res != NULL) + return res; + + return res; +} + + +long csch_search_all_selected(csch_sheet_t *sheet, csch_cgrp_t *src, vtp0_t *dst, int recursive) +{ + htip_entry_t *e; + long cnt = 0; + + if (src == NULL) + src = &sheet->direct; + + for(e = htip_first(&src->id2obj); e != NULL; e = htip_next(&src->id2obj, e)) { + csch_chdr_t *obj = e->value; + if (obj->selected) { + vtp0_append(dst, obj); + cnt++; + } + if (csch_obj_is_grp(obj) && (recursive || !csch_grp_is_atomic(sheet, (csch_cgrp_t *)obj))) + cnt += csch_search_all_selected(sheet, (csch_cgrp_t *)obj, dst, recursive); + } + + return cnt; +} Index: tags/1.0.5/src/libcschem/search.h =================================================================== --- tags/1.0.5/src/libcschem/search.h (nonexistent) +++ tags/1.0.5/src/libcschem/search.h (revision 10414) @@ -0,0 +1,78 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - sch-rnd (executable) + * Copyright (C) 2020 Tibor 'Igor2' Palinkas + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include + +typedef struct csch_search_obj_first_s csch_search_obj_first_t; + +/* Called for any input object, return non-zero to ignore object */ +typedef int (*csch_search_obj_ignore_cb_t)(csch_search_obj_first_t *ctx, csch_chdr_t *obj); + +csch_rtree_dir_t csch_search(csch_sheet_t *sheet, csch_rtree_box_t *query, csch_rtree_cb_t *found_obj, void *ctx); + +/* Find object with highest click-priority in query box. + Return group instead of the child object if group lock applies. + The masked version narrows search to object types matching the mask. + The filter version calls an user function for filtering out results. */ +csch_chdr_t *csch_search_first_gui(csch_sheet_t *sheet, csch_rtree_box_t *query); +csch_chdr_t *csch_search_first_mask(csch_sheet_t *sheet, csch_rtree_box_t *query, csch_cmask_t mask); +csch_chdr_t *csch_search_first_gui_filter(csch_sheet_t *sheet, csch_rtree_box_t *query, csch_search_obj_ignore_cb_t ignore); + +/* Same as csch_search_first_gui() but allows a few special cases, like + picking non-floater terminals. + The filter version calls an user function for filtering out results. */ +csch_chdr_t *csch_search_first_gui_inspect(csch_sheet_t *sheet, csch_rtree_box_t *query); +csch_chdr_t *csch_search_first_gui_inspect_filter(csch_sheet_t *sheet, csch_rtree_box_t *query, csch_search_obj_ignore_cb_t ignore); + +/* Same as csch_search_first() and csch_search_first_gui(), except these + will find the first locked object. Useful for implementing the lock tool. */ +csch_chdr_t *csch_search_first_locked(csch_sheet_t *sheet, csch_rtree_box_t *query); +csch_chdr_t *csch_search_first_locked_gui(csch_sheet_t *sheet, csch_rtree_box_t *query); + +/* List all objects that are selected under src group; if src is NULL, list + under sheet. Listing means appending object ptr to dst. If recursive is + non-zero, recurse to group objects */ +long csch_search_all_selected(csch_sheet_t *sheet, csch_cgrp_t *src, vtp0_t *dst, int recursive); + + + +/*** Low level API ***/ + + +struct csch_search_obj_first_s { + csch_chdr_t *res; + long score; + csch_rtree_box_t *query; + csch_search_obj_ignore_cb_t ignore;/* if not NULL: called for any input object, return non-zero to ignore object */ + csch_cmask_t mask; /* if not 0, ignore objects not matching this mask */ + unsigned explicitly_locked_only:1; /* if 1, search only explicitly locked objects */ + unsigned ignore_wirenet_grp:1; /* if 1, do not return wirenet groups (i.e. when clicked at empty space within bbox) */ + unsigned allow_term:1; /* when 1, allow picking up terminals bypassing symbol lock */ + + void *user_ctx; +}; + +csch_rtree_dir_t csch_search_obj_first_cb(void *ctx_, void *obj_, const csch_rtree_box_t *box); Index: tags/1.0.5/src/libcschem/triangle.c =================================================================== --- tags/1.0.5/src/libcschem/triangle.c (nonexistent) +++ tags/1.0.5/src/libcschem/triangle.c (revision 10414) @@ -0,0 +1,110 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include "config.h" + +#include "triangle.h" + +static double dot(g2d_vect_t p1, g2d_vect_t p2) +{ + return (double)p1.x * (double)p2.x + (double)p1.y * (double)p2.y; +} + +/* Compute whether point is inside a triangle formed by 3 other points + Algorithm from http://www.blackpawn.com/texts/pointinpoly/default.html + Same as in librnd poly lib. */ +int csch_point_in_triangle(g2d_vect_t A, g2d_vect_t B, g2d_vect_t C, g2d_vect_t P) +{ + g2d_vect_t v0, v1, v2; + double dot00, dot01, dot02, dot11, dot12; + double invDenom; + double u, v; + + /* Compute vectors */ + v0.x = C.x - A.x; + v0.y = C.y - A.y; + v1.x = B.x - A.x; + v1.y = B.y - A.y; + v2.x = P.x - A.x; + v2.y = P.y - A.y; + + /* Compute dot products */ + dot00 = dot(v0, v0); + dot01 = dot(v0, v1); + dot02 = dot(v0, v2); + dot11 = dot(v1, v1); + dot12 = dot(v1, v2); + + /* Compute barycentric coordinates */ + invDenom = 1. / (dot00 * dot11 - dot01 * dot01); + u = (dot11 * dot02 - dot01 * dot12) * invDenom; + v = (dot00 * dot12 - dot01 * dot02) * invDenom; + + /* Check if point is in triangle */ + return (u > 0.0) && (v > 0.0) && (u + v < 1.0); +} + +int csch_any_point_in_triangle(g2d_vect_t A, g2d_vect_t B, g2d_vect_t C, g2d_vect_t *P, int npts) +{ + g2d_vect_t v0, v1, v2; + double dot00, dot01, dot02, dot11, dot12; + double invDenom; + double u, v; + int n; + + /* Compute vectors */ + v0.x = C.x - A.x; + v0.y = C.y - A.y; + v1.x = B.x - A.x; + v1.y = B.y - A.y; + + + /* Compute dot products */ + dot00 = dot(v0, v0); + dot01 = dot(v0, v1); + dot11 = dot(v1, v1); + + /* Compute barycentric coordinates */ + invDenom = 1. / (dot00 * dot11 - dot01 * dot01); + + /* calc only the variable part for each point, return the first time we are in */ + for(n = 0; n < npts; n++,P++) { + v2.x = (*P).x - A.x; + v2.y = (*P).y - A.y; + dot02 = dot(v0, v2); + dot12 = dot(v1, v2); + + /* Compute barycentric coordinates */ + u = (dot11 * dot02 - dot01 * dot12) * invDenom; + v = (dot00 * dot12 - dot01 * dot02) * invDenom; + + /* Check if point is in triangle */ + if ((u > 0.0) && (v > 0.0) && (u + v < 1.0)) + return 1; + } + + return 0; +} Index: tags/1.0.5/src/libcschem/triangle.h =================================================================== --- tags/1.0.5/src/libcschem/triangle.h (nonexistent) +++ tags/1.0.5/src/libcschem/triangle.h (revision 10414) @@ -0,0 +1,36 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include GENGEO2D_TYPECFG +#include "gengeo2d/prim.h" + +/* Returns 1 if P is within triangle A-B-C */ +int csch_point_in_triangle(g2d_vect_t A, g2d_vect_t B, g2d_vect_t C, g2d_vect_t P); + +/* Returns 1 if any point of P (of length npts) is within triangle A-B-C; + This is more efficient than multiple calls to csch_point_in_triangle() + with the same triangle, because some claculations are done only once. */ +int csch_any_point_in_triangle(g2d_vect_t A, g2d_vect_t B, g2d_vect_t C, g2d_vect_t *P, int npts); Index: tags/1.0.5/src/libcschem/undo.c =================================================================== --- tags/1.0.5/src/libcschem/undo.c (nonexistent) +++ tags/1.0.5/src/libcschem/undo.c (revision 10414) @@ -0,0 +1,216 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * Copyright (C) 1994,1995,1996 Thomas Nau (from pcb-rnd) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include "event.h" + +#include "undo.h" + +int csch_undo(csch_sheet_t *sheet) +{ + int res; + + if (sheet->undo.num_undo == 0) { + rnd_message(RND_MSG_INFO, "Nothing to undo - buffer is empty\n"); + return -1; + } + + if (sheet->undo.serial == 0) { + rnd_message(RND_MSG_ERROR, "ERROR: Attempt to csch_undo() with Serial == 0\n Please save your work and report this bug.\n"); + return -1; + } + + if ((sheet->undo.tail != NULL) && (sheet->undo.tail->serial > sheet->undo.serial)) { + rnd_message(RND_MSG_ERROR, "ERROR: Bad undo serial number %d in undo stack - expecting %d or lower\n" + " Please save your work and report this bug.\n", sheet->undo.tail->serial, sheet->undo.serial); + + /* It is likely that the serial number got corrupted through some bad + use of the save_serial() / restore_serial() APIs. + Reset the serial number to be consistent with that of the last + operation on the undo stack in the hope that this might clear + the problem and allow the user to hit Undo again. */ + sheet->undo.serial = sheet->undo.tail->serial + 1; + return -1; + } + + res = uundo_undo(&sheet->undo); + + if (res != 0) + rnd_message(RND_MSG_ERROR, "ERROR: Failed to undo some operations\n"); + + rnd_event(&sheet->hidlib, CSCH_EVENT_UNDO_POST, "i", CSCH_UNDO_EV_UNDO); + + return res; +} + + +int csch_redo(csch_sheet_t *sheet) +{ + int res; + + if (sheet->undo.num_redo == 0) { + rnd_message(RND_MSG_INFO, "Nothing to redo. Perhaps changes have been made since last undo\n"); + return 0; + } + + if ((sheet->undo.tail != NULL) && (sheet->undo.tail->next != NULL) && (sheet->undo.tail->next->serial > sheet->undo.serial)) { + + rnd_message(RND_MSG_ERROR, "ERROR: Bad undo serial number %d in redo stack - expecting %d or higher\n" + " Please save your work and report this bug.\n", sheet->undo.tail->next->serial, sheet->undo.serial); + + /* It is likely that the serial number got corrupted through some bad + * use of the save_serial() / restore_serial() APIs. + * + * Reset the serial number to be consistent with that of the first + * operation on the redo stack in the hope that this might clear + * the problem and allow the user to hit Redo again. + */ + + sheet->undo.serial = sheet->undo.tail->next->serial; + return 0; + } + + res = uundo_redo(&sheet->undo); + + if (res != 0) + rnd_message(RND_MSG_ERROR, "ERROR: Failed to redo some operations\n"); + + rnd_event(&sheet->hidlib, CSCH_EVENT_UNDO_POST, "i", CSCH_UNDO_EV_REDO); + + return res; +} + + +void csch_undo_clear_list(csch_sheet_t *sheet, rnd_bool Force) +{ + if (sheet->undo.num_undo && (Force || rnd_hid_message_box(&sheet->hidlib, "warning", "clear undo buffer", "Do you reall want to clear 'undo' buffer?", "yes", 1, "no", 0, NULL) == 1)) { + uundo_list_clear(&sheet->undo); + rnd_event(&sheet->hidlib, CSCH_EVENT_UNDO_POST, "i", CSCH_UNDO_EV_CLEAR_LIST); + } +} + +void csch_undo_inc_serial(csch_sheet_t *sheet) +{ + uundo_inc_serial(&sheet->undo); + rnd_event(&sheet->hidlib, CSCH_EVENT_UNDO_POST, "i", CSCH_UNDO_EV_REDO); +} + + +static const char undo_cookie[] = "libcschem/undo.c"; + +static const char csch_acts_Undo[] = "undo()\n" "undo(ClearList|FreezeSerial|UnfreezeSerial|FreezeAdd|UnfreezeAdd|IncSerial|GetSerial|Above)"; +static const char csch_acth_Undo[] = "Undo recent changes."; +/* DOC: undo.html */ +fgw_error_t csch_act_Undo(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *function = NULL; + csch_sheet_t *sheet = CSCH_ACT_SHEET; + + RND_ACT_MAY_CONVARG(1, FGW_STR, Undo, function = argv[1].val.str); + if (!function || !*function) { + rnd_hid_notify_crosshair_change(RND_ACT_DESIGN, rnd_false); + if (rnd_tool_undo_act(RND_ACT_DESIGN)) + if (csch_undo(sheet) == 0) { +TODO("changed:"); +/* csch_board_set_changed_flag(PCB_ACT_BOARD, rnd_true);*/ + } + } + else if (function) { + rnd_hid_notify_crosshair_change(RND_ACT_DESIGN, rnd_false); + if (rnd_strcasecmp(function, "ClearList") == 0) + csch_undo_clear_list(sheet, rnd_false); + else if (rnd_strcasecmp(function, "FreezeSerial") == 0) + uundo_freeze_serial(&sheet->undo); + else if (rnd_strcasecmp(function, "UnFreezeSerial") == 0) + uundo_unfreeze_serial(&sheet->undo); + else if (rnd_strcasecmp(function, "FreezeAdd") == 0) + uundo_freeze_add(&sheet->undo); + else if (rnd_strcasecmp(function, "UnFreezeAdd") == 0) + uundo_unfreeze_add(&sheet->undo); + else if (rnd_strcasecmp(function, "IncSerial") == 0) + csch_undo_inc_serial(sheet); + else if (rnd_strcasecmp(function, "GetSerial") == 0) { + res->type = FGW_LONG; + res->val.nat_long = sheet->undo.serial; + return 0; + } + else if (rnd_strcasecmp(function, "GetNum") == 0) { + res->type = FGW_LONG; + res->val.nat_long = sheet->undo.num_undo; + return 0; + } + else if (rnd_strcasecmp(function, "Above") == 0) { + long ser; + RND_ACT_CONVARG(2, FGW_LONG, Undo, ser = argv[2].val.nat_long); + uundo_undo_above(&sheet->undo, ser); + } + + } + rnd_hid_notify_crosshair_change(RND_ACT_DESIGN, rnd_true); + RND_ACT_IRES(0); + return 0; +} + + +static const char csch_acts_Redo[] = "redo()"; +static const char csch_acth_Redo[] = "Redo recent \"undo\" operations."; +/* DOC: redo.html */ +fgw_error_t csch_act_Redo(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + csch_sheet_t *sheet = CSCH_ACT_SHEET; + + rnd_hid_notify_crosshair_change(RND_ACT_DESIGN, rnd_false); + if (rnd_tool_redo_act(RND_ACT_DESIGN)) + if (csch_redo(sheet)) { + /* board has changed; but it was handled in the swap code anyway */ + } + rnd_hid_notify_crosshair_change(RND_ACT_DESIGN, rnd_true); + RND_ACT_IRES(0); + return 0; +} + +static rnd_action_t csch_undo_act_list[] = { + {"Undo", csch_act_Undo, csch_acth_Undo, csch_acts_Undo}, + {"Redo", csch_act_Redo, csch_acth_Redo, csch_acts_Redo} +}; + +void csch_undo_act_init(void) +{ + RND_REGISTER_ACTIONS(csch_undo_act_list, undo_cookie); +} + +void csch_undo_act_uninit(void) +{ + rnd_remove_actions_by_cookie(undo_cookie); +} + Index: tags/1.0.5/src/libcschem/undo.h =================================================================== --- tags/1.0.5/src/libcschem/undo.h (nonexistent) +++ tags/1.0.5/src/libcschem/undo.h (revision 10414) @@ -0,0 +1,64 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#ifndef CSCH_UNDO_H +#define CSCH_UNDO_H + +#include "concrete.h" + +typedef enum csch_undo_ev_e { + CSCH_UNDO_EV_UNDO, + CSCH_UNDO_EV_REDO, + CSCH_UNDO_EV_CLEAR_LIST, + CSCH_UNDO_EV_TRUNCATE +} csch_undo_ev_t; + +int csch_undo(csch_sheet_t *sheet); +int csch_redo(csch_sheet_t *sheet); +void csch_undo_clear_list(csch_sheet_t *sheet, rnd_bool Force); +void csch_undo_inc_serial(csch_sheet_t *sheet); + +void csch_undo_act_init(void); +void csch_undo_act_uninit(void); + +/* Helper for debugging undo bugs: place a visible mark in the undo list */ +#define csch_undo_add_mark(sheet, comment) \ + do { \ + csch_source_arg_t *src = csch_attrib_src_c(NULL, 0, 0, NULL); \ + csch_attr_modify_str(sheet, &sheet->direct, 0, comment, NULL, src, 1); \ + } while(0) + + +/*** helpers for implementing undo swaps ***/ + +/* Returns arg if not NULL, else obj->field; field and arg have the same type + but arg is a pointer. */ +#define CSCH_UNDO_MODIFY_ARG(obj, field, arg) (arg == NULL ? (obj)->field : *arg) +#define CSCH_UNDO_MODIFY(obj, field) CSCH_UNDO_MODIFY_ARG(obj, field, field) +#define CSCH_UNDO_RMODIFY_ARG(obj, field, arg) (arg == NULL ? (obj)->field : (relative ? (obj)->field + *arg : *arg)) +#define CSCH_UNDO_RMODIFY(obj, field) CSCH_UNDO_RMODIFY_ARG(obj, field, field) + +#endif Index: tags/1.0.5/src/libcschem/util_abst.c =================================================================== --- tags/1.0.5/src/libcschem/util_abst.c (nonexistent) +++ tags/1.0.5/src/libcschem/util_abst.c (revision 10414) @@ -0,0 +1,43 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - lib: compile helpers + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include "config.h" + +#include "util_abst.h" + +int csch_cgrp_is_in_asrc(const csch_cgrp_t *c, const csch_ahdr_t *a) +{ + long n; + + for(n = 0; n < a->srcs.used; n++) { + if (a->srcs.array[n] == c) + return 1; + } + + return 0; +} Index: tags/1.0.5/src/libcschem/util_abst.h =================================================================== --- tags/1.0.5/src/libcschem/util_abst.h (nonexistent) +++ tags/1.0.5/src/libcschem/util_abst.h (revision 10414) @@ -0,0 +1,10 @@ +#ifndef LIBCSCHEM_UTIL_ABST_H +#define LIBCSCHEM_UTIL_ABST_H + +#include +#include + +/* Returns whether concrete c is a source of abstract a */ +int csch_cgrp_is_in_asrc(const csch_cgrp_t *c, const csch_ahdr_t *a); + +#endif Index: tags/1.0.5/src/libcschem/util_compile.c =================================================================== --- tags/1.0.5/src/libcschem/util_compile.c (nonexistent) +++ tags/1.0.5/src/libcschem/util_compile.c (revision 10414) @@ -0,0 +1,187 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - lib: compile helpers + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include "config.h" + +#include +#include + +#include "abstract.h" +#include "compile.h" +#include "libcschem.h" +#include "engine.h" +#include "actions_csch.h" + +#include "util_compile.h" + +csch_anet_t *csch_cmp_merge_nets(csch_anet_t *n1, csch_anet_t *n2) +{ + csch_anet_t *src, *dst; + long n, i; + + if (n1 == n2) + return n1; + + /* dst should be the one without user chosen name */ + if (!n1->no_uname && !n2->no_uname) { + csch_anet_t *top, *bottom; + + if (n1->hdepth == n2->hdepth) { + rnd_message(RND_MSG_ERROR, "csch_cmp_merge_nets(): different networks '%s' and '%s' can not be connected\n", n1->name, n2->name); + return NULL; + } + if (CSCH_CFG(hier_net_allow_rename, 0) == 0) { + rnd_message(RND_MSG_ERROR, "csch_cmp_merge_nets(): the same network is explicitly named differently between hierarchi levels: '%s' and '%s'\n", n1->name, n2->name); + return NULL; + } + + if (n1->hdepth < n2->hdepth) { + top = n1; + bottom = n2; + } + else { + top = n2; + bottom = n1; + } + if (CSCH_CFG(hier_net_rename_prefer_top, 1) != 0) { + dst = top; + src = bottom; + } + else { + dst = bottom; + src = top; + } + } + else if (!n1->no_uname) { + dst = n1; + src = n2; + } + else { + dst = n2; + src = n1; + } + + /* switch over the concrete->abstract pointers on src net so src concrete + objects know they belong to dst net now */ + for(n = 0; n < src->hdr.srcs.used; n++) { + csch_cgrp_t *cgrp = src->hdr.srcs.array[n]; + long i; + + if (!csch_obj_is_grp(&cgrp->hdr)) + continue; + + for(i = 0; i < cgrp->aid.used; i++) + if (cgrp->aid.array[i] == src->hdr.aid) + cgrp->aid.array[i] = dst->hdr.aid; + } + + for(n = 0; n < src->conns.used; n++) { + csch_aport_t *ap = (csch_aport_t *)src->conns.array[n]; + if (ap->hdr.type == CSCH_ATYPE_PORT) + ap->conn.net = NULL; /* disconnect from src */ + csch_compile_connect_net_to(&dst, &ap->hdr, 1); + } + src->conns.used = 0; + + /* copy/merge all attributes */ + csch_attrib_copy_all_undoable(NULL, NULL, &dst->hdr.attr, &src->hdr.attr, 0); + + /* copy all sources from src to dst */ + for(n = 0; n < src->hdr.srcs.used; n++) + csch_compile_add_source(src->hdr.srcs.array[n], &dst->hdr); + + /* remove sources from the source net which should become empty */ + for(n = 0; n < src->hdr.srcs.used; n++) { + csch_cgrp_t *obj = src->hdr.srcs.array[n]; + for(i = 0; i < obj->aid.used; i++) { + if (obj->aid.array[i] == src->hdr.aid) { + vtl0_remove(&obj->aid, i, 1); + break; + } + } + } + src->hdr.srcs.used = 0; + src->hdr.ghost = "csch_cmp_merge_nets()"; + + return dst; +} + +int csch_cmp_nameconn_port_net(csch_project_t *project, csch_acomp_t *comp, const char *portname, const char *netname, int require_conn, int view_id, csch_hier_path_t *hpath) +{ + csch_aport_t *port = csch_aport_get(comp->hdr.abst, comp, portname, 1); + csch_anet_t *net; /* net from the argument */ + csch_ascope_t scope; + char *name_glob, *name_loc; + + if (port == NULL) { + rnd_message(RND_MSG_ERROR, "Component '%s' doesn't contain port named '%s'\n", comp->name, portname); + return -1; + } + + scope = csch_split_name_scope(&netname); + + /* Translate name, including hierarchical address prefixes */ + csch_eng_call_namemod(project, view_id, hpath, CSCH_ENGHK_ATTRIB_NET_NAME_TO_NET_NAME, + &name_glob, &name_loc, netname, FGW_AOBJ, comp, FGW_INVALID); + + net = csch_anet_get_at(comp->hdr.abst, comp->hlev, scope, name_loc); + if (net == NULL) + net = csch_anet_new(comp->hdr.abst, comp->hlev, scope, name_glob, name_loc, 0); + + csch_eng_free_namemod(&name_glob, &name_loc); + + if (net == NULL) { + rnd_message(RND_MSG_ERROR, "Netname '%s' does not exist\n", netname); + return -1; + } + if (port->conn.net == NULL) { +TODO("TODO#rgc: drc/require_graphical_conn should be checked in drc"); +/* TODO: cases to check: + - place resistor, add conn array 4:foo; this should connect a 4th port of + the resistor to network foo, with no error; csch_compile_connect_net_to() + below does that properly; require_conn=0 case + - place an unconnected gnd symbol; it has an 1:GND which would do the same, + but with an extra drc attribute on the port this should rather throw + an error; require_conn=1 case +*/ + csch_compile_connect_net_to(&net, &port->hdr, 1); + if (require_conn) { + csch_attrib_t *a = csch_attrib_get(&port->hdr.attr, "drc/require_graphical_conn"); + if ((a != NULL) && rnd_istrue(a->val)) { + rnd_message(RND_MSG_ERROR, "Port '%s-%s' has a non-graphical connection to net %s, but no graphical connection\n", comp->name, portname, netname); + return -1; + } + else + return 0; + } + return 0; + } + + return (csch_cmp_merge_nets(net, port->conn.net) != NULL) ? 0 : -1; +} + Index: tags/1.0.5/src/libcschem/util_compile.h =================================================================== --- tags/1.0.5/src/libcschem/util_compile.h (nonexistent) +++ tags/1.0.5/src/libcschem/util_compile.h (revision 10414) @@ -0,0 +1,20 @@ +#ifndef LIBCSCHEM_UTIL_COMPILE_H +#define LIBCSCHEM_UTIL_COMPILE_H + +#include + +/* Connect a port to a network. Returns: + +1: connection is made + 0: already connected (the specific port to the specific net) + -1: error, no connection made (e.g. netname collision) + If require_conn is non-zero, throw an error message when there is no + graphical connection on the port (useful for gnd/vcc/rail symbols). +*/ +int csch_cmp_nameconn_port_net(csch_project_t *prj, csch_acomp_t *comp, const char *portname, const char *netname, int require_conn, int view_id, csch_hier_path_t *hpath); + +/* Merge n1 and n2, keeping one of them, making the other empty; return the + one kept. (Tries to keep the one with name) */ +csch_anet_t *csch_cmp_merge_nets(csch_anet_t *n1, csch_anet_t *n2); + + +#endif Index: tags/1.0.5/src/libcschem/util_endpoint.c =================================================================== --- tags/1.0.5/src/libcschem/util_endpoint.c (nonexistent) +++ tags/1.0.5/src/libcschem/util_endpoint.c (revision 10414) @@ -0,0 +1,109 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - sch-rnd (executable) + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include "config.h" + +#include "cnc_line.h" +#include "intersect.h" +#include + +#include "util_endpoint.h" + +typedef struct find_wire_s { + csch_sheet_t *sheet; + csch_chdr_t *obj; + htepu_t *dst; + int (*incl)(void *udata, csch_chdr_t *obj); + void *udata; +} find_wire_t; + +static csch_rtree_dir_t find_wire_cb(void *ctx_, void *obj_, const csch_rtree_box_t *box) +{ + find_wire_t *ctx = (find_wire_t *)ctx_; + csch_line_t *line = obj_; + + if (obj_ == ctx->obj) + return csch_RTREE_DIR_NOT_FOUND_CONT; + + if ((line->hdr.type == CSCH_CTYPE_LINE) && (line->hdr.parent != NULL) && (line->hdr.parent->role == CSCH_ROLE_WIRE_NET)) { + g2d_vect_t iscp[2]; + long len, n; + int zerolen = 0; + + if (line->hdr.parent != ctx->obj->parent) + return csch_RTREE_DIR_NOT_FOUND_CONT; + + if ((ctx->incl != NULL) && (!ctx->incl(ctx->udata, &line->hdr))) + return csch_RTREE_DIR_NOT_FOUND_CONT; + + if ((line->inst.c.p1.x == line->inst.c.p2.x) && (line->inst.c.p1.y == line->inst.c.p2.y)) + zerolen = 1; + + len = csch_obj_intersect_obj(ctx->sheet, ctx->obj, &line->hdr, iscp, 2); + for(n = 0; n < len; n++) { + htepu_key_t key; + htepu_value_t val = {0}; + key.obj = &line->hdr; + key.x = iscp[n].x; + key.y = iscp[n].y; + val.newx = iscp[n].x; + val.newy = iscp[n].y; + if ((key.x == line->inst.c.p1.x) && (key.y == line->inst.c.p1.y)) { + if (zerolen) + key.epi = CSCH_EPI_ALL; + else + key.epi = CSCH_EPI_START; + } + else if ((key.x == line->inst.c.p2.x) && (key.y == line->inst.c.p2.y)) + key.epi = CSCH_EPI_END; + else + key.epi = CSCH_EPI_MID; + htepu_insert(ctx->dst, key, val); + } + return csch_RTREE_DIR_FOUND_CONT; + } + return csch_RTREE_DIR_NOT_FOUND_CONT; +} + + +void csch_endpoint_list_connected(csch_sheet_t *sheet, htepu_t *dst, csch_chdr_t *obj, int (*incl)(void *udata, csch_chdr_t *obj), void *udata) +{ + find_wire_t ctx = {0}; + csch_rtree_box_t query; + + if (obj->type != CSCH_CTYPE_LINE) + return; /* only line is supported now */ + + ctx.sheet = sheet; + ctx.obj = obj; + ctx.dst = dst; + ctx.incl = incl; + ctx.udata = udata; + + query.x1 = obj->bbox.x1-1; query.y1 = obj->bbox.y1-1; + query.x2 = obj->bbox.x2+1; query.y2 = obj->bbox.y2+1; + csch_rtree_search_obj(&sheet->dsply[CSCH_DSPLY_WIRE], &query, find_wire_cb, &ctx); +} Index: tags/1.0.5/src/libcschem/util_endpoint.h =================================================================== --- tags/1.0.5/src/libcschem/util_endpoint.h (nonexistent) +++ tags/1.0.5/src/libcschem/util_endpoint.h (revision 10414) @@ -0,0 +1,13 @@ +#ifndef LIBCSCHEM_UTIL_ENDPOINT_GRP +#define LIBCSCHEM_UTIL_ENDPOINT_GRP + +#include +#include + +/* List endpoint connected wirenet objects for obj from the same wirenet + in dst. If incl is not NULL, it is called on each candidate object before + collecting potential intersection points; if incl returns zero, the object + is not included/considered. */ +void csch_endpoint_list_connected(csch_sheet_t *sheet, htepu_t *dst, csch_chdr_t *obj, int (*incl)(void *udata, csch_chdr_t *obj), void *udata); + +#endif Index: tags/1.0.5/src/libcschem/util_export.c =================================================================== --- tags/1.0.5/src/libcschem/util_export.c (nonexistent) +++ tags/1.0.5/src/libcschem/util_export.c (revision 10414) @@ -0,0 +1,306 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - core library + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include "config.h" + +#include +#include +#include "concrete.h" +#include "compile.h" +#include "plug_io.h" + +#include "util_export.h" + +char *cschem_export_filename(rnd_design_t *hl, const char *explicit, const char *base_prefix, const char *base_suffix, const char *ext) +{ + csch_sheet_t *sheet = (csch_sheet_t *)hl; + gds_t tmp; + + if (explicit != NULL) { + if ((base_prefix == NULL) && (base_suffix == NULL)) + return rnd_strdup(explicit); + + gds_init(&tmp); + + if (base_prefix != NULL) { + char *sep = strrchr(explicit, '/'); + if (sep != NULL) { + gds_append_len(&tmp, sheet->hidlib.loadname, sep - explicit + 1); + gds_append_str(&tmp, base_prefix); + gds_append_str(&tmp, sep + 1); + } + else { + gds_append_str(&tmp, base_prefix); + gds_append_str(&tmp, explicit); + } + } + else + gds_append_str(&tmp, explicit); + + if (base_suffix != NULL) { + char *sep = strrchr(tmp.array, '.'); + if (sep != NULL) + gds_insert_len(&tmp, sep - tmp.array, (char *)base_suffix, strlen(base_suffix)); + else + gds_append_str(&tmp, base_suffix); + } + return tmp.array; /* tmp is not uninited because ownership is passed back to the caller */ + } + + + gds_init(&tmp); + + if (sheet->hidlib.loadname != NULL) { + int n; + + if (base_prefix != NULL) { + char *sep = strrchr(sheet->hidlib.loadname, '/'); + if (sep != NULL) { + gds_append_len(&tmp, sheet->hidlib.loadname, sep - sheet->hidlib.loadname + 1); + gds_append_str(&tmp, base_prefix); + gds_append_str(&tmp, sep + 1); + } + else { + gds_append_str(&tmp, base_prefix); + gds_append_str(&tmp, sheet->hidlib.loadname); + } + } + else + gds_append_str(&tmp, sheet->hidlib.loadname); + + /* truncate "extension" */ + for(n = tmp.used-1; n > 0; n--) { + if (tmp.array[n] == '.') { + tmp.used = n; + break; + } + } + } + else { + if (base_prefix != NULL) + gds_append_str(&tmp, base_prefix); + gds_append_str(&tmp, "unknown"); + } + + if (base_suffix != NULL) + gds_append_str(&tmp, base_suffix); + + gds_append_str(&tmp, ext); + + return tmp.array; /* tmp is not uninited because ownership is passed back to the caller */ +} + +static char nope[] = "no abstract"; + +int cschem_export_compile_pre(csch_project_t *prj, const char *view_name, void **cookie) +{ + int view_id = CSCH_VIEW_DEFAULT; + + *cookie = prj->abst; + + if ((view_name == NULL) || (*view_name == '\0')) { + if (prj->abst != NULL) { + *cookie = nope; /* do not attempt to free prj->abst on _post */ + return 0; /* already compiled and no different view requested */ + } + } + else { /* view requested */ + view_id = csch_view_get_id(prj, view_name); + if (view_id < 0) { + rnd_message(RND_MSG_ERROR, "Invalid view name: '%s'\n", view_name); + goto error; + } + } + + /* old one saved in cookie */ + prj->abst = calloc(sizeof(csch_abstract_t), 1); + csch_abstract_init(prj->abst); + if (csch_compile_project(prj, view_id, prj->abst, 0) != 0) { + csch_abstract_uninit(prj->abst); + prj->abst = *cookie; + rnd_message(RND_MSG_ERROR, "Failed to compile view: '%s'\n", view_name); + goto error; + } + + return 0; + + error:; + *cookie = nope; /* do not attempt to free prj->abst on _post */ + return -1; +} + +void cschem_export_compile_post(csch_project_t *prj, void **cookie) +{ + if (*cookie != nope) { + /* remove abstract model compiled for the export, restore original */ + csch_abstract_uninit(prj->abst); + prj->abst = *cookie; + } + + *cookie = NULL; +} + + + +static int use_project_name(csch_sheet_t *sheet, int exp_prj) +{ + csch_project_t *prj = (csch_project_t *)sheet->hidlib.project; + + /* exporting a single sheet: always use sheet name */ + if (!exp_prj) + return 0; + + /* if there is an explicit project file, always export project by project name */ + if (!prj->dummy) + return 1; + + /* if we have an implicit project with a single file, use the file name */ + if (sheet->hidlib.project->designs.used < 2) + return 0; + + /* multiple files with implicit project file: use project name */ + return 1; +} + +/* Always leaves room for at least 3 more bytes starting from \0 */ +void csch_sheet_export_name(csch_sheet_t *sheet, int exp_prj, char epath[CSCH_PATH_MAX], long exp_idx) +{ + if (use_project_name(sheet, exp_prj)) { + if ((sheet->hidlib.project != NULL) && (sheet->hidlib.project->prjdir != NULL)) { + const char *pname = NULL, *sep; + + sep = strrchr(sheet->hidlib.project->prjdir, '/'); + if (sep == NULL) + pname = sheet->hidlib.project->prjdir; + else + pname = sep+1; + if (strlen(pname) >= CSCH_PATH_MAX-4) { + sprintf(epath, "long_named_sheet_%ld*", exp_idx); + return; + } + else + sprintf(epath, "%s*", pname); + } + else + strcpy(epath, "implicit_project*"); + } + else if (sheet->hidlib.loadname != NULL) { + char *ext; + if (strlen(sheet->hidlib.loadname) >= CSCH_PATH_MAX-4) { + sprintf(epath, "long_named_sheet_%ld*", exp_idx); + return; + } + strcpy(epath, sheet->hidlib.loadname); + ext = strrchr(epath, '.'); + if ((ext != NULL) && ((strcmp(ext, ".rs") == 0) || (strcmp(ext, ".lht") == 0) || (strcmp(ext, ".csch") == 0))) + strcpy(ext, "*"); + else + strcat(epath, "*"); + } + else + sprintf(epath, "anon_sheet_%ld*", exp_idx); +} + +void csch_project_export_name(csch_project_t *prj, csch_sheet_t *sheet, char epath[CSCH_PATH_MAX], const char *exp_fmt, const char *view_name) +{ + + /* automatic view name */ + if (view_name == NULL) { + void **v = vtp0_get(&prj->views, prj->curr, 0); + + if ((v != NULL) && (*v != NULL)) { + csch_view_t *view = *v; + view_name = view->fgw_ctx.name; + } + else + view_name = "no_view"; + } + + if (prj->hdr.loadname != NULL) { + char *end; + if (strlen(prj->hdr.loadname) + strlen(view_name) >= CSCH_PATH_MAX) + goto fallback; + strcpy(epath, prj->hdr.loadname); + end = strrchr(epath, '/'); + if (strcmp(end, "/project.lht") == 0) + sprintf(end, "/netlist.%s*", view_name); + } + else { + fallback:; + if (sheet != NULL) { + if (sheet->hidlib.loadname != NULL) { + long len = strlen(sheet->hidlib.loadname); + char *s, *end; + + memcpy(epath, sheet->hidlib.loadname, len); + for(s = end = epath + len; s > sheet->hidlib.loadname+1; s--) { + if (*s == '.') { + end = s; + break; + } + } + *end = '.'; + end++; + len = strlen(view_name); + memcpy(end, view_name, len); + end += len; + end[0] = '*'; + end[1] = '\0'; + } + else + goto fallback2; + } + else { + fallback2:; + sprintf(epath, "netlist.%s*", view_name); + } + } +} + +void csch_derive_default_filename(rnd_design_t *dsg, int exp_prj, rnd_hid_attr_val_t *filename_attrib, const char *suffix) +{ + csch_sheet_t *sheet = (csch_sheet_t *)dsg; + char tmp[CSCH_PATH_MAX]; + char *e; + + csch_sheet_export_name(sheet, exp_prj, tmp, sheet->uid); + e = strchr(tmp, '*'); + if (e != NULL) { + if ((CSCH_PATH_MAX - (e - tmp)) > strlen(suffix)+1) { + strcpy(e, suffix); + } + else { + e[0] = '_'; + e[1] = '\0'; + } + } + + free((char *)filename_attrib->str); + filename_attrib->str = rnd_strdup(tmp); +} + Index: tags/1.0.5/src/libcschem/util_export.h =================================================================== --- tags/1.0.5/src/libcschem/util_export.h (nonexistent) +++ tags/1.0.5/src/libcschem/util_export.h (revision 10414) @@ -0,0 +1,30 @@ +#include +#include +#include +#include + +#define CSCH_PATH_MAX 8192 + +/* Derive path name for get_export_options() */ +void csch_derive_default_filename(rnd_design_t *dsg, int exp_prj, rnd_hid_attr_val_t *filename_attrib, const char *suffix); + +/* Allocate a new output file name; use explicit if available or construct + the name from hl's filename replacing it's "extension". Optional + base_suffix and/or base_prefix are prepended and/or appended to the base + file (basename without ext) name after it is generated. */ +char *cschem_export_filename(rnd_design_t *hl, const char *explicit, const char *base_prefix, const char *base_suffix, const char *ext); + +/* Compile abstract model for export if view_name is neither NULL nor empty. + Cookie is an opaque pointer-storage provided by the caller. Call _post after + the export. */ +int cschem_export_compile_pre(csch_project_t *prj, const char *view_name, void **cookie); + +/* Restore project state after a compilation-for-export */ +void cschem_export_compile_post(csch_project_t *prj, void **cookie); + + +/*** internal ***/ +void csch_sheet_export_name(csch_sheet_t *sheet, int exp_prj, char epath[CSCH_PATH_MAX], long exp_idx); + +/* sheet is used if project name is not possible to figure; may be NULL */ +void csch_project_export_name(csch_project_t *prj, csch_sheet_t *sheet, char epath[CSCH_PATH_MAX], const char *exp_fmt, const char *view_name); Index: tags/1.0.5/src/libcschem/util_grp.c =================================================================== --- tags/1.0.5/src/libcschem/util_grp.c (nonexistent) +++ tags/1.0.5/src/libcschem/util_grp.c (revision 10414) @@ -0,0 +1,353 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - sch-rnd (executable) + * Copyright (C) 2020,2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include "config.h" + +#include +#include +#include + +#include + +#include "concrete.h" +#include "cnc_grp.h" +#include "cnc_pen.h" +#include "cnc_text.h" +#include "cnc_any_obj.h" +#include "cnc_obj.h" +#include "cnc_conn.h" +#include "operation.h" +#include "op_common.h" +#include "util_wirenet.h" + +#include "util_grp.h" + +/* cschem convention for minimum terminal grid */ +#define DEF_TERM_GRID 4000.0 + +/* Find and return the bottom floater text object */ +static csch_text_t *bottom_floater(const csch_cgrp_t *grp) +{ + htip_entry_t *e; + csch_text_t *best = NULL; + csch_coord_t besty = CSCH_COORD_MAX; + + for(e = htip_first(&grp->id2obj); e != NULL; e = htip_next(&grp->id2obj, e)) { + csch_text_t *t = e->value; + + if ((t->hdr.type != CSCH_CTYPE_TEXT) || !t->hdr.floater) continue; + + if (t->spec1.y < besty) { + besty = t->spec1.y; + best = t; + } + } + + return best; +} + +/* look at grp and fill in x1;y1 where the next floater dyntext should be placed */ +static void floater_placement_below(const csch_cgrp_t *grp, const csch_cpen_t *pen, csch_coord_t *x1, csch_coord_t *y1) +{ + csch_text_t *bottom; + + bottom = bottom_floater(grp); + if (bottom != NULL) { + csch_coord_t step = pen->font_height; + step = ceil(step / DEF_TERM_GRID) * DEF_TERM_GRID; + *x1 = bottom->spec1.x; + *y1 = bottom->spec1.y - step; + } + else { + /* first floater; start placing at the center */ + *x1 = floor(((grp->hdr.bbox.x1 + grp->hdr.bbox.x2) / 2.0 - grp->x) / DEF_TERM_GRID) * DEF_TERM_GRID; + *y1 = floor(((grp->hdr.bbox.y1 + grp->hdr.bbox.y2) / 2.0 - grp->y) / DEF_TERM_GRID) * DEF_TERM_GRID; + } +} + +static void floater_placement(const csch_cgrp_t *grp, const csch_cpen_t *pen, csch_coord_t *x1, csch_coord_t *y1, csch_coord_t *hint_xy) +{ + switch(grp->role) { + case CSCH_ROLE_WIRE_NET: + if (hint_xy != NULL) { + *x1 = hint_xy[0]; + *y1 = hint_xy[1]; + return; + } + break; + default: break; + } + + /* fallback: place at grp center or below last */ + floater_placement_below(grp, pen, x1, y1); +} + + +/* Heuristics to decide default pen preferences */ +static const char **def_pen_names(csch_cgrp_t *grp, const char *key) +{ + switch(grp->role) { + case CSCH_ROLE_SYMBOL: + { + static const char *def_pen_sym[] = {"sym-decor", "sheet-decor", NULL}; + return def_pen_sym; + } + break; + + case CSCH_ROLE_WIRE_NET: + case CSCH_ROLE_BUS_NET: + case CSCH_ROLE_HUB_POINT: + { + static const char *def_pen_wire[] = {"wire", "sheet-decor", NULL}; + return def_pen_wire; + } + break; + + case CSCH_ROLE_JUNCTION: + { + static const char *def_pen_junc[] = {"junction", "wire", "sheet-decor", NULL}; + return def_pen_junc; + } + break; + + case CSCH_ROLE_BUS_TERMINAL: + case CSCH_ROLE_TERMINAL: + { + static const char *def_pen_term[] = {"term-primary", "sym-decor", "sheet-decor", NULL}; + return def_pen_term; + } + break; + + + case CSCH_ROLE_invalid: + case CSCH_ROLE_empty: + break; + } + + /* final fallback */ + { + static const char *def_pen_any[] = {"sheet-decor", NULL}; + return def_pen_any; + } +} + +csch_text_t *csch_auto_attr_place(csch_sheet_t *sheet, csch_cgrp_t *grp, const char *key, const char *stroke, const char *atempl, csch_coord_t *hint_xy) +{ + csch_text_t *text; + csch_cpen_t *pen = NULL; + const char **pn, **opn; + csch_coord_t x1, y1; + + if (stroke != NULL) + pen = csch_pen_resolve(grp, stroke); + + if (pen == NULL) { + for(opn = pn = def_pen_names(grp, key); (pen == NULL) && (*pn != NULL); pn++) { + pen = csch_pen_resolve(grp, *pn); + if ((pen != NULL) && (pen->font_height <= 0)) + pen = NULL; + } + } + + if (pen == NULL) { + rnd_message(RND_MSG_ERROR, "Can't place floater: no pen found\n; please define one of the following pens:"); + for(pn = opn; *pn != NULL; pn++) + rnd_message(RND_MSG_ERROR, " %s", *pn); + rnd_message(RND_MSG_ERROR, "\n"); + return 0; + } + + if (hint_xy != NULL) + csch_cgrp_inverse_xform(grp, &hint_xy[0], &hint_xy[1], 1); + + floater_placement(grp, pen, &x1, &y1, hint_xy); + + + text = (csch_text_t *)csch_op_create(sheet, grp, CSCH_CTYPE_TEXT); + text->spec1.x = x1; + text->spec1.y = y1; + if (atempl != NULL) + text->text = rnd_strdup(atempl); + else + text->text = rnd_strdup_printf("%%../A.%s%%", key); + text->hdr.stroke_name = csch_comm_str(sheet, pen->name.str, 1); + text->hdr.floater = 1; + text->dyntext = 1; + csch_text_update(sheet, text, 1); + + csch_cobj_redraw(text); + + return text; +} + +csch_text_t *csch_auto_attr_create(csch_sheet_t *sheet, csch_cgrp_t *grp, const char *key, const char *val, const char *stroke, const char *atempl) +{ + csch_source_arg_t *src; + + src = csch_attrib_src_c(NULL, 0, 0, NULL); + + csch_cobj_attrib_set(sheet, grp, CSCH_ATP_USER_DEFAULT, key, val, src); + if (stroke != NULL) + return csch_auto_attr_place(sheet, grp, key, stroke, atempl, NULL); + return NULL; +} + +/* Rename object pen references within the group using regex subst; this can + be used to rename sheet-decor pens to sym-decor. */ +static void grp_pen_rename(csch_sheet_t *sheet, csch_cgrp_t *grp, const char *regex, const char *subst) +{ + htip_entry_t *e; + re_sei_t *rx = re_sei_comp(regex); + + for(e = htip_first(&grp->id2obj); e != NULL; e = htip_next(&grp->id2obj, e)) { + csch_chdr_t *obj = e->value; + if ((obj->stroke_name.str != NULL) && re_sei_exec(rx, obj->stroke_name.str)) { + char *dst; + if (re_sei_subst(rx, &dst, obj->stroke_name.str, subst, 0)) { + csch_comm_str_t stroke_name = csch_comm_str(sheet, dst, 1); + csch_chdr_pen_name_modify(sheet, obj, &stroke_name, NULL, 1); + } + } + if ((obj->fill_name.str != NULL) && re_sei_exec(rx, obj->fill_name.str)) { + char *dst; + if (re_sei_subst(rx, &dst, obj->fill_name.str, subst, 0)) { + csch_comm_str_t fill_name = csch_comm_str(sheet, dst, 1); + csch_chdr_pen_name_modify(sheet, obj, NULL, &fill_name, 1); + } + } + } + + re_sei_free(rx); +} + +void csch_cgrp_update_dsply_recurse(csch_sheet_t *sheet, csch_cgrp_t *grp) +{ + htip_entry_t *e; + + csch_cobj_update_dsply(sheet, &grp->hdr); + + for(e = htip_first(&grp->id2obj); e != NULL; e = htip_next(&grp->id2obj, e)) { + csch_chdr_t *obj = e->value; + if (csch_obj_is_grp(obj)) + csch_cgrp_update_dsply_recurse(sheet, (csch_cgrp_t *)obj); + else + csch_cobj_update_dsply(sheet, obj); + } +} + + +void csch_cgrp_role_side_effects(csch_sheet_t *sheet, csch_cgrp_t *grp, csch_role_t role) +{ + csch_text_t *t; + static int zero = 0; + + /* side effects for advanced groups */ + switch(role) { + case CSCH_ROLE_SYMBOL: + csch_auto_attr_create(sheet, grp, "role", "symbol", NULL, NULL); + csch_auto_attr_create(sheet, grp, "name", "REFDES", "sym-primary", NULL); + grp_pen_rename(sheet, grp, "^sheet-", "sym-"); + break; + case CSCH_ROLE_TERMINAL: + csch_auto_attr_create(sheet, grp, "role", "terminal", NULL, NULL); + t = csch_auto_attr_create(sheet, grp, "name", "TERMNAME", "term-primary", "%../a.display/name%"); + grp_pen_rename(sheet, grp, "^sheet-", "term-"); + + csch_commprp_modify(sheet, &t->hdr, NULL, &zero, 1); + break; + + default: break; + } + + csch_cgrp_update_dsply_recurse(sheet, grp); +} + + +static void csch_cgrp_replace_attr(csch_sheet_t *sheet, csch_cgrp_t *new, csch_cgrp_t *dst, csch_cgrp_t *src, csch_cgrp_replace_how_t how) +{ + if (how & CSCH_REPLGRP_KEEP_DST_ATTR) { + htsp_entry_t *e, *already; + for(e = htsp_first(&dst->attr); e != NULL; e = htsp_next(&dst->attr, e)) { + if (how & CSCH_REPLGRP_PREFER_DST_ATTR) + already = NULL; + else + already = htsp_getentry(&new->attr, e->key); + + if (already == NULL) { + csch_attrib_t *newa = csch_attrib_dup(e->value); + htsp_set(&new->attr, newa->key, newa); + } + } + } +} + +int csch_cgrp_replace(csch_sheet_t *sheet, csch_cgrp_t *dst, csch_cgrp_t *src, csch_cgrp_replace_how_t how) +{ + csch_cgrp_t *newg; + csch_chdr_t *newo; + + uundo_freeze_serial(&sheet->undo); + csch_wirenet_recalc_freeze(sheet); + + newo = csch_cobj_dup(sheet, dst->hdr.parent, &src->hdr, 0, 0); + + if (newo == NULL) { + csch_wirenet_recalc_unfreeze(sheet); + uundo_unfreeze_serial(&sheet->undo); + return -1; + } + + newg = ((csch_cgrp_t *)newo); + newg->sym_prefer_loclib = 0; /* lib buffer paste related special casing */ + + /* copy transformation */ + newg->spec_rot = dst->spec_rot; + newg->x = dst->x; + newg->y = dst->y; + newg->mirx = dst->mirx; + newg->miry = dst->miry; + + csch_cgrp_replace_attr(sheet, newg, dst, src, how); + + csch_op_remove(sheet, &dst->hdr); + + csch_cgrp_update(sheet, newg, 1); + csch_op_inserted(sheet, newo->parent, newo); + + + csch_conn_auto_recalc(sheet, newo); + + csch_wirenet_recalc_unfreeze(sheet); + uundo_unfreeze_serial(&sheet->undo); + uundo_inc_serial(&sheet->undo); + + return 0; +} + + + Index: tags/1.0.5/src/libcschem/util_grp.h =================================================================== --- tags/1.0.5/src/libcschem/util_grp.h (nonexistent) +++ tags/1.0.5/src/libcschem/util_grp.h (revision 10414) @@ -0,0 +1,29 @@ +#ifndef LIBCSCHEM_UTIL_GRP +#define LIBCSCHEM_UTIL_GRP + +#include "cnc_text.h" + +/* Place a new floater for an existing attribute, by attr key + If hint_xy is not NULL, it contains coords where the GUI action started, in + sheet coords */ +csch_text_t *csch_auto_attr_place(csch_sheet_t *sheet, csch_cgrp_t *grp, const char *key, const char *stroke, const char *atempl, csch_coord_t *hint_xy); + +/* Create a new attribute and place a dyntext-floater for it if stroke is + not NULL; returns the floater created. */ +csch_text_t *csch_auto_attr_create(csch_sheet_t *sheet, csch_cgrp_t *grp, const char *key, const char *val, const char *stroke, const char *atempl); + +/* Apply conventional side effects of role on grp: create attributes, rename pens */ +void csch_cgrp_role_side_effects(csch_sheet_t *sheet, csch_cgrp_t *grp, csch_role_t role); + +/* Calls csch_cobj_update_dsply() recursively */ +void csch_cgrp_update_dsply_recurse(csch_sheet_t *sheet, csch_cgrp_t *grp); + + +typedef enum csch_cgrp_replace_how_e { /* bitfield */ + CSCH_REPLGRP_KEEP_DST_ATTR = 1, /* preserve attributes of the dst group */ + CSCH_REPLGRP_PREFER_DST_ATTR = 2 /* if an attribute is specified both in dst and src, prefer dst's */ +} csch_cgrp_replace_how_t; + +int csch_cgrp_replace(csch_sheet_t *sheet, csch_cgrp_t *dst, csch_cgrp_t *src, csch_cgrp_replace_how_t how); + +#endif Index: tags/1.0.5/src/libcschem/util_lib_fs.c =================================================================== --- tags/1.0.5/src/libcschem/util_lib_fs.c (nonexistent) +++ tags/1.0.5/src/libcschem/util_lib_fs.c (revision 10414) @@ -0,0 +1,94 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2019,2020 Tibor 'Igor2' Palinkas + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include +#include "config.h" +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "util_lib_fs.h" + + +char *csch_lib_fs_realpath(rnd_design_t *hl, const char *root) +{ + char *patha, *rp; + const char *path = root; + + if (*path == '?') + path++; + + patha = rnd_build_fn(hl, path); + rp = rnd_lrealpath(patha); + free(patha); + return rp; +} + +void csch_lib_fs_map(rnd_design_t *hl, csch_lib_backend_t *be, csch_lib_t *parent, gds_t *path, csch_lib_type_t (*type_cb)(rnd_design_t *, const char *fn)) +{ + DIR *dir; + struct dirent *de; + long save = path->used, restore; + csch_lib_t *newent; + + dir = rnd_opendir(hl, path->array); + if (dir == NULL) + return; + + gds_append(path, '/'); + restore = path->used; + + while((de = rnd_readdir(dir)) != NULL) { + if (*de->d_name == '.') continue; + + gds_append_str(path, de->d_name); + + if (rnd_is_dir(hl, path->array)) { + newent = csch_lib_alloc_append(be, parent, rnd_strdup(de->d_name), CSCH_SLIB_DIR); + csch_lib_fs_map(hl, be, newent, path, type_cb); + } + else { + csch_lib_type_t type = type_cb(hl, path->array); + if (type != CSCH_SLIB_invalid) + newent = csch_lib_alloc_append(be, parent, rnd_strdup(de->d_name), type); + else + newent = NULL; + } + if (newent != NULL) + newent->realpath = rnd_strdup(path->array); + path->used = restore; + } + + path->used = save; + rnd_closedir(dir); +} Index: tags/1.0.5/src/libcschem/util_lib_fs.h =================================================================== --- tags/1.0.5/src/libcschem/util_lib_fs.h (nonexistent) +++ tags/1.0.5/src/libcschem/util_lib_fs.h (revision 10414) @@ -0,0 +1,42 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2019 Tibor 'Igor2' Palinkas + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include "config.h" + +#include +#include + +#include + +#include + +/* look up library root_path's real path, skipping the ? prefix */ +char *csch_lib_fs_realpath(rnd_design_t *hl, const char *root_path); + +/* map path dir recursively for library entries; check each entry with + type_cb, if it returns invalid type, omit the entry. */ +void csch_lib_fs_map(rnd_design_t *hl, csch_lib_backend_t *be, csch_lib_t *parent, gds_t *path, csch_lib_type_t (*type_cb)(rnd_design_t *, const char *fn)); + Index: tags/1.0.5/src/libcschem/util_loclib.c =================================================================== --- tags/1.0.5/src/libcschem/util_loclib.c (nonexistent) +++ tags/1.0.5/src/libcschem/util_loclib.c (revision 10414) @@ -0,0 +1,134 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2022, 2024 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/* Utility functions for maintaining a local (per sheet) library */ + +#include "config.h" + +#include + +#include +#include + +#include "util_loclib.h" + +csch_cgrp_t *csch_loclib_get_root_by_name(csch_sheet_t *sheet, const char *name, csch_source_arg_t *src, int alloc, int *alloced) +{ + htip_entry_t *e; + + if (alloc) + *alloced = 0; + + for(e = htip_first(&sheet->indirect.id2obj); e != NULL; e = htip_next(&sheet->indirect.id2obj, e)) { + csch_cgrp_t *grp = e->value; + const char *gpurp = csch_attrib_get_str(&grp->attr, "purpose"); + if ((gpurp != NULL) && (strcmp(gpurp, name) == 0)) { + csch_attr_src_free(src); + return grp; + } + } + + if (alloc) { + csch_cgrp_t *grp = csch_cgrp_alloc(sheet, &sheet->indirect, csch_oid_new(sheet, &sheet->indirect)); + csch_attrib_set(&grp->attr, 0, "purpose", name, src, NULL); + *alloced = 1; + csch_sheet_set_changed(sheet, 1); + return grp; + } + + csch_attr_src_free(src); + return NULL; +} + +csch_cgrp_t *csch_loclib_get_root(csch_sheet_t *sheet, csch_lib_master_t *master, csch_source_arg_t *src, int alloc, int *alloced) +{ + return csch_loclib_get_root_by_name(sheet, master->name, src, alloc, alloced); +} + + +int csch_loclib_get_roots(csch_lib_t **root_dir_out, csch_cgrp_t **root_grp_out, csch_lib_master_t *master, csch_sheet_t *sheet, csch_source_arg_t *src, int alloc, int *alloced) +{ + csch_lib_root_t *libroot; + csch_lib_t *root_dir; + csch_cgrp_t *root_grp; + + + *root_dir_out = NULL; + *root_grp_out = NULL; + if (alloc) + *alloced = 0; + + if (master->uid >= sheet->local_libs.used) { + rnd_message(RND_MSG_ERROR, "%s: master out of bounds #1\nPlease report this bug!\n", master->name); + csch_attr_src_free(src); + return -1; + } + + libroot = sheet->local_libs.array[master->uid]; + if (libroot->roots.used < 1) { + rnd_message(RND_MSG_ERROR, "%s: master out of bounds #2\nPlease report this bug!\n", master->name); + csch_attr_src_free(src); + return -1; + } + + root_dir = libroot->roots.array[0]; + + root_grp = csch_loclib_get_root(sheet, master, src, alloc, alloced); + if (root_grp == NULL) { + if (alloc) + rnd_message(RND_MSG_ERROR, "%s: failed to create local devmap lib\nPlease report this bug!\n", master->name); + return -1; + } + + *root_dir_out = root_dir; + *root_grp_out = root_grp; + + return 0; +} + +long csch_loclib_reload_all(csch_sheet_t *sheet, csch_lib_root_t *libroot) +{ + long n, i, cnt = 0; + + for(n = 0; n < libroot->roots.used; n++) { + csch_lib_t *root = libroot->roots.array[n]; + if (strcmp(root->name, "") == 0) { + for(i = root->children.used-1; i >= 0; i--) { + csch_lib_t *l = root->children.array[i]; + if ((l != NULL) && (l->backend != NULL) && (l->backend->loc_refresh_from_ext != NULL)) { + if (l->backend->loc_refresh_from_ext(sheet, l) == 0) + cnt++; + } + } + break; + } + } + + return cnt; +} + Index: tags/1.0.5/src/libcschem/util_loclib.h =================================================================== --- tags/1.0.5/src/libcschem/util_loclib.h (nonexistent) +++ tags/1.0.5/src/libcschem/util_loclib.h (revision 10414) @@ -0,0 +1,50 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2022, 2024 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/* Utility functions for maintaining a local (per sheet) library */ + +#include +#include + +/* Return the group whose purpose matches purpose from under sheet's + indirect group. If alloc is 1, and the group does not exist, it is + created using src and *alloced is set to 1. + Always frees src's fields. */ +csch_cgrp_t *csch_loclib_get_root(csch_sheet_t *sheet, csch_lib_master_t *master, csch_source_arg_t *src, int alloc, int *alloced); +csch_cgrp_t *csch_loclib_get_root_by_name(csch_sheet_t *sheet, const char *name, csch_source_arg_t *src, int alloc, int *alloced); + + +/* Resolve library root dir and indirect root group for a local lib master. + If alloc==1, create it using src when missing. Returns 0 on success. On + failure there's no root dir in indirect. + Always frees src's fields. */ +int csch_loclib_get_roots(csch_lib_t **root_dir_out, csch_cgrp_t **root_grp_out, csch_lib_master_t *master, csch_sheet_t *sheet, csch_source_arg_t *src, int alloc, int *alloced); + +/* Reload all loclib entries from external libraries. Used in actions like + SymlibReloadAllLocal() */ +long csch_loclib_reload_all(csch_sheet_t *sheet, csch_lib_root_t *libroot); Index: tags/1.0.5/src/libcschem/util_parse.c =================================================================== --- tags/1.0.5/src/libcschem/util_parse.c (nonexistent) +++ tags/1.0.5/src/libcschem/util_parse.c (revision 10414) @@ -0,0 +1,235 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - libcschem (core library) + * Copyright (C) 2020 Tibor 'Igor2' Palinkas + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include "config.h" + +#include +#include +#include +#include +#include + +#include "cnc_any_obj.h" +#include "engine.h" +#include "project.h" + +#include "util_parse.h" + +/*** load_cache low levels ***/ + + /* called when the file is first loaded; should allocate (ldch_file_t *) */ +static ldch_file_t *ldlht_parse_alloc(ldch_low_parser_t *parser, void *call_ctx, const char *fn) +{ + return ldch_file_alloc(parser->ctx, parser, sizeof(lht_doc_t *)); +} + + /* called after parse_alloc() on initial load or after free_payload() on reload */ +static int ldlht_parse(ldch_low_parser_t *parser, void *call_ctx, ldch_file_t *file, const char *fn) +{ + char *errmsg; + lht_doc_t **payload = (lht_doc_t **)&file->low_payload; + + *payload = lht_dom_load(fn, &errmsg); + if (*payload == NULL) { + rnd_message(RND_MSG_ERROR, "Failed to parse lihata file '%s': %s\n", fn, errmsg); + return -1; + } + return 0; +} + + /* should free the in-memory document/parse-tree; a call to parse() may follow when reloading */ +static void ldlht_free_payload(ldch_low_parser_t *low, ldch_file_t *file) +{ + lht_doc_t **payload = (lht_doc_t **)&file->low_payload; + if (*payload != NULL) + lht_dom_uninit(*payload); +} + +lht_doc_t *ldch_lht_get_doc(ldch_file_t *file) +{ + lht_doc_t **payload = (lht_doc_t **)&file->low_payload; + return *payload; +} + +ldch_low_parser_t *ldch_lht_reg_low_parser(ldch_ctx_t *ctx) +{ + ldch_low_parser_t *p = ldch_reg_low_parser(ctx, "lihata"); + + p->parse_alloc = ldlht_parse_alloc; + p->parse = ldlht_parse; + p->free_payload = ldlht_free_payload; + + return p; +} + + +/*** lihata parsers ***/ + +static void csch_lht_parse_attribs_val(csch_sheet_t *sheet, csch_cgrp_t *dstg, csch_attribs_t *dsta, const char *key, lht_node_t *n, void (*error)(void *ectx, lht_node_t *n, const char *msg), void *ectx, int prio) +{ + lht_node_t *i, *np, *nv; + long idx; + const char *val; + csch_source_arg_t *src; + + if (dstg != NULL) { + assert(csch_obj_is_grp(&dstg->hdr)); + } + + switch(n->type) { + case LHT_TEXT: /* plain text: scalar attrib */ + val = n->data.text.value; + src = csch_attrib_src_c(n->file_name, n->line, n->col, NULL); + if (dstg != NULL) + csch_cobj_attrib_set(sheet, dstg, prio, key, val, src); + else + csch_attrib_set(dsta, prio, key, val, src, NULL); + break; + case LHT_LIST: /* array attrib */ + /* first create the attribute as an empty array, just in case it is indeed an empty arrya with no child */ + src = csch_attrib_src_c(n->file_name, n->line, n->col, NULL); + if (dstg != NULL) + csch_cobj_attrib_set(sheet, dstg, prio, key, NULL, src); + else + csch_attrib_set(dsta, prio, key, NULL, src, NULL); + + for(i = n->data.list.first, idx = 0; i != NULL; i = i->next) { + if (i->type != LHT_TEXT) { + error(ectx, i, "invalid node type for an attribute list item"); + continue; + } + val = i->data.text.value; + src = csch_attrib_src_c(i->file_name, i->line, i->col, NULL); + if (dstg != NULL) + csch_cobj_attrib_seti(sheet, dstg, prio, key, idx, val, src); + else + csch_attrib_seti(dsta, prio, key, idx, val, src, NULL); + idx++; + } + break; + case LHT_HASH: /* subtree with explicit prio value */ + nv = lht_dom_hash_get(n, "value"); + if (nv == NULL) { + error(ectx, n, "missing attribute value subtree"); + return; + } + if ((nv->type != LHT_TEXT) && (nv->type != LHT_LIST)) { + error(ectx, n, "wrong attribute value subtree type (must be text or list)"); + return; + } + np = lht_dom_hash_get(n, "prio"); + if (np != NULL) { + if (np->type == LHT_TEXT) { + char *end; + prio = strtol(np->data.text.value, &end, 10); + if (*end != '\0') { + error(ectx, n, "prio value is not integer"); + return; + } + if ((prio < 0) || (prio > 32767)) { + error(ectx, n, "attribute prio is out of range"); + return; + } + } + else { + error(ectx, n, "wrong attribute prio type (must be text)"); + return; + } + } + csch_lht_parse_attribs_val(sheet, dstg, dsta, key, nv, error, ectx, prio); + break; + default: + error(ectx, n, "invalid node type for an attribute"); + } +} + +int csch_lht_parse_attribs_(csch_sheet_t *sheet, csch_chdr_t *dsth, csch_attribs_t *dsta, lht_node_t *subtree, void (*error)(void *ectx, lht_node_t *n, const char *msg), void *ectx) +{ + lht_node_t *n; + lht_dom_iterator_t it; + csch_cgrp_t *dstg = (csch_cgrp_t *)dsth; + + if ((subtree == NULL) || (subtree->type != LHT_HASH)) + return 0; + + if (dsth != NULL) { + assert(csch_obj_is_grp(dsth)); + } + + for(n = lht_dom_first(&it, subtree); n != NULL; n = lht_dom_next(&it)) + csch_lht_parse_attribs_val(sheet, dstg, dsta, n->name, n, error, ectx, CSCH_ATP_USER_DEFAULT); + + return 0; +} + +int csch_lht_parse_attribs(csch_attribs_t *dst, lht_node_t *subtree, void (*error)(void *ectx, lht_node_t *n, const char *msg), void *ectx) +{ + return csch_lht_parse_attribs_(NULL, NULL, dst, subtree, error, ectx); +} + +static lht_node_t *csch_view2lht_engines_in_(lht_node_t *nv, const csch_view_t *view) +{ + lht_node_t *ne, *neng, *nd; + long n; + + ne = lht_dom_node_alloc(LHT_LIST, "engines"); + lht_dom_hash_put(nv, ne); + for(n = 0; n < view->engines.used; n++) { + csch_view_eng_t *e = view->engines.array[n]; + neng = lht_dom_node_alloc(LHT_HASH, e->obj->name); + lht_dom_list_append(ne, neng); + + nd = lht_dom_node_alloc(LHT_TEXT, "plugin"); + nd->data.text.value = rnd_strdup(e->obj->engine->name); + lht_dom_hash_put(neng, nd); + + if (e->options != NULL) { + nd = lht_dom_node_alloc(LHT_TEXT, "options"); + nd->data.text.value = rnd_strdup(e->options); + lht_dom_hash_put(neng, nd); + } + } + return nv; +} + +lht_node_t *csch_view2lht_in(lht_node_t *nv, const csch_view_t *view) +{ + lht_node_t *old; + + /* purge old nodes under nv so they can be replaced with newly allocated */ + old = lht_dom_hash_get(nv, "engines"); + if (old != NULL) + lht_tree_del(old); + + return csch_view2lht_engines_in_(nv, view); +} + +lht_node_t *csch_view2lht(const csch_view_t *view) +{ + lht_node_t *nv = lht_dom_node_alloc(LHT_HASH, view->fgw_ctx.name); + return csch_view2lht_engines_in_(nv, view); +} + Index: tags/1.0.5/src/libcschem/util_parse.h =================================================================== --- tags/1.0.5/src/libcschem/util_parse.h (nonexistent) +++ tags/1.0.5/src/libcschem/util_parse.h (revision 10414) @@ -0,0 +1,17 @@ +#include +#include +#include +#include + +lht_doc_t *ldch_lht_get_doc(ldch_file_t *file); +ldch_low_parser_t *ldch_lht_reg_low_parser(ldch_ctx_t *ctx); + +int csch_lht_parse_attribs_(csch_sheet_t *sheet, csch_chdr_t *dsth, csch_attribs_t *dsta, lht_node_t *subtree, void (*error)(void *ectx, lht_node_t *n, const char *msg), void *ectx); +int csch_lht_parse_attribs(csch_attribs_t *dst, lht_node_t *subtree, void (*error)(void *ectx, lht_node_t *n, const char *msg), void *ectx); + +/* Build a lihata subtree for a view; return NULL on error */ +lht_node_t *csch_view2lht(const csch_view_t *view); + +/* Same as csch_view2lht, but takes view_node, an existing ha:viewname and + replaces its children node with the new conversion */ +lht_node_t *csch_view2lht_in(lht_node_t *view_node, const csch_view_t *view); Index: tags/1.0.5/src/libcschem/util_project.c =================================================================== --- tags/1.0.5/src/libcschem/util_project.c (nonexistent) +++ tags/1.0.5/src/libcschem/util_project.c (revision 10414) @@ -0,0 +1,123 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - sch-rnd (executable) + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust in 2023) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include "config.h" + +#include +#include +#include + +#include "project.h" +#include "util_export.h" +#include "util_project.h" + +/* Compare sheet->hidlib.fullpath to the lreapath() of each string item on the + config list and returns 1 if there was a match. List items that are relative + paths are prefixed using prefix if prefix is not NULL. */ +static int sheet_on_list(csch_sheet_t *sheet, const rnd_conflist_t *list, const char *prefix) +{ + rnd_conf_listitem_t *item_li; + + /* HACK: use manual ->next looping because list may be an off-config list + with broken ->parent */ + for(item_li = rnd_conflist_first((rnd_conflist_t *)list); item_li != NULL; item_li = item_li->link.next) { + if (item_li->type == RND_CFN_STRING) { + const char *item_path, *item_str = item_li->val.string[0]; + char *preal, *freeme; + + if ((prefix == NULL) || rnd_is_path_abs(item_str)) { + freeme = NULL; + item_path = item_str; + } + else + item_path = freeme = rnd_concat(prefix, "/", item_str, NULL); + + preal = rnd_lrealpath(item_path); + free(freeme); + + if (preal != NULL) { + int res = strcmp(sheet->hidlib.fullpath, preal); + free(preal); + if (res == 0) + return 1; + } + else + free(preal); + } + + } + return 0; +} + +void csch_sheet_type_detect(csch_sheet_t *sheet, const rnd_conflist_t *roots, const rnd_conflist_t *aux) +{ + char prjdir[CSCH_PATH_MAX], *prefix = NULL; + + sheet->stype = CSCH_SHTY_unknown; + + if (sheet->hidlib.project == NULL) + return; + + if (sheet->hidlib.project->fullpath != NULL) { + int len = strlen(sheet->hidlib.project->fullpath); + + memcpy(prjdir, sheet->hidlib.project->fullpath, len+1); + if ((len > 11) && (strcmp(prjdir + len-11, "project.lht") == 0)) + prjdir[len-12] = '\0'; + prefix = prjdir; + } + + if (sheet_on_list(sheet, roots, prefix)) { + sheet->stype = CSCH_SHTY_ROOT; + return; + } + + if (sheet_on_list(sheet, aux, prefix)) { + sheet->stype = CSCH_SHTY_AUX; + return; + } + + sheet->stype = CSCH_SHTY_UNLISTED; +} + + +int csch_project_is_partial(csch_project_t *prj) +{ + long n, root_sheets = 0; + + for(n = 0; n < prj->hdr.designs.used; n++) { + csch_sheet_t *sheet = prj->hdr.designs.array[n]; + if (sheet->stype == CSCH_SHTY_ROOT) + root_sheets++; + } + + /* rnd_trace("prj partial: counted %ld want %ld\n", root_sheets, prj->num_root_sheets); */ + + return root_sheets != prj->num_root_sheets; +} + Index: tags/1.0.5/src/libcschem/util_project.h =================================================================== --- tags/1.0.5/src/libcschem/util_project.h (nonexistent) +++ tags/1.0.5/src/libcschem/util_project.h (revision 10414) @@ -0,0 +1,15 @@ +#ifndef CSCH_UTIL_PROJECT_H +#define CSCH_UTIL_PROJECT_H + +#include +#include + +/* Look at sheet's project and fill in sheet->type accordingly + (root, aux or unlisted) */ +void csch_sheet_type_detect(csch_sheet_t *sheet, const rnd_conflist_t *roots, const rnd_conflist_t *aux); + +/* Return 1 if not all root sheets are loaded, 0 otherwise */ +int csch_project_is_partial(csch_project_t *prj); + + +#endif Index: tags/1.0.5/src/libcschem/util_wirenet.c =================================================================== --- tags/1.0.5/src/libcschem/util_wirenet.c (nonexistent) +++ tags/1.0.5/src/libcschem/util_wirenet.c (revision 10414) @@ -0,0 +1,1298 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - sch-rnd (executable) + * Copyright (C) 2020,2022..2024 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022, Entrust in 2023) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include "config.h" + +#include +#include + +#include +#include +#include +#include "search.h" +#include "operation.h" +#include "cnc_line.h" +#include "cnc_grp.h" +#include "cnc_pen.h" +#include "cnc_conn.h" +#include "cnc_text.h" +#include "cnc_text_dyn.h" +#include +#include +#include "htPo.h" +#include "intersect.h" + +#include "util_wirenet.h" + +int csch_wirenet_dbg_junct = 0; + +void csch_wirenet_recalc_obj_conn(csch_sheet_t *sheet, csch_chdr_t *wobj) +{ + csch_recalc_obj_conn(sheet, wobj, CSCH_DSPLY_HUBTERM, CSCH_DSPLY_invalid); +} + +void csch_wirenet_recalc_wirenet_conn(csch_sheet_t *sheet, csch_cgrp_t *grp) +{ + htip_entry_t *e; + for(e = htip_first(&grp->id2obj); e != NULL; e = htip_next(&grp->id2obj, e)) + csch_wirenet_recalc_obj_conn(sheet, e->value); +} + + +typedef struct { + csch_line_t *res; + csch_chdr_t *ignore; + g2d_vect_t pt; +} find_wire_t; + +static csch_rtree_dir_t find_wire_cb(void *ctx_, void *obj_, const csch_rtree_box_t *box) +{ + find_wire_t *ctx = (find_wire_t *)ctx_; + csch_line_t *line = obj_; + + if (obj_ == ctx->ignore) + return csch_RTREE_DIR_NOT_FOUND_CONT; + + /* accept lines that are in a wirenet */ + if ((line->hdr.type == CSCH_CTYPE_LINE) && (line->hdr.parent != NULL) && (line->hdr.parent->role == CSCH_ROLE_WIRE_NET)) { + /* make sure the point is really on the line (matters for diagonal lines) */ + if (g2d_dist2_cline_pt(&line->inst.c, ctx->pt) < 2) { + ctx->res = obj_; + return csch_RTREE_DIR_FOUND_STOP; + } + } + return csch_RTREE_DIR_NOT_FOUND_CONT; +} + + +static csch_line_t *find_wire(csch_sheet_t *sheet, csch_coord_t x, csch_coord_t y, csch_chdr_t *ignore) +{ + find_wire_t ctx = {0}; + csch_rtree_box_t query; + + ctx.ignore = ignore; + ctx.pt.x = x; ctx.pt.y = y; + query.x1 = x-2; query.y1 = y-2; + query.x2 = x+2; query.y2 = y+2; + csch_rtree_search_obj(&sheet->dsply[CSCH_DSPLY_WIRE], &query, find_wire_cb, &ctx); + + return ctx.res; +} + +csch_cgrp_t *csch_wirenet_new_from(csch_sheet_t *sheet, const csch_cgrp_t *attr_src) +{ + csch_source_arg_t *src; + csch_cgrp_t *grp = (csch_cgrp_t *)csch_op_create(sheet, &sheet->direct, CSCH_CTYPE_GRP); + + if (grp == NULL) { + rnd_message(RND_MSG_ERROR, "Internal error: failed to create direct group for wirenet\n"); + return NULL; + } + + if (attr_src == NULL) { + src = csch_attrib_src_c(NULL, 0, 0, "manual_draw_wirenet"); + csch_attrib_set(&grp->attr, 0, "role", "wire-net", src, NULL); + } + else + csch_attrib_copy_all(&grp->attr, &attr_src->attr); + + csch_cgrp_attrib_update(sheet, grp, 0, "role", "wire-net"); + + if (sheet->util_wirenet.recalc_inhibit) + htpi_set(&sheet->util_wirenet.recalc_wn, grp, 1); + + return grp; +} + +csch_cgrp_t *csch_wirenet_new(csch_sheet_t *sheet) +{ + return csch_wirenet_new_from(sheet, NULL); +} + + +RND_INLINE void remove_grp_if_empty(csch_sheet_t *sheet, csch_cgrp_t *grp) +{ + if ((grp == NULL) || (grp->id2obj.used != 0) || (csch_obj_is_deleted(&grp->hdr))) + return; + csch_op_remove(sheet, (csch_chdr_t *)grp); +} + + +/*** wire (line) merge ***/ +typedef struct { + csch_sheet_t *sheet; + csch_line_t *self; + csch_cgrp_t *wirenet; + long dir; + vtp0_t lines; /* list of other lines to merge */ +} wire_merge_t; + +/* Return unique direction; 180 degree shift doesn't make a difference */ +RND_INLINE long line_dir(csch_line_t *line) +{ + double l, dx = line->inst.c.p2.x - line->inst.c.p1.x, dy = line->inst.c.p2.y - line->inst.c.p1.y; + int sig, sdx, sdy; + + if ((dx == 0) && (dy == 0)) + return 0; + + sdx = (dx < 0) ? -1 : +1; + sdy = (dy < 0) ? -1 : +1; + sig = (sdx == sdy) ? +1 : -1; + + l = sqrt(dx*dx + dy*dy); + dx = floor(dx / l * 1000.0); + dy = floor(dy / l * 1000000.0); + + return (dx + dy) * sig; +} + +static csch_rtree_dir_t wire_merge_cb(void *ctx_, void *obj_, const csch_rtree_box_t *box) +{ + wire_merge_t *ctx = ctx_; + csch_line_t *line = obj_; + long dir; + + /* must be another line in the same wirenet */ + if ((line == ctx->self) || (line->hdr.type != CSCH_CTYPE_LINE) || (line->hdr.parent != ctx->wirenet)) + return csch_RTREE_DIR_NOT_FOUND_CONT; + + /* merge only if directions match */ + dir = line_dir(line); + if (dir != ctx->dir) + return csch_RTREE_DIR_NOT_FOUND_CONT; + + /* merge only if they intersect - close parallel diagonals have + overlapping bbox without actual intersection shall not be merged */ + if (csch_obj_intersect_obj(line->hdr.sheet, &line->hdr, &ctx->self->hdr, NULL, 0) < 1) + return csch_RTREE_DIR_NOT_FOUND_CONT; + + vtp0_append(&ctx->lines, line); + return csch_RTREE_DIR_FOUND_CONT; +} + +void csch_wirenet_recalc_merge(csch_sheet_t *sheet, csch_line_t *line, int remove_overlap) +{ + wire_merge_t ctx = {0}; + g2d_vect_t min, max; + int n, order12; + csch_coord_t x1, y1, x2, y2; + + ctx.sheet = sheet; + ctx.dir = line_dir(line); + ctx.self = line; + ctx.wirenet = line->hdr.parent; + + csch_rtree_search_obj(&sheet->dsply[CSCH_DSPLY_WIRE], &line->hdr.bbox, wire_merge_cb, &ctx); + + if (ctx.lines.used > 0) { +/* rnd_trace("Merge #%d (%ld) with:\n", line->hdr.oid, ctx.dir);*/ + if (ctx.dir == 1000) /* horizontal, use x */ + order12 = (line->inst.c.p1.x < line->inst.c.p2.x); + else + order12 = (line->inst.c.p1.y < line->inst.c.p2.y); + + if (order12) { + min = line->inst.c.p1; + max = line->inst.c.p2; + } + else { + min = line->inst.c.p2; + max = line->inst.c.p1; + } + + for(n = 0; n < ctx.lines.used; n++) { + csch_line_t *l = ctx.lines.array[n]; + + if (remove_overlap) { + int full_overlap = (g2d_dist2_cline_pt(&l->inst.c, line->inst.c.p1) <= 4) && (g2d_dist2_cline_pt(&l->inst.c, line->inst.c.p1) <= 4); + if (full_overlap) { + int trunc = 0, full = 0; + + /* figure which end(s) of the shorter "line" is on the + longer "l" just found. Set trunc=1 only if at least one endpoint of + the two lines match */ + x1 = l->inst.c.p1.x; y1 = l->inst.c.p1.y; + x2 = l->inst.c.p2.x; y2 = l->inst.c.p2.y; + if (g2d_vect_t_eq_g2d_vect_t(l->inst.c.p1, line->inst.c.p1)) { + x1 = line->inst.c.p2.x; y1 = line->inst.c.p2.y; + trunc = 1; + if (g2d_vect_t_eq_g2d_vect_t(l->inst.c.p2, line->inst.c.p2)) + full = 1; + } + else if (g2d_vect_t_eq_g2d_vect_t(l->inst.c.p1, line->inst.c.p2)) { + x1 = line->inst.c.p1.x; y1 = line->inst.c.p1.y; + trunc = 1; + if (g2d_vect_t_eq_g2d_vect_t(l->inst.c.p2, line->inst.c.p1)) + full = 1; + } + if (g2d_vect_t_eq_g2d_vect_t(l->inst.c.p2, line->inst.c.p1)) { + x2 = line->inst.c.p2.x; y2 = line->inst.c.p2.y; + trunc = 1; + if (g2d_vect_t_eq_g2d_vect_t(l->inst.c.p1, line->inst.c.p2)) + full = 1; + } + else if (g2d_vect_t_eq_g2d_vect_t(l->inst.c.p2, line->inst.c.p2)) { + x2 = line->inst.c.p1.x; y2 = line->inst.c.p1.y; + trunc = 1; + if (g2d_vect_t_eq_g2d_vect_t(l->inst.c.p2, line->inst.c.p1)) + full = 1; + } + + /* if we got here with trunc == 0, the shorter line is in + the middle of the longer line and we shouldn't truncate for + this overlap. (This is when no endpoint-endpoint match is found) */ + if (trunc) { + ctx.wirenet->wirenet_recalc_lock = 1; + ctx.wirenet->wirenet_split_lock = 1; + + if (!full) { + /* truncate l, removing the segment overlapping with "line" */ + csch_cgrp_vinverse_xform(ctx.wirenet, &x1, &y1, &x2, &y2, NULL); + csch_line_modify(sheet, l, &x1, &y1, &x2, &y2, 1, 0, 0); + } + else { + /* upon full overlap, remove l */ + csch_op_remove(sheet, &l->hdr); + } + + /* remove the new "line", it's in overlap */ + csch_op_remove(sheet, &line->hdr); + + ctx.wirenet->wirenet_recalc_lock = 0; + ctx.wirenet->wirenet_split_lock = 0; + csch_wirenet_recalc_junctions(sheet, ctx.wirenet); + goto quit; + } + } + } + +/* rnd_trace(" #%d\n", l->hdr.oid);*/ + if (ctx.dir == 1000) { /* horizontal, use x */ + if (l->inst.c.p1.x < min.x) + min = l->inst.c.p1; + if (l->inst.c.p1.x > max.x) + max = l->inst.c.p1; + if (l->inst.c.p2.x < min.x) + min = l->inst.c.p2; + if (l->inst.c.p2.x > max.x) + max = l->inst.c.p2; + } + else { + if (l->inst.c.p1.y < min.y) + min = l->inst.c.p1; + if (l->inst.c.p1.y > max.y) + max = l->inst.c.p1; + if (l->inst.c.p2.y < min.y) + min = l->inst.c.p2; + if (l->inst.c.p2.y > max.y) + max = l->inst.c.p2; + } + } + + /* extend the new line; inverse-transform edit coords so they are in the + wirenet's coord system */ + x1 = min.x; y1 = min.y; + x2 = max.x; y2 = max.y; + + ctx.wirenet->wirenet_recalc_lock = 1; + ctx.wirenet->wirenet_split_lock = 1; + + csch_cgrp_vinverse_xform(ctx.wirenet, &x1, &y1, &x2, &y2, NULL); + csch_line_modify(sheet, line, &x1, &y1, &x2, &y2, 1, 0, 0); + + /* remove rest of the lines */ + for(n = 0; n < ctx.lines.used; n++) { + csch_op_remove(sheet, ctx.lines.array[n]); + /* no need to move connections: the new, extended line got all connections in csch_line_modify() above */ + } + + ctx.wirenet->wirenet_recalc_lock = 0; + ctx.wirenet->wirenet_split_lock = 0; + csch_wirenet_recalc_junctions(sheet, ctx.wirenet); + +/* rnd_trace("final: %d;%d %d;%d\n", min.x, min.y, max.x, max.y);*/ + } + + quit:; + vtp0_uninit(&ctx.lines); +} + +/* append group to list if not already on list; O(n^2) because we expect + very few groups */ +static void grp_append(vtp0_t *list, csch_cgrp_t *grp) +{ + long n; + for(n = 0; n < list->used; n++) + if (list->array[n] == grp) + return; + vtp0_append(list, grp); +} + +typedef struct { + g2d_cline_t cline; + vtp0_t *list; + csch_cgrp_t *exclude_parent; +} find_wire_end_t; + +static csch_rtree_dir_t find_wire_end_cb(void *ctx_, void *obj_, const csch_rtree_box_t *box) +{ + find_wire_end_t *ctx = ctx_; + csch_line_t *lin = obj_; + + if ((ctx->exclude_parent != NULL) && (lin->hdr.parent == ctx->exclude_parent)) + return csch_RTREE_DIR_NOT_FOUND_CONT; + + if (lin->hdr.type == CSCH_CTYPE_LINE) + if ((g2d_dist2_cline_pt(&ctx->cline, lin->inst.c.p1) < 2) || (g2d_dist2_cline_pt(&ctx->cline, lin->inst.c.p2) < 2)) + grp_append(ctx->list, lin->hdr.parent); + + return csch_RTREE_DIR_NOT_FOUND_CONT; +} + +/* append wirenet lines that end on target line */ +static void find_wire_ends_on_line(csch_sheet_t *sheet, vtp0_t *list, csch_coord_t x1, csch_coord_t y1, csch_coord_t x2, csch_coord_t y2, csch_cgrp_t *exclude_wn) +{ + + csch_rtree_box_t b; + find_wire_end_t ctx; + + ctx.list = list; + ctx.cline.p1.x = x1; ctx.cline.p1.y = y1; + ctx.cline.p2.x = x2; ctx.cline.p2.y = y2; + ctx.exclude_parent = exclude_wn; + + b.x1 = G2D_MIN(x1, x2); b.y1 = G2D_MIN(y1, y2); + b.x2 = G2D_MAX(x1, x2); b.y2 = G2D_MAX(y1, y2); + + csch_rtree_search_obj(&sheet->dsply[CSCH_DSPLY_WIRE], &b, find_wire_end_cb, &ctx); +} + +typedef enum { /* bitfield */ + MERGE_WARN_SILENT = 1, + MERGE_WARN_NON_FATAL = 2 +} merge_warn_t; + +/* A new wire line is about to be drawn (or transformed) to x1;y1 -> x2;y2. + Search all wirenets that it connects and merge them returning: + -1 on error + 0 if no merge took place (wire goes into a new wirenet group) + +1 if merges took place + If return is 1, parent_out is loaded with wirenet group the new line should + be part of. +*/ +int csch_wirenet_newline_merge_parent(csch_sheet_t *sheet, csch_coord_t x1, csch_coord_t y1, csch_coord_t x2, csch_coord_t y2, csch_cgrp_t **parent_out, merge_warn_t warn, csch_chdr_t *ignore) +{ + csch_line_t *w1, *w2; + csch_cgrp_t *parent = NULL; + int res = -1; + vtp0_t adj_grp = {0}; /* of (csch_cgrp_t *) */ + long n; + + /* pick up wires at the end of the new line */ + w1 = find_wire(sheet, x1, y1, ignore); + w2 = find_wire(sheet, x2, y2, ignore); + if (w1 != NULL) grp_append(&adj_grp, w1->hdr.parent); + if (w2 != NULL) grp_append(&adj_grp, w2->hdr.parent); + find_wire_ends_on_line(sheet, &adj_grp, x1, y1, x2, y2, NULL); + +/* rnd_trace("wirenet merging: found %d adjacent groups\n", adj_grp.used);*/ + + if (adj_grp.used > 1) { + csch_cgrp_t *g0; + const char *netname = NULL; + + /* make sure no mistmatching net names are merged */ + g0 = adj_grp.array[0]; + for(n = 0; n < adj_grp.used; n++) { + csch_cgrp_t *g = adj_grp.array[n]; + const char *nn; + + if (g == NULL) + continue; + nn = csch_attrib_get_str(&g->attr, "name"); + if (nn == NULL) + continue; + if (netname == NULL) { + netname = nn; + g0 = g; + continue; + } + if ((strcmp(netname, nn) != 0)) { + if ((warn & MERGE_WARN_SILENT) == 0) { + if ((warn & MERGE_WARN_NON_FATAL) == 0) + rnd_message(RND_MSG_ERROR, "Can't connect (merge) wirenets with different name: '%s' vs. '%s'\n", netname, nn); + else + rnd_message(RND_MSG_ERROR, "Merged wirenets with different name: '%s' vs. '%s'\n", netname, nn); + } + if ((warn & MERGE_WARN_NON_FATAL) == 0) + goto error; + } + } + +/* rnd_trace(" merge wirenets\n");*/ + parent = g0; + parent->role = 0; /* disable side effects during the merge */ + for(n = 0; n < adj_grp.used; n++) { + csch_cgrp_t *g = adj_grp.array[n]; + if ((g != NULL) && (g != g0)) { + g->role = 0; + csch_op_merge_into(sheet, parent, g); + g->role = CSCH_ROLE_WIRE_NET; + } + } + parent->role = CSCH_ROLE_WIRE_NET; + res = 1; + } + else if (adj_grp.used == 1) { +/* rnd_trace(" append to one existing wirenet\n"); */ + parent = adj_grp.array[0]; /* append to the existing group */ + res = 1; + } + else { +/* rnd_trace(" new wirenet\n"); */ + res = 0; + } + + if (parent == NULL) + goto error; + + for(n = 0; n < adj_grp.used; n++) { + csch_cgrp_t *g = adj_grp.array[n]; + remove_grp_if_empty(sheet, g); + } + + error:; + if (parent_out != NULL) + *parent_out = parent; + + vtp0_uninit(&adj_grp); + + return res; +} + +/* Get every dyntext re-rendered; useful after a forced netname change */ +static void csch_wirenet_invalidate_dyntext(csch_sheet_t *sheet, csch_cgrp_t *grp) +{ + htip_entry_t *e; + + for(e = htip_first(&grp->id2obj); e != NULL; e = htip_next(&grp->id2obj, e)) { + csch_text_t *text = e->value; + if ((text->hdr.type == CSCH_CTYPE_TEXT) && (text->dyntext)) { + csch_text_dyntext_inval(text); + csch_text_invalidate_font(text); + } + } +} + +/* check every line of an already placed group to see if any wirenet-wirenet + connection is made and merge the groups if so */ +static void csch_wirenet_recalc_merges(csch_sheet_t *sheet, csch_cgrp_t *grp) +{ + htip_entry_t *e; + vtp0_t adj_grp = {0}; /* of (csch_cgrp_t *) */ + long n; + + assert(grp->role == CSCH_ROLE_WIRE_NET); + + for(e = htip_first(&grp->id2obj); e != NULL; e = htip_next(&grp->id2obj, e)) { + csch_line_t *lin = e->value, *w1, *w2; + + if (lin->hdr.type != CSCH_CTYPE_LINE) continue; + + w1 = find_wire(sheet, lin->inst.c.p1.x, lin->inst.c.p1.y, &lin->hdr); + w2 = find_wire(sheet, lin->inst.c.p2.x, lin->inst.c.p2.y, &lin->hdr); + if ((w1 != NULL) && (w1->hdr.parent != grp)) grp_append(&adj_grp, w1->hdr.parent); + if ((w2 != NULL) && (w2->hdr.parent != grp)) grp_append(&adj_grp, w2->hdr.parent); + find_wire_ends_on_line(sheet, &adj_grp, lin->inst.c.p1.x, lin->inst.c.p1.y, lin->inst.c.p2.x, lin->inst.c.p2.y, grp); + } + + rnd_trace("-- grp merges for wirenet #%ld:\n", grp->hdr.oid); + if (adj_grp.used > 0) { + const char *old_name = csch_attrib_get_str(&grp->attr, "name"); + const char *new_name = NULL, *final_name = old_name; + int num_names = (old_name == NULL) ? 0 : 1; + vtp0_t newos = {0}; + + /* figure number of names and new name, if needed */ + for(n = 0; n < adj_grp.used; n++) { + csch_cgrp_t *agrp = adj_grp.array[n]; + const char *name = csch_attrib_get_str(&agrp->attr, "name"); + if (name == NULL) + continue; + if (final_name == NULL) + new_name = final_name = name; + num_names++; + if ((num_names > 1) && (strcmp(name, final_name) != 0)) + rnd_message(RND_MSG_ERROR, "Have to replace netname '%s' with '%s' due to network merge\n", name, final_name); + } + + grp->role = 0; /* disable side effects during the merge */ + for(n = 0; n < adj_grp.used; n++) { + csch_cgrp_t *agrp = adj_grp.array[n]; + rnd_trace(" #%ld\n", agrp->hdr.oid); + agrp->role = 0; + csch_op_merge_into_remember(sheet, grp, agrp, &newos); + agrp->role = CSCH_ROLE_WIRE_NET; + if (agrp->hdr.parent != NULL) + csch_op_remove(sheet, &agrp->hdr); + } + grp->role = CSCH_ROLE_WIRE_NET; + + /* revisit each object merged from adj grp, there may be overlapping lines, + those didn't get merged because we disabled side effects */ + for(n = 0; n < newos.used; n++) { + csch_chdr_t *line = newos.array[n]; + if (line->type == CSCH_CTYPE_LINE) + csch_wirenet_recalc_merge(sheet, (csch_line_t *)line, 0); + } + vtp0_uninit(&newos); + + + if (new_name != NULL) { + csch_source_arg_t *src = csch_attrib_src_c(NULL, 0, 0, "graphical network merge"); + csch_attrib_set(&grp->attr, 0, "name", new_name, src, NULL); + csch_wirenet_invalidate_dyntext(sheet, grp); + } + + csch_wirenet_recalc_junctions(sheet, grp); + csch_wirenet_recalc_wirenet_conn(sheet, grp); + } + + vtp0_uninit(&adj_grp); +} + + +typedef struct { + csch_line_t *res; + g2d_vect_t p1, p2; +} find_existing_t; + +static csch_rtree_dir_t find_existing_cb(void *ctx_, void *obj_, const csch_rtree_box_t *box) +{ + find_existing_t *ctx = (find_existing_t *)ctx_; + csch_line_t *line = obj_; + + /* accept lines that are in a wirenet */ + if ((line->hdr.type == CSCH_CTYPE_LINE) && (line->hdr.parent != NULL) && (line->hdr.parent->role == CSCH_ROLE_WIRE_NET)) { + /* accept only if both endpoints of the new line is on the existing line */ + if ((g2d_dist2_cline_pt(&line->inst.c, ctx->p1) < 4) && (g2d_dist2_cline_pt(&line->inst.c, ctx->p2) < 4)) { + ctx->res = line; + return csch_RTREE_DIR_FOUND_STOP; + } + } + return csch_RTREE_DIR_NOT_FOUND_CONT; +} + +static csch_line_t *csch_wirenet_find_existing(csch_sheet_t *sheet, csch_coord_t x1, csch_coord_t y1, csch_coord_t x2, csch_coord_t y2) +{ + find_existing_t ctx; + csch_rtree_box_t query; + + ctx.res = NULL; + ctx.p1.x = x1; ctx.p1.y = y1; + ctx.p2.x = x2; ctx.p2.y = y2; + + query.x1 = RND_MIN(x1, x2)-2; query.y1 = RND_MIN(y1, y2)-2; + query.x2 = RND_MAX(x1, x2)+2; query.y2 = RND_MAX(y1, y2)+2; + csch_rtree_search_obj(&sheet->dsply[CSCH_DSPLY_WIRE], &query, find_existing_cb, &ctx); + + return ctx.res; +} + +csch_line_t *csch_wirenet_draw_line_in(csch_sheet_t *sheet, csch_cgrp_t *parent, csch_comm_str_t stroke_name, csch_coord_t x1, csch_coord_t y1, csch_coord_t x2, csch_coord_t y2) +{ + csch_line_t *line; + + /* transform the coords of the new line to undo the parent group's + transformations */ + csch_cgrp_vinverse_xform(parent, &x1, &y1, NULL); + csch_cgrp_vinverse_xform(parent, &x2, &y2, NULL); + + line = (csch_line_t *)csch_op_create(sheet, parent, CSCH_CTYPE_LINE); + line->spec.p1.x = x1; line->spec.p1.y = y1; + line->spec.p2.x = x2; line->spec.p2.y = y2; + line->hdr.stroke_name = stroke_name; + csch_line_update(sheet, line, 1); + csch_cgrp_bbox_update(sheet, parent); + + return line; +} + +csch_chdr_t *csch_wirenet_draw(csch_sheet_t *sheet, csch_comm_str_t stroke_name, csch_coord_t x1, csch_coord_t y1, csch_coord_t x2, csch_coord_t y2) +{ + csch_line_t *line; + csch_cgrp_t *parent; + int merge_res; + + uundo_freeze_serial(&sheet->undo); + + /* do not draw a wire that's already drawn: full or partial overlap with + existing line without extending it */ + line = csch_wirenet_find_existing(sheet, x1, y1, x2, y2); + if (line != NULL) { + uundo_unfreeze_serial(&sheet->undo); + rnd_message(RND_MSG_WARNING, "not drawing new wire that fully overlaps with existing wire\n"); + return NULL; + } + + merge_res = csch_wirenet_newline_merge_parent(sheet, x1, y1, x2, y2, &parent, 0, NULL); + if (merge_res < 0) { + uundo_unfreeze_serial(&sheet->undo); + uundo_inc_serial(&sheet->undo); + return NULL; + } + + if (parent == NULL) + parent = csch_wirenet_new(sheet); + + if (parent == NULL) + return NULL; + + line = csch_wirenet_draw_line_in(sheet, parent, stroke_name, x1, y1, x2, y2); + + if (merge_res > 0) { + int lock_save = parent->wirenet_split_lock; + + /* no split possible by drawing a new line; without disabling it, line ptr + can change and that will break the calls below. Example: + work/bug_files/merge* @ r6498 where recalc_merge() fails because line + already has parent==NULL because recalc_junction() temporarily broke + up the net */ + parent->wirenet_split_lock = 1; + csch_wirenet_recalc_junctions(sheet, parent); + parent->wirenet_split_lock = lock_save; + } + + csch_wirenet_recalc_obj_conn(sheet, &line->hdr); + csch_wirenet_recalc_merge(sheet, line, 0); /* must be the last */ + + uundo_unfreeze_serial(&sheet->undo); + uundo_inc_serial(&sheet->undo); + + return &line->hdr; +} + +typedef struct { + htPo_t jl; /* junction list */ + htpi_t obj2seg; /* assigns an unique segment ID to each object */ + int seg_next; /* next segment ID to use */ + + unsigned has_segmap:1; +} crmap_t; + +RND_INLINE void map_seg_obj(crmap_t *map, csch_chdr_t *obj) +{ + csch_line_t *l = (csch_line_t *)obj; + + if (obj->type != CSCH_CTYPE_LINE) { + if (obj->type == CSCH_CTYPE_TEXT) { + /* normal case: typically a netname floater */ + } + else + rnd_message(RND_MSG_ERROR, "Internal error: non-line objects as wirenet seg is not yet supported\n"); + return; + } + + htpi_set(&map->obj2seg, l, map->seg_next); + map->seg_next++; +} + +RND_INLINE void map_seg_cr(crmap_t *map, csch_line_t *lo, csch_line_t *lp, int segmap_lp_junction, int lp_is_junc) +{ + int id_lo, id_lp; + + id_lo = htpi_get(&map->obj2seg, lo); + id_lp = htpi_get(&map->obj2seg, lp); + + if ((id_lo == 0) && (id_lp == 0)) { + /* neither object of the pair has a segment ID yet */ + htpi_set(&map->obj2seg, lo, map->seg_next); + if (segmap_lp_junction || !lp_is_junc) + htpi_set(&map->obj2seg, lp, map->seg_next); + map->seg_next++; + } + else if ((id_lo != 0) && (id_lp != 0)) { + /* both have segment IDs but they are different; renumber lp's to match lo's */ + htpi_entry_t *e; + for(e = htpi_first(&map->obj2seg); e != NULL; e = htpi_next(&map->obj2seg, e)) { + if (e->value == id_lp) + e->value = id_lo; + } + } + else if (id_lo != 0) { + if (segmap_lp_junction || !lp_is_junc) + htpi_set(&map->obj2seg, lp, id_lo); + } + else if (id_lp != 0) + htpi_set(&map->obj2seg, lo, id_lp); +} + + +static void map_wirenet_crossings(crmap_t *map, csch_sheet_t *sheet, csch_cgrp_t *wirenet, int enable_segmap, int segmap_junctions, int map_misc) +{ + htip_entry_t *e; + htPo_key_t jk; + htPo_value_t jv; + + htPo_init(&map->jl, htPo_keyhash, htPo_keyeq); + if (enable_segmap) { + map->seg_next = 1; + htpi_init(&map->obj2seg, ptrhash, ptrkeyeq); + map->has_segmap = 1; + } + else + map->has_segmap = 0; + + if (csch_wirenet_dbg_junct) rnd_trace("^^^ map_wirenet_crossings\n"); + for(e = htip_first(&wirenet->id2obj); e != NULL; e = htip_next(&wirenet->id2obj, e)) { + csch_chdr_t *obj = e->value; + int junc = csch_obj_is_junction(obj); + + if (csch_wirenet_dbg_junct) rnd_trace(" obj ID=#%ld junc=%d", obj->oid, junc); + if (obj->type == CSCH_CTYPE_LINE) { + csch_line_t *lin = e->value; + if (csch_wirenet_dbg_junct) rnd_trace(" {%ld %ld %ld %ld}", lin->inst.c.p1.x, lin->inst.c.p1.y, lin->inst.c.p2.x, lin->inst.c.p2.y); + } + if (csch_wirenet_dbg_junct) rnd_trace("\n"); + + if (junc) { /* verify if an existing junction is still valid */ + jk.x = (obj->bbox.x1 + obj->bbox.x2)/2; + jk.y = (obj->bbox.y1 + obj->bbox.y2)/2; + jv = htPo_get(&map->jl, jk); + jv.ptr = obj; + htPo_set(&map->jl, jk, jv); + } + else if (obj->type == CSCH_CTYPE_LINE) { /* look for crossings */ + csch_rtree_it_t it; + csch_chdr_t *pair; + for(pair = csch_rtree_first(&it, &obj->sheet->dsply[CSCH_DSPLY_WIRE], &obj->bbox); pair != NULL; pair = csch_rtree_next(&it)) { + csch_line_t *lo = (csch_line_t *)obj, *lp = (csch_line_t *)pair; + g2d_vect_t ip[2] = {0}; + g2d_offs_t offs[2] = {-5, -5}; + int n, len; + int lp_is_junc; + + if ((pair == obj) || (pair->type != CSCH_CTYPE_LINE) || (pair->parent != wirenet)) continue; + len = g2d_iscp_cline_cline(&lo->inst.c, &lp->inst.c, ip, offs); /* all junction coords are in sheet coord system because of bboxes */ + lp_is_junc = csch_obj_is_junction(&lp->hdr); + if (csch_wirenet_dbg_junct) rnd_trace(" junc isc len=%d\n", len); + for(n = 0; n < len; n++) { + jk.x = ip[n].x; + jk.y = ip[n].y; + jv = htPo_get(&map->jl, jk); + if (!lp_is_junc) + jv.i++; + if ((offs[n] > 0) && (offs[n] < 1) && !lp_is_junc && (line_dir(lo) != line_dir(lp))) + jv.i++; /* mid-point crossing should have a junction even for only 2 participants */ + if (jv.wire == NULL) + jv.wire = lo; + if (csch_wirenet_dbg_junct) rnd_trace(" [%d] junc find: %ld %ld i=%d\n", n, jk.x,jk.y, jv.i); + htPo_set(&map->jl, jk, jv); + if (enable_segmap) + map_seg_cr(map, lo, lp, segmap_junctions, lp_is_junc); + } + } + } + else if (map_misc) + htpi_set(&map->obj2seg, obj, -1); + + if (enable_segmap) { + if (segmap_junctions || !junc) { + /* start a new segment for lo if it didn't cross anything */ + if (htpi_get(&map->obj2seg, obj) == 0) + map_seg_obj(map, obj); + } + } + } +} + +static void map_uninit(crmap_t *map) +{ + htPo_uninit(&map->jl); + if (map->has_segmap) + htpi_uninit(&map->obj2seg); +} + +/* There may be non-line objects, typically floaters, placed around + the net, not participating in the connectivity; they are in + seg -1 after the mapping. Put each in the seg they are closest to */ +static void map_misc_to_closest(crmap_t *map) +{ + htpi_entry_t *e, *e2; + for(e = htpi_first(&map->obj2seg); e != NULL; e = htpi_next(&map->obj2seg, e)) { + int oseg = e->value; + csch_chdr_t *obj = e->key; + double best_score = -1, d2; + g2d_vect_t org; + + if (oseg >= 0) + continue; + + switch(obj->type) { + case CSCH_CTYPE_TEXT: + org.x = ((csch_text_t *)obj)->inst1.x; + org.y = ((csch_text_t *)obj)->inst1.y; + break; + default: + org.x = (obj->bbox.x1 + obj->bbox.x2)/2; + org.y = (obj->bbox.y1 + obj->bbox.y2)/2; + } + + for(e2 = htpi_first(&map->obj2seg); e2 != NULL; e2 = htpi_next(&map->obj2seg, e2)) { + int seg = e2->value; + csch_line_t *cand = e2->key; + + if (seg < 0) continue; + if (cand->hdr.type != CSCH_CTYPE_LINE) continue; + + d2 = g2d_dist2_cline_pt(&cand->inst.c, org); + + if ((best_score < 0) || (d2 < best_score)) { + best_score = d2; + e->value = seg; + } + } + } +} + +/* Returns 1 if the map actually using multiple segments */ +static int map_is_multiseg(crmap_t *map) +{ + htpi_entry_t *e; + int first_seg = -1; + + for(e = htpi_first(&map->obj2seg); e != NULL; e = htpi_next(&map->obj2seg, e)) { + int seg = e->value; + if (seg < 0) + continue; + if (first_seg >= 0) { + if (seg != first_seg) + return 1; + } + else + first_seg = seg; + } + + return 0; +} + +void csch_wirenet_recalc_junctions(csch_sheet_t *sheet, csch_cgrp_t *wirenet) +{ + crmap_t map; + htPo_entry_t *je; + + if (sheet->util_wirenet.recalc_inhibit) { + htpi_set(&sheet->util_wirenet.recalc_wn, wirenet, 1); + return; + } + + if (wirenet->wirenet_recalc_lock) + return; + + wirenet->wirenet_recalc_lock = 1; + + map_wirenet_crossings(&map, sheet, wirenet, 1, 1, 1); + + if (csch_wirenet_dbg_junct) rnd_trace("^^^ junctions wirenet=#%ld:\n", wirenet->hdr.oid); + for(je = htPo_first(&map.jl); je != NULL; je = htPo_next(&map.jl, je)) { + if (csch_wirenet_dbg_junct) rnd_trace(" %ld;%ld [%d] %p\n", je->key.x, je->key.y, je->value.i, je->value.ptr); + if ((je->value.i > 2) && (je->value.ptr == NULL)) { + int wseg; + csch_coord_t x1, y1, x2, y2; + csch_chdr_t *wire; + csch_line_t *line = (csch_line_t *)csch_op_create(sheet, wirenet, CSCH_CTYPE_LINE); + if (csch_wirenet_dbg_junct) rnd_trace(" create at %ld %ld\n", je->key.x, je->key.y); + + /* all junction coords are in sheet coord system because of bboxes */ + x1 = x2 = je->key.x; + y1 = y2 = je->key.y; + csch_cgrp_vinverse_xform(wirenet, &x1, &y1, &x2, &y2, NULL); + line->spec.p1.x = line->spec.p2.x = x1; + line->spec.p1.y = line->spec.p2.y = y1; + + /* create the junction */ + line->hdr.stroke_name = sheet->junction_pen_name; + csch_line_update(sheet, line, 1); + csch_cgrp_bbox_update(sheet, wirenet); + + /* copy a random participant wire's segment as the new junction's segment */ + wire = je->value.wire; + wseg = htpi_get(&map.obj2seg, wire); + if (wseg != 0) + htpi_set(&map.obj2seg, line, wseg); + else + rnd_message(RND_MSG_ERROR, "Internal error: new junction has no segment"); + } + else if ((je->value.i < 3) && (je->value.ptr != NULL)) { + if (csch_wirenet_dbg_junct) rnd_trace(" remove at %ld %ld\n", je->key.x, je->key.y); + csch_op_remove(sheet, je->value.ptr); + } + } + + if (csch_wirenet_dbg_junct) rnd_trace("SegS: %d\n", map.seg_next); + + if (map_is_multiseg(&map)) { + /* pick up floaters */ + map_misc_to_closest(&map); + + /* if we have more than one segments, that means the wirenet broke up; + create new wirenets for each segment and move objects into them */ + if (!wirenet->wirenet_split_lock && (map.seg_next > 2)) { + htpi_entry_t *e; + csch_cgrp_t **new_seg = calloc(sizeof(csch_cgrp_t), map.seg_next); + + /* seg 0 is not used by the mapper; seg 1 is the segment we keep as original; from 2 up are the new segments (allocated on request) */ + for(e = htpi_first(&map.obj2seg); e != NULL; e = htpi_next(&map.obj2seg, e)) { + int seg = e->value; + csch_chdr_t *obj = e->key; + if ((seg > 1) && (!csch_obj_is_deleted(obj))) { + if (csch_wirenet_dbg_junct) rnd_trace(" obj move #%ld/%p -> %d\n", obj->oid, obj, seg); + if (new_seg[seg] == NULL) { + new_seg[seg] = csch_wirenet_new_from(sheet, wirenet); + new_seg[seg]->hdr.selected = wirenet->hdr.selected; + } + csch_op_move_into(sheet, new_seg[seg], obj, 0, 0); + } + } + free(new_seg); + } + + remove_grp_if_empty(sheet, wirenet); + } + + map_uninit(&map); + + wirenet->wirenet_recalc_lock = 0; +} + +/* Recalculate junctions of a wirenet and remove the wirenet if it became empty */ +RND_INLINE void wirenet_remove_or_recalc(csch_sheet_t *sheet, csch_cgrp_t *wirenet) +{ + csch_wirenet_recalc_junctions(sheet, wirenet); + + if (!csch_obj_is_deleted(&wirenet->hdr)) + if (htip_first(&wirenet->id2obj) == NULL) /* empty */ + csch_op_remove(sheet, &wirenet->hdr); +} + +/* figure if wirenet is a single segment and matches line's segment; keep + the original wirenet with the original line and create new wirenet for + each different segment */ +static void csch_wirenet_newseg2wirenets(csch_sheet_t *sheet, crmap_t *map, csch_line_t *line, vtp0_t *new_wirenets) +{ + int my_seg; + htpi_entry_t *e; + csch_cgrp_t **wn, *wn_; + + my_seg = htpi_get(&map->obj2seg, line); +/* rnd_trace("my_seg=%d\n", my_seg);*/ + for(e = htpi_first(&map->obj2seg); e != NULL; e = htpi_next(&map->obj2seg, e)) { + csch_chdr_t *obj = e->key; + int seg = e->value; + +/* rnd_trace(" seg: %d\n", seg);*/ + if (!csch_obj_is_junction(&line->hdr)) { /* real wire lines should not get removed */ + assert(!csch_obj_is_deleted(&line->hdr)); + } + if (seg != my_seg) { + wn = (csch_cgrp_t **)vtp0_get(new_wirenets, seg, 0); + if ((wn == NULL) || (*wn == NULL)) { + wn_ = csch_wirenet_new_from(sheet, line->hdr.parent); + if (line->hdr.parent != NULL) + wn_->hdr.selected = line->hdr.parent->hdr.selected; + vtp0_set(new_wirenets, seg, wn_); + wn = &wn_; + } + (*wn)->wirenet_split_lock = 1; + if (obj->parent != 0) + obj->parent->wirenet_split_lock = 1; + csch_op_move_into(sheet, *wn, obj, 0, 0); + if (obj->parent != 0) + obj->parent->wirenet_split_lock = 0; + (*wn)->wirenet_split_lock = 0; +/* rnd_trace(" moved %d to wn %d\n", obj->oid, (*wn)->hdr.oid);*/ + } + if (!csch_obj_is_junction(&line->hdr)) { /* real wire lines should not get removed */ + assert(!csch_obj_is_deleted(&line->hdr)); + } + } +} + +void csch_wirenet_recalc(csch_sheet_t *sheet, csch_cgrp_t *line_wn) +{ + crmap_t map; + csch_line_t *line; + htip_entry_t *e; + vtp0_t new_wirenets = {0}; + long n; + + map_wirenet_crossings(&map, sheet, line_wn, 1, 0, 1); + + /* pick up floaters */ + map_misc_to_closest(&map); + + /* collect new wirenets; pick one line randomly for the segment that is + kept in the old/existing wirenet */ + e = htip_first(&line_wn->id2obj); + if (e == NULL) + return; + + line = e->value; + csch_wirenet_newseg2wirenets(sheet, &map, line, &new_wirenets); + + for(n = 0; n < new_wirenets.used; n++) { + if ((new_wirenets.array[n] != NULL) && (!csch_obj_is_deleted(new_wirenets.array[n]))) { + /* in case it now touches another wirenet, merge them */ + csch_wirenet_recalc_merges(sheet, new_wirenets.array[n]); + + /* recalc junctions and conns if not merged */ + if (!csch_obj_is_deleted(new_wirenets.array[n])) { + wirenet_remove_or_recalc(sheet, new_wirenets.array[n]); + csch_wirenet_recalc_wirenet_conn(sheet, new_wirenets.array[n]); + } + } + } + + if (!csch_obj_is_deleted(&line_wn->hdr)) + wirenet_remove_or_recalc(sheet, line_wn); + + map_uninit(&map); + vtp0_uninit(&new_wirenets); +} + + +void csch_wirenet_recalc_line_chg(csch_sheet_t *sheet, csch_line_t *line) +{ + crmap_t map; + vtp0_t new_wirenets = {0}; + csch_cgrp_t *line_wn = line->hdr.parent; + long n; + + assert(!csch_obj_is_deleted(&line->hdr)); + + if ((line_wn == NULL) || (line_wn->role != CSCH_ROLE_WIRE_NET)) + return; + + if (sheet->util_wirenet.recalc_inhibit) { + htpi_set(&sheet->util_wirenet.recalc_wn, line_wn, 1); + return; + } + + map_wirenet_crossings(&map, sheet, line_wn, 1, 0, 1); + + /* pick up floaters */ + map_misc_to_closest(&map); + + csch_wirenet_newseg2wirenets(sheet, &map, line, &new_wirenets); + + /* Install conns at new coords before net merge; order matters, because if + the wirenet of the edited line gets merged into another, existing wirenet, + that will inherit the connections we find here; but if connections + are calculated only after the merge in csch_wirenet_newline_merge_parent(), + then "line" is already a deleted object from the old, now deleted wirenet + and the connection is not made on deleted objects. + Test case: tests/manual/cn1 */ + csch_wirenet_recalc_obj_conn(sheet, &line->hdr); + + /* check if the endpoints of the line now connects other wirenets and merge them */ + { + csch_cgrp_t *parent; + int merge_res; + + merge_res = csch_wirenet_newline_merge_parent(sheet, line->inst.c.p1.x, line->inst.c.p1.y, line->inst.c.p2.x, line->inst.c.p2.y, &parent, MERGE_WARN_NON_FATAL, &line->hdr); + if (merge_res > 0) + csch_wirenet_recalc_junctions(sheet, parent); + } + + for(n = 0; n < new_wirenets.used; n++) { + if ((new_wirenets.array[n] != NULL) && (!csch_obj_is_deleted(new_wirenets.array[n]))) { + wirenet_remove_or_recalc(sheet, new_wirenets.array[n]); + csch_wirenet_recalc_wirenet_conn(sheet, new_wirenets.array[n]); + } + } + + if (!csch_obj_is_deleted(&line_wn->hdr)) + wirenet_remove_or_recalc(sheet, line_wn); + + map_uninit(&map); + +} + + +void csch_wirenet_recalc_freeze(csch_sheet_t *sheet) +{ + int last = sheet->util_wirenet.recalc_inhibit; + sheet->util_wirenet.recalc_inhibit++; + if (last > sheet->util_wirenet.recalc_inhibit) + rnd_message(RND_MSG_ERROR, "sheet->util_wirenet.recalc_inhibit overflow; save and exit!\n"); +} + +void csch_wirenet_recalc_unfreeze(csch_sheet_t *sheet) +{ + if (sheet->util_wirenet.recalc_inhibit == 0) { + rnd_message(RND_MSG_ERROR, "sheet->util_wirenet.recalc_inhibit underflow; save and exit!\n"); + return; + } + + sheet->util_wirenet.recalc_inhibit--; + + if (sheet->util_wirenet.recalc_inhibit == 0) { + htpi_entry_t *e; + for(e = htpi_first(&sheet->util_wirenet.recalc_wn); e != NULL; e = htpi_next(&sheet->util_wirenet.recalc_wn, e)) { + csch_cgrp_t *grp = e->key; + if (!csch_obj_is_deleted(&grp->hdr)) + csch_wirenet_recalc(sheet, grp); + } + + for(e = htpi_first(&sheet->util_wirenet.recalc_wn); e != NULL; e = htpi_first(&sheet->util_wirenet.recalc_wn)) { + csch_cgrp_t *grp = e->key; + + csch_wirenet_recalc_merges(sheet, grp); + csch_wirenet_recalc_junctions(sheet, grp); + + htpi_delentry(&sheet->util_wirenet.recalc_wn, e); + } + } +} + + + +int csch_wire_count_junctions(csch_chdr_t *wno, int *mid_cnt_out) +{ + csch_cgrp_t *wn = wno->parent; + csch_line_t *wline = (csch_line_t *)wno; + htip_entry_t *e; + int cnt = 0, mid_cnt = 0; + + assert(wn->role == CSCH_ROLE_WIRE_NET); + assert(wno->type == CSCH_CTYPE_LINE); + + for(e = htip_first(&wn->id2obj); e != NULL; e = htip_next(&wn->id2obj, e)) { + csch_chdr_t *junc = e->value; + g2d_cvect_t jv; + double offs; + + if (!csch_obj_is_junction(junc)) continue; + + jv.x = (double)(junc->bbox.x1 + junc->bbox.x2)/2.0; + jv.y = (double)(junc->bbox.y1 + junc->bbox.y2)/2.0; + offs = g2d__offs_cline_pt(&wline->inst.c, jv); + if ((offs > 0.0) && (offs < 1.0)) + mid_cnt++; + cnt++; + } + + if (mid_cnt_out != NULL) + *mid_cnt_out = mid_cnt; + + return cnt; +} + + + + +typedef struct { + csch_chdr_t *res; + g2d_cline_t path; +} safe_wire_t; + +static csch_rtree_dir_t safe_wire_cb(void *ctx_, void *obj_, const csch_rtree_box_t *box) +{ + safe_wire_t *ctx = (safe_wire_t *)ctx_; + csch_line_t *line = obj_; + + /* accept lines that are in a wirenet */ + if ((line->hdr.type == CSCH_CTYPE_LINE) && (line->hdr.parent != NULL) && (line->hdr.parent->role == CSCH_ROLE_WIRE_NET)) { + g2d_vect_t ip[2]; + g2d_offs_t offs[2]; + int n, len; + + /* check if any intersection is on the line's endpoint */ + len = g2d_iscp_cline_cline(&line->inst.c, &ctx->path, ip, offs); + for(n = 0; n < len; n++) { + if ((offs[n] == 0.0) || (offs[n] == 1.0)) { + if ((ip[n].x == ctx->path.p1.x) && (ip[n].y == ctx->path.p1.y)) continue; /* hitting endpoint on path is okay */ + if ((ip[n].x == ctx->path.p2.x) && (ip[n].y == ctx->path.p2.y)) continue; + + ctx->res = obj_; + return csch_RTREE_DIR_FOUND_STOP; + } + } + } + return csch_RTREE_DIR_NOT_FOUND_CONT; +} + + +int csch_is_wireline_safe(csch_sheet_t *sheet, csch_coord_t x1, csch_coord_t y1, csch_coord_t x2, csch_coord_t y2) +{ + csch_rtree_dir_t res; + safe_wire_t ctx = {0}; + csch_rtree_box_t query; + + ctx.path.p1.x = x1; ctx.path.p1.y = y1; + ctx.path.p2.x = x2; ctx.path.p2.y = y2; + + if (x1 > x2) rnd_swap(csch_coord_t, x1, x2); + if (y1 > y2) rnd_swap(csch_coord_t, y1, y2); + query.x1 = x1-2; query.y1 = y1-2; + query.x2 = x2+2; query.y2 = y2+2; + res = csch_rtree_search_obj(&sheet->dsply[CSCH_DSPLY_WIRE], &query, safe_wire_cb, &ctx); + + return !(res & csch_RTREE_DIR_FOUND); +} + +void csch_wirenet_post_remove_checks(csch_sheet_t *sheet, csch_cgrp_t *wn, int undoable) +{ + htip_entry_t *e, *next; + int has_wires = 0; + + /* check if the wirenet has anything else than floaters and connections */ + for(e = htip_first(&wn->id2obj); e != NULL; e = htip_next(&wn->id2obj, e)) { + csch_chdr_t *obj = e->value; + if (!obj->floater && (obj->type != CSCH_CTYPE_CONN) && !csch_obj_is_junction(obj)) { + has_wires = 1; + break; + } + } + + if (!has_wires) { + /* remove all floaters */ + for(e = htip_first(&wn->id2obj); e != NULL; e = next) { + csch_chdr_t *obj = e->value; + next = htip_next(&wn->id2obj, e); + if (obj->floater) { + if (undoable) + csch_op_remove(sheet, obj); + else + csch_cnc_remove(sheet, obj); + } + } + } +} + Index: tags/1.0.5/src/libcschem/util_wirenet.h =================================================================== --- tags/1.0.5/src/libcschem/util_wirenet.h (nonexistent) +++ tags/1.0.5/src/libcschem/util_wirenet.h (revision 10414) @@ -0,0 +1,94 @@ +#ifndef CSCH_UTIL_WIRENET_H +#define CSCH_UTIL_WIRENET_H + +#include + +/* Create a line object to be part of a wire-net. Undoable. There are three + cases on which wirenet: + - if either end is connected to a wirenet, or both ends connected to the + same wirenet, the line is created within that wirenet group + - if one end is connected to one wirenet and the other end is connected + to another wirenet, the wirenet at x2;y2 is merged into the wirenet at + x1;y1 and the new line is added in the remaining wirenet group + - if neither endpoint lands on an existing wirenet, a new wirenet group + is created. + + Returns the new line object. +*/ +csch_chdr_t *csch_wirenet_draw(csch_sheet_t *sheet, csch_comm_str_t stroke_name, csch_coord_t x1, csch_coord_t y1, csch_coord_t x2, csch_coord_t y2); + +/* Recalculate all junction marks on a wirenet, removing stale ones and + adding new ines where multiple lines are crossing */ +void csch_wirenet_recalc_junctions(csch_sheet_t *sheet, csch_cgrp_t *wirenet); + +/* Recalculate wirenets after a line has changed geometry if the line was + in a wirenet. Potential outcome include: + - wirenet split in two if the bridge object is (re)moved + - two or more wirenets merged + - input line object changes its parent (jumps wirenet) +*/ +void csch_wirenet_recalc_line_chg(csch_sheet_t *sheet, csch_line_t *line); + +/* Return true if object is a wirenet junction */ +RND_INLINE int csch_obj_is_junction(csch_chdr_t *obj); + +void csch_recalc_obj_conn(csch_sheet_t *sheet, csch_chdr_t *wobj, csch_displayer_t target, csch_displayer_t target2); + +/* Inhibit wirenet recalculations and recalculate everything once at the end; + useful during multiple wirenet line manipulation operations bundled */ +void csch_wirenet_recalc_freeze(csch_sheet_t *sheet); +void csch_wirenet_recalc_unfreeze(csch_sheet_t *sheet); + + +void csch_wirenet_recalc_obj_conn(csch_sheet_t *sheet, csch_chdr_t *wobj); + +/* Count number of junctions on a wire object wno. If mid_cnt_out is not NULL, + load it with the number of junctions that are not falling at either + endpoint of wno. */ +int csch_wire_count_junctions(csch_chdr_t *wno, int *mid_cnt_out); + +/* Returns true if line between x1;y1 and x2;y2 is safe to draw: a random + other line won't have its endpoint in the middle of the new line */ +int csch_is_wireline_safe(csch_sheet_t *sheet, csch_coord_t x1, csch_coord_t y1, csch_coord_t x2, csch_coord_t y2); + +/* Called after an object is removed from a wirenet; removes floaters if the + wirenet is empty */ +void csch_wirenet_post_remove_checks(csch_sheet_t *sheet, csch_cgrp_t *wn, int undoable); + + +/*** low level ***/ + +/* Create a new wire line within a wirenet without updating or recalculating + the wirenet */ +csch_line_t *csch_wirenet_draw_line_in(csch_sheet_t *sheet, csch_cgrp_t *parent, csch_comm_str_t stroke_name, csch_coord_t x1, csch_coord_t y1, csch_coord_t x2, csch_coord_t y2); + +/* merges any lines that connect with "line" from within the same wirenet and + has the same direction; if remove_overlap is 0, line is never removed; + if remove_overlap is 1, if line fully overlaps with an existing wire from + one end of that wire, the wire is truncated (and line is removed) */ +void csch_wirenet_recalc_merge(csch_sheet_t *sheet, csch_line_t *line, int remove_overlap); + + +/*** implementation ***/ +RND_INLINE int csch_obj_is_junction(csch_chdr_t *obj) +{ + /* simplest case: zero-length line is implied to be a junction */ + if (obj->type == CSCH_CTYPE_LINE) { + csch_line_t *line = (csch_line_t *)obj; + if ((line->spec.p1.x == line->spec.p2.x) && (line->spec.p1.y == line->spec.p2.y)) + return 1; + } + + /* non-line drawing object, or line with non-zero length: check if parent is a junction grp */ + if (!csch_obj_is_grp(obj)) + obj = &obj->parent->hdr; + + if (csch_obj_is_grp(obj)) { /* more complex junction graphics must go in a role=junction grp */ + csch_cgrp_t *grp = (csch_cgrp_t *)obj; + return (grp->role == CSCH_ROLE_JUNCTION); + } + + return 0; /* anything else is wire */ +} + +#endif Index: tags/1.0.5/src/libcschem/vtcnc.c =================================================================== --- tags/1.0.5/src/libcschem/vtcnc.c (nonexistent) +++ tags/1.0.5/src/libcschem/vtcnc.c (revision 10414) @@ -0,0 +1,3 @@ +#define GVT_DONT_UNDEF +#include "vtcnc.h" +#include Index: tags/1.0.5/src/libcschem/vtcnc.h =================================================================== --- tags/1.0.5/src/libcschem/vtcnc.h (nonexistent) +++ tags/1.0.5/src/libcschem/vtcnc.h (revision 10414) @@ -0,0 +1,20 @@ +#ifndef VTCSCH_CNC_H +#define VTCSCH_CNC_H + +#include +#include +#include "libcschem/common_types.h" + +#define GVT(x) csch_vtcnc_ ## x + +#define GVT_ELEM_TYPE csch_chdr_t* +#define GVT_SIZE_TYPE long +#define GVT_DOUBLING_THRS 4096 +#define GVT_START_SIZE 32 +#define GVT_FUNC +#define GVT_SET_NEW_BYTES_TO 0 +#include +#define GVT_REALLOC(vect, ptr, size) realloc(ptr, size) +#define GVT_FREE(vect, ptr) free(ptr) +#include +#endif Index: tags/1.0.5/src/libcschem/vtcoutline.c =================================================================== --- tags/1.0.5/src/libcschem/vtcoutline.c (nonexistent) +++ tags/1.0.5/src/libcschem/vtcoutline.c (revision 10414) @@ -0,0 +1,4 @@ +#include "libcschem/concrete.h" +#define GVT_DONT_UNDEF +#include "vtcoutline.h" +#include Index: tags/1.0.5/src/libcschem/vtcoutline.h =================================================================== --- tags/1.0.5/src/libcschem/vtcoutline.h (nonexistent) +++ tags/1.0.5/src/libcschem/vtcoutline.h (revision 10414) @@ -0,0 +1,28 @@ +#ifndef VTCSCH_COUTLINE_H +#define VTCSCH_COUTLINE_H + +#include +#include +#include "libcschem/concrete.h" +#include "libcschem/cnc_arc.h" +#include "libcschem/cnc_line.h" + +typedef union csch_coutline_s { /* outline object of a polygon */ + csch_chdr_t hdr; + csch_line_t line; + csch_arc_t arc; +} csch_coutline_t; + +#define GVT(x) csch_vtcoutline_ ## x + +#define GVT_ELEM_TYPE csch_coutline_t +#define GVT_SIZE_TYPE long +#define GVT_DOUBLING_THRS 256 +#define GVT_START_SIZE 16 +#define GVT_FUNC +#define GVT_SET_NEW_BYTES_TO 0 +#include +#define GVT_REALLOC(vect, ptr, size) realloc(ptr, size) +#define GVT_FREE(vect, ptr) free(ptr) +#include +#endif Index: tags/1.0.5/src/libcschem/vtoid.c =================================================================== --- tags/1.0.5/src/libcschem/vtoid.c (nonexistent) +++ tags/1.0.5/src/libcschem/vtoid.c (revision 10414) @@ -0,0 +1,3 @@ +#define GVT_DONT_UNDEF +#include "vtoid.h" +#include Index: tags/1.0.5/src/libcschem/vtoid.h =================================================================== --- tags/1.0.5/src/libcschem/vtoid.h (nonexistent) +++ tags/1.0.5/src/libcschem/vtoid.h (revision 10414) @@ -0,0 +1,20 @@ +#ifndef CSCH_VTOID_H +#define CSCH_VTOID_H + +#include +#include +#include "libcschem/common_types.h" + +#define GVT(x) csch_vtoid_ ## x + +#define GVT_ELEM_TYPE csch_oid_t +#define GVT_SIZE_TYPE long +#define GVT_DOUBLING_THRS 1024 +#define GVT_START_SIZE 4 +#define GVT_FUNC +#define GVT_SET_NEW_BYTES_TO 0 +#include +#define GVT_REALLOC(vect, ptr, size) realloc(ptr, size) +#define GVT_FREE(vect, ptr) free(ptr) +#include +#endif Index: tags/1.0.5/src/libcschem/vtoidpath.c =================================================================== --- tags/1.0.5/src/libcschem/vtoidpath.c (nonexistent) +++ tags/1.0.5/src/libcschem/vtoidpath.c (revision 10414) @@ -0,0 +1,5 @@ +#include +#include "vtoid.h" +#define GVT_DONT_UNDEF +#include "vtoidpath.h" +#include Index: tags/1.0.5/src/libcschem/vtoidpath.h =================================================================== --- tags/1.0.5/src/libcschem/vtoidpath.h (nonexistent) +++ tags/1.0.5/src/libcschem/vtoidpath.h (revision 10414) @@ -0,0 +1,21 @@ +#ifndef CSCH_VTOIDPATH_H +#define CSCH_VTOIDPATH_H + +#include +#include +#include "libcschem/common_types.h" +#include "libcschem/oidpath.h" + +#define GVT(x) csch_vtoidpath_ ## x + +#define GVT_ELEM_TYPE csch_oidpath_t +#define GVT_SIZE_TYPE long +#define GVT_DOUBLING_THRS 1024 +#define GVT_START_SIZE 4 +#define GVT_FUNC +#define GVT_SET_NEW_BYTES_TO 0 +#include +#define GVT_REALLOC(vect, ptr, size) realloc(ptr, size) +#define GVT_FREE(vect, ptr) free(ptr) +#include +#endif Index: tags/1.0.5/src/plugins/Buildin.tmpasm =================================================================== --- tags/1.0.5/src/plugins/Buildin.tmpasm (nonexistent) +++ tags/1.0.5/src/plugins/Buildin.tmpasm (revision 10414) @@ -0,0 +1,20 @@ +# tmpasm script for compiling a plugin_src/ module as a buildin +# Requires variables before the include: +# /local/rnd/mod basename of the module (e.g. autoplace) +# /local/rnd/mod/OBJS full path of all object files +# /local/rnd/mod/OBJS_C99 full path of all object files for non-c89 +# /local/rnd/mod/CONF config file name + +append /local/csch/buildin_pups [@@/local/rnd/mod@=@/local/rnd/mod@/@/local/rnd/mod@.pup@] {\n} + +append /local/csch/MOD_OBJS ?/local/rnd/mod/OBJS +append /local/csch/MOD_OBJS_C99 ?/local/rnd/mod/OBJS_C99 +append /local/csch/MOD_LDFLAGS /local/rnd/mod/LDFLAGS +append /local/csch/MOD_CFLAGS /local/rnd/mod/CFLAGS +append /local/csch/MOD_RULES [@ + +mod_@/local/rnd/mod@: all + +@] + +include /local/csch/tmpasm/common_enabled Index: tags/1.0.5/src/plugins/Common_enabled.tmpasm =================================================================== --- tags/1.0.5/src/plugins/Common_enabled.tmpasm (nonexistent) +++ tags/1.0.5/src/plugins/Common_enabled.tmpasm (revision 10414) @@ -0,0 +1,142 @@ +# explicit rules: .y -> .c +# do not assume old yacc to work to different file names, do the generation +# in a separate directory to allow parallel compilation with -j +switch /local/rnd/mod/YACC + case {^$} end + default + foreach /local/n in /local/rnd/mod/YACC + put /local/bn /local/n + sub {/local/bn} {^.*/} {} + put /local/dn /local/n + sub {/local/dn} {/[^/]*$} {} + + if /local/csch/want_parsgen + then + append /local/rnd/RULES [@ +# yacc for @/local/rnd/mod@ +@/local/n@.c @/local/n@.h: @/local/n@.y + cd @/local/dn@ && bison --defines=@/local/bn@.h --output=@/local/bn@.c --report-file=@/local/bn@.output -d @/local/bn@.y +@] + else + append /local/rnd/RULES [@ +# dummy yacc for @/local/rnd/mod@ +@/local/n@.c @/local/n@.h: + echo "skipping yacc..." +@] + end + end + end +end + +# explicit rules: .l -> .c +# do not assume old lex to work to different file names, do the generation +# in a separate directory to allow parallel compilation with -j +switch /local/rnd/mod/LEX + case {^$} end + default + foreach /local/n in /local/rnd/mod/LEX + if /local/csch/want_parsgen + then + put /local/bn /local/n + sub {/local/bn} {^.*/} {} + put /local/dn /local/n + sub {/local/dn} {/[^/]*$} {} + + append /local/rnd/RULES [@ +# lex for @/local/rnd/mod@ +@/local/n@.c @/local/n@.h: @/local/n@.l + cd @/local/dn@ && flex --outfile=@/local/bn@.c --header-file=@/local/bn@.h @/local/bn@.l +@] + else + append /local/rnd/RULES [@ +# dummy lex for @/local/rnd/mod@ +@/local/n@.c: + echo "skipping flex..." +@] + end + end + end +end + +# explicit rules: .y -> .c (byaccic) +switch /local/rnd/mod/BYACCIC + case {^$} end + default + foreach /local/n in /local/rnd/mod/BYACCIC + put /local/bn /local/n + sub {/local/bn} {^.*/} {} + put /local/dn /local/n + sub {/local/dn} {/[^/]*$} {} + + if /local/csch/want_parsgen_byaccic + then + append /local/rnd/RULES [@ +# byaccic for @/local/rnd/mod@ +@/local/n@.c @/local/n@.h: @/local/n@.y + byaccic -o ../plugins/@/local/rnd/mod@/@/local/bn@.c -H ../plugins/@/local/rnd/mod@/@/local/bn@.h -v ../plugins/@/local/rnd/mod@/@/local/bn@.desc ../plugins/@/local/rnd/mod@/@/local/bn@.y +@] + else + append /local/rnd/RULES [@ +# dummy byaccic for @/local/rnd/mod@ +@/local/n@.c @/local/n@.h: + echo "skipping byaccic..." +@] + end + end + end +end + +# explicit rules: .l -> .c (ureglex) +switch /local/rnd/mod/UREGLEX + case {^$} end + default + foreach /local/n in /local/rnd/mod/UREGLEX + if /local/csch/want_parsgen_byaccic + then + put /local/bn /local/n + sub {/local/bn} {^.*/} {} + put /local/dn /local/n + sub {/local/dn} {/[^/]*$} {} + + append /local/rnd/RULES [@ +# lex for @/local/rnd/mod@ +@/local/n@.c @/local/n@.h: @/local/n@.ul + cd @/local/dn@ && ureglex -C -c @/local/bn@.c -h @/local/bn@.h -l @/local/bn@.ul +@] + else + append /local/rnd/RULES [@ +# dummy ureglex for @/local/rnd/mod@ +@/local/n@.c: + echo "skipping ureglex..." +@] + end + end + end +end + + +put /local/rnd/mod/enabled {1} + +include /local/csch/tmpasm/plugin_conf +include /local/csch/tmpasm/plugin_sphash +include /local/csch/tmpasm/plugin_intconf + +append /local/rnd/CLEANFILES ?/local/rnd/mod/CLEANFILES +append /local/rnd/DISTCLEANFILES ?/local/rnd/mod/DISTCLEANFILES + +put /local/rnd/mod/enabled {} +put /local/rnd/mod/OBJS {} +put /local/rnd/mod/OBJS_C99 {} +put /local/rnd/mod/LDFLAGS {} +put /local/rnd/mod/CFLAGS {} +put /local/rnd/mod/YACC {} +put /local/rnd/mod/LEX {} +put /local/rnd/mod/BYACCIC {} +put /local/rnd/mod/UREGLEX {} +put /local/rnd/mod/SPHASH {} +put /local/rnd/mod/SPHASH_ARGS {} +put /local/rnd/mod/CLEANFILES {} +put /local/rnd/mod/DISTCLEANFILES {} +put /local/rnd/mod {} +put /local/rnd/mod/CONFFILE {} +put /local/rnd/mod/CONFVAR {} Index: tags/1.0.5/src/plugins/Disable.tmpasm =================================================================== --- tags/1.0.5/src/plugins/Disable.tmpasm (nonexistent) +++ tags/1.0.5/src/plugins/Disable.tmpasm (revision 10414) @@ -0,0 +1,24 @@ +# tmpasm script for disable a plugin_src/ module +# Requires variables before the include: +# /local/rnd/mod/OBJS full path of all object files + +# append all objects to the source list used only for dependencies +# NOTE: .o suffixes will be replaced with .c before generating the dep +append /local/pcb/DEPSRCS ?/local/rnd/mod/OBJS +append /local/pcb/DEPSRCS ?/local/rnd/mod/OBJS_C99 + +put /local/rnd/mod/enabled {0} + +include /local/csch/tmpasm/plugin_conf +include /local/csch/tmpasm/plugin_sphash +include /local/csch/tmpasm/plugin_intconf + +put /local/rnd/mod/enabled {} +put /local/rnd/mod/OBJS {} +put /local/rnd/mod/OBJS_C99 {} +put /local/rnd/mod/CONF {} +put /local/rnd/mod/LDFLAGS {} +put /local/rnd/mod/CFLAGS {} +put /local/rnd/mod {} +put /local/rnd/mod/CONFFILE {} +put /local/rnd/mod/CONFVAR {} Index: tags/1.0.5/src/plugins/Plugin.tmpasm =================================================================== --- tags/1.0.5/src/plugins/Plugin.tmpasm (nonexistent) +++ tags/1.0.5/src/plugins/Plugin.tmpasm (revision 10414) @@ -0,0 +1,49 @@ +# tmpasm script for compiling a plugin_src/ module as a plugin +# Requires variables before the include: +# /local/rnd/mod basename of the module (e.g. autoplace) +# /local/rnd/mod/OBJS full path of all object files +# /local/rnd/mod/OBJS_C99 full path of all object files for non-c89 + +# clean up input vars +uniq /local/rnd/mod/OBJS +uniq /local/rnd/mod/OBJS_C99 +uniq /local/rnd/mod/CFLAGS +uniq /local/rnd/mod/LDFLAGS +uniq /local/rnd/mod/LIBS + +# generate .c -> .o rules in /local/comp/output +put /local/comp/OBJS_C89 ?/local/rnd/mod/OBJS +put /local/comp/OBJS_C99 ?/local/rnd/mod/OBJS_C99 +put /local/comp/C89FLAGS [@ $(C89FLAGS) @/local/rnd/mod/CFLAGS@ @] +put /local/comp/C99FLAGS [@ $(CFLAGS) @/local/rnd/mod/CFLAGS@ @] +include /local/csch/tmpasm/comp_var + +append /local/pcb/all [@ $(PLUGIDIR)/@/local/rnd/mod@.so @] + +append /local/rnd/rules/install_ [@ + $(SCCBOX) $(HOW) "$(PLUGDIR)/@/local/rnd/mod@/@/local/rnd/mod@.so" "$(LIBDIR)/plugins/@/local/rnd/mod@.so" + $(SCCBOX) $(HOW) "$(PLUGDIR)/@/local/rnd/mod@/@/local/rnd/mod@.pup" "$(LIBDIR)/plugins/@/local/rnd/mod@.pup"@] + +append /local/rnd/CLEANFILES [@ $(PLUGDIR)/@/local/rnd/mod@/@/local/rnd/mod@.so $(PLUGIDIR)/@/local/rnd/mod@.so $(PLUGIDIR)/@/local/rnd/mod@.pup @/local/rnd/mod/OBJS@ @/local/rnd/mod/OBJS_C99@ @] + +append /local/csch/MOD_RULES [@ + +### Module @/local/rnd/mod@: plugin ### + +$(PLUGDIR)/@/local/rnd/mod@/@/local/rnd/mod@.so: @/local/rnd/mod/OBJS@ @/local/rnd/mod/OBJS_C99@ + $(CC) -shared @cc/rdynamic@ -o $(PLUGDIR)/@/local/rnd/mod@/@/local/rnd/mod@.so @/local/rnd/mod/OBJS@ @/local/rnd/mod/OBJS_C99@ $(LDFLAGS) @/local/rnd/mod/LDFLAGS@ + +mod_@/local/rnd/mod@: $(PLUGIDIR)/@/local/rnd/mod@.so + +$(PLUGIDIR)/@/local/rnd/mod@.so: $(PLUGDIR)/@/local/rnd/mod@/@/local/rnd/mod@.so + $(MKDIR) $(PLUGIDIR) + $(CP) $(PLUGDIR)/@/local/rnd/mod@/@/local/rnd/mod@.so $(PLUGIDIR)/@/local/rnd/mod@.so + $(CP) $(PLUGDIR)/@/local/rnd/mod@/@/local/rnd/mod@.pup $(PLUGIDIR)/@/local/rnd/mod@.pup + +# module .c -> .o rules +@/local/comp/output@ + +### Module @/local/rnd/mod@ end ### +@] + +include /local/csch/tmpasm/common_enabled Index: tags/1.0.5/src/plugins/README =================================================================== --- tags/1.0.5/src/plugins/README (nonexistent) +++ tags/1.0.5/src/plugins/README (revision 10414) @@ -0,0 +1 @@ +core plugins Index: tags/1.0.5/src/plugins/act_draw/Makefile =================================================================== --- tags/1.0.5/src/plugins/act_draw/Makefile (nonexistent) +++ tags/1.0.5/src/plugins/act_draw/Makefile (revision 10414) @@ -0,0 +1,2 @@ +all: + cd ../../sch-rnd && make mod_act_draw Index: tags/1.0.5/src/plugins/act_draw/Plug.tmpasm =================================================================== --- tags/1.0.5/src/plugins/act_draw/Plug.tmpasm (nonexistent) +++ tags/1.0.5/src/plugins/act_draw/Plug.tmpasm (revision 10414) @@ -0,0 +1,10 @@ +put /local/rnd/mod {act_draw} +put /local/rnd/mod/OBJS [@ + $(PLUGDIR)/act_draw/act_draw.o +@] + +switch /local/module/act_draw/controls + case {buildin} include /local/csch/tmpasm/buildin; end; + case {plugin} include /local/csch/tmpasm/plugin; end; + case {disable} include /local/csch/tmpasm/disable; end; +end Index: tags/1.0.5/src/plugins/act_draw/act_draw.c =================================================================== --- tags/1.0.5/src/plugins/act_draw/act_draw.c (nonexistent) +++ tags/1.0.5/src/plugins/act_draw/act_draw.c (revision 10414) @@ -0,0 +1,372 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - drawing actions for scripting + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRAWOPTARG \ + int retptr = 0, noundo = 0, ao = 0; \ + for(;;) { \ + if (((argv[ao+1].type & FGW_STR) == FGW_STR) && (strcmp(argv[ao+1].val.str, "noundo") == 0)) { \ + noundo = 1; \ + ao++; \ + } \ + else if (((argv[ao+1].type & FGW_STR) == FGW_STR) && (strcmp(argv[ao+1].val.str, "retptr") == 0)) { \ + retptr = 1; \ + ao++; \ + } \ + else \ + break; \ + } + +#define RETPTR(ptr) \ + if (retptr) \ + fgw_ptr_reg(&rnd_fgw, res, CSCH_PTR_DOMAIN_COBJ, FGW_PTR | FGW_STRUCT, ptr); \ + else \ + RND_ACT_IRES(0); + + +#define DRAWSCOPE(actname, dst_grp) \ + do { \ + rnd_design_t *hl = rnd_multi_get_current(); \ + csch_sheet_t *sheet = (csch_sheet_t *)hl; \ + const char *scope; \ + ao++; \ + if (((argv[ao].type & FGW_PTR) == FGW_PTR) && ((argv[ao].type & FGW_STRUCT) == FGW_STRUCT)) { \ + it_is_ptr:; \ + if (fgw_ptr_in_domain(&rnd_fgw, &argv[ao], CSCH_PTR_DOMAIN_COBJ)) { \ + dst_grp = argv[ao].val.ptr_void; \ + if (csch_obj_is_grp(&dst_grp->hdr)) \ + break; \ + rnd_message(RND_MSG_ERROR, "Invalid scope argument in action " #actname ": concrete object is not a group\n"); \ + return FGW_ERR_ARG_CONV; \ + } \ + if (fgw_ptr_in_domain(&rnd_fgw, &argv[ao], CSCH_PTR_DOMAIN_SHEET)) { \ + sheet = argv[ao].val.ptr_void; \ + dst_grp = &sheet->direct; \ + break; \ + } \ + rnd_message(RND_MSG_ERROR, "Invalid scope argument in action " #actname ": wrong pointer domain\n"); \ + return FGW_ERR_ARG_CONV; \ + } \ + RND_ACT_CONVARG(ao, FGW_STR, actname, scope = argv[ao].val.str); \ + if ((scope[0] == '0') && (scope[1] == 'x')) { \ + RND_ACT_CONVARG(ao, FGW_PTR, DrawRelease, ;); \ + goto it_is_ptr; \ + } \ + if (strncmp(scope, "object:", 7) == 0) {\ + csch_oidpath_t idp = {0}; \ + if (csch_oidpath_parse(&idp, scope+7) != 0) { \ + rnd_message(RND_MSG_ERROR, "Failed to convert object ID: '%s' in " #actname "\n", scope+7); \ + return FGW_ERR_ARG_CONV; \ + } \ + dst_grp = (csch_cgrp_t *)csch_oidpath_resolve(sheet, &idp); \ + csch_oidpath_free(&idp); \ + if (!csch_obj_is_grp(&dst_grp->hdr)) { \ + rnd_message(RND_MSG_ERROR, "Object is not a group: '%s' in " #actname "\n", scope+7); \ + return FGW_ERR_ARG_CONV; \ + } \ + } \ + else if (strcmp(scope, "sheet") == 0) \ + dst_grp = &sheet->direct; \ + else { \ + rnd_message(RND_MSG_ERROR, "Invalid scope argument in action " #actname ": '%s'\n", scope); \ + return FGW_ERR_ARG_CONV; \ + } \ + } while(0) + +static const char csch_acts_DrawRelease[] = "DrawRelease(objptr)\n"; +static const char csch_acth_DrawRelease[] = "Release the pointer of an object. Call this after Draw*(retptr,...) when the object is no longer needed. Unreleased objects are leaked. Warning: there is NO reference counting; getting the same object twice will get only one registration, then releasing \"one of them\" will release both! NEVER keep pointers across invocations."; +static fgw_error_t csch_act_DrawRelease(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + RND_ACT_CONVARG(1, FGW_PTR, DrawRelease, ;); + + if (!fgw_ptr_in_domain(&rnd_fgw, &argv[1], CSCH_PTR_DOMAIN_COBJ)) { + rnd_message(RND_MSG_ERROR, "Invalid argument in action DrawRelease: pointer is not a concrete object\n"); + return FGW_ERR_ARG_CONV; + } + + fgw_ptr_unreg(&rnd_fgw, &argv[1], CSCH_PTR_DOMAIN_COBJ); + + RND_ACT_IRES(0); + return 0; +} + +static const char csch_acts_DrawLine[] = "DrawLine([noundo], [retptr], scope, x1, y1, x2, y2, [pen])\n"; +static const char csch_acth_DrawLine[] = "Draw a decoration line."; +static fgw_error_t csch_act_DrawLine(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + csch_cgrp_t *dst_grp; + const char *penstr = "sheet-decor"; + csch_coord_t x1, y1, x2, y2; + csch_line_t *line; + + DRAWOPTARG; + DRAWSCOPE(DrawLine, dst_grp); + + RND_ACT_CONVARG(ao+1, FGW_LONG, DrawLine, x1 = argv[ao+1].val.nat_long); + RND_ACT_CONVARG(ao+2, FGW_LONG, DrawLine, y1 = argv[ao+2].val.nat_long); + RND_ACT_CONVARG(ao+3, FGW_LONG, DrawLine, x2 = argv[ao+3].val.nat_long); + RND_ACT_CONVARG(ao+4, FGW_LONG, DrawLine, y2 = argv[ao+4].val.nat_long); + RND_ACT_MAY_CONVARG(ao+5, FGW_STR, DrawLine, penstr = argv[ao+5].val.str); + + if (noundo) + uundo_freeze_add(&dst_grp->hdr.sheet->undo); + + line = (csch_line_t *)csch_op_create(dst_grp->hdr.sheet, dst_grp, CSCH_CTYPE_LINE); + line->spec.p1.x = x1; line->spec.p1.y = y1; + line->spec.p2.x = x2; line->spec.p2.y = y2; + line->hdr.stroke_name = csch_comm_str(dst_grp->hdr.sheet, penstr, 1); + csch_line_update(dst_grp->hdr.sheet, line, 1); + + if (noundo) + uundo_unfreeze_add(&dst_grp->hdr.sheet->undo); + + RETPTR(line); + return 0; +} + +static const char csch_acts_DrawCircle[] = "DrawCircle([noundo], [retptr], scope, cx, cy, r, [pen])\n"; +static const char csch_acth_DrawCircle[] = "Draw a 360 degree arc (full circle)."; +static fgw_error_t csch_act_DrawCircle(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + csch_cgrp_t *dst_grp; + const char *penstr = "sheet-decor"; + csch_coord_t cx, cy, r; + csch_arc_t *arc; + + DRAWOPTARG; + DRAWSCOPE(DrawCircle, dst_grp); + + RND_ACT_CONVARG(ao+1, FGW_LONG, DrawCircle, cx = argv[ao+1].val.nat_long); + RND_ACT_CONVARG(ao+2, FGW_LONG, DrawCircle, cy = argv[ao+2].val.nat_long); + RND_ACT_CONVARG(ao+3, FGW_LONG, DrawCircle, r = argv[ao+3].val.nat_long); + RND_ACT_MAY_CONVARG(ao+4, FGW_STR, DrawCircle, penstr = argv[ao+4].val.str); + + if (noundo) + uundo_freeze_add(&dst_grp->hdr.sheet->undo); + + arc = (csch_arc_t *)csch_op_create(dst_grp->hdr.sheet, dst_grp, CSCH_CTYPE_ARC); + arc->spec.c.x = cx; arc->spec.c.y = cy; + arc->spec.r = r; + arc->spec.start = 0; arc->spec.delta = 2*G2D_PI; + + arc->hdr.stroke_name = csch_comm_str(dst_grp->hdr.sheet, penstr, 1); + csch_arc_update(dst_grp->hdr.sheet, arc, 1); + + if (noundo) + uundo_unfreeze_add(&dst_grp->hdr.sheet->undo); + + RETPTR(arc); + return 0; +} + +static const char csch_acts_DrawArc[] = "DrawArc([noundo], [retptr], scope, cx, cy, r, start_ang, delta_ang, [pen])\n"; +static const char csch_acth_DrawArc[] = "Draw an arc. Angles are in degrees."; +static fgw_error_t csch_act_DrawArc(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + csch_cgrp_t *dst_grp; + const char *penstr = "sheet-decor"; + csch_coord_t cx, cy, r; + double sa, da; + csch_arc_t *arc; + + DRAWOPTARG; + DRAWSCOPE(DrawArc, dst_grp); + + RND_ACT_CONVARG(ao+1, FGW_LONG, DrawArc, cx = argv[ao+1].val.nat_long); + RND_ACT_CONVARG(ao+2, FGW_LONG, DrawArc, cy = argv[ao+2].val.nat_long); + RND_ACT_CONVARG(ao+3, FGW_LONG, DrawArc, r = argv[ao+3].val.nat_long); + RND_ACT_CONVARG(ao+4, FGW_DOUBLE, DrawArc, sa = argv[ao+4].val.nat_double); + RND_ACT_CONVARG(ao+5, FGW_DOUBLE, DrawArc, da = argv[ao+5].val.nat_double); + RND_ACT_MAY_CONVARG(ao+6, FGW_STR, DrawArc, penstr = argv[ao+6].val.str); + + if (noundo) + uundo_freeze_add(&dst_grp->hdr.sheet->undo); + + arc = (csch_arc_t *)csch_op_create(dst_grp->hdr.sheet, dst_grp, CSCH_CTYPE_ARC); + arc->spec.c.x = cx; arc->spec.c.y = cy; + arc->spec.r = r; + arc->spec.start = sa / RND_RAD_TO_DEG; arc->spec.delta = da / RND_RAD_TO_DEG; + + arc->hdr.stroke_name = csch_comm_str(dst_grp->hdr.sheet, penstr, 1); + csch_arc_update(dst_grp->hdr.sheet, arc, 1); + + if (noundo) + uundo_unfreeze_add(&dst_grp->hdr.sheet->undo); + + RETPTR(arc); + return 0; +} + +static const char csch_acts_DrawWire[] = "DrawWire([noundo], [retptr], scope, x1, y1, x2, y2, [pen])\n"; +static const char csch_acth_DrawWire[] = "Draw a wire on the sheet of scope. Draws junctions and makes connections and merges nets as needed."; +static fgw_error_t csch_act_DrawWire(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + csch_cgrp_t *dst_grp; + const char *penstr = "wire"; + csch_coord_t x1, y1, x2, y2; + csch_chdr_t *wire; + + DRAWOPTARG; + DRAWSCOPE(DrawWire, dst_grp); + + RND_ACT_CONVARG(ao+1, FGW_LONG, DrawWire, x1 = argv[ao+1].val.nat_long); + RND_ACT_CONVARG(ao+2, FGW_LONG, DrawWire, y1 = argv[ao+2].val.nat_long); + RND_ACT_CONVARG(ao+3, FGW_LONG, DrawWire, x2 = argv[ao+3].val.nat_long); + RND_ACT_CONVARG(ao+4, FGW_LONG, DrawWire, y2 = argv[ao+4].val.nat_long); + RND_ACT_MAY_CONVARG(ao+5, FGW_STR, DrawWire, penstr = argv[ao+5].val.str); + + if (noundo) + uundo_freeze_add(&dst_grp->hdr.sheet->undo); + + wire = csch_wirenet_draw(dst_grp->hdr.sheet, csch_comm_str(dst_grp->hdr.sheet, penstr, 1), x1, y1, x2, y2); + + if (noundo) + uundo_unfreeze_add(&dst_grp->hdr.sheet->undo); + + RETPTR(wire); + return 0; +} + +static const char csch_acts_DrawText[] = "DrawText([noundo], [retptr], scope, x, y, text, [pen])\n"; +static const char csch_acth_DrawText[] = "Create a non-bbox-specified text object."; +static fgw_error_t csch_act_DrawText(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + csch_cgrp_t *dst_grp; + char *textstr; + const char *penstr = "sheet-decor"; + csch_coord_t x, y; + csch_text_t *text; + + DRAWOPTARG; + DRAWSCOPE(DrawText, dst_grp); + + RND_ACT_CONVARG(ao+1, FGW_LONG, DrawText, x = argv[ao+1].val.nat_long); + RND_ACT_CONVARG(ao+2, FGW_LONG, DrawText, y = argv[ao+2].val.nat_long); + RND_ACT_CONVARG(ao+3, FGW_STR, DrawText, textstr = argv[ao+3].val.str); + RND_ACT_MAY_CONVARG(ao+4, FGW_STR, DrawText, penstr = argv[ao+4].val.str); + + if (noundo) + uundo_freeze_add(&dst_grp->hdr.sheet->undo); + + + text = (csch_text_t *)csch_op_create(dst_grp->hdr.sheet, dst_grp, CSCH_CTYPE_TEXT); + + text->spec1.x = x; + text->spec1.y = y; + text->text = rnd_strdup(textstr); + text->hdr.stroke_name = csch_comm_str(dst_grp->hdr.sheet, penstr, 1); + csch_text_update(dst_grp->hdr.sheet, text, 1); + + if (noundo) + uundo_unfreeze_add(&dst_grp->hdr.sheet->undo); + + RETPTR(text); + return 0; +} + + +static const char csch_acts_DrawGroup[] = "DrawGroup([noundo], [retptr], scope, [key, value], [key, value]...)\n"; +static const char csch_acth_DrawGroup[] = "Create a new concrete group. Optionally create key=value string attributes in the new group."; +static fgw_error_t csch_act_DrawGroup(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + csch_cgrp_t *dst_grp, *new_grp; + int n; + + DRAWOPTARG; + DRAWSCOPE(DrawGroup, dst_grp); + + if (noundo) + uundo_freeze_add(&dst_grp->hdr.sheet->undo); + + new_grp = (csch_cgrp_t *)csch_op_create(dst_grp->hdr.sheet, dst_grp, CSCH_CTYPE_GRP); + for(n = ao+1; n < argc; n+=2) { + const char *key, *val; + csch_source_arg_t *src; + + RND_ACT_CONVARG(n+0, FGW_STR, DrawGroup, key = argv[n+0].val.str); + RND_ACT_CONVARG(n+1, FGW_STR, DrawGroup, val = argv[n+1].val.str); + + src = csch_attrib_src_c(NULL, 0, 0, "DrawGroup"); + csch_attrib_set(&new_grp->attr, CSCH_ATP_USER_DEFAULT, key, val, src, NULL); + } + csch_cgrp_update(dst_grp->hdr.sheet, new_grp, 1); + + if (noundo) + uundo_unfreeze_add(&dst_grp->hdr.sheet->undo); + + RETPTR(new_grp); + return 0; +} + + +rnd_action_t draw_action_list[] = { + {"DrawRelease", csch_act_DrawRelease, csch_acth_DrawRelease, csch_acts_DrawRelease}, + {"DrawLine", csch_act_DrawLine, csch_acth_DrawLine, csch_acts_DrawLine}, + {"DrawCircle", csch_act_DrawCircle, csch_acth_DrawCircle, csch_acts_DrawCircle}, + {"DrawArc", csch_act_DrawArc, csch_acth_DrawArc, csch_acts_DrawArc}, + {"DrawWire", csch_act_DrawWire, csch_acth_DrawWire, csch_acts_DrawWire}, + {"DrawText", csch_act_DrawText, csch_acth_DrawText, csch_acts_DrawText}, + {"DrawGroup", csch_act_DrawGroup, csch_acth_DrawGroup, csch_acts_DrawGroup} +}; + +static const char *draw_cookie = "draw plugin"; + +int pplg_check_ver_act_draw(int ver_needed) { return 0; } + +void pplg_uninit_act_draw(void) +{ + rnd_remove_actions_by_cookie(draw_cookie); +} + +int pplg_init_act_draw(void) +{ + RND_API_CHK_VER; + + RND_REGISTER_ACTIONS(draw_action_list, draw_cookie) + return 0; +} Index: tags/1.0.5/src/plugins/act_draw/act_draw.pup =================================================================== --- tags/1.0.5/src/plugins/act_draw/act_draw.pup (nonexistent) +++ tags/1.0.5/src/plugins/act_draw/act_draw.pup (revision 10414) @@ -0,0 +1,7 @@ +$class feature +$short Draw object actions +$long Actions for drawing objects on a graphical sheet or symbol +$package core +$state works +default buildin +autoload 1 Index: tags/1.0.5/src/plugins/act_read/Makefile =================================================================== --- tags/1.0.5/src/plugins/act_read/Makefile (nonexistent) +++ tags/1.0.5/src/plugins/act_read/Makefile (revision 10414) @@ -0,0 +1,2 @@ +all: + cd ../../sch-rnd && make mod_act_read Index: tags/1.0.5/src/plugins/act_read/Plug.tmpasm =================================================================== --- tags/1.0.5/src/plugins/act_read/Plug.tmpasm (nonexistent) +++ tags/1.0.5/src/plugins/act_read/Plug.tmpasm (revision 10414) @@ -0,0 +1,13 @@ +put /local/rnd/mod {act_read} +put /local/rnd/mod/OBJS [@ + $(PLUGDIR)/act_read/act_read.o + $(PLUGDIR)/act_read/keywords_sphash.o +@] +put /local/rnd/mod/SPHASH {$(PLUGDIR)/act_read/keywords.sphash} + + +switch /local/module/act_read/controls + case {buildin} include /local/csch/tmpasm/buildin; end; + case {plugin} include /local/csch/tmpasm/plugin; end; + case {disable} include /local/csch/tmpasm/disable; end; +end Index: tags/1.0.5/src/plugins/act_read/act_idpath.c =================================================================== --- tags/1.0.5/src/plugins/act_read/act_idpath.c (nonexistent) +++ tags/1.0.5/src/plugins/act_read/act_idpath.c (revision 10414) @@ -0,0 +1,254 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - object access for scripts + * Copyright (C) 2019 Tibor 'Igor2' Palinkas in pcb-rnd + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* includeed from act_read.c */ + +static const char csch_acts_IDPList[] = + "IDPList(alloc)\n" + "IDPList(free|clear|print|dup|length, list)\n" + "IDPList(get|pop|remove, list, idx)\n" + "IDPList(prepend|append|push, list, idpath)" + ; +static const char csch_acth_IDPList[] = "Basic idpath list manipulation."; +static fgw_error_t csch_act_IDPList(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *cmd_; + csch_oidpath_list_t *list; + csch_oidpath_t *idp; + int cmd; + long idx; + + RND_ACT_CONVARG(1, FGW_STR, IDPList, cmd_ = argv[1].val.str); + + cmd = act_read_keywords_sphash(cmd_); + if (cmd == act_read_keywords_alloc) { + list = calloc(sizeof(csch_oidpath_list_t), 1); + fgw_ptr_reg(&rnd_fgw, res, RND_PTR_DOMAIN_IDPATH_LIST, FGW_PTR | FGW_STRUCT, list); + return 0; + } + RND_ACT_CONVARG(2, FGW_IDPATH_LIST, IDPList, list = fgw_idpath_list(&argv[2])); + + if (!fgw_ptr_in_domain(&rnd_fgw, &argv[2], RND_PTR_DOMAIN_IDPATH_LIST)) + return FGW_ERR_PTR_DOMAIN; + + switch(cmd) { + case act_read_keywords_clear: + csch_oidpath_list_clear(list); + RND_ACT_IRES(0); + return 0; + + case act_read_keywords_length: + RND_ACT_IRES(csch_oidpath_list_length(list)); + return 0; + + case act_read_keywords_free: + fgw_ptr_unreg(&rnd_fgw, &argv[2], RND_PTR_DOMAIN_IDPATH_LIST); + csch_oidpath_list_clear(list); + free(list); + RND_ACT_IRES(0); + return 0; + + case act_read_keywords_append: + case act_read_keywords_push: + case act_read_keywords_prepend: + RND_ACT_CONVARG(3, FGW_IDPATH, IDPList, idp = fgw_idpath(&argv[3])); + if (!fgw_ptr_in_domain(&rnd_fgw, &argv[3], RND_PTR_DOMAIN_IDPATH)) + return FGW_ERR_PTR_DOMAIN; + if (cmd == act_read_keywords_append) + csch_oidpath_list_append(list, idp); + else /* prepend or push */ + csch_oidpath_list_insert(list, idp); + RND_ACT_IRES(0); + return 0; + + case act_read_keywords_remove: + RND_ACT_CONVARG(3, FGW_LONG, IDPList, idx = argv[3].val.nat_long); + idp = csch_oidpath_list_nth(list, idx); + if (idp == NULL) { + RND_ACT_IRES(-1); + return 0; + } + csch_oidpath_list_remove(idp); + RND_ACT_IRES(0); + return 0; + + case act_read_keywords_get: + RND_ACT_CONVARG(3, FGW_LONG, IDPList, idx = argv[3].val.nat_long); + idp = csch_oidpath_list_nth(list, idx); + if (idp == NULL) { + res->type = FGW_PTR; + res->val.ptr_struct = NULL; + return 0; + } + fgw_ptr_reg(&rnd_fgw, res, RND_PTR_DOMAIN_IDPATH, FGW_PTR | FGW_STRUCT, idp); + return 0; + + case act_read_keywords_pop: + idp = csch_oidpath_list_first(list); + if (idp == NULL) { + res->type = FGW_PTR; + res->val.ptr_struct = NULL; + return 0; + } + fgw_ptr_reg(&rnd_fgw, res, RND_PTR_DOMAIN_IDPATH, FGW_PTR | FGW_STRUCT, idp); + csch_oidpath_list_remove(idp); + return 0; + + case act_read_keywords_print: + { + gds_t tmp; + int first = 1; + + gds_init(&tmp); + for(idp = csch_oidpath_list_first(list); idp != NULL; idp = csch_oidpath_list_next(idp)) { + if (!first) + gds_append(&tmp, ' '); + csch_oidpath_to_str_append(&tmp, idp); + first = 0; + } + res->type = FGW_STR | FGW_DYN; + res->val.str = tmp.array; + } + return 0; + + } + + return -1; +} + +static const char csch_acts_IDP[] = "IDP([print|free|dup], idpath)\n"; +static const char csch_acth_IDP[] = "Basic idpath manipulation."; +static fgw_error_t csch_act_IDP(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + csch_sheet_t *sheet = CSCH_ACT_SHEET; + const char *cmd; + csch_oidpath_t *idp; + csch_chdr_t *obj; + + RND_ACT_CONVARG(1, FGW_STR, IDP, cmd = argv[1].val.str); + RND_ACT_CONVARG(2, FGW_IDPATH, IDP, idp = fgw_idpath(&argv[2])); + if ((idp == NULL) || !fgw_ptr_in_domain(&rnd_fgw, &argv[2], RND_PTR_DOMAIN_IDPATH)) + return FGW_ERR_PTR_DOMAIN; + + + switch(act_read_keywords_sphash(cmd)) { + case act_read_keywords_free: + csch_oidpath_list_remove(idp); + fgw_ptr_unreg(&rnd_fgw, &argv[2], RND_PTR_DOMAIN_IDPATH); + csch_oidpath_free(idp); + free(idp); + RND_ACT_IRES(0); + return 0; + + case act_read_keywords_dup: + obj = csch_oidpath_resolve(sheet, idp); + idp = calloc(sizeof(csch_oidpath_t), 1); + csch_oidpath_from_obj(idp, obj); + res->type = FGW_IDPATH; + fgw_ptr_reg(&rnd_fgw, res, RND_PTR_DOMAIN_IDPATH, FGW_PTR | FGW_STRUCT, idp); + return 0; + + case act_read_keywords_print: + res->type = FGW_STR | FGW_DYN; + res->val.str = csch_oidpath_to_str(idp); + return 0; + } + + return -1; +} + +static const char csch_acts_GetParentGrp[] = "GetParentGrp([root_data,] idpath)\n"; +static const char csch_acth_GetParentGrp[] = "Return the oidpath of the immediate parent group of an object"; +static fgw_error_t csch_act_GetParentGrp(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + csch_sheet_t *sheet = CSCH_ACT_SHEET; + csch_oidpath_t *idp; + csch_cgrp_t *root_grp = NULL; + int iidx = 1; + csch_chdr_t *obj; + + res->type = FGW_PTR | FGW_STRUCT; + res->val.ptr_void = NULL; + + if (argc > 2) { + RND_ACT_CONVARG(1, FGW_DATA, GetParentGrp, root_grp = fgw_data(&argv[1])); + iidx++; + } + + RND_ACT_CONVARG(iidx, FGW_IDPATH, IDPList, idp = fgw_idpath(&argv[iidx])); + if ((idp == NULL) || !fgw_ptr_in_domain(&rnd_fgw, &argv[iidx], RND_PTR_DOMAIN_IDPATH)) + return FGW_ERR_PTR_DOMAIN; + + if (root_grp != NULL) + obj = csch_oidpath_resolve_in(root_grp, idp); + else + obj = csch_oidpath_resolve(sheet, idp); + + if (obj == NULL) + return 0; + + idp = calloc(sizeof(csch_oidpath_t), 1); + csch_oidpath_from_obj(idp, &obj->parent->hdr); + fgw_ptr_reg(&rnd_fgw, res, RND_PTR_DOMAIN_IDPATH, FGW_PTR | FGW_STRUCT, idp); + return 0; +} + +static const char csch_acts_GetObjType[] = "GetObjType([root_data,] idpath)\n"; +static const char csch_acth_GetObjType[] = "Return the type of the object named in oidpath as a string."; +static fgw_error_t csch_act_GetObjType(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + csch_sheet_t *sheet = CSCH_ACT_SHEET; + csch_oidpath_t *idp; + csch_cgrp_t *root_grp = NULL; + int iidx = 1; + csch_chdr_t *obj; + + res->type = FGW_STR; + res->val.str = NULL; + + if (argc > 2) { + RND_ACT_CONVARG(1, FGW_DATA, GetObjType, root_grp = fgw_data(&argv[1])); + iidx++; + } + + RND_ACT_CONVARG(iidx, FGW_IDPATH, IDPList, idp = fgw_idpath(&argv[iidx])); + if ((idp == NULL) || !fgw_ptr_in_domain(&rnd_fgw, &argv[iidx], RND_PTR_DOMAIN_IDPATH)) + return FGW_ERR_PTR_DOMAIN; + + if (root_grp != NULL) + obj = csch_oidpath_resolve_in(root_grp, idp); + else + obj = csch_oidpath_resolve(sheet, idp); + + if (obj == NULL) + return 0; + + res->val.cstr = csch_ctype_name(obj->type); + return 0; +} Index: tags/1.0.5/src/plugins/act_read/act_read.c =================================================================== --- tags/1.0.5/src/plugins/act_read/act_read.c (nonexistent) +++ tags/1.0.5/src/plugins/act_read/act_read.c (revision 10414) @@ -0,0 +1,98 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - object access for scripts + * Copyright (C) 2019 Tibor 'Igor2' Palinkas in pcb-rnd + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include + +#include +#include +#include + +#include +#include + +#include "keywords_sphash.h" + +#include "act_idpath.c" +#include "act_search.c" +#include "act_rtree.c" + +static const char csch_acts_GetValue[] = "GetValue(input, units, relative, default_unit)"; +static const char csch_acth_GetValue[] = "Convert a coordinate value. Returns an unitless double or FGW_ERR_ARG_CONV. The 3rd parameter controls whether to require relative coordinates (+- prefix). Wraps rnd_get_value_ex()."; +static fgw_error_t csch_act_GetValue(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *input, *units, *def_unit; + int relative, a; + double v; + rnd_bool success; + + RND_ACT_CONVARG(1, FGW_STR, GetValue, input = argv[1].val.str); + RND_ACT_CONVARG(2, FGW_STR, GetValue, units = argv[2].val.str); + RND_ACT_CONVARG(3, FGW_INT, GetValue, relative = argv[3].val.nat_int); + RND_ACT_CONVARG(4, FGW_STR, GetValue, def_unit = argv[1].val.str); + + if (*units == '\0') + units = NULL; + + v = rnd_get_value_ex(input, units, &a, NULL, def_unit, &success); + if (!success || (relative && a)) + return FGW_ERR_ARG_CONV; + + res->type = FGW_DOUBLE; + res->val.nat_double = v; + return 0; +} + +rnd_action_t act_read_action_list[] = { + {"GetValue", csch_act_GetValue, csch_acth_GetValue, csch_acts_GetValue}, + {"IDPList", csch_act_IDPList, csch_acth_IDPList, csch_acts_IDPList}, + {"IDP", csch_act_IDP, csch_acth_IDP, csch_acts_IDP}, + {"GetParentGrp", csch_act_GetParentGrp, csch_acth_GetParentGrp, csch_acts_GetParentGrp}, + {"GetObjType", csch_act_GetObjType, csch_acth_GetObjType, csch_acts_GetObjType}, + {"SearchObjAt", csch_act_SearchObjAt, csch_acth_SearchObjAt, csch_acts_SearchObjAt}, + {"SearchObjAtUnsel", csch_act_SearchObjAt, csch_acth_SearchObjAt, csch_acts_SearchObjAt}, + {"SearchObjAtGuiInspect", csch_act_SearchObjAt, csch_acth_SearchObjAt, csch_acts_SearchObjAt}, + {"SchGetXY", csch_act_SchGetXY, csch_acth_SchGetXY, csch_acts_SchGetXY}, + {"RtreeList", csch_act_RtreeList, csch_acth_RtreeList, csch_acts_RtreeList} +}; + +static const char *act_read_cookie = "act_read"; + +int pplg_check_ver_act_read(int ver_needed) { return 0; } + +void pplg_uninit_act_read(void) +{ + rnd_remove_actions_by_cookie(act_read_cookie); +} + +int pplg_init_act_read(void) +{ + RND_API_CHK_VER; + RND_REGISTER_ACTIONS(act_read_action_list, act_read_cookie) + return 0; +} Index: tags/1.0.5/src/plugins/act_read/act_read.pup =================================================================== --- tags/1.0.5/src/plugins/act_read/act_read.pup (nonexistent) +++ tags/1.0.5/src/plugins/act_read/act_read.pup (revision 10414) @@ -0,0 +1,7 @@ +$class feature +$short action wrappers for data access +$long Data access related API as actions +$state works +$package (core) +default buildin +autoload 1 Index: tags/1.0.5/src/plugins/act_read/act_rtree.c =================================================================== --- tags/1.0.5/src/plugins/act_read/act_rtree.c (nonexistent) +++ tags/1.0.5/src/plugins/act_read/act_rtree.c (revision 10414) @@ -0,0 +1,88 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - object access for scripts + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* includeed from act_read.c */ + +#include +#include +#include +#include + +static const char csch_acts_RtreeList[] = "RtreeList[rtree_name, [x1, y1, x2, y2])\n"; +static const char csch_acth_RtreeList[] = "Return a list of idpaths for objects overlapping with the box specified (empty list if no object is found). Error is indicated by returning nil. If coordinates are not specified the whole tree is searched."; +/* DOC: rtreelist.html */ +static fgw_error_t csch_act_RtreeList(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + csch_sheet_t *sheet = CSCH_ACT_SHEET; + csch_rtree_t *rtree; + const char *rtree_name; + csch_rtree_it_t it; + csch_chdr_t *o; + csch_oidpath_list_t *list; + int has_bbox = 0; + csch_rtree_box_t qbox; + + RND_ACT_CONVARG(1, FGW_STR, RtreeList, rtree_name = argv[1].val.str); + rtree = csch_rtree_lookup_by_name(sheet, rtree_name); + if (rtree == NULL) { + res->type = FGW_VOID | FGW_PTR; + res->val.ptr_void = 0; + return 0; + } + + if (argc == 6) { + RND_ACT_CONVARG(2, FGW_COORD, RtreeList, qbox.x1 = fgw_coord(&argv[2])); + RND_ACT_CONVARG(3, FGW_COORD, RtreeList, qbox.y1 = fgw_coord(&argv[3])); + RND_ACT_CONVARG(4, FGW_COORD, RtreeList, qbox.x2 = fgw_coord(&argv[4])); + RND_ACT_CONVARG(5, FGW_COORD, RtreeList, qbox.y2 = fgw_coord(&argv[5])); + has_bbox = 1; + } + + list = calloc(sizeof(csch_oidpath_list_t), 1); + fgw_ptr_reg(&rnd_fgw, res, RND_PTR_DOMAIN_IDPATH_LIST, FGW_PTR | FGW_STRUCT, list); + + if (has_bbox) { + for(o = csch_rtree_first(&it, rtree, &qbox); o != NULL; o = csch_rtree_next(&it)) { + fgw_arg_t tmp; + csch_oidpath_t *idp = calloc(sizeof(csch_oidpath_t), 1); + csch_oidpath_from_obj(idp, o); + fgw_ptr_reg(&rnd_fgw, &tmp, RND_PTR_DOMAIN_IDPATH, FGW_PTR | FGW_STRUCT, idp); + csch_oidpath_list_append(list, idp); + } + } + else { + for(o = csch_rtree_all_first(&it, rtree); o != NULL; o = csch_rtree_all_next(&it)) { + fgw_arg_t tmp; + csch_oidpath_t *idp = calloc(sizeof(csch_oidpath_t), 1); + csch_oidpath_from_obj(idp, o); + fgw_ptr_reg(&rnd_fgw, &tmp, RND_PTR_DOMAIN_IDPATH, FGW_PTR | FGW_STRUCT, idp); + csch_oidpath_list_append(list, idp); + } + } + + return 0; +} + Index: tags/1.0.5/src/plugins/act_read/act_search.c =================================================================== --- tags/1.0.5/src/plugins/act_read/act_search.c (nonexistent) +++ tags/1.0.5/src/plugins/act_read/act_search.c (revision 10414) @@ -0,0 +1,139 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - object access for scripts + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* includeed from act_read.c */ + +#include +#include +#include +#include + +static const char csch_acts_SearchObjAt[] = + "SearchObjAt[UnSel|GuiInspect](cursor|crosshair, msg, [r])\n" + "SearchObjAt[UnSel|GuiInspect](x, y, [r])\n"; +static const char csch_acth_SearchObjAt[] = "Return the most preferred object at mouse cursor (or crosshair) or x;y coord; search in a raduis of r coords. The unsel variant ignores selected objects. The GuiInspect variant uses the priorities right-click does. Msg is a string displayed when cursor coord is requested but cursor is not active (see GetXY()). Returns nil or an idpath."; +static fgw_error_t csch_act_SearchObjAt(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + csch_sheet_t *sheet = CSCH_ACT_SHEET; + const char *actname = argv[0].val.func->name; + csch_oidpath_t *idp; + csch_chdr_t *obj; + rnd_coord_t x, y, r = sch_rnd_slop; + + if ((argv[1].type & FGW_STR) == FGW_STR) { + const char *where, *msg; + rnd_coord_t rx, ry; + int curs, ch = 0; + + RND_ACT_CONVARG(1, FGW_STR, SearchObjAt, where = argv[1].val.str); + + curs = (rnd_strcasecmp(where, "cursor") == 0); + if (!curs) + ch = (rnd_strcasecmp(where, "crosshair") == 0); + + if (!curs && !ch) + goto coords; + + RND_ACT_CONVARG(2, FGW_STR, SearchObjAt, msg = argv[2].val.str); + rnd_hid_get_coords(msg, &rx, &ry, 0); + if (curs) { + x = P2C(rx); + y = P2C(ry); + } + else { + x = P2C(sch_rnd_crosshair_x); + y = P2C(sch_rnd_crosshair_y); + } + } + else { + coords:; + RND_ACT_CONVARG(1, FGW_COORD, SearchObjAt, x = fgw_coord(&argv[1])); + RND_ACT_CONVARG(2, FGW_COORD, SearchObjAt, y = fgw_coord(&argv[2])); + } + RND_ACT_MAY_CONVARG(3, FGW_COORD, SearchObjAt, r = fgw_coord(&argv[3])); + + switch(actname[11]) { + case '\0': obj = sch_rnd_search_obj_at(sheet, x, y, r); break; + case 'u': + case 'U': obj = sch_rnd_search_obj_at_unsel(sheet, x, y, r); break; + case 'g': + case 'G': obj = sch_rnd_search_first_gui_inspect(sheet, C2P(x), C2P(y)); break; + default: + rnd_message(RND_MSG_ERROR, "Internal error: SearchObjAt() called with the wrong action name\n"); + return FGW_ERR_ARG_CONV; + } + + if (obj == NULL) + return 0; + + idp = calloc(sizeof(csch_oidpath_t), 1); + csch_oidpath_from_obj(idp, obj); + res->type = FGW_IDPATH; + fgw_ptr_reg(&rnd_fgw, res, RND_PTR_DOMAIN_IDPATH, FGW_PTR | FGW_STRUCT, idp); + return 0; +} + +static const char csch_acts_SchGetXY[] = "SchGetXY(cursor|crosshair, msg, X|Y)\n"; +static const char csch_acth_SchGetXY[] = "Return the cursor (or crosshair) x or y coord. Msg is a string displayed when cursor coord is requested but cursor is not active (see GetXY())."; +static fgw_error_t csch_act_SchGetXY(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *where, *msg, *what; + rnd_coord_t rx, ry; + csch_coord_t x, y; + + RND_ACT_CONVARG(1, FGW_STR, SchGetXY, where = argv[1].val.str); + RND_ACT_CONVARG(2, FGW_STR, SchGetXY, msg = argv[2].val.str); + RND_ACT_CONVARG(3, FGW_STR, SchGetXY, what = argv[3].val.str); + + rnd_hid_get_coords(msg, &rx, &ry, 0); + + if (rnd_strcasecmp(where, "cursor") == 0) { + x = P2C(rx); + y = P2C(ry); + } + else if (rnd_strcasecmp(where, "crosshair") == 0) { + x = P2C(sch_rnd_crosshair_x); + y = P2C(sch_rnd_crosshair_y); + } + else { + rnd_message(RND_MSG_ERROR, "SchGetXY(): invalid first argument\n"); + return FGW_ERR_ARG_CONV; + } + + res->type = FGW_LONG; + switch(*what) { + case 'x': case 'X': res->val.nat_long = x; break; + case 'y': case 'Y': res->val.nat_long = y; break; + default: + rnd_message(RND_MSG_ERROR, "SchGetXY(): invalid third argument\n"); + return FGW_ERR_ARG_CONV; + } + + return 0; +} + Index: tags/1.0.5/src/plugins/act_read/keywords.sphash =================================================================== --- tags/1.0.5/src/plugins/act_read/keywords.sphash (nonexistent) +++ tags/1.0.5/src/plugins/act_read/keywords.sphash (revision 10414) @@ -0,0 +1,13 @@ +alloc +append +clear +dup +field +free +get +length +pop +push +prepend +print +remove Index: tags/1.0.5/src/plugins/backann/Makefile =================================================================== --- tags/1.0.5/src/plugins/backann/Makefile (nonexistent) +++ tags/1.0.5/src/plugins/backann/Makefile (revision 10414) @@ -0,0 +1,2 @@ +all: + cd ../../sch-rnd && make mod_backann Index: tags/1.0.5/src/plugins/backann/Plug.tmpasm =================================================================== --- tags/1.0.5/src/plugins/backann/Plug.tmpasm (nonexistent) +++ tags/1.0.5/src/plugins/backann/Plug.tmpasm (revision 10414) @@ -0,0 +1,15 @@ +put /local/rnd/mod {backann} +put /local/rnd/mod/OBJS [@ + $(PLUGDIR)/backann/backann.o + $(PLUGDIR)/backann/bap_sphash.o + $(PLUGDIR)/backann/check_ba.o + $(PLUGDIR)/backann/auto_ba.o +@] + +put /local/rnd/mod/SPHASH {$(PLUGDIR)/backann/bap.sphash} + +switch /local/module/backann/controls + case {buildin} include /local/csch/tmpasm/buildin; end; + case {plugin} include /local/csch/tmpasm/plugin; end; + case {disable} include /local/csch/tmpasm/disable; end; +end Index: tags/1.0.5/src/plugins/backann/auto_ba.c =================================================================== --- tags/1.0.5/src/plugins/backann/auto_ba.c (nonexistent) +++ tags/1.0.5/src/plugins/backann/auto_ba.c (revision 10414) @@ -0,0 +1,542 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - back annotation + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + + +#include + + + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "backann.h" +#include "auto_ba.h" + +/*** generic/helper ***/ + +/* Figure if an attribute modification entry can be autofixed */ +static sch_rnd_backann_auto_t *auto_attr(sch_rnd_backann_t *ctx, sch_rnd_ba_t *ba, csch_attribs_t *attrs, const char *key, const char *want, csch_ahdr_t *fallback_aobj) +{ + csch_attrib_t *attr = csch_attrib_get(attrs, key); + sch_rnd_backann_auto_t *res; + long n; + int prio, found = 0, is_str; + csch_chdr_t *cobj; + csch_ahdr_t *aobj; + const char *desc; + + if ((attr != NULL) && (attr->source.used >= 1)) { + /* pick the first actual write going back from the end, ignore failed writes */ + for(n = attr->source.used-1; n >= 0; n--) { + int pr; + csch_attrib_src_type_t type; + char *source = attr->source.array[n]; + + pr = csch_attrib_src_parse(ctx->sheet, source, &prio, &type, &cobj, &aobj, NULL, &desc); + if ((pr != 0) || (type & CSCH_ASRCT_FAIL)) + continue; + + found = 1; + break; + } + + if (!found) + return NULL; + + is_str = (attr->val != NULL); + } + else { /* setting an attribute that doesn't exist -> set it on the first source object */ + aobj = fallback_aobj; + if (aobj->srcs.used < 1) + return NULL; /* no source object available */ + cobj = aobj->srcs.array[0]; + is_str = 1; + } + + assert(csch_obj_is_grp(cobj)); + + res = malloc(sizeof(sch_rnd_backann_auto_t)); + res->attr.type = SCH_RND_BAA_ATTR; + res->attr.grp = (csch_cgrp_t *)cobj; + res->attr.key = rnd_strdup(key); + res->attr.want_val = (want == NULL) ? NULL : rnd_strdup(want); + res->attr.is_str = is_str; + + return res; +} + +void csch_get_term_conns(vtp0_t *dst, csch_cgrp_t *term) +{ + htip_entry_t *e; + for(e = htip_first(&term->id2obj); e != NULL; e = htip_next(&term->id2obj, e)) { + csch_chdr_t *obj = e->value; + long n; + + for(n = 0; n < obj->conn.used; n++) + vtp0_append(dst, obj->conn.array[n]); + + if (csch_obj_is_grp(obj)) + csch_get_term_conns(dst, (csch_cgrp_t *)obj); + } +} + +/* Figure whuch end of tl is furhter away from the center of term's bbox and + load that into x;y */ +static void term_line_outer_coord(csch_cgrp_t *term, csch_line_t *tl, csch_coord_t *x, csch_coord_t *y) +{ + csch_coord_t cx, cy; + + cx = (term->hdr.bbox.x1 + term->hdr.bbox.x2)/2; + cy = (term->hdr.bbox.x1 + term->hdr.bbox.x2)/2; + if (rnd_distance2(cx, cy, tl->inst.c.p1.x, tl->inst.c.p1.y) > rnd_distance2(cx, cy, tl->inst.c.p2.x, tl->inst.c.p2.y)) { + *x = tl->inst.c.p1.x; + *y = tl->inst.c.p1.y; + } + else { + *x = tl->inst.c.p2.x; + *y = tl->inst.c.p2.y; + } +} + +/* term is a terminal group, wn is a wirenet group, they are on the same + sheet. Find the endpoint of the terminal to draw a wire from to + the closest point of the wirenet. Return length^2 and fill in + termo with the terminal object and wno with the wirenet object affected. + Lin is csch_coord_t[4], filled in with the x1;y1;x2;y2 coords of the + new wire to be drawn. */ +double find_straight_line_between(csch_cgrp_t *term, csch_cgrp_t *wn, csch_chdr_t **termo, csch_chdr_t **wno, csch_coord_t *lin) +{ + htip_entry_t *te, *we; + double best_len2 = 0, len2; + + + assert(term->hdr.sheet == wn->hdr.sheet); + assert(csch_obj_is_grp(&term->hdr)); + assert(csch_obj_is_grp(&wn->hdr)); + assert(term->role == CSCH_ROLE_TERMINAL); + assert(wn->role == CSCH_ROLE_WIRE_NET); + + *termo = NULL; + *wno = NULL; + + for(te = htip_first(&term->id2obj); te != NULL; te = htip_next(&term->id2obj, te)) { + csch_line_t *tl = te->value; + csch_coord_t tx, ty; + g2d_vect_t tc, pr; + + if (tl->hdr.type != CSCH_CTYPE_LINE) continue; + + term_line_outer_coord(term, tl, &tx, &ty); + tc.x = tx; tc.y = ty; + + for(we = htip_first(&wn->id2obj); we != NULL; we = htip_next(&wn->id2obj, we)) { + double offs; + csch_line_t *wl = we->value; + + if (wl->hdr.type != CSCH_CTYPE_LINE) continue; + + /* project preferred terminal end onto the wirenet line to get the other end */ + offs = g2d_project_pt_cline(tc, &wl->inst.c); + if (offs < 0.0) offs = 0.0; + else if (offs > 1.0) offs = 1.0; + pr = g2d_cline_offs(&wl->inst.c, offs); + len2 = rnd_distance2(pr.x, pr.y, tc.x, tc.y); + if ((best_len2 == 0) || (len2 < best_len2)) { + best_len2 = len2; + lin[0] = tc.x; lin[1] = tc.y; + lin[2] = pr.x; lin[3] = pr.y; + *termo = &tl->hdr; + *wno = &wl->hdr; + } + } + } + + return best_len2; +} + +/* Figure graphical connection and fill in related objects; if the connection + exists, conn_out is filled with the conn object making the connection. + termo and wno are filled in with the non-group drawing objects participating + in the connection from the terminal's or the wirenet's side, respectively. + If newline is not NULL and there's no connection, find a terminal and a + wirenet on the same sheet and figure a straight line that'd connect them */ +static int get_term_net_gr_conn(csch_project_t *prj, const char *netname, const char *compname, const char *termname, csch_chdr_t **termo_out, csch_chdr_t **wno_out, csch_conn_t **conn_out, csch_coord_t *newline) +{ + csch_anet_t *net; + csch_acomp_t *comp; + csch_aport_t *port; + long tn, cn; + vtp0_t conns = {0}; + int resi = -1; + csch_chdr_t *found_wire = NULL, *found_term = NULL; + + if (termo_out != NULL) *termo_out = NULL; + if (wno_out != NULL) *wno_out = NULL; + if (conn_out != NULL) *conn_out = NULL; + + if (prj->abst == NULL) + return -1; + + net = csch_anet_get(prj->abst, netname); + if (net == NULL) + return -1; + + comp = csch_acomp_get(prj->abst, compname); + if (comp == NULL) + return -1; + + port = csch_aport_get(prj->abst, comp, termname, 0); + if (port == NULL) + return -1; + + /* collect all connection objects of all our concrete terminals, recursively */ + for(tn = 0; tn < port->hdr.srcs.used; tn++) { + csch_chdr_t *termo = port->hdr.srcs.array[tn]; + csch_cgrp_t *termg = (csch_cgrp_t *)termo; + + if (!csch_obj_is_grp(termo) || (termg->role != CSCH_ROLE_TERMINAL)) + continue; + + rnd_trace("Found term: %p\n", termo); + + csch_get_term_conns(&conns, termg); + } + + /* find a conn object that connects our terminal to our wirenet */ + for(cn = 0; cn < conns.used; cn++) { + csch_chdr_t *termo = NULL; + long on; + csch_conn_t *conn = conns.array[cn]; + rnd_trace(" [%ld] conn %p\n", cn, conn); + + for(on = 0; on < conn->conn.used; on++) { + csch_chdr_t *obj = conn->conn.array[on]; + if ((obj->parent->role == CSCH_ROLE_TERMINAL) && (csch_cgrp_is_in_asrc(obj->parent, &port->hdr))) + found_term = termo = obj; + else if ((obj->parent->role == CSCH_ROLE_WIRE_NET) && (csch_cgrp_is_in_asrc(obj->parent, &net->hdr))) { + rnd_trace(" found wn obj %p\n", obj); + resi = 0; + found_wire = obj; + if (conn_out != NULL) *conn_out = conn; + } + + /* we are done if we have both a wire and a terminal object */ + if ((found_wire != NULL) && (found_term != NULL)) { + if (termo_out != NULL) *termo_out = found_term; + if (wno_out != NULL) *wno_out = found_wire; + goto done; + } + } + } + + /* no suitable existing connection found */ + if (newline != NULL) { + double best_len2 = 0; + + /* find a pair of terminal-wirenet on the same sheet */ + for(tn = 0; tn < port->hdr.srcs.used; tn++) { + csch_cgrp_t *term = (csch_cgrp_t *)port->hdr.srcs.array[tn]; + long w; + + for(w = 0; w < net->hdr.srcs.used; w++) { + csch_cgrp_t *wn = (csch_cgrp_t *)net->hdr.srcs.array[w]; + if (wn->hdr.sheet == term->hdr.sheet) { + csch_coord_t lin[4]; + csch_chdr_t *termo, *wno; + double len2 = find_straight_line_between(term, wn, &termo, &wno, lin); + if ((len2 > 0) && ((best_len2 == 0) || (len2 < best_len2))) { + best_len2 = len2; + memcpy(newline, lin, sizeof(lin)); + if (termo_out != NULL) *termo_out = termo; + if (wno_out != NULL) *wno_out = wno; + } + } + } + } + } + + done:; + vtp0_uninit(&conns); + return resi; +} + + +void calc_break_grconn_fixable(sch_rnd_backann_auto_t *res) +{ + csch_chdr_t *wireo = res->break_grconn.wire_obj; + csch_chdr_t *termo = res->break_grconn.term_obj; + csch_line_t *wirel = (csch_line_t *)wireo; + csch_sheet_t *sheet = wireo->sheet; + g2d_vect_t iscp[2]; + long len; + double wlen, dx, dy; + + /* assume we can't fix this by default */ + res->break_grconn.endp = 0; + + /* can tune endpoint of line wires only */ + if (wireo->type != CSCH_CTYPE_LINE) + return; + + /* if there is not exactly one intersections it's a complicated case */ + len = csch_obj_intersect_obj(sheet, wireo, termo, iscp, 2); + if (len != 1) + return; + + dx = wirel->inst.c.p1.x - wirel->inst.c.p2.x; + dy = wirel->inst.c.p1.y - wirel->inst.c.p2.y; + wlen = sqrt(dx*dx + dy*dy); + + /* wire too short for safe endpoint modification */ + if (wlen < 2000) + return; + + /* iscp[0] has the wire point that should be moved away - if it's an + endpoint of that wire; else it's a T junction and we are not going to + fix that */ + if ((wirel->inst.c.p1.x == iscp[0].x) && (wirel->inst.c.p1.y == iscp[0].y)) { + res->break_grconn.endp = 1; + res->break_grconn.newx = wirel->inst.c.p1.x - dx / wlen * 1000; + res->break_grconn.newy = wirel->inst.c.p1.y - dy / wlen * 1000; +/* rnd_trace("endp1 to %ld %ld\n", res->break_grconn.newx, res->break_grconn.newy);*/ + } + else if ((wirel->inst.c.p2.x == iscp[0].x) && (wirel->inst.c.p2.y == iscp[0].y)) { + res->break_grconn.endp = 2; + res->break_grconn.newx = wirel->inst.c.p2.x + dx / wlen * 1000; + res->break_grconn.newy = wirel->inst.c.p2.y + dy / wlen * 1000; +/* rnd_trace("endp2 to %ld %ld\n", res->break_grconn.newx, res->break_grconn.newy);*/ + } +} + +/*** instructions ***/ +static sch_rnd_backann_auto_t *auto_conn_del(sch_rnd_backann_t *ctx, sch_rnd_ba_t *ba) +{ + csch_project_t *prj = (csch_project_t *)ctx->sheet->hidlib.project; + csch_chdr_t *termo, *wno; + csch_anet_t *net; + csch_conn_t *conn; + sch_rnd_backann_auto_t *res; + int jnc_mid; + int tricky = 0; + + + + if (get_term_net_gr_conn(prj, ba->value.conn_del.net, ba->value.conn_del.comp, ba->value.conn_del.term, &termo, &wno, &conn, NULL) != 0) + return NULL; + + net = csch_anet_get(prj->abst, ba->value.conn_del.net); + if (net == NULL) + return NULL; + + if (net->conns.used == 1) { + /* by now we are sure our terminal is connected to the net so this one + connection must be the same as net's conn list's. In this case + remove the whole wirenet (removal of the last connection means + removal of the wirenet). */ + res = calloc(sizeof(sch_rnd_backann_auto_t), 1); + res->del.type = SCH_RND_BAA_DEL; + res->del.obj = &wno->parent->hdr; + return res; + } + + + csch_wire_count_junctions(wno, &jnc_mid); + + /* t1---+---t2; if removed for t1, the section between the mid junction and t2 is also broken */ + /* t1-------t2; if removed for t1, the connection to t2 is also broken */ + tricky |= (wno->conn.used > 1); + + /* t1---+---+; if removed for t1, the section between the mid junction and endpoint is also broken */ + tricky |= (jnc_mid > 0); + + if (tricky) { + res = malloc(sizeof(sch_rnd_backann_auto_t)); + res->break_grconn.type = SCH_RND_BAA_BREAK_GRCONN; + res->break_grconn.wire_obj = wno; + res->break_grconn.term_obj = termo; + calc_break_grconn_fixable(res); + } + else { + res = calloc(sizeof(sch_rnd_backann_auto_t), 1); + res->del.type = SCH_RND_BAA_DEL; + res->del.obj = wno; + } + + return res; +} + +static sch_rnd_backann_auto_t *auto_conn_add(sch_rnd_backann_t *ctx, sch_rnd_ba_t *ba) +{ + csch_project_t *prj = (csch_project_t *)ctx->sheet->hidlib.project; + csch_chdr_t *termo, *wno; + csch_conn_t *conn; + sch_rnd_backann_auto_t *res; + csch_coord_t newline[4]; + + if (get_term_net_gr_conn(prj, ba->value.conn_del.net, ba->value.conn_del.comp, ba->value.conn_del.term, &termo, &wno, &conn, newline) == 0) + return NULL; + + res = malloc(sizeof(sch_rnd_backann_auto_t)); + res->make_grconn.type = SCH_RND_BAA_MAKE_GRCONN; + res->make_grconn.wire_obj = wno; + res->make_grconn.term_obj = termo; + res->make_grconn.x1 = newline[0]; + res->make_grconn.y1 = newline[1]; + res->make_grconn.x2 = newline[2]; + res->make_grconn.y2 = newline[3]; + + return res; +} + +static sch_rnd_backann_auto_t *auto_net_attr(sch_rnd_backann_t *ctx, sch_rnd_ba_t *ba) +{ + csch_project_t *prj = (csch_project_t *)ctx->sheet->hidlib.project; + csch_anet_t *net; + + net = csch_anet_get(prj->abst, ba->value.net_attr.net); + if (net == NULL) + return NULL; + + return auto_attr(ctx, ba, &net->hdr.attr, ba->value.net_attr.key, ba->value.net_attr.val, &net->hdr); +} + +static sch_rnd_backann_auto_t *auto_comp_attr(sch_rnd_backann_t *ctx, sch_rnd_ba_t *ba) +{ + csch_project_t *prj = (csch_project_t *)ctx->sheet->hidlib.project; + csch_acomp_t *comp; + + comp = csch_acomp_get(prj->abst, ba->value.comp_attr.comp); + if (comp == NULL) + return NULL; + + return auto_attr(ctx, ba, &comp->hdr.attr, ba->value.comp_attr.key, ba->value.comp_attr.val, &comp->hdr); +} + +static sch_rnd_backann_auto_t *auto_term_attr(sch_rnd_backann_t *ctx, sch_rnd_ba_t *ba) +{ + csch_project_t *prj = (csch_project_t *)ctx->sheet->hidlib.project; + csch_acomp_t *comp; + csch_aport_t *port; + + comp = csch_acomp_get(prj->abst, ba->value.term_attr.comp); + if (comp == NULL) + return NULL; + + port = csch_aport_get(prj->abst, comp, ba->value.term_attr.term, 0); + if (port == NULL) + return NULL; + + return auto_attr(ctx, ba, &port->hdr.attr, ba->value.term_attr.key, ba->value.term_attr.val, &port->hdr); +} + +static sch_rnd_backann_auto_t *auto_comp_add(sch_rnd_backann_t *ctx, sch_rnd_ba_t *ba) +{ +/* csch_project_t *prj = (csch_project_t *)ctx->sheet->hidlib.project;*/ + sch_rnd_backann_auto_t *res; + + res = malloc(sizeof(sch_rnd_backann_auto_t)); + res->log.type = SCH_RND_BAA_LOG; + res->log.str = rnd_strdup_printf("Use the {w l} library window to place a symbol\nthen {a a} to change its name to %s\n", ba->value.comp_add.comp); + + return res; +} + +static sch_rnd_backann_auto_t *auto_comp_del(sch_rnd_backann_t *ctx, sch_rnd_ba_t *ba) +{ + csch_project_t *prj = (csch_project_t *)ctx->sheet->hidlib.project; + csch_acomp_t *comp; + sch_rnd_backann_auto_t *res; + + comp = csch_acomp_get(prj->abst, ba->value.comp_del.comp); + if ((comp == NULL) || (comp->hdr.srcs.used < 1)) + return NULL; + + res = calloc(sizeof(sch_rnd_backann_auto_t), 1); + res->del.type = SCH_RND_BAA_DEL; + if (comp->hdr.srcs.used > 1) { + long n; + vtp0_enlarge(&res->del.objlist, comp->hdr.srcs.used-1); + for(n = 0; n < comp->hdr.srcs.used; n++) + res->del.objlist.array[n] = comp->hdr.srcs.array[n]; + } + else + res->del.obj = comp->hdr.srcs.array[0]; /* save an extra allocation for a common case when there's only one object */ + + return res; +} + +/*** API ***/ + +sch_rnd_backann_auto_t *sch_rnd_backann_auto_entry(sch_rnd_backann_t *ctx, sch_rnd_ba_t *ba) +{ + switch(ba->type) { + case SCH_RND_BAT_NETINFO: return NULL; + case SCH_RND_BAT_CONN_DEL: return auto_conn_del(ctx, ba); + case SCH_RND_BAT_CONN_ADD: return auto_conn_add(ctx, ba); + case SCH_RND_BAT_NET_ATTR: return auto_net_attr(ctx, ba); + case SCH_RND_BAT_COMP_ATTR: return auto_comp_attr(ctx, ba); + case SCH_RND_BAT_TERM_ATTR: return auto_term_attr(ctx, ba); + case SCH_RND_BAT_COMP_DEL: return auto_comp_del(ctx, ba); + case SCH_RND_BAT_COMP_ADD: return auto_comp_add(ctx, ba); + case SCH_RND_BAT_invalid: break; + } + return NULL; +} + +void sch_rnd_backann_auto_free(sch_rnd_backann_auto_t *au) +{ + if (au == NULL) return; + switch(au->any.type) { + case SCH_RND_BAA_ATTR: + free(au->attr.key); + free(au->attr.want_val); + break; + + case SCH_RND_BAA_LOG: + free(au->log.str); + break; + + case SCH_RND_BAA_DEL: + vtp0_uninit(&au->del.objlist); + break; + + /* no dynamic allocated fields */ + case SCH_RND_BAA_BREAK_GRCONN: + case SCH_RND_BAA_MAKE_GRCONN: + break; + } + free(au); +} + Index: tags/1.0.5/src/plugins/backann/auto_ba.h =================================================================== --- tags/1.0.5/src/plugins/backann/auto_ba.h (nonexistent) +++ tags/1.0.5/src/plugins/backann/auto_ba.h (revision 10414) @@ -0,0 +1,63 @@ +typedef enum { + SCH_RND_BAA_ATTR, /* need to edit an attribute */ + SCH_RND_BAA_DEL, /* need to remove an object */ + SCH_RND_BAA_BREAK_GRCONN, /* need to break graphical connection, but don't know how exactly */ + SCH_RND_BAA_MAKE_GRCONN, /* need to make a graphical connection, but don't know how exactly */ + SCH_RND_BAA_LOG /* print an error in the message log */ +} sch_rnd_backann_auto_type_t; + +/* Changing the attribute of obj to want_val would resolve a backann entry */ +typedef struct sch_rnd_backann_auto_attr_s { + sch_rnd_backann_auto_type_t type; + csch_cgrp_t *grp; + int is_str; + char *key; + char *want_val; +} sch_rnd_backann_auto_attr_t; + +/* Removing the specified obj would resolve a backann entry */ +typedef struct sch_rnd_backann_auto_del_s { + sch_rnd_backann_auto_type_t type; + csch_chdr_t *obj; + vtp0_t objlist; /* when multiple objects are to be removed */ +} sch_rnd_backann_auto_del_t; + +/* The user needs to break graphical connection between the two objects */ +typedef struct sch_rnd_backann_auto_break_grconn_s { + sch_rnd_backann_auto_type_t type; + csch_chdr_t *term_obj, *wire_obj; + /* if fixable: */ + int endp; /* 1 or 2, for moving x1;y1 or x2;y2 of the wire line */ + csch_coord_t newx, newy; /* new coords for that endpoint */ +} sch_rnd_backann_auto_break_grconn_t; + +/* The user needs to make a graphical connection between the two objects */ +typedef struct sch_rnd_backann_auto_make_grconn_s { + sch_rnd_backann_auto_type_t type; + csch_chdr_t *term_obj, *wire_obj; + csch_coord_t x1, y1, x2, y2; /* suggested wire line endpoints (any-angle); x1;y1 is on the terminal side, x2;y2 is on the wire side */ +} sch_rnd_backann_auto_make_grconn_t; + +typedef struct sch_rnd_backann_auto_log_s { + sch_rnd_backann_auto_type_t type; + char *str; +} sch_rnd_backann_auto_log_t; + +typedef union sch_rnd_backann_auto_s { + sch_rnd_backann_auto_attr_t attr; + sch_rnd_backann_auto_del_t del; + sch_rnd_backann_auto_break_grconn_t break_grconn; + sch_rnd_backann_auto_make_grconn_t make_grconn; + sch_rnd_backann_auto_log_t log; + + struct { + sch_rnd_backann_auto_type_t type; + } any; +} sch_rnd_backann_auto_t; + +/* Return a malloc()'d description of what needs changed, or NULL if can't + be auto-fixed */ +sch_rnd_backann_auto_t *sch_rnd_backann_auto_entry(sch_rnd_backann_t *ctx, sch_rnd_ba_t *ba); + +/* Free au and all its fields */ +void sch_rnd_backann_auto_free(sch_rnd_backann_auto_t *au); Index: tags/1.0.5/src/plugins/backann/backann.c =================================================================== --- tags/1.0.5/src/plugins/backann/backann.c (nonexistent) +++ tags/1.0.5/src/plugins/backann/backann.c (revision 10414) @@ -0,0 +1,205 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - back annotation + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + + +#include + +#include + +#include +#include +#include +#include +#include + +static const char sch_backann_cookie[] = "backann plugin"; + +#define GVT_DONT_UNDEF +#include "backann.h" + +#define GVT_REALLOC(vect, ptr, size) realloc(ptr, size) +#define GVT_FREE(vect, ptr) free(ptr) +#include + + +#include "check_ba.h" +#include "auto_ba.h" + +#include "dlg_ba.c" +#include "parse_backann.c" + +htpp_t sch_rnd_prj2backann; +int sch_rnd_prj2backann_inited; + +void sch_rnd_backann_uninit(sch_rnd_backann_t *ctx) +{ + assert(sch_rnd_prj2backann_inited); + htpp_pop(&sch_rnd_prj2backann, (csch_project_t *)ctx->sheet->hidlib.project); + backann_free_list(ctx); + free(ctx); +} + +static void sch_rnd_backann_close(sch_rnd_backann_t *ctx) +{ + rnd_dad_retovr_t retovr = {0}; + rnd_hid_dad_close(ctx->dlg_hid_ctx, &retovr, 0); +} + +void sch_rnd_backann_update(sch_rnd_backann_t *ctx) +{ + sch_rnd_backann_check(ctx); + backann_data2dlg(ctx); +} + + +static const char csch_acts_Backann[] = "Backann([filename])\n"; +static const char csch_acth_Backann[] = "Load a back annotation file for interactive back annotation"; +static fgw_error_t csch_act_Backann(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_design_t *hidlib = RND_ACT_DESIGN; + sch_rnd_backann_t ctx = {0}, *pctx; + + if (!sch_rnd_prj2backann_inited) { + htpp_init(&sch_rnd_prj2backann, ptrhash, ptrkeyeq); + sch_rnd_prj2backann_inited = 1; + } + + ctx.sheet = (csch_sheet_t *)hidlib; + RND_ACT_MAY_CONVARG(1, FGW_STR, Backann, ctx.fn = argv[1].val.str); + + if (ctx.fn == NULL) { + static char *default_file = NULL; + static const char *flt_bap[] = {"*.bap", NULL}; + static const char *flt_any[] = {"*", "*.*", NULL}; + const rnd_hid_fsd_filter_t flt[] = { + {"pcb-rnd back annotation", NULL, flt_bap}, + {"all", NULL, flt_any}, + {NULL, NULL,NULL} + }; + + ctx.fn = rnd_hid_fileselect(rnd_gui, + "Load back annotation file...", "Picks a back annotation file\n", + default_file, ".bap", flt, "backann", RND_HID_FSD_READ, NULL); + + free(default_file); + default_file = NULL; + + if (ctx.fn == NULL) { + RND_ACT_IRES(1); + return 0; /* cancel */ + } + } + + pctx = htpp_get(&sch_rnd_prj2backann, (csch_project_t *)ctx.sheet->hidlib.project); + if (pctx != NULL) { + RND_ACT_IRES(1); + rnd_message(RND_MSG_ERROR, "A back annotation session is already active for this project\n"); + return 0; + } + + + if (backann_parse(&ctx) != 0) { + RND_ACT_IRES(1); + return 0; + } + + /* make ctx permament */ + pctx = malloc(sizeof(sch_rnd_backann_t)); + memcpy(pctx, &ctx, sizeof(sch_rnd_backann_t)); + + sch_rnd_backann_check(pctx); + backann_dlg(pctx); + htpp_set(&sch_rnd_prj2backann, (csch_project_t *)ctx.sheet->hidlib.project, pctx); + + RND_ACT_IRES(0); + return 0; +} + +static rnd_action_t sch_backann_action_list[] = { + {"Backann", csch_act_Backann, csch_acth_Backann, csch_acts_Backann}, +}; + +static void backann_ev_compiled(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + htpp_entry_t *e; + + if (!sch_rnd_prj2backann_inited) return; + + for(e = htpp_first(&sch_rnd_prj2backann); e != NULL; e = htpp_next(&sch_rnd_prj2backann, e)) { + sch_rnd_backann_t *ctx = e->value; + if (&ctx->sheet->hidlib == hidlib) + sch_rnd_backann_update(e->value); + } +} + +static void backann_ev_preunload(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + htpp_entry_t *e; + + if (!sch_rnd_prj2backann_inited) return; + + for(e = htpp_first(&sch_rnd_prj2backann); e != NULL; e = htpp_next(&sch_rnd_prj2backann, e)) { + sch_rnd_backann_t *ctx = e->value; + if (&ctx->sheet->hidlib == hidlib) + sch_rnd_backann_close(ctx); + } +} + + + +int pplg_check_ver_backann(int ver_needed) { return 0; } + +void pplg_uninit_backann(void) +{ + if (sch_rnd_prj2backann_inited) { + htpp_entry_t *e; + + for(e = htpp_first(&sch_rnd_prj2backann); e != NULL; e = htpp_next(&sch_rnd_prj2backann, e)) + sch_rnd_backann_close(e->value); + } + + rnd_remove_actions_by_cookie(sch_backann_cookie); + rnd_event_unbind_allcookie(sch_backann_cookie); + if (sch_rnd_prj2backann_inited) { + htpp_uninit(&sch_rnd_prj2backann); + sch_rnd_prj2backann_inited = 0; + } +} + +int pplg_init_backann(void) +{ + RND_API_CHK_VER; + + RND_REGISTER_ACTIONS(sch_backann_action_list, sch_backann_cookie); + + rnd_event_bind(CSCH_EVENT_PRJ_COMPILED, backann_ev_compiled, NULL, sch_backann_cookie); + rnd_event_bind(CSCH_EVENT_SHEET_PREUNLOAD, backann_ev_preunload, NULL, sch_backann_cookie); + + return 0; +} + Index: tags/1.0.5/src/plugins/backann/backann.h =================================================================== --- tags/1.0.5/src/plugins/backann/backann.h (nonexistent) +++ tags/1.0.5/src/plugins/backann/backann.h (revision 10414) @@ -0,0 +1,69 @@ +#include + +#include + +typedef enum sch_rnd_ba_type_e { + SCH_RND_BAT_invalid = 0, + SCH_RND_BAT_NETINFO, + SCH_RND_BAT_CONN_DEL, + SCH_RND_BAT_CONN_ADD, + SCH_RND_BAT_NET_ATTR, + SCH_RND_BAT_COMP_ATTR, + SCH_RND_BAT_TERM_ATTR, + SCH_RND_BAT_COMP_ADD, + SCH_RND_BAT_COMP_DEL +} sch_rnd_ba_type_t; + +typedef enum sch_rnd_ba_status_e { + SCH_RND_BAS_UNKNOWN, + SCH_RND_BAS_PENDING, + SCH_RND_BAS_DONE +} sch_rnd_ba_status_t; + +typedef struct sch_rnd_ba_s { + sch_rnd_ba_type_t type; + char *raw; /* only raw is allocated, value fields are pointing into raw */ + union { + struct { char *net, *comp, *term; } netinfo; + struct { char *comp, *term, *net; } conn_del; + struct { char *comp, *term, *net; } conn_add; + struct { char *net, *key, *val; } net_attr; + struct { char *comp, *key, *val; } comp_attr; + struct { char *comp; } comp_add; + struct { char *comp; } comp_del; + + struct { char *comp, *term, *key, *val; } term_attr; + + struct { char *a0, *a1, *a2, *a3; } any4; + } value; + sch_rnd_ba_status_t status; + unsigned optional:1; /* do not enforce (e.g. netinfo when changed by later entries */ +} sch_rnd_ba_t; + +/* Elem=sch_rnd_ba_t; init=0 */ +#define GVT(x) vtba_ ## x +#define GVT_ELEM_TYPE sch_rnd_ba_t +#define GVT_SIZE_TYPE size_t +#define GVT_DOUBLING_THRS 4096 +#define GVT_START_SIZE 32 +#define GVT_FUNC +#define GVT_SET_NEW_BYTES_TO 0 +#include +#include + + +typedef struct sch_rnd_backann_s { + RND_DAD_DECL_NOINIT(dlg) + csch_sheet_t *sheet; + char *fn; + vtba_t list; + + /* widgets */ + int wlist; +} sch_rnd_backann_t; + +extern htpp_t sch_rnd_prj2backann; +extern int sch_rnd_prj2backann_inited; + +void sch_rnd_backann_uninit(sch_rnd_backann_t *ctx); + Index: tags/1.0.5/src/plugins/backann/backann.pup =================================================================== --- tags/1.0.5/src/plugins/backann/backann.pup (nonexistent) +++ tags/1.0.5/src/plugins/backann/backann.pup (revision 10414) @@ -0,0 +1,8 @@ +$class feature +$short back annotation +$long interactive back annotation +$state works +$package (core) +dep lib_tedax +default buildin +autoload 1 Index: tags/1.0.5/src/plugins/backann/bap.sphash =================================================================== --- tags/1.0.5/src/plugins/backann/bap.sphash (nonexistent) +++ tags/1.0.5/src/plugins/backann/bap.sphash (revision 10414) @@ -0,0 +1,13 @@ +# this list holds both bap and tEDAx keywords +net_info +change_attrib +del_conn +add_conn +attr_conn +add_comp +del_comp +attr_comp +fattr_comp +attr_pin +begin +end Index: tags/1.0.5/src/plugins/backann/check_ba.c =================================================================== --- tags/1.0.5/src/plugins/backann/check_ba.c (nonexistent) +++ tags/1.0.5/src/plugins/backann/check_ba.c (revision 10414) @@ -0,0 +1,231 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - back annotation + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + + +#include + +#include +#include + +#include "backann.h" +#include "check_ba.h" + + +/*** generic/helper ***/ + +/* Compare attribute to what the user wants and set ba->status accordingly */ +static int check_attr(sch_rnd_ba_t *ba, csch_attribs_t *attrs, const char *key, const char *want) +{ + const char *has = csch_attrib_get_str(attrs, key); + int match = 0; + + /*rnd_trace("attr has='%s' want='%s'\n", has, want);*/ + + if ((want == NULL) || (*want == '\0')) { + /* user requests a delete */ + match = (has == NULL) || (*has == '\0'); + } + else { + /* user requests a value */ + if ((has == NULL) || (*has == '\0')) + match = 0; + else + match = (strcmp(has, want) == 0); + } + + ba->status = match ? SCH_RND_BAS_DONE : SCH_RND_BAS_PENDING; + return 0; /* accept entry either way */ +} + +/* Check if net and term are connected; returns +1 on connected, 0 on not + connected and -1 on error */ +int check_term_net_connected(csch_project_t *prj, const char *netname, const char *compname, const char *termname) +{ + csch_anet_t *net; + csch_acomp_t *comp; + csch_aport_t *port; + + if (prj->abst == NULL) + return -1; + + net = csch_anet_get(prj->abst, netname); + if (net == NULL) + return -1; + + comp = csch_acomp_get(prj->abst, compname); + if (comp == NULL) + return -1; + + port = csch_aport_get(prj->abst, comp, termname, 0); + if (port == NULL) + return -1; + + return port->conn.net == net; +} + +/*** insrtuctions ***/ +static int check_netinfo(sch_rnd_backann_t *ctx, sch_rnd_ba_t *ba, long *pend) +{ + csch_project_t *prj = (csch_project_t *)ctx->sheet->hidlib.project; + int cn = check_term_net_connected(prj, ba->value.netinfo.net, ba->value.netinfo.comp, ba->value.netinfo.term); + if (cn <= 0) { + if (ba->optional) + return 0; + return -1; + } + + ba->status = SCH_RND_BAS_DONE; + return 0; +} + +static int check_conn_del(sch_rnd_backann_t *ctx, sch_rnd_ba_t *ba, long *pend) +{ + csch_project_t *prj = (csch_project_t *)ctx->sheet->hidlib.project; + int cn = check_term_net_connected(prj, ba->value.conn_del.net, ba->value.conn_del.comp, ba->value.conn_del.term); + + if (cn < 0) + return -1; + + ba->status = !cn ? SCH_RND_BAS_DONE : SCH_RND_BAS_PENDING; + + return 0; +} + +static int check_conn_add(sch_rnd_backann_t *ctx, sch_rnd_ba_t *ba, long *pend) +{ + csch_project_t *prj = (csch_project_t *)ctx->sheet->hidlib.project; + int cn = check_term_net_connected(prj, ba->value.conn_add.net, ba->value.conn_add.comp, ba->value.conn_add.term); + + if (cn < 0) + return -1; + + ba->status = cn ? SCH_RND_BAS_DONE : SCH_RND_BAS_PENDING; + + return 0; +} + +static int check_comp_del(sch_rnd_backann_t *ctx, sch_rnd_ba_t *ba, long *pend) +{ + csch_project_t *prj = (csch_project_t *)ctx->sheet->hidlib.project; + csch_acomp_t *acomp = csch_acomp_get(prj->abst, ba->value.comp_del.comp); + + ba->status = (acomp == NULL) ? SCH_RND_BAS_DONE : SCH_RND_BAS_PENDING; + + return 0; +} + +static int check_comp_add(sch_rnd_backann_t *ctx, sch_rnd_ba_t *ba, long *pend) +{ + csch_project_t *prj = (csch_project_t *)ctx->sheet->hidlib.project; + csch_acomp_t *acomp = csch_acomp_get(prj->abst, ba->value.comp_del.comp); + + ba->status = (acomp != NULL) ? SCH_RND_BAS_DONE : SCH_RND_BAS_PENDING; + + return 0; +} + + +static int check_net_attr(sch_rnd_backann_t *ctx, sch_rnd_ba_t *ba, long *pend) +{ + csch_project_t *prj = (csch_project_t *)ctx->sheet->hidlib.project; + csch_anet_t *net; + + net = csch_anet_get(prj->abst, ba->value.net_attr.net); + if (net == NULL) + return -1; + + return check_attr(ba, &net->hdr.attr, ba->value.net_attr.key, ba->value.net_attr.val); +} + +static int check_comp_attr(sch_rnd_backann_t *ctx, sch_rnd_ba_t *ba, long *pend) +{ + csch_project_t *prj = (csch_project_t *)ctx->sheet->hidlib.project; + csch_acomp_t *comp; + + comp = csch_acomp_get(prj->abst, ba->value.comp_attr.comp); + if (comp == NULL) + return -1; + + return check_attr(ba, &comp->hdr.attr, ba->value.comp_attr.key, ba->value.comp_attr.val); +} + +static int check_term_attr(sch_rnd_backann_t *ctx, sch_rnd_ba_t *ba, long *pend) +{ + csch_project_t *prj = (csch_project_t *)ctx->sheet->hidlib.project; + csch_acomp_t *comp; + csch_aport_t *port; + + comp = csch_acomp_get(prj->abst, ba->value.term_attr.comp); + if (comp == NULL) + return -1; + + port = csch_aport_get(prj->abst, comp, ba->value.term_attr.term, 0); + if (port == NULL) + return -1; + + return check_attr(ba, &port->hdr.attr, ba->value.term_attr.key, ba->value.term_attr.val); +} + + +int sch_rnd_backann_check_entry(sch_rnd_backann_t *ctx, sch_rnd_ba_t *ba, long *pend) +{ + switch(ba->type) { + case SCH_RND_BAT_NETINFO: return check_netinfo(ctx, ba, pend); + case SCH_RND_BAT_CONN_DEL: return check_conn_del(ctx, ba, pend); + case SCH_RND_BAT_CONN_ADD: return check_conn_add(ctx, ba, pend); + case SCH_RND_BAT_NET_ATTR: return check_net_attr(ctx, ba, pend); + case SCH_RND_BAT_COMP_ATTR: return check_comp_attr(ctx, ba, pend); + case SCH_RND_BAT_TERM_ATTR: return check_term_attr(ctx, ba, pend); + case SCH_RND_BAT_COMP_DEL: return check_comp_del(ctx, ba, pend); + case SCH_RND_BAT_COMP_ADD: return check_comp_add(ctx, ba, pend); + case SCH_RND_BAT_invalid: break; + } + return -1; +} + +long sch_rnd_backann_check(sch_rnd_backann_t *ctx) +{ + csch_project_t *prj = (csch_project_t *)ctx->sheet->hidlib.project; + long n, pend = 0; + int good = 1; pend = 0; + + if (prj->abst == NULL) + good = 0; + + for(n = 0; n < ctx->list.used; n++) { + sch_rnd_ba_t *ba = &ctx->list.array[n]; + ba->status = SCH_RND_BAS_UNKNOWN; + if (good) { + if (sch_rnd_backann_check_entry(ctx, ba, &pend) != 0) + good = 0; + } + else + pend++; + } + return pend; +} Index: tags/1.0.5/src/plugins/backann/check_ba.h =================================================================== --- tags/1.0.5/src/plugins/backann/check_ba.h (nonexistent) +++ tags/1.0.5/src/plugins/backann/check_ba.h (revision 10414) @@ -0,0 +1,11 @@ +/* Execute means: check back annotation entries against the abstract model. */ + +/* execute a single entry of the list; returns 0 if the next entry could be + executed or -1 if the chain breaks */ +int sch_rnd_backann_check_entry(sch_rnd_backann_t *ctx, sch_rnd_ba_t *ba, long *pend); + + +/* Execute all entries from the list and return the number of entries + that potentially need user action; 0 means everything has been back + annotated succesfully */ +long sch_rnd_backann_check(sch_rnd_backann_t *ctx); Index: tags/1.0.5/src/plugins/backann/dlg_ba.c =================================================================== --- tags/1.0.5/src/plugins/backann/dlg_ba.c (nonexistent) +++ tags/1.0.5/src/plugins/backann/dlg_ba.c (revision 10414) @@ -0,0 +1,473 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - back annotation + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + + +#include + +#include + +#include +#include +#include +#include +#include + +static void backann_dlg_close_cb(void *caller_data, rnd_hid_attr_ev_t ev) +{ + sch_rnd_backann_t *ctx = caller_data; + + RND_DAD_FREE(ctx->dlg); + sch_rnd_backann_uninit(ctx); +} + +static char *backann_entry_status(sch_rnd_ba_t *ba) +{ + const char *stname = ""; + switch(ba->status) { + case SCH_RND_BAS_UNKNOWN: stname = "n/a"; break; + case SCH_RND_BAS_PENDING: stname = "PEND"; break; + case SCH_RND_BAS_DONE: stname = "done"; break; + } + return rnd_strdup(stname); +} + +static char *backann_sprint_entry(sch_rnd_ba_t *ba) +{ + switch(ba->type) { + case SCH_RND_BAT_NETINFO: + return rnd_strdup_printf("net info: net %s connects to comp %s term %s%s", ba->value.netinfo.net, ba->value.netinfo.comp, ba->value.netinfo.term, (ba->optional ? " OPTIONAL" : "")); + case SCH_RND_BAT_CONN_DEL: + return rnd_strdup_printf("delete conn: net %s and comp %s term %s", ba->value.conn_del.net, ba->value.conn_del.comp, ba->value.conn_del.term); + case SCH_RND_BAT_CONN_ADD: + return rnd_strdup_printf("create conn: net %s and comp %s term %s", ba->value.conn_add.net, ba->value.conn_add.comp, ba->value.conn_add.term); + case SCH_RND_BAT_NET_ATTR: + return rnd_strdup_printf("set attr: net %s and %s=%s", ba->value.net_attr.net, ba->value.net_attr.key, ba->value.net_attr.val); + case SCH_RND_BAT_COMP_ATTR: + return rnd_strdup_printf("set attr: component %s and %s=%s", ba->value.comp_attr.comp, ba->value.comp_attr.key, ba->value.comp_attr.val); + case SCH_RND_BAT_TERM_ATTR: + return rnd_strdup_printf("set attr: comp %s term %s and %s=%s", ba->value.term_attr.comp, ba->value.term_attr.term, ba->value.term_attr.key, ba->value.term_attr.val); + case SCH_RND_BAT_COMP_DEL: + return rnd_strdup_printf("delete comp %s", ba->value.comp_del.comp); + case SCH_RND_BAT_COMP_ADD: + return rnd_strdup_printf("create comp %s", ba->value.comp_add.comp); + case SCH_RND_BAT_invalid: break; + } + return rnd_strdup_printf("Invalid entry (%ld)", ba->type); +} + +static void backann_data2dlg(sch_rnd_backann_t *ctx) +{ + rnd_hid_attribute_t *attr; + rnd_hid_tree_t *tree; + rnd_hid_row_t *r; + char *cursor_path = NULL; + char *cell[4]; + long n; + + attr = &ctx->dlg[ctx->wlist]; + tree = attr->wdata; + + /* remember cursor path */ + r = rnd_dad_tree_get_selected(attr); + if (r != NULL) + cursor_path = rnd_strdup(r->path); + + rnd_dad_tree_clear(tree); + for(n = 0; n < ctx->list.used; n++) { + sch_rnd_ba_t *ba = &ctx->list.array[n]; + + if (ba->type == SCH_RND_BAT_NETINFO) + continue; + + cell[0] = rnd_strdup_printf("%ld", n); + cell[1] = backann_entry_status(ba); + cell[2] = backann_sprint_entry(ba); + cell[3] = NULL; + r = rnd_dad_tree_append_under(attr, NULL, cell); + r->user_data2.lng = n; + } + + + /* restore cursor */ + if (cursor_path != NULL) { + rnd_hid_attr_val_t hv; + hv.str = cursor_path; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wlist, &hv); + free(cursor_path); + } +} + +static void ba_select_cb(rnd_hid_attribute_t *attrib, void *hid_ctx, rnd_hid_row_t *row) +{ +/* rnd_hid_tree_t *tree = attrib->wdata; + sch_rnd_backann_t *ctx = tree->user_ctx;*/ +} + +static int sch_rnd_backann_ensure_abst(sch_rnd_backann_t *ctx) +{ + csch_project_t *prj = (csch_project_t *)ctx->sheet->hidlib.project; + if (prj->abst == NULL) + rnd_actionva(&ctx->sheet->hidlib, "CompileProject", NULL); + if (prj->abst != NULL) + return 0; + return -1; +} + +#define BTN_GET_BA_AU \ + rnd_hid_attribute_t *attr = &ctx->dlg[ctx->wlist]; \ + rnd_hid_row_t *r = rnd_dad_tree_get_selected(attr); \ + sch_rnd_ba_t *ba = NULL; \ + sch_rnd_backann_auto_t *au; \ + long baid; \ + if (r == NULL) { \ + rnd_message(RND_MSG_ERROR, "Select a back annotation item first!\n"); \ + return; \ + } \ + baid = r->user_data2.lng; \ + if ((baid >= 0) && (baid < ctx->list.used)) \ + ba = &ctx->list.array[baid]; \ + if (ba == NULL) { \ + rnd_message(RND_MSG_ERROR, "Internal error: invalid ba index\n"); \ + return; \ + } \ + if (sch_rnd_backann_ensure_abst(ctx) != 0) { \ + rnd_message(RND_MSG_ERROR, "Failed to compile the project; can't do much without an abstract model!\n"); \ + return; \ + } \ + au = sch_rnd_backann_auto_entry(ctx, ba); \ + if (au == NULL) { \ + rnd_message(RND_MSG_ERROR, "Can not figure this entry (backann_auto_entry failed)\n"); \ + return; \ + } + +static void append_print_obj(gds_t *dst, csch_chdr_t *obj) +{ + csch_oidpath_t oidp = {0}; + + gds_append_str(dst, "object:"); + csch_oidpath_from_obj(&oidp, obj); + csch_oidpath_to_str_append(dst, &oidp); + csch_oidpath_free(&oidp); +} + +static void details_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr_btn) +{ + sch_rnd_backann_t *ctx = caller_data; + BTN_GET_BA_AU; + + switch(au->any.type) { + case SCH_RND_BAA_ATTR: + if (au->attr.grp != NULL) { + gds_t tmp = {0}; + csch_oidpath_t oidp = {0}; + fgw_arg_t args[4], ares; + csch_sheet_t *sheet = au->attr.grp->hdr.sheet; + + gds_append_str(&tmp, "object:"); + csch_oidpath_from_obj(&oidp, &au->attr.grp->hdr); + csch_oidpath_to_str_append(&tmp, &oidp); + csch_oidpath_free(&oidp); + + args[1].type = FGW_STR | FGW_DYN; args[1].val.str = tmp.array; + args[2].type = FGW_STR; args[2].val.cstr = au->attr.key; + rnd_actionv_bin(&sheet->hidlib, "AttributeDialog", &ares, 3, args); + fgw_arg_free(&rnd_fgw, &ares); + + /* tmp is free'd because it's been passed with FGW_DYN */ + } + else + rnd_message(RND_MSG_ERROR, "Can not find the object whose attributes are to be edited\n"); + break; + + case SCH_RND_BAA_DEL: + if ((au->del.obj != NULL) || (au->del.objlist.used > 0)) { + if (au->del.obj != NULL) { + gds_t tmp = {0}; + fgw_arg_t args[4], ares; + csch_sheet_t *sheet = au->del.obj->sheet; + + append_print_obj(&tmp, au->del.obj); + + args[1].type = FGW_STR | FGW_DYN; args[1].val.str = tmp.array; + rnd_actionv_bin(&sheet->hidlib, "TreeDialog", &ares, 2, args); + fgw_arg_free(&rnd_fgw, &ares); + /* tmp is free'd because it's been passed with FGW_DYN */ + } + if (au->del.objlist.used > 0) { + fgw_arg_t args[4], ares; + csch_chdr_t *obj = au->del.objlist.array[0]; + csch_sheet_t *sheet = obj->sheet; + + args[1].type = FGW_STR; args[1].val.str = "objarr"; + fgw_ptr_reg(&rnd_fgw, &args[2], CSCH_PTR_DOMAIN_COBJ_ARR, FGW_PTR | FGW_STRUCT, &au->del.objlist); + rnd_actionv_bin(&sheet->hidlib, "TreeDialog", &ares, 3, args); + fgw_ptr_unreg(&rnd_fgw, &args[2], CSCH_PTR_DOMAIN_COBJ_ARR); + } + } + else + rnd_message(RND_MSG_ERROR, "Can not find the object to delete\n"); + break; + + case SCH_RND_BAA_BREAK_GRCONN: + if (au->break_grconn.wire_obj != NULL) { + gds_t tmp = {0}; + csch_oidpath_t oidp = {0}; + fgw_arg_t args[4], ares; + csch_sheet_t *sheet = au->break_grconn.wire_obj->sheet; + + gds_append_str(&tmp, "object:"); + csch_oidpath_from_obj(&oidp, au->break_grconn.wire_obj); + csch_oidpath_to_str_append(&tmp, &oidp); + csch_oidpath_free(&oidp); + + args[1].type = FGW_STR | FGW_DYN; args[1].val.str = tmp.array; + rnd_actionv_bin(&sheet->hidlib, "TreeDialog", &ares, 2, args); + fgw_arg_free(&rnd_fgw, &ares); + /* tmp is free'd because it's been passed with FGW_DYN */ + } + else + rnd_message(RND_MSG_ERROR, "Can not find the wire to disconnect\n"); + break; + + case SCH_RND_BAA_MAKE_GRCONN: + if (au->make_grconn.term_obj != NULL) { + gds_t tmp = {0}; + csch_oidpath_t oidp = {0}; + fgw_arg_t args[4], ares; + csch_sheet_t *sheet = au->make_grconn.term_obj->sheet; + + gds_append_str(&tmp, "object:"); + csch_oidpath_from_obj(&oidp, au->break_grconn.term_obj); + csch_oidpath_to_str_append(&tmp, &oidp); + csch_oidpath_free(&oidp); + + args[1].type = FGW_STR | FGW_DYN; args[1].val.str = tmp.array; + rnd_actionv_bin(&sheet->hidlib, "TreeDialog", &ares, 2, args); + fgw_arg_free(&rnd_fgw, &ares); + /* tmp is free'd because it's been passed with FGW_DYN */ + } + else + rnd_message(RND_MSG_ERROR, "Can not find the terminal to connect\n"); + break; + + case SCH_RND_BAA_LOG: + rnd_message(RND_MSG_ERROR, "Tips for this entry:\n%s\n", au->log.str); + break; + + + default: + rnd_message(RND_MSG_ERROR, "Can not figure this entry (operation not handled in details_cb switch)\n"); + } + + sch_rnd_backann_auto_free(au); +} + +typedef enum { HOR, VER, PT, OTHER } dir_t; + +/* Returns if a line is horizontal, vertical, a point or other (non-line or diag) */ +static dir_t line_dir(csch_line_t *lin) +{ + int h, v; + + if (lin->hdr.type != CSCH_CTYPE_LINE) + return OTHER; + + + h = (lin->inst.c.p1.y == lin->inst.c.p2.y); + v = (lin->inst.c.p1.x == lin->inst.c.p2.x); + + if (h && v) return PT; + if (h) return HOR; + if (v) return VER; + return OTHER; +} + +/* Draw two wires, x1;y1 -> x2;y2 -> x3;y3 if they are safe */ +static int draw_L_wires_(csch_sheet_t *sheet, csch_coord_t x1, csch_coord_t y1, csch_coord_t x2, csch_coord_t y2, csch_coord_t x3, csch_coord_t y3) +{ + csch_comm_str_t pen; + + /* colinear -> return error so straight line is drawn */ + if ((x1 == x2) && (x1 == x3)) + return -1; + if ((y1 == y2) && (y1 == y3)) + return -1; + + if (!csch_is_wireline_safe(sheet, x1, y1, x2, y2)) + return -1; + if (!csch_is_wireline_safe(sheet, x2, y2, x3, y3)) + return -1; + + pen = csch_comm_str(sheet, "wire", 1); + csch_wirenet_draw(sheet, pen, x1, y1, x2, y2); + csch_wirenet_draw(sheet, pen, x2, y2, x3, y3); + return 0; +} + +/* Attempt to draw an L shaped wire pair from mk's term (choose most fitting + direction). Returns -1 if not found/drawn */ +static int draw_L_wires(sch_rnd_backann_auto_make_grconn_t *mk) +{ + csch_sheet_t *sheet = mk->term_obj->sheet; + dir_t dir1 = line_dir((csch_line_t *)mk->term_obj); + dir_t dir2 = line_dir((csch_line_t *)mk->wire_obj); + + if ((dir1 == HOR) && (dir2 == HOR)) return -1; /* go for a single straight line */ + if ((dir1 == VER) && (dir2 == VER)) return -1; /* go for a single straight line */ + + /* try to leave terminal in the same direction as the terminal is */ + if (dir1 == HOR) + return draw_L_wires_(sheet, mk->x1, mk->y1, mk->x2, mk->y1, mk->x2, mk->y2); + + if (dir1 == VER) + return draw_L_wires_(sheet, mk->x1, mk->y1, mk->x1, mk->y2, mk->x2, mk->y2); + + return -1; /* terminal is not a line */ +} + +static void autofix_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr_btn) +{ + sch_rnd_backann_t *ctx = caller_data; + BTN_GET_BA_AU; + + switch(au->any.type) { + case SCH_RND_BAA_ATTR: + if (au->attr.grp == NULL) { + rnd_message(RND_MSG_ERROR, "Can not modify derived attribute\n"); + break; + } + if (au->attr.is_str) { + csch_sheet_t *sheet = au->attr.grp->hdr.sheet; + csch_source_arg_t *source = csch_attrib_src_c(NULL, 0, 0, "back annotation autofix"); + + if (au->attr.want_val != NULL) + csch_attr_modify_str(sheet, au->attr.grp, -1, au->attr.key, au->attr.want_val, source, 1); + else + csch_attr_modify_del(sheet, au->attr.grp, au->attr.key, 1); + } + else + rnd_message(RND_MSG_ERROR, "Can not modify array type attribute\n"); + break; + + case SCH_RND_BAA_DEL: + if (au->del.obj != NULL) { + if (!csch_obj_is_deleted(au->del.obj)) + csch_op_remove(au->del.obj->sheet, au->del.obj); + } + if (au->del.objlist.used > 0) { + long n; + for(n = 0; n < au->del.objlist.used; n++) { + csch_chdr_t *obj = au->del.objlist.array[n]; + if (!csch_obj_is_deleted(obj)) + csch_op_remove(obj->sheet, obj); + } + } + break; + + case SCH_RND_BAA_BREAK_GRCONN: + if (au->break_grconn.endp == 1) { + csch_line_t *wire = (csch_line_t *)au->break_grconn.wire_obj; + uundo_freeze_serial(&wire->hdr.sheet->undo); + csch_line_modify(wire->hdr.sheet, wire, &au->break_grconn.newx, &au->break_grconn.newy, NULL, NULL, 1, 0, 0); + uundo_unfreeze_serial(&wire->hdr.sheet->undo); + uundo_inc_serial(&wire->hdr.sheet->undo); + } + else if (au->break_grconn.endp == 2) { + csch_line_t *wire = (csch_line_t *)au->break_grconn.wire_obj; + uundo_freeze_serial(&wire->hdr.sheet->undo); + csch_line_modify(wire->hdr.sheet, wire, NULL, NULL, &au->break_grconn.newx, &au->break_grconn.newy, 1, 0, 0); + uundo_unfreeze_serial(&wire->hdr.sheet->undo); + uundo_inc_serial(&wire->hdr.sheet->undo); + } + else + rnd_message(RND_MSG_ERROR, "Graphical connection can not be safely broken by removing a wire\nPlease edit the wirenet manually!\n"); + break; + + case SCH_RND_BAA_MAKE_GRCONN: + if ((au->make_grconn.term_obj != NULL) && (au->make_grconn.wire_obj != NULL)) { + csch_sheet_t *sheet = au->make_grconn.term_obj->sheet; + if (draw_L_wires(&au->make_grconn) == 0) + break; + if (csch_is_wireline_safe(sheet, au->make_grconn.x1, au->make_grconn.y1, au->make_grconn.x2, au->make_grconn.y2)) { + csch_wirenet_draw(sheet, csch_comm_str(sheet, "wire", 1), au->make_grconn.x1, au->make_grconn.y1, au->make_grconn.x2, au->make_grconn.y2); + rnd_gui->invalidate_all(rnd_gui); + } + else + rnd_message(RND_MSG_ERROR, "Can't make graphical connection: wire would hit other wire ends.\nPlease make the connection manually!\n"); + } + else + rnd_message(RND_MSG_ERROR, "Can't make graphical connection: wirenet and terminal doesn't share the same sheet.\nPlease make the connection manually!\n"); + + break; + + case SCH_RND_BAA_LOG: + rnd_message(RND_MSG_ERROR, "This one needs to be done manually:\n%s\n", au->log.str); + break; + + default: + rnd_message(RND_MSG_ERROR, "Can not figure this entry (operation not handled in autofix_cb switch)\n"); + } + + sch_rnd_backann_auto_free(au); +} + +static void backann_dlg(sch_rnd_backann_t *ctx) +{ + const char *hdr[] = {"#", "status", "instruction", NULL}; + rnd_hid_dad_buttons_t clbtn[] = {{"Close", 0}, {NULL, 0}}; + + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_TREE(ctx->dlg, 3, 0, hdr); /* top: list of instructions */ + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_TREE_SET_CB(ctx->dlg, selected_cb, ba_select_cb); + RND_DAD_TREE_SET_CB(ctx->dlg, ctx, ctx); + ctx->wlist = RND_DAD_CURRENT(ctx->dlg); + + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "Details"); + RND_DAD_HELP(ctx->dlg, "Show details of the issue and tips on resolving it"); + RND_DAD_CHANGE_CB(ctx->dlg, details_cb); + + RND_DAD_BUTTON(ctx->dlg, "Auto-fix"); + RND_DAD_HELP(ctx->dlg, "If possible, perform the change to resolve the issue automatically"); + RND_DAD_CHANGE_CB(ctx->dlg, autofix_cb); + + RND_DAD_BEGIN_VBOX(ctx->dlg); /* spring */ + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_END(ctx->dlg); + + RND_DAD_BUTTON_CLOSES(ctx->dlg, clbtn); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + + RND_DAD_DEFSIZE(ctx->dlg, 200, 400); + RND_DAD_NEW("Backann", ctx->dlg, "Back annotation", ctx, 0, backann_dlg_close_cb); /* type=local */ + + backann_data2dlg(ctx); +} Index: tags/1.0.5/src/plugins/backann/parse_backann.c =================================================================== --- tags/1.0.5/src/plugins/backann/parse_backann.c (nonexistent) +++ tags/1.0.5/src/plugins/backann/parse_backann.c (revision 10414) @@ -0,0 +1,149 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - back annotation parser + * Copyright (C) 2022, 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022 and Entrust in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/* Parse line based text formats for back annotation */ + +#include + +#include +#include + +#include +#include + +static void backann_free_entry(sch_rnd_backann_t *ctx, sch_rnd_ba_t *ba) +{ + free(ba->raw); + ba->raw = NULL; + ba->type = SCH_RND_BAT_invalid; +} + +static void backann_free_list(sch_rnd_backann_t *ctx) +{ + long n; + for(n = 0; n < ctx->list.used; n++) + backann_free_entry(ctx, &ctx->list.array[n]); + vtba_uninit(&ctx->list); +} + +static sch_rnd_ba_t *ba_find_conn_del(sch_rnd_backann_t *ctx, const char *net, const char *comp, const char *term) +{ + long n; + for(n = 0; n < ctx->list.used; n++) { + sch_rnd_ba_t *ba = &ctx->list.array[n]; + if (ba->type == SCH_RND_BAT_CONN_DEL) { + if ((strcmp(net, ba->value.conn_del.net) == 0) && (strcmp(comp, ba->value.conn_del.comp) == 0) && (strcmp(term, ba->value.conn_del.term) == 0)) + return ba; + } + } + return NULL; +} + +static void backann_postproc(sch_rnd_backann_t *ctx) +{ + long n; + for(n = 0; n < ctx->list.used; n++) { + sch_rnd_ba_t *ba = &ctx->list.array[n]; + ba->optional = 0; + if (ba->type != SCH_RND_BAT_NETINFO) continue; + if (ba_find_conn_del(ctx, ba->value.netinfo.net, ba->value.netinfo.comp, ba->value.netinfo.term) != NULL) + ba->optional = 1; + } +} + +#include "parse_bap.c" +#include "parse_tedax.c" + +typedef enum { + FT_UNKNOWN, + FT_BAP, + FT_TEDAX +} file_type_t; + +static int backann_parse(sch_rnd_backann_t *ctx) +{ + FILE *f; + char *line, buff[1024]; + long lineno = 0; + int err = 0; + file_type_t ft = FT_UNKNOWN; + tedax_backann_t tdx = {0}; + + f = rnd_fopen(&ctx->sheet->hidlib, ctx->fn, "r"); + if (f == NULL) { + rnd_message(RND_MSG_ERROR, "Failed to open back annotation pack '%s'\n", ctx->fn); + return -1; + } + + while((line = fgets(buff, sizeof(buff), f)) != NULL) { + lineno++; + while(isspace(*line)) line++; + if ((*line == '#') || (*line == '\0')) continue; + + switch(ft) { + case FT_UNKNOWN: + if ((strncmp(line, "tEDAx", 5) == 0) && (isspace(line[5]))) { + char *ver = line+5; + while(isspace(*ver)) ver++; + if (*ver != 'v') { + rnd_message(RND_MSG_ERROR, "backann tEDAx: invalid version tag '%s' in %s:%ld\n", ver, ctx->fn, lineno); + err = 1; + break; + } + ver++; + if (atoi(ver) != 1) { + rnd_message(RND_MSG_ERROR, "backann tEDAx: invalid version number '%s' in %s:%ld\n", ver, ctx->fn, lineno); + err = 1; + break; + } + ft = FT_TEDAX; + break; /* parse from the next line */ + } + ft = FT_BAP; + /* fall through: first line of a bap (unfortunately has no header) */ + case FT_BAP: + err |= backann_parse_bap(ctx, line, lineno); + break; + case FT_TEDAX: + err |= backann_parse_tedax(ctx, &tdx, line, lineno); + break; + } + + if (err) + break; + } + + fclose(f); + + if (err) + backann_free_list(ctx); + else + backann_postproc(ctx); + + return err; +} Index: tags/1.0.5/src/plugins/backann/parse_bap.c =================================================================== --- tags/1.0.5/src/plugins/backann/parse_bap.c (nonexistent) +++ tags/1.0.5/src/plugins/backann/parse_bap.c (revision 10414) @@ -0,0 +1,198 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - back annotation parser + * Copyright (C) 2022, 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022 and Entrust in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/* Parse the old pcb-rnd bap format designed for geda back in 2016; included + from the common line parser */ + + +#include "bap_sphash.h" + +static char *concat_raw(char **str, int *len, int numstr) +{ + int n, totlen = 0; + char *start, *end; + + for(n = 0; n < numstr; n++) + totlen += len[n] + 1; + + end = start = malloc(totlen); + + for(n = 0; n < numstr; end += len[n]+1, n++) + memcpy(end, str[n], len[n]+1); + + return start; +} + +/* Shift the next token from "src" (current token's start); pointer to next + token start is stored in dst; true length (no separators) of src stored in + srclen. New token ends at any char at seps; whitepsace before the new + token is removed */ +#define shiftl(dst, srclen, src, seps, error_inst) \ +do { \ + char *sep = strpbrk(src, seps); \ + if (sep == NULL) { error_inst; } \ + else { \ + *sep = '\0'; \ + srclen = sep - src; \ + sep++; \ + while(isspace(*sep)) sep++; \ + dst = sep; \ + } \ +} while(0) +#define shiftlc(dst, srclen, src, sepc, error_inst) \ +do { \ + char *sep = strchr(src, sepc); \ + if (sep == NULL) { error_inst; } \ + else { \ + *sep = '\0'; \ + srclen = sep - src; \ + sep++; \ + while(isspace(*sep)) sep++; \ + dst = sep; \ + } \ +} while(0) + +static int backann_parse_net_info(sch_rnd_backann_t *ctx, sch_rnd_ba_type_t type, char *raw, long lineno) +{ + char *a[4]; + sch_rnd_ba_t *ba; + int len[4]; + + a[0] = raw; + + shiftl(a[1], len[0], a[0], " \t", { + rnd_message(RND_MSG_ERROR, "Missing second arg in %s:%ld\n", ctx->fn, lineno); + goto error; + }); + +/* rnd_trace("NET INFO:\n");*/ + + while(*a[1] != '\0') { + + shiftlc(a[2], len[1], a[1], '-', { + rnd_message(RND_MSG_ERROR, "Missing comp name arg in %s:%ld\n", ctx->fn, lineno); + goto error; + }); + + shiftl(a[3], len[2], a[2], " \t\r\n", { + rnd_message(RND_MSG_ERROR, "Missing term name arg in %s:%ld\n", ctx->fn, lineno); + goto error; + }); + + ba = vtba_alloc_append(&ctx->list, 1); + ba->type = type; + ba->raw = concat_raw(a, len, 3); + ba->value.any4.a0 = ba->raw; + ba->value.any4.a1 = ba->value.any4.a0 + len[0] + 1; + ba->value.any4.a2 = ba->value.any4.a1 + len[1] + 1; + ba->value.any4.a3 = NULL; + +/* rnd_trace(" '%s' '%s' '%s' sep='%s'\n", ba->value.any4.a0, ba->value.any4.a1, ba->value.any4.a2, a[3]);*/ + a[1] = a[3]; + } + + return 0; + + error:; + return -1; +} + + +static int backann_parse_entry(sch_rnd_backann_t *ctx, sch_rnd_ba_type_t type, char *args, long lineno) +{ + int len[4]; + char *raw, *a[4]; + sch_rnd_ba_t *ba; + + raw = rnd_strdup(args); + a[0] = raw; + + if ((type == SCH_RND_BAT_CONN_ADD) || (type == SCH_RND_BAT_CONN_DEL)) { + shiftlc(a[1], len[0], a[0], '-', { + rnd_message(RND_MSG_ERROR, "Missing term name %s:%ld\n", ctx->fn, lineno); + goto error; + }); + } + else { + shiftl(a[1], len[0], a[0], " \t", { + rnd_message(RND_MSG_ERROR, "Missing second arg in %s:%ld\n", ctx->fn, lineno); + goto error; + }); + } + + shiftl(a[2], len[1], a[1], " \t", { + rnd_message(RND_MSG_ERROR, "Missing third arg in %s:%ld\n", ctx->fn, lineno); + goto error; + }); + + shiftl(a[3], len[2], a[2], "\r\n", { + rnd_message(RND_MSG_ERROR, "Missing fourth arg termination in %s:%ld (line too long?)\n", ctx->fn, lineno); + goto error; + }); + + (void)len[0]; + + ba = vtba_alloc_append(&ctx->list, 1); + ba->type = type; + ba->raw = raw; + ba->value.any4.a0 = a[0]; + ba->value.any4.a1 = a[1]; + ba->value.any4.a2 = a[2]; + ba->value.any4.a3 = a[3]; + return 0; + + error:; + free(raw); + return -1; +} + +static int backann_parse_bap(sch_rnd_backann_t *ctx, char *line, int lineno) +{ + char *args = strpbrk(line, " \t\r\n"); + + if (args == NULL) { + rnd_message(RND_MSG_ERROR, "backann bap: Invalid command (no args) in %s:%ld\n", ctx->fn, lineno); + return 1; + } + + *args = '\0'; + args++; + while(isspace(*args)) args++; + + switch(backann_bap_sphash(line)) { + case backann_bap_net_info: return backann_parse_net_info(ctx, SCH_RND_BAT_NETINFO, args, lineno); + case backann_bap_change_attrib: return backann_parse_entry(ctx, SCH_RND_BAT_COMP_ATTR, args, lineno); + case backann_bap_del_conn: return backann_parse_entry(ctx, SCH_RND_BAT_CONN_DEL, args, lineno); + case backann_bap_add_conn: return backann_parse_entry(ctx, SCH_RND_BAT_CONN_ADD, args, lineno); + default: + rnd_message(RND_MSG_ERROR, "backann bap: Unknown command '%s' in %s:%ld\n", line, ctx->fn, lineno); + return 1; + } + + return 1; +} Index: tags/1.0.5/src/plugins/backann/parse_tedax.c =================================================================== --- tags/1.0.5/src/plugins/backann/parse_tedax.c (nonexistent) +++ tags/1.0.5/src/plugins/backann/parse_tedax.c (revision 10414) @@ -0,0 +1,198 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - back annotation parser + * Copyright (C) 2022, 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022 and Entrust in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/* Parse tEDAx backann blocks; included from the common line parser */ + +#include + +typedef struct { + int ver; +} tedax_backann_t; + +static int tedax_parse_net_info(sch_rnd_backann_t *ctx, tedax_backann_t *tdx, char *raw, int argc, char *argv[], int lineno) +{ + sch_rnd_ba_t *ba = vtba_alloc_append(&ctx->list, 1); + + if (argc != 4) { + rnd_message(RND_MSG_ERROR, "backann tEDAx: syntax error: wrong number of arguments for %s %s:%ld\n", argv[0], ctx->fn, lineno); + return -1; + } + + ba->type = SCH_RND_BAT_NETINFO; + ba->raw = raw; + ba->value.netinfo.net = argv[1]; + ba->value.netinfo.comp = argv[2]; + ba->value.netinfo.term = argv[3]; + + return 0; +} + +static int tedax_parse_add_del_conn(sch_rnd_backann_t *ctx, tedax_backann_t *tdx, char *raw, int argc, char *argv[], int lineno) +{ + sch_rnd_ba_t *ba = vtba_alloc_append(&ctx->list, 1); + + if (argc != 4) { + rnd_message(RND_MSG_ERROR, "backann tEDAx: syntax error: wrong number of arguments for %s %s:%ld\n", argv[0], ctx->fn, lineno); + return -1; + } + + ba->type = (*(argv[0]) == 'a') ? SCH_RND_BAT_CONN_ADD : SCH_RND_BAT_CONN_DEL; + ba->raw = raw; + ba->value.conn_add.net = argv[1]; + ba->value.conn_add.comp = argv[2]; + ba->value.conn_add.term = argv[3]; + + return 0; +} + +static int tedax_parse_attr_conn(sch_rnd_backann_t *ctx, tedax_backann_t *tdx, char *raw, int argc, char *argv[], int lineno) +{ + sch_rnd_ba_t *ba = vtba_alloc_append(&ctx->list, 1); + + if ((argc != 3) && (argc != 4)) { + rnd_message(RND_MSG_ERROR, "backann tEDAx: syntax error: wrong number of arguments for %s %s:%ld\n", argv[0], ctx->fn, lineno); + return -1; + } + + ba->type = SCH_RND_BAT_NET_ATTR; + ba->raw = raw; + ba->value.net_attr.net = argv[1]; + ba->value.net_attr.key = argv[2]; + ba->value.net_attr.val = argv[3]; + + return 0; +} + +static int tedax_parse_add_del_comp(sch_rnd_backann_t *ctx, tedax_backann_t *tdx, char *raw, int argc, char *argv[], int lineno) +{ + sch_rnd_ba_t *ba = vtba_alloc_append(&ctx->list, 1); + + if (tdx->ver < 2) + rnd_message(RND_MSG_ERROR, "backann tEDAx: component add/del did not exist in backann v1 in %s:%ld\n", ctx->fn, lineno); + + if (argc != 2) { + rnd_message(RND_MSG_ERROR, "backann tEDAx: syntax error: wrong number of arguments for %s %s:%ld\n", argv[0], ctx->fn, lineno); + return -1; + } + + ba->type = (*(argv[0]) == 'a') ? SCH_RND_BAT_COMP_ADD : SCH_RND_BAT_COMP_DEL; + ba->raw = raw; + ba->value.comp_add.comp = argv[1]; + return 0; +} + +static int tedax_parse_attr_comp(sch_rnd_backann_t *ctx, tedax_backann_t *tdx, char *raw, int argc, char *argv[], int lineno) +{ + sch_rnd_ba_t *ba = vtba_alloc_append(&ctx->list, 1); + + if ((argc != 3) && (argc != 4)) { + rnd_message(RND_MSG_ERROR, "backann tEDAx: syntax error: wrong number of arguments for %s %s:%ld\n", argv[0], ctx->fn, lineno); + return -1; + } + + ba->type = SCH_RND_BAT_COMP_ATTR; + ba->raw = raw; + ba->value.comp_attr.comp = argv[1]; + ba->value.comp_attr.key = argv[2]; + ba->value.comp_attr.val = argv[3]; + + return 0; +} + +static int tedax_parse_attr_pin(sch_rnd_backann_t *ctx, tedax_backann_t *tdx, char *raw, int argc, char *argv[], int lineno) +{ + sch_rnd_ba_t *ba = vtba_alloc_append(&ctx->list, 1); + + if ((argc != 4) && (argc != 5)) { + rnd_message(RND_MSG_ERROR, "backann tEDAx: syntax error: wrong number of arguments for %s %s:%ld\n", argv[0], ctx->fn, lineno); + return -1; + } + + ba->type = SCH_RND_BAT_TERM_ATTR; + ba->raw = raw; + ba->value.term_attr.comp = argv[1]; + ba->value.term_attr.term = argv[2]; + ba->value.term_attr.key = argv[3]; + ba->value.term_attr.val = argv[4]; + + return 0; +} + + + + +static int backann_parse_tedax(sch_rnd_backann_t *ctx, tedax_backann_t *tdx, char *line, int lineno) +{ + char *tmp, *argv[16], *vers; + int argc, len; + + len = strlen(line)+1; + tmp = malloc(len); + + memset(argv, 0, sizeof(argv)); + argc = tedax_getline_mem(&line, tmp, len, argv, sizeof(argv)/sizeof(argv[0])); + if (argc < 0) { + rnd_message(RND_MSG_ERROR, "backann tEDAx: failed to tokenize in %s:%ld\n", ctx->fn, lineno); + goto error; + } + + switch(backann_bap_sphash(argv[0])) { + case backann_bap_begin: + if (strcmp(argv[1], "backann") != 0) { + rnd_message(RND_MSG_ERROR, "backann tEDAx: wrong block '%s'; expected backann %s:%ld\n", argv[1], ctx->fn, lineno); + goto error; + } + vers = argv[2]; + tdx->ver = atoi(vers+1); + if (*vers != 'v') { + rnd_message(RND_MSG_ERROR, "backann tEDAx: wrong block version; expected backann %s:%ld\n", ctx->fn, lineno); + goto error; + } + free(tmp); + return 0; + case backann_bap_end: free(tmp); return 0; + case backann_bap_net_info: return tedax_parse_net_info(ctx, tdx, tmp, argc, argv, lineno); + case backann_bap_add_conn: return tedax_parse_add_del_conn(ctx, tdx, tmp, argc, argv, lineno); + case backann_bap_del_conn: return tedax_parse_add_del_conn(ctx, tdx, tmp, argc, argv, lineno); + case backann_bap_attr_conn: return tedax_parse_attr_conn(ctx, tdx, tmp, argc, argv, lineno); + case backann_bap_add_comp: return tedax_parse_add_del_comp(ctx, tdx, tmp, argc, argv, lineno); + case backann_bap_del_comp: return tedax_parse_add_del_comp(ctx, tdx, tmp, argc, argv, lineno); + case backann_bap_attr_comp: return tedax_parse_attr_comp(ctx, tdx, tmp, argc, argv, lineno); + case backann_bap_fattr_comp: return tedax_parse_attr_comp(ctx, tdx, tmp, argc, argv, lineno); + case backann_bap_attr_pin: return tedax_parse_attr_pin(ctx, tdx, tmp, argc, argv, lineno); + default: + rnd_message(RND_MSG_ERROR, "backann tEDAx: invalid instruction '%s' %s:%ld\n", argv[0], ctx->fn, lineno); + goto error; + } + + return 0; + + error:; + free(tmp); + return 1; +} Index: tags/1.0.5/src/plugins/construct/Makefile =================================================================== --- tags/1.0.5/src/plugins/construct/Makefile (nonexistent) +++ tags/1.0.5/src/plugins/construct/Makefile (revision 10414) @@ -0,0 +1,2 @@ +all: + cd ../../sch-rnd && make mod_construct Index: tags/1.0.5/src/plugins/construct/Plug.tmpasm =================================================================== --- tags/1.0.5/src/plugins/construct/Plug.tmpasm (nonexistent) +++ tags/1.0.5/src/plugins/construct/Plug.tmpasm (revision 10414) @@ -0,0 +1,10 @@ +put /local/rnd/mod {construct} +put /local/rnd/mod/OBJS [@ + $(PLUGDIR)/construct/construct.o +@] + +switch /local/module/construct/controls + case {buildin} include /local/csch/tmpasm/buildin; end; + case {plugin} include /local/csch/tmpasm/plugin; end; + case {disable} include /local/csch/tmpasm/disable; end; +end Index: tags/1.0.5/src/plugins/construct/breakup.c =================================================================== --- tags/1.0.5/src/plugins/construct/breakup.c (nonexistent) +++ tags/1.0.5/src/plugins/construct/breakup.c (revision 10414) @@ -0,0 +1,69 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - break up groups + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/* Break up group into individual objects */ + +#include +#include +#include +#include +#include +#include + +static int sch_rnd_breakup_grp(csch_sheet_t *sheet, csch_cgrp_t *dst, csch_cgrp_t *src, int silent) +{ + long res = 0; + htip_entry_t *e; + + for(e = htip_first(&src->id2obj); e != NULL; e = htip_next(&src->id2obj, e)) { + csch_chdr_t *newo = csch_op_copy_into(sheet, dst, e->value); + if (newo != NULL) + csch_inst2spec(sheet, newo, e->value, 1); + else + res = -1; + } + + return res; +} + +static int sch_rnd_breakup_poly(csch_sheet_t *sheet, csch_cgrp_t *dst, csch_cpoly_t *src, int silent) +{ + int res = 0; + long n; + + for(n = 0; n < src->outline.used; n++) { + csch_coutline_t *olo = &src->outline.array[n]; + csch_chdr_t *newo = csch_op_copy_into(sheet, dst, &olo->hdr); + if (newo == NULL) + res = -1; + } + + return res; +} + + Index: tags/1.0.5/src/plugins/construct/construct.c =================================================================== --- tags/1.0.5/src/plugins/construct/construct.c (nonexistent) +++ tags/1.0.5/src/plugins/construct/construct.c (revision 10414) @@ -0,0 +1,260 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - construct groups + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + + +#include + +#include +#include +#include +#include + +#include +#include + +static const char sch_construct_cookie[] = "construct plugin"; + +RND_INLINE int can_convert(csch_sheet_t *sheet, csch_chdr_t *obj, unsigned int *warn, int by_selection) +{ + if (obj->parent != &sheet->direct) { + + if (by_selection) { /* when going by selection, do not warn objects part of first-level selected group */ + csch_cgrp_t *g; + for(g = obj->parent; g->hdr.parent != &sheet->direct; g = g->hdr.parent) ; + if (g->hdr.selected) + return 0; + } + + if ((warn != NULL) && (!(*warn & 1))) { + rnd_message(RND_MSG_WARNING, "Some objects are not copied into the group because they are already part of a group\n"); + *warn |= 1; + } + return 0; /* do not convert objects already part of a group */ + } + return 1; +} + +#include "breakup.c" +#include "conv_grp.c" +#include "conv_poly.c" + + +static const char csch_acts_Convert[] = "Convert(selected|buffer|object|list, poly[gon]|group|sym[bol]|term[inal], [oidlist])\n"; +static const char csch_acth_Convert[] = "Convert objects into a polygon or a group."; +static fgw_error_t csch_act_Convert(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_design_t *hidlib = RND_ACT_DESIGN; + csch_sheet_t *sheet = (csch_sheet_t *)hidlib; + csch_cgrp_t *grp; + vtp0_t objs = {0}; + int src, type; + long n; + + RND_ACT_CONVARG(1, FGW_KEYWORD, Convert, src = fgw_keyword(&argv[1])); + RND_ACT_CONVARG(2, FGW_KEYWORD, Convert, type = fgw_keyword(&argv[2])); + + uundo_freeze_serial(&sheet->undo); + switch(src) { + case F_Selected: + if (csch_search_all_selected(sheet, NULL, &objs, 1) == 0) { + rnd_message(RND_MSG_ERROR, "no movable object selected\n"); + goto error; + } + break; + + case F_Object: + + case F_Buffer: + case F_List: + rnd_message(RND_MSG_ERROR, "not yet implemented, sorry\n"); + goto error; + + default: + rnd_message(RND_MSG_ERROR, "Convert: wrong first arg\n"); + goto error; + } + + switch(type) { + case F_Poly: + case F_Polygon: + if (sch_rnd_conv_poly(sheet, &sheet->direct, &objs, 0) == NULL) + goto error; + break; + + case F_Group: + case F_Sym: + case F_Symbol: + case F_Term: + case F_Terminal: + if ((grp = sch_rnd_conv_grp(sheet, &sheet->direct, &objs, P2C(sch_rnd_crosshair_x), P2C(sch_rnd_crosshair_y), 0)) == NULL) + goto error; + break; + + default: + rnd_message(RND_MSG_ERROR, "Convert: wrong second arg\n"); + goto error; + } + + /* side effects for advanced groups */ + switch(type) { + case F_Sym: + case F_Symbol: + csch_cgrp_role_side_effects(sheet, grp, CSCH_ROLE_SYMBOL); + break; + case F_Term: + case F_Terminal: + csch_cgrp_role_side_effects(sheet, grp, CSCH_ROLE_TERMINAL); + break; + default: break; + } + + for(n = 0; n < objs.used; n++) + csch_op_remove(sheet, objs.array[n]); + + uundo_unfreeze_serial(&sheet->undo); + uundo_inc_serial(&sheet->undo); + vtp0_uninit(&objs); + RND_ACT_IRES(0); + return 0; + + error:; + uundo_unfreeze_serial(&sheet->undo); + vtp0_uninit(&objs); + RND_ACT_IRES(-1); + return 0; +} + +static const char csch_acts_Breakup[] = "Breakup(selected|buffer|object, group|poly[gon]|all, [sheet|grp-oid])\n"; +static const char csch_acth_Breakup[] = "Breakup group(s) found in context named in first arg, place resulting objects in the context named in second arg if present or on sheet if not present"; +static fgw_error_t csch_act_Breakup(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_design_t *hidlib = RND_ACT_DESIGN; + csch_sheet_t *sheet = (csch_sheet_t *)hidlib; + const char *dsts = NULL; + csch_cgrp_t *dst = NULL; + vtp0_t srcs = {0}; + csch_cmask_t mask; + int src, types; + long n; + + RND_ACT_CONVARG(1, FGW_KEYWORD, Breakup, src = fgw_keyword(&argv[1])); + RND_ACT_CONVARG(2, FGW_KEYWORD, Breakup, types = fgw_keyword(&argv[2])); + RND_ACT_MAY_CONVARG(3, FGW_STR, Breakup, dsts = argv[3].val.cstr); + + uundo_freeze_serial(&sheet->undo); + switch(types) { + case F_Poly: + case F_Polygon: + mask = CSCH_CMASK_POLY; + break; + case F_Group: + mask = CSCH_CMASK_ANY_GRP; + break; + case F_Any: + mask = CSCH_CMASK_ANY; + break; + default: + rnd_message(RND_MSG_ERROR, "Breakup: invalid second argument\n"); + goto error; + } + + + switch(src) { + case F_Selected: + if (csch_search_all_selected(sheet, NULL, &srcs, 1) == 0) { + rnd_message(RND_MSG_ERROR, "not object selected\n"); + goto error; + } + break; + + case F_Object: + + case F_Buffer: + case F_List: + rnd_message(RND_MSG_ERROR, "not yet implemented, sorry\n"); + goto error; + + default: + rnd_message(RND_MSG_ERROR, "Breakup: wrong first arg\n"); + goto error; + } + + if ((dsts == NULL) || (strcmp(dsts, "sheet") == 0)) { + dst = &sheet->direct; + } + else { + rnd_message(RND_MSG_ERROR, "Breakup: oid in third argument not yet supported\n"); + goto error; + } + + for(n = 0; n < srcs.used; n++) { + csch_chdr_t *obj = srcs.array[n]; + + if (!csch_ctype_in_cmask(obj->type, mask)) continue; + + if (csch_obj_is_grp(obj)) + sch_rnd_breakup_grp(sheet, dst, (csch_cgrp_t *)obj, 0); + else if (obj->type == CSCH_CTYPE_POLY) + sch_rnd_breakup_poly(sheet, dst, (csch_cpoly_t *)obj, 0); + csch_op_remove(sheet, obj); + } + + uundo_unfreeze_serial(&sheet->undo); + uundo_inc_serial(&sheet->undo); + vtp0_uninit(&srcs); + RND_ACT_IRES(0); + return 0; + + error:; + uundo_unfreeze_serial(&sheet->undo); + vtp0_uninit(&srcs); + RND_ACT_IRES(-1); + return 0; +} + +static rnd_action_t sch_construct_action_list[] = { + {"Convert", csch_act_Convert, csch_acth_Convert, csch_acts_Convert}, + {"Breakup", csch_act_Breakup, csch_acth_Breakup, csch_acts_Breakup} +}; + + +int pplg_check_ver_construct(int ver_needed) { return 0; } + +void pplg_uninit_construct(void) +{ + rnd_remove_actions_by_cookie(sch_construct_cookie); +} + +int pplg_init_construct(void) +{ + RND_API_CHK_VER; + + RND_REGISTER_ACTIONS(sch_construct_action_list, sch_construct_cookie); + return 0; +} + Index: tags/1.0.5/src/plugins/construct/construct.pup =================================================================== --- tags/1.0.5/src/plugins/construct/construct.pup (nonexistent) +++ tags/1.0.5/src/plugins/construct/construct.pup (revision 10414) @@ -0,0 +1,7 @@ +$class feature +$short convert/breakup functionality +$long construct complex objects from atoms, break up groups +$state works +$package (core) +default buildin +autoload 1 Index: tags/1.0.5/src/plugins/construct/conv_grp.c =================================================================== --- tags/1.0.5/src/plugins/construct/conv_grp.c (nonexistent) +++ tags/1.0.5/src/plugins/construct/conv_grp.c (revision 10414) @@ -0,0 +1,67 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - convert groups + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/* Convert floating objects to group (low level) */ + +#include +#include +#include +#include +#include + +#include + +static csch_cgrp_t *sch_rnd_conv_grp(csch_sheet_t *sheet, csch_cgrp_t *parent, vtp0_t *objs, csch_coord_t ox, csch_coord_t oy, int silent) +{ + long n; + unsigned int warn = 0; + csch_cgrp_t *grp = (csch_cgrp_t *)csch_op_create(sheet, parent, CSCH_CTYPE_GRP); + + for(n = 0; n < objs->used; n++) { + csch_chdr_t *newo, *obj = objs->array[n]; + + if (!can_convert(sheet, obj, &warn, 1)) { + vtp0_remove(objs, n, 1); + n--; + continue; + } + + newo = csch_cobj_dup(sheet, grp, obj, 0, 0); + if ((newo != NULL) && ((ox != 0) || (oy != 0))) + csch_move(sheet, newo, -ox, -oy, 0); + } + + grp->x = ox; + grp->y = oy; + + csch_cgrp_update(sheet, grp, 1); + + return grp; +} + + Index: tags/1.0.5/src/plugins/construct/conv_poly.c =================================================================== --- tags/1.0.5/src/plugins/construct/conv_poly.c (nonexistent) +++ tags/1.0.5/src/plugins/construct/conv_poly.c (revision 10414) @@ -0,0 +1,311 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - convert to polygon + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/* Convert floating objects to polygon (low level) */ + +#include +#include +#include +#include +#include +#include + +typedef struct { + csch_chdr_t *objs[2]; /* remember at most 2 objects for a point; 3rd is a junction -> error */ + char side[2]; /* 0 means start, 1 means end */ + char visited; /* loop mapping: endpoint already visited */ +} end_t; + +static int keyeq(g2d_vect_t a, g2d_vect_t b) +{ + return (a.x == b.x) && (a.y == b.y); +} + +static unsigned int keyhash(g2d_vect_t key) +{ + return jenhash32(key.x) ^ jenhash32(key.y >> 1); +} + +static end_t end_invalid = {{0, 0}, {64, 64}}; + +/* Hash: g2d_vect_t -> end_t */ +typedef g2d_vect_t htend_key_t; +typedef end_t htend_value_t; +#define HT(x) htend_ ## x +#define HT_INVALID_VALUE end_invalid +#include +#include +#undef HT + +#define INSERT(x_, y_, sd) \ +do { \ + g2d_vect_t v; \ + htend_entry_t *e; \ + v.x = x_; v.y = y_; \ + e = htend_getentry(&ends, v); \ + if (e == NULL) { \ + end_t end = {0}; \ + end.objs[0] = obj; \ + end.side[0] = sd; \ + htend_set(&ends, v, end); \ + } \ + else { \ + if (e->value.objs[1] == NULL) { \ + e->value.objs[1] = obj; \ + e->value.side[1] = sd; \ + } \ + else { \ + if (!silent) { \ + rnd_message(RND_MSG_ERROR, "Convert to polygon failed: more than 2 object endpoints in the same point at %d;%d\n", x_, y_); \ + goto quit; \ + } \ + } \ + } \ +} while(0) + + +/* Return next (neighbor) endpoint jumping using from's ->objs[idx] */ +RND_INLINE htend_entry_t *cursor_next_idx(htend_t *ends, htend_entry_t *from, int idx) +{ + csch_coord_t x0, y0, x1, y1; + htend_key_t nk; + int res; + htend_entry_t *e; + + res = csch_cobj_get_endxy(from->value.objs[idx], 0, &x0, &y0); + assert(res == 0); + res = csch_cobj_get_endxy(from->value.objs[idx], 1, &x1, &y1); + assert(res == 0); + + if ((from->key.x == x0) && (from->key.y == y0)) { + nk.x = x1; + nk.y = y1; + } + else { + assert((from->key.x == x1) && (from->key.y == y1)); + nk.x = x0; + nk.y = y0; + } + + e = htend_getentry(ends, nk); + assert(e != NULL); + return e; +} + +/* Starting from the top left corner, figure start direction */ +RND_INLINE htend_entry_t *cursor_first(htend_t *ends, htend_entry_t *topleft, csch_chdr_t **bridge) +{ + htend_entry_t *next0, *next1, *next; + + /* top left means: y is minimum; the next node in CCW must have a smaller y; + if both neigbours have smaller y, topleft is a ^ triangle upper point, + choose the next with smaller x (left side) */ + next0 = cursor_next_idx(ends, topleft, 0); + next1 = cursor_next_idx(ends, topleft, 1); + + if ((next0->key.y < topleft->key.y) && (next1->key.y < topleft->key.y)) { + /* both smaller case */ + if (next0->key.x < next1->key.x) { + *bridge = topleft->value.objs[0]; + next = next0; + } + else { + *bridge = topleft->value.objs[1]; + next = next1; + } + } + else { + /* only next0 or next1 is below topleft, the other has the same y */ + if (next0->key.y < topleft->key.y) { + *bridge = topleft->value.objs[0]; + next = next0; + } + else { + *bridge = topleft->value.objs[1]; + next = next1; + } + } + + return next; +} + +RND_INLINE htend_entry_t *cursor_next(htend_t *ends, htend_entry_t *from, csch_chdr_t **bridge) +{ + htend_entry_t *n0 = cursor_next_idx(ends, from, 0); + htend_entry_t *n1 = cursor_next_idx(ends, from, 1); + + /* we are coming from an already visited endpoint */ + assert(n0->value.visited || n1->value.visited); + + if (n0->value.visited) { + *bridge = from->value.objs[1]; + return n1; + } + if (n1->value.visited) { + *bridge = from->value.objs[0]; + return n0; + } + + /* can't get here because either neighbor is already visited */ + abort(); + return NULL; +} + +RND_INLINE void copy_ol_obj(csch_coutline_t *dst, const csch_chdr_t *src, int swap) +{ + /* assumes dst bytes are set to 0 */ + + dst->hdr.type = src->type; + switch(src->type) { + case CSCH_CTYPE_LINE: + { + const csch_line_t *l = (const csch_line_t *)src; + dst->line.spec.p1 = swap ? l->spec.p2 : l->spec.p1; + dst->line.spec.p2 = swap ? l->spec.p1 : l->spec.p2; + } + break; + case CSCH_CTYPE_ARC: + { + const csch_arc_t *a = (const csch_arc_t *)src; + dst->arc.spec = a->spec; + if (swap) { + dst->arc.spec.start = a->spec.start + a->spec.delta; + dst->arc.spec.delta = -a->spec.delta; + } + } + break; + + default: + /* can't happen */ + break; + } +} + +static csch_cpoly_t *sch_rnd_conv_poly(csch_sheet_t *sheet, csch_cgrp_t *parent, vtp0_t *atoms, int silent) +{ + long n; + htend_t ends; + csch_cpoly_t *poly = NULL; + csch_chdr_t *bridge; + htend_entry_t *e, *topleft, *cursor; + + /* sanity check for object type */ + if (atoms->used < 3) { + if (!silent) + rnd_message(RND_MSG_ERROR, "Can't convert objects to polygon: need at least 3 objects\n"); + return NULL; + } + + for(n = 0; n < atoms->used; n++) { + csch_chdr_t *obj = atoms->array[n]; + if ((obj->type != CSCH_CTYPE_LINE) && (obj->type != CSCH_CTYPE_ARC)) { + if (!silent) + rnd_message(RND_MSG_ERROR, "Can't convert objects to polygon: all objects need to be line or arc\n"); + return NULL; + } + } + + htend_init(&ends, keyhash, keyeq); + + /* build endpoint hash */ + for(n = 0; n < atoms->used; n++) { + csch_chdr_t *obj = atoms->array[n]; + csch_coord_t x[2], y[2]; + int er; + + er = csch_cobj_get_endxy(obj, 0, &x[0], &y[0]); + er |= csch_cobj_get_endxy(obj, 1, &x[1], &y[1]); + if (er != 0) { + if (!silent) + rnd_message(RND_MSG_ERROR, "Can't convert objects to polygon: failed to query object end coords\n"); + return NULL; + } + if ((x[0] == x[1]) && (y[0] == y[1])) { + if (!silent) + rnd_message(RND_MSG_ERROR, "Polygon convert: ignoring zero-length object\n"); + continue; + } + + INSERT(x[0], y[0], 0); + INSERT(x[1], y[1], 1); + } + + /* find top y coord that has the smallest x coord, also make sure we have the chance for a closed loop */ + for(topleft = e = htend_first(&ends); e != NULL; e = htend_next(&ends, e)) { + if (e->value.objs[1] == NULL) { + if (!silent) { + rnd_message(RND_MSG_ERROR, "Convert to polygon failed: loop not closed at %d;%d\n", e->key.x, e->key.y); + goto quit; + } + } + if (e->key.y > topleft->key.y) + topleft = e; + else if ((e->key.y == topleft->key.y) && (e->key.x < topleft->key.x)) + topleft = e; + } + + /* find which objects need to be swapped for a loop; we are after all + sanity checks so this can't fail: we have a closed loop */ + poly = (csch_cpoly_t *)csch_op_create(sheet, parent, CSCH_CTYPE_POLY); + topleft->value.visited = 1; + bridge = NULL; + for(n = 0, cursor = cursor_first(&ends, topleft, &bridge); !cursor->value.visited; cursor = cursor_next(&ends, cursor, &bridge), n++) { + csch_coord_t xe, ye; + csch_coutline_t *ol; + int swap; + + cursor->value.visited = 1; + csch_cobj_get_endxy(bridge, 1, &xe, &ye); + + /* if end of the bridge object is not where we landed, the bridge object is + in reverse and needs swapping before insertion */ + swap = (xe != cursor->key.x) || (ye != cursor->key.y); + + ol = csch_vtcoutline_alloc_append(&poly->outline, 1); + copy_ol_obj(ol, bridge, swap); + printf("mark: %ld %ld (swap=%d)\n", cursor->key.x, cursor->key.y, swap); + + /* defeat a special case: topleft had to be marked visited so the first + next() call knew where to proceed, but we didn't really add any + object from topleft; but there are surely at least 3 objects, so + after after adding two, unmark topleft so it can be visited last */ + if (n == 1) + topleft->value.visited = 0; + } + + poly->hdr.stroke_name = bridge->stroke_name; + poly->has_stroke = 1; + csch_poly_update(sheet, poly, 1); + + quit:; + htend_uninit(&ends); + + return poly; +} + +#undef INSERT Index: tags/1.0.5/src/plugins/diag/Makefile =================================================================== --- tags/1.0.5/src/plugins/diag/Makefile (nonexistent) +++ tags/1.0.5/src/plugins/diag/Makefile (revision 10414) @@ -0,0 +1,2 @@ +all: + cd ../../sch-rnd && make mod_diag Index: tags/1.0.5/src/plugins/diag/Plug.tmpasm =================================================================== --- tags/1.0.5/src/plugins/diag/Plug.tmpasm (nonexistent) +++ tags/1.0.5/src/plugins/diag/Plug.tmpasm (revision 10414) @@ -0,0 +1,10 @@ +put /local/rnd/mod {diag} +put /local/rnd/mod/OBJS [@ + $(PLUGDIR)/diag/diag.o +@] + +switch /local/module/diag/controls + case {buildin} include /local/csch/tmpasm/buildin; end; + case {plugin} include /local/csch/tmpasm/plugin; end; + case {disable} include /local/csch/tmpasm/disable; end; +end Index: tags/1.0.5/src/plugins/diag/diag.c =================================================================== --- tags/1.0.5/src/plugins/diag/diag.c (nonexistent) +++ tags/1.0.5/src/plugins/diag/diag.c (revision 10414) @@ -0,0 +1,117 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - daignostics/debug + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + + +#include +#include +#include +#include +#include +#include +#include +#include + +extern long sch_rnd_font_score_debug; +static const char csch_acts_FontFind[] = "FontFind(name, style)\n"; +static const char csch_acth_FontFind[] = "Finds a font by the same name:style combo pens use"; +static fgw_error_t csch_act_FontFind(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *name, *style; + void *font; + + RND_ACT_CONVARG(1, FGW_STR, FontFind, name = argv[1].val.str); + RND_ACT_CONVARG(2, FGW_STR, FontFind, style = argv[2].val.str); + + sch_rnd_font_score_debug++; + font = sch_rnd_font_lookup(name, style); + rnd_message(RND_MSG_INFO, "FontFind: %p\n", font); + sch_rnd_font_score_debug--; + + RND_ACT_IRES(0); + return 0; +} + +static const char csch_acts_UndoSplit[] = "UndoSplit()\n"; +static const char csch_acth_UndoSplit[] = "Renumber undo serials so they can be undone separately"; +static fgw_error_t csch_act_UndoSplit(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_design_t *hl = RND_ACT_DESIGN; + csch_sheet_t *sheet = (csch_sheet_t *)hl; + uundo_item_t *i; + uundo_serial_t ser, base = 0, cnt; + + ser = -1; + + for(i = sheet->undo.head; i != NULL; i = i->next) { + if (ser != i->serial) { + base += 10000; + ser = i->serial; + cnt = 0; + } + i->serial = base + cnt; + cnt++; + } + sheet->undo.serial = base + cnt; + + rnd_event(&sheet->hidlib, CSCH_EVENT_UNDO_POST, "i", CSCH_UNDO_EV_UNDO); + + RND_ACT_IRES(0); + return 0; +} + +static const char csch_acts_d1[] = "d1()\n"; +static const char csch_acth_d1[] = "debug action for development"; +static fgw_error_t csch_act_d1(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + RND_ACT_IRES(0); + return 0; +} + + +rnd_action_t diag_action_list[] = { + {"FontFind", csch_act_FontFind, csch_acth_FontFind, csch_acts_FontFind}, + {"UndoSplit", csch_act_UndoSplit, csch_acth_UndoSplit, csch_acts_UndoSplit}, + {"d1", csch_act_d1, csch_acth_d1, csch_acts_d1} +}; + +static const char *diag_cookie = "diag plugin"; + +int pplg_check_ver_diag(int ver_needed) { return 0; } + +void pplg_uninit_diag(void) +{ + rnd_remove_actions_by_cookie(diag_cookie); +} + +int pplg_init_diag(void) +{ + RND_API_CHK_VER; + + RND_REGISTER_ACTIONS(diag_action_list, diag_cookie) + return 0; +} Index: tags/1.0.5/src/plugins/diag/diag.pup =================================================================== --- tags/1.0.5/src/plugins/diag/diag.pup (nonexistent) +++ tags/1.0.5/src/plugins/diag/diag.pup (revision 10414) @@ -0,0 +1,7 @@ +$class feature +$short diagnostic acts. for devs +$long Actions for sch-rnd core diagnostics, intended for developers. These are not in core because end users normally don't need these. As a plugin, due to dynamic loading, it can be dropped on an existing sch-rnd installation with minimal risk of scaring away a reproducible bug. +$package debug +$state works +default buildin +autoload 1 Index: tags/1.0.5/src/plugins/export_abst/Makefile =================================================================== --- tags/1.0.5/src/plugins/export_abst/Makefile (nonexistent) +++ tags/1.0.5/src/plugins/export_abst/Makefile (revision 10414) @@ -0,0 +1,2 @@ +all: + cd ../../sch-rnd && make mod_export_abst Index: tags/1.0.5/src/plugins/export_abst/Plug.tmpasm =================================================================== --- tags/1.0.5/src/plugins/export_abst/Plug.tmpasm (nonexistent) +++ tags/1.0.5/src/plugins/export_abst/Plug.tmpasm (revision 10414) @@ -0,0 +1,10 @@ +put /local/rnd/mod {export_abst} +put /local/rnd/mod/OBJS [@ + $(PLUGDIR)/export_abst/export_abst.o +@] + +switch /local/module/export_abst/controls + case {buildin} include /local/csch/tmpasm/buildin; end; + case {plugin} include /local/csch/tmpasm/plugin; end; + case {disable} include /local/csch/tmpasm/disable; end; +end Index: tags/1.0.5/src/plugins/export_abst/export_abst.c =================================================================== --- tags/1.0.5/src/plugins/export_abst/export_abst.c (nonexistent) +++ tags/1.0.5/src/plugins/export_abst/export_abst.c (revision 10414) @@ -0,0 +1,205 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - export the abstract model + * Copyright (C) 2020 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static csch_plug_io_t eabst; + +static int abst_export_prio(const char *fn, const char *fmt, csch_plug_io_type_t type) +{ + if (type != CSCH_IOTYP_NETLIST) + return 0; + if ((rnd_strcasecmp(fmt, "abst") == 0) || (rnd_strcasecmp(fmt, "abstract") == 0)) + return 100; + if (rnd_strcasecmp(fmt, "txt") == 0) + return 50; + return 0; +} + +#include "hid_impl.c" + +static void abst_export_attrs(FILE *f, csch_ahdr_t *obj, const char *ind) +{ + htsp_entry_t *e; + + fprintf(f, "%sattributes\n", ind); + for(e = htsp_first(&obj->attr); e != NULL; e = htsp_next(&obj->attr, e)) { + csch_attrib_t *a = e->value; + if (a->val == NULL) { + long n; + fprintf(f, "%s %s []\n", ind, a->key); + for(n = 0; n < a->arr.used; n++) + fprintf(f, "%s %s\n", ind, a->arr.array[n]); + } + else + fprintf(f, "%s %s=%s\n", ind, a->key, a->val); + + } +} + +static void abst_export_comps(FILE *f, csch_abstract_t *abs) +{ + htsp_entry_t *e, *p; + fprintf(f, "components\n"); + for(e = htsp_first(&abs->comps); e != NULL; e = htsp_next(&abs->comps, e)) { + csch_acomp_t *comp = e->value; + + if (comp->hdr.ghost && !abst_values[HA_ghost].lng) + continue; + + fprintf(f, " %s\n", comp->name); + if (comp->hdr.ghost) + fprintf(f, " GHOST\n"); + if (comp->hdr.omit) + fprintf(f, " OMIT\n"); + + if (abst_values[HA_comp_attrs].lng) + abst_export_attrs(f, &comp->hdr, " "); + + fprintf(f, " ports\n"); + for(p = htsp_first(&comp->ports); p != NULL; p = htsp_next(&comp->ports, p)) { + csch_aport_t *port = p->value; + fprintf(f, " %s\n", p->key); + if (abst_values[HA_port_attrs].lng) + abst_export_attrs(f, &port->hdr, " "); + } + TODO("bus: export bus ports"); + } +} + +static void abst_export_nets(FILE *f, csch_abstract_t *abs) +{ + htsp_entry_t *e; + long n; + + fprintf(f, "nets\n"); + for(e = htsp_first(&abs->nets); e != NULL; e = htsp_next(&abs->nets, e)) { + csch_anet_t *net = e->value; + + if (net->hdr.ghost && !abst_values[HA_ghost].lng) + continue; + + fprintf(f, " %s\n", net->name); + if (net->hdr.ghost) + fprintf(f, " GHOST\n"); + if (net->hdr.omit) + fprintf(f, " OMIT\n"); + + + if (abst_values[HA_net_attrs].lng) + abst_export_attrs(f, &net->hdr, " "); + + fprintf(f, " conns %lu\n", (unsigned long)net->conns.used); + for(n = 0; n < net->conns.used; n++) { + const char *paop = "", *pacl = ""; + csch_aport_t *port = net->conns.array[n]; + csch_acomp_t *comp = port->parent; + const char *comp_name = comp == NULL ? "" : comp->name; + const char *port_name = port == NULL ? "" : port->name; + + if (port->hdr.omit) { + paop = "(omit "; + pacl = ")"; + } + + if (port->referer != NULL) + fprintf(f, " (via %s-%s)\n", port->referer->name, port_name); + else + fprintf(f, " %s%s-%s%s\n", paop, comp_name, port_name, pacl); + } + } +} + + +static int abst_export_project_abst(const char *fn, const char *fmt, csch_abstract_t *abs, rnd_hid_attr_val_t *options) +{ + TODO("get hidlib as an arg") + rnd_design_t *hidlib = NULL; + FILE *f = rnd_fopen(hidlib, fn, "w"); + if (f == NULL) + return -1; + + fprintf(f, "cschem abstract model v1\n"); + + abst_export_comps(f, abs); + abst_export_nets(f, abs); + TODO("bus: export buses"); + + fclose(f); + return 0; +} + + +int pplg_check_ver_export_abst(int ver_needed) { return 0; } + +void pplg_uninit_export_abst(void) +{ + csch_plug_io_unregister(&eabst); + rnd_export_remove_opts_by_cookie(abst_cookie); + rnd_hid_remove_hid(&abst_hid); +} + +int pplg_init_export_abst(void) +{ + RND_API_CHK_VER; + + eabst.name = "export abstract model to text"; + eabst.export_prio = abst_export_prio; + eabst.export_project_abst = abst_export_project_abst; + eabst.ext_export_project = ".txt"; + csch_plug_io_register(&eabst); + + + rnd_hid_nogui_init(&abst_hid); + + abst_hid.struct_size = sizeof(rnd_hid_t); + abst_hid.name = "abst"; + abst_hid.description = "Exports project's abstract model to text"; + abst_hid.exporter = 1; + + abst_hid.get_export_options = abst_get_export_options; + abst_hid.do_export = abst_do_export; + abst_hid.parse_arguments = abst_parse_arguments; + abst_hid.argument_array = abst_values; + + abst_hid.usage = abst_usage; + + rnd_hid_register_hid(&abst_hid); + rnd_hid_load_defaults(&abst_hid, abst_options, NUM_OPTIONS); + + return 0; +} + Index: tags/1.0.5/src/plugins/export_abst/export_abst.pup =================================================================== --- tags/1.0.5/src/plugins/export_abst/export_abst.pup (nonexistent) +++ tags/1.0.5/src/plugins/export_abst/export_abst.pup (revision 10414) @@ -0,0 +1,9 @@ +$class export +$short export abstract model +$long export project's abstract model to text +$state works +$fmt-native no +$fmt-feature-e abstract model text +$package export-extra +default buildin +autoload 1 Index: tags/1.0.5/src/plugins/export_abst/hid_impl.c =================================================================== --- tags/1.0.5/src/plugins/export_abst/hid_impl.c (nonexistent) +++ tags/1.0.5/src/plugins/export_abst/hid_impl.c (revision 10414) @@ -0,0 +1,114 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - abstract model export + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include +#include +#include +#include +#include +#include + +static const char abst_cookie[] = "abst export hid"; + +static const rnd_export_opt_t abst_options[] = { + {"outfile", "Name of the abstract model output file", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0}, +#define HA_outfile 0 + + {"include-ghosts", "Print ghost (empty, unused) objects as well", + RND_HATT_BOOL, 0, 0, {0, 0, 0}, 0}, +#define HA_ghost 1 + + {"comp-attrs", "Print component attributes", + RND_HATT_BOOL, 0, 0, {1, 0, 0}, 0}, +#define HA_comp_attrs 2 + + {"port-attrs", "Print port attributes", + RND_HATT_BOOL, 0, 0, {1, 0, 0}, 0}, +#define HA_port_attrs 3 + + {"net-attrs", "Print net attributes", + RND_HATT_BOOL, 0, 0, {1, 0, 0}, 0}, +#define HA_net_attrs 4 + + {"view", "Name of the view to export (use first view when not specified)", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0}, +#define HA_view 5 +}; + +#define NUM_OPTIONS (sizeof(abst_options)/sizeof(abst_options[0])) + +static rnd_hid_attr_val_t abst_values[NUM_OPTIONS]; + +static const rnd_export_opt_t *abst_get_export_options(rnd_hid_t *hid, int *n, rnd_design_t *dsg, void *appspec) +{ + const char *val = abst_values[HA_outfile].str; + + if ((dsg != NULL) && ((val == NULL) || (*val == '\0'))) + csch_derive_default_filename(dsg, 1, &abst_values[HA_outfile], ".abst"); + + if (n) + *n = NUM_OPTIONS; + return abst_options; +} + +static void abst_do_export(rnd_hid_t *hid, rnd_design_t *design, rnd_hid_attr_val_t *options, void *appspec) +{ + csch_sheet_t *sheet = (csch_sheet_t *)design; + int viewid = CSCH_VIEW_DEFAULT; + + if (!options) { + abst_get_export_options(hid, 0, design, appspec); + options = abst_values; + } + + if ((options[HA_view].str != NULL) && (options[HA_view].str[0] != '\0')) { + viewid = csch_view_get_id((csch_project_t *)sheet->hidlib.project, options[HA_view].str); + if (viewid < 0) { + rnd_message(RND_MSG_ERROR, "No such view in the project: '%s'\n", options[HA_view].str); + return; + } + } + + sch_rnd_export_prj_abst((csch_project_t *)sheet->hidlib.project, sheet, viewid, "abst", options[HA_outfile].str, options); +} + +static int abst_usage(rnd_hid_t *hid, const char *topic) +{ + fprintf(stderr, "\nabstract model exporter command line arguments:\n\n"); + rnd_hid_usage(abst_options, sizeof(abst_options) / sizeof(abst_options[0])); + fprintf(stderr, "\nUsage: sch-rnd [generic_options] -x abst [options] foo.rs\n\n"); + return 0; +} + + +static int abst_parse_arguments(rnd_hid_t *hid, int *argc, char ***argv) +{ + rnd_export_register_opts2(hid, abst_options, sizeof(abst_options) / sizeof(abst_options[0]), abst_cookie, 0); + return rnd_hid_parse_command_line(argc, argv); +} + +rnd_hid_t abst_hid = {0}; Index: tags/1.0.5/src/plugins/export_bom/Makefile =================================================================== --- tags/1.0.5/src/plugins/export_bom/Makefile (nonexistent) +++ tags/1.0.5/src/plugins/export_bom/Makefile (revision 10414) @@ -0,0 +1,2 @@ +all: + cd ../../sch-rnd && make mod_export_bom Index: tags/1.0.5/src/plugins/export_bom/Plug.tmpasm =================================================================== --- tags/1.0.5/src/plugins/export_bom/Plug.tmpasm (nonexistent) +++ tags/1.0.5/src/plugins/export_bom/Plug.tmpasm (revision 10414) @@ -0,0 +1,13 @@ +put /local/rnd/mod {export_bom} +put /local/rnd/mod/OBJS [@ + $(PLUGDIR)/export_bom/export_bom.o +@] +put /local/rnd/mod/CONF {$(PLUGDIR)/export_bom/bom_conf.h} +put /local/rnd/mod/CONFFILE {export_bom.conf} +put /local/rnd/mod/CONFVAR {export_bom_conf_internal} + +switch /local/module/export_bom/controls + case {buildin} include /local/csch/tmpasm/buildin; end; + case {plugin} include /local/csch/tmpasm/plugin; end; + case {disable} include /local/csch/tmpasm/disable; end; +end Index: tags/1.0.5/src/plugins/export_bom/bom_conf.h =================================================================== --- tags/1.0.5/src/plugins/export_bom/bom_conf.h (nonexistent) +++ tags/1.0.5/src/plugins/export_bom/bom_conf.h (revision 10414) @@ -0,0 +1,14 @@ +#ifndef SCH_RND_BOM_CONF_H +#define SCH_RND_BOM_CONF_H + +#include + +typedef struct { + const struct { + const struct { + RND_CFT_LIST templates; + } export_bom; + } plugins; +} conf_bom_t; + +#endif Index: tags/1.0.5/src/plugins/export_bom/export_bom.c =================================================================== --- tags/1.0.5/src/plugins/export_bom/export_bom.c (nonexistent) +++ tags/1.0.5/src/plugins/export_bom/export_bom.c (revision 10414) @@ -0,0 +1,188 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - Bill of Materials export + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "bom_conf.h" + +#include "conf_internal.c" + +#define CONF_FN "export_bom.conf" + +conf_bom_t conf_bom; + +/* Maximum length of a template name (in the config file, in the enum) */ +#define MAX_TEMP_NAME_LEN 128 + +typedef csch_acomp_t bom_obj_t; +#include "../../src_3rd/rnd_inclib/lib_bom/lib_bom.h" + +static const char *subst_user(bom_subst_ctx_t *ctx, const char *key) +{ + if (strncmp(key, "sym.", 4) == 0) { + key += 4; + + if (strncmp(key, "a.", 2) == 0) return csch_attrib_get_str(&ctx->obj->hdr.attr, key+2); + else if (strcmp(key, "name") == 0) return ctx->name; + if (strcmp(key, "prefix") == 0) { + static char tmp[256]; /* this is safe: caller will make a copy right after we return */ + char *o = tmp; + const char *t; + int n = 0; + + for(t = ctx->name; isalpha(*t) && (n < sizeof(tmp)-1); t++,n++,o++) + *o = *t; + *o = '\0'; + return tmp; + } + } + + return NULL; +} + + +static csch_plug_io_t ebom; + +static int bom_export_prio(const char *fn, const char *fmt, csch_plug_io_type_t type) +{ + if (type != CSCH_IOTYP_NETLIST) + return 0; + if (rnd_strcasecmp(fmt, "bom") == 0) + return 100; + return 0; +} + +#include "hid_impl.c" + + +static int print_bom(const char *fn, csch_abstract_t *abst, bom_template_t *templ) +{ + rnd_design_t *hidlib = rnd_multi_get_current(); + FILE *f; + bom_subst_ctx_t ctx = {0}; + htsp_entry_t *e; + + f = rnd_fopen_askovr(hidlib, fn, "w", NULL); + if (f == NULL) { + rnd_message(RND_MSG_ERROR, "Cannot open file %s for writing\n", fn); + return 1; + } + + bom_print_begin(&ctx, f, templ); + + for(e = htsp_first(&abst->comps); e != NULL; e = htsp_next(&abst->comps, e)) { + csch_acomp_t *comp = e->value; + if (comp->hdr.omit) continue; + if (comp->hdr.dnp) continue; + bom_print_add(&ctx, comp, comp->name); + } + + bom_print_all(&ctx); + bom_print_end(&ctx); + fclose(f); + + return 0; +} + +static int bom_export_project_bom(const char *fn, const char *fmt, csch_abstract_t *abst, rnd_hid_attr_val_t *options) +{ + bom_template_t templ = {0}; + char **tid; + + tid = vts0_get(&bom_fmt_ids, options[HA_format].lng, 0); + if ((tid == NULL) || (*tid == NULL)) { + rnd_message(RND_MSG_ERROR, "export_bom: invalid template selected\n"); + return -1; + } + + bom_init_template(&templ, &conf_bom.plugins.export_bom.templates, *tid); + print_bom(fn, abst, &templ); + return 0; +} + +#include "../../src_3rd/rnd_inclib/lib_bom/lib_bom.c" + +int pplg_check_ver_export_bom(int ver_needed) { return 0; } + +void pplg_uninit_export_bom(void) +{ + csch_plug_io_unregister(&ebom); + rnd_export_remove_opts_by_cookie(bom_cookie); + rnd_hid_remove_hid(&bom_hid); + + rnd_conf_unreg_file(CONF_FN, export_bom_conf_internal); + rnd_conf_unreg_fields("plugins/export_bom/"); + + bom_fmt_uninit(); +} + +int pplg_init_export_bom(void) +{ + RND_API_CHK_VER; + + ebom.name = "export Bill of Materials"; + ebom.export_prio = bom_export_prio; + ebom.export_project_abst = bom_export_project_bom; + ebom.ext_export_project = ".txt"; + csch_plug_io_register(&ebom); + + rnd_conf_reg_file(CONF_FN, export_bom_conf_internal); + +#define conf_reg(field,isarray,type_name,cpath,cname,desc,flags) \ + rnd_conf_reg_field(conf_bom, field,isarray,type_name,cpath,cname,desc,flags); +#include "bom_conf_fields.h" + + rnd_hid_nogui_init(&bom_hid); + + bom_hid.struct_size = sizeof(rnd_hid_t); + bom_hid.name = "bom"; + bom_hid.description = "Exports project's Bill of Materials"; + bom_hid.exporter = 1; + + bom_hid.get_export_options = bom_get_export_options; + bom_hid.do_export = bom_do_export; + bom_hid.parse_arguments = bom_parse_arguments; + bom_hid.argument_array = bom_values; + + bom_hid.usage = bom_usage; + + rnd_hid_register_hid(&bom_hid); + rnd_hid_load_defaults(&bom_hid, bom_options, NUM_OPTIONS); + + bom_fmt_init(); + + return 0; +} + Index: tags/1.0.5/src/plugins/export_bom/export_bom.conf =================================================================== --- tags/1.0.5/src/plugins/export_bom/export_bom.conf (nonexistent) +++ tags/1.0.5/src/plugins/export_bom/export_bom.conf (revision 10414) @@ -0,0 +1,37 @@ +### conf file header (compacted) +li:pcb-rnd-conf-v1 { ha:overwrite { ha:plugins { ha:export_bom { li:templates { + +### tempalates + +# default sch-rnd BoM ######################################################### +schrnd.name = default sch-rnd BoM +schrnd.header = {# +# sch-rnd BoM Version 1.1 +# Quantity, Description, Value, RefDes +# -------------------------------------------- +} +schrnd.sort_id = {%sym.prefix%__"%escape.sym.a.device%__%sym.a.footprint%__%sym.a.value%__%sym.a.color%__%sym.a.tolerance%} +schrnd.item = {%count%,"%escape.sym.a.device% %escape.sym.a.footprint%","%escape.sym.a.value|(unknown)%",%names% +} +schrnd.footer = {} +schrnd.needs_escape = {"} +schrnd.skip_if_empty = {%sym.a.footprint%} +schrnd.list_sep = { } + +# default sch-rnd BoM v2 ######################################################### +schrnd2.name = sch-rnd BoM v2 +schrnd2.header = {# +# sch-rnd BoM Version 2.0 +# Quantity, Description, Value, Tolerance, Color, RefDes +# -------------------------------------------- +} +schrnd2.sort_id = {%sym.prefix%__"%escape.sym.a.device%__%sym.a.footprint%__%sym.a.value%__%sym.a.color%__%sym.a.tolerance%} +schrnd2.item = {%count%,"%escape.sym.a.device% %escape.sym.a.footprint%","%escape.sym.a.value|(unknown)%","%escape.sym.a.tolerance|%","%escape.sym.a.color|%",%names% +} +schrnd2.footer = {} +schrnd2.needs_escape = {"} +schrnd2.skip_if_empty = {%sym.a.footprint%} +schrnd2.list_sep = { } + +### conf file footer (compacted) +} } } } } Index: tags/1.0.5/src/plugins/export_bom/export_bom.pup =================================================================== --- tags/1.0.5/src/plugins/export_bom/export_bom.pup (nonexistent) +++ tags/1.0.5/src/plugins/export_bom/export_bom.pup (revision 10414) @@ -0,0 +1,9 @@ +$class export +$short export Bill of Materials +$long export a BoM based on the components of the abstract model, using configurable templates +$state works +$fmt-native no +$fmt-feature-e Bill of Materials +$package export-extra +default buildin +autoload 1 Index: tags/1.0.5/src/plugins/export_bom/hid_impl.c =================================================================== --- tags/1.0.5/src/plugins/export_bom/hid_impl.c (nonexistent) +++ tags/1.0.5/src/plugins/export_bom/hid_impl.c (revision 10414) @@ -0,0 +1,112 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - Bill of Materials export + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include +#include +#include +#include +#include +#include + +static const char bom_cookie[] = "bom export hid"; + +static rnd_export_opt_t bom_options[] = { + {"bomfile", "Name of the BoM output file", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0}, +#define HA_outfile 0 + + {"format", "file format (template)", + RND_HATT_ENUM, 0, 0, {0, 0, 0}, NULL}, +#define HA_format 1 + + {"view", "Name of the view to export (use first view when not specified)", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0}, +#define HA_view 2 +}; + +#define NUM_OPTIONS (sizeof(bom_options)/sizeof(bom_options[0])) + +static rnd_hid_attr_val_t bom_values[NUM_OPTIONS]; + +static const rnd_export_opt_t *bom_get_export_options(rnd_hid_t *hid, int *n, rnd_design_t *dsg, void *appspec) +{ + const char *val = bom_values[HA_outfile].str; + + /* load all formats from the config */ + bom_build_fmts(&conf_bom.plugins.export_bom.templates); + + if (bom_fmt_names.used == 0) { + rnd_message(RND_MSG_ERROR, "export_bom: can not set up export options: no template available\n"); + return NULL; + } + + bom_options[HA_format].enumerations = (const char **)bom_fmt_names.array; + + if ((dsg != NULL) && ((val == NULL) || (*val == '\0'))) + csch_derive_default_filename(dsg, 1, &bom_values[HA_outfile], ".txt"); + + if (n) + *n = NUM_OPTIONS; + return bom_options; +} + +static void bom_do_export(rnd_hid_t *hid, rnd_design_t *design, rnd_hid_attr_val_t *options, void *appspec) +{ + csch_sheet_t *sheet = (csch_sheet_t *)design; + int viewid = CSCH_VIEW_DEFAULT; + + if (!options) { + bom_get_export_options(hid, 0, design, appspec); + options = bom_values; + } + + if ((options[HA_view].str != NULL) && (options[HA_view].str[0] != '\0')) { + viewid = csch_view_get_id((csch_project_t *)sheet->hidlib.project, options[HA_view].str); + if (viewid < 0) { + rnd_message(RND_MSG_ERROR, "No such view in the project: '%s'\n", options[HA_view].str); + return; + } + } + + sch_rnd_export_prj_abst((csch_project_t *)sheet->hidlib.project, sheet, viewid, "bom", options[HA_outfile].str, options); +} + +static int bom_usage(rnd_hid_t *hid, const char *topic) +{ + fprintf(stderr, "\nBill of Materials exporter command line arguments:\n\n"); + rnd_hid_usage(bom_options, sizeof(bom_options) / sizeof(bom_options[0])); + fprintf(stderr, "\nUsage: sch-rnd [generic_options] -x bom [options] foo.rs\n\n"); + return 0; +} + + +static int bom_parse_arguments(rnd_hid_t *hid, int *argc, char ***argv) +{ + rnd_export_register_opts2(hid, bom_options, sizeof(bom_options) / sizeof(bom_options[0]), bom_cookie, 0); + return rnd_hid_parse_command_line(argc, argv); +} + +rnd_hid_t bom_hid = {0}; Index: tags/1.0.5/src/plugins/export_lpr/Makefile =================================================================== --- tags/1.0.5/src/plugins/export_lpr/Makefile (nonexistent) +++ tags/1.0.5/src/plugins/export_lpr/Makefile (revision 10414) @@ -0,0 +1,2 @@ +all: + cd ../../sch-rnd && make mod_export_lpr Index: tags/1.0.5/src/plugins/export_lpr/Plug.tmpasm =================================================================== --- tags/1.0.5/src/plugins/export_lpr/Plug.tmpasm (nonexistent) +++ tags/1.0.5/src/plugins/export_lpr/Plug.tmpasm (revision 10414) @@ -0,0 +1,10 @@ +put /local/rnd/mod {export_lpr} +put /local/rnd/mod/OBJS [@ + $(PLUGDIR)/export_lpr/lpr.o +@] + +switch /local/module/export_lpr/controls + case {buildin} include /local/csch/tmpasm/buildin; end; + case {plugin} include /local/csch/tmpasm/plugin; end; + case {disable} include /local/csch/tmpasm/disable; end; +end Index: tags/1.0.5/src/plugins/export_lpr/export_lpr.pup =================================================================== --- tags/1.0.5/src/plugins/export_lpr/export_lpr.pup (nonexistent) +++ tags/1.0.5/src/plugins/export_lpr/export_lpr.pup (revision 10414) @@ -0,0 +1,10 @@ +$class export +$short lpr exporter (printer) +$long Export to lpr (using export_ps to generate postscript) +$state works +$fmt-native no +$fmt-feature-w printer (using ps) +$package export-extra +default buildin +dep export_ps +autoload 1 Index: tags/1.0.5/src/plugins/export_lpr/lpr.c =================================================================== --- tags/1.0.5/src/plugins/export_lpr/lpr.c (nonexistent) +++ tags/1.0.5/src/plugins/export_lpr/lpr.c (revision 10414) @@ -0,0 +1,45 @@ + /* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include + +#include +#include +#include + +#include "../export_ps/export_ps.h" + +int pplg_check_ver_export_lpr(int ver_needed) { return 0; } + +void pplg_uninit_export_lpr(void) +{ + rnd_lpr_uninit(); +} + +int pplg_init_export_lpr(void) +{ + return rnd_lpr_init(&ps_hid, ps_ps_init, ps_hid_export_to_file, NULL, NULL); +} Index: tags/1.0.5/src/plugins/export_png/Makefile =================================================================== --- tags/1.0.5/src/plugins/export_png/Makefile (nonexistent) +++ tags/1.0.5/src/plugins/export_png/Makefile (revision 10414) @@ -0,0 +1,2 @@ +all: + cd ../../sch-rnd && make mod_export_png Index: tags/1.0.5/src/plugins/export_png/Plug.tmpasm =================================================================== --- tags/1.0.5/src/plugins/export_png/Plug.tmpasm (nonexistent) +++ tags/1.0.5/src/plugins/export_png/Plug.tmpasm (revision 10414) @@ -0,0 +1,10 @@ +put /local/rnd/mod {export_png} +put /local/rnd/mod/OBJS [@ + $(PLUGDIR)/export_png/export_png.o +@] + +switch /local/module/export_png/controls + case {buildin} include /local/csch/tmpasm/buildin; end; + case {plugin} include /local/csch/tmpasm/plugin; end; + case {disable} include /local/csch/tmpasm/disable; end; +end Index: tags/1.0.5/src/plugins/export_png/export_png.c =================================================================== --- tags/1.0.5/src/plugins/export_png/export_png.c (nonexistent) +++ tags/1.0.5/src/plugins/export_png/export_png.c (revision 10414) @@ -0,0 +1,370 @@ + /* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +static rnd_hid_t png_hid; + +const char *png_cookie = "png HID"; + +static rnd_drwpx_t pctx_, *pctx = &pctx_; + +static FILE *png_f; + +static const rnd_export_opt_t png_attribute_list[] = { + {"outfile", "Graphics output file", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0}, +#define HA_pngfile 0 + + {"dpi", "Scale factor (pixels/inch). 0 to scale to specified size", + RND_HATT_INTEGER, 0, 10000, {100, 0, 0}, 0}, +#define HA_dpi 1 + + {"x-max", "Maximum width (pixels). 0 to not constrain", + RND_HATT_INTEGER, 0, 10000, {0, 0, 0}, 0}, +#define HA_xmax 2 + + {"y-max", "Maximum height (pixels). 0 to not constrain", + RND_HATT_INTEGER, 0, 10000, {0, 0, 0}, 0}, +#define HA_ymax 3 + + {"xy-max", "Maximum width and height (pixels). 0 to not constrain", + RND_HATT_INTEGER, 0, 10000, {0, 0, 0}, 0}, +#define HA_xymax 4 + + {"monochrome", "Convert to monochrome", + RND_HATT_BOOL, 0, 0, {0, 0, 0}, 0}, +#define HA_mono 5 + + {"fill-gray-threshold", "In monochrome, fill polygons with gray if color is lighter than this percentage (0 is black, 100 is white)", + RND_HATT_INTEGER, 0, 100, {80, 0, 0}, 0}, +#define HA_fill_gray_threshold 6 + + {"use-alpha", "Make the background transparent", + RND_HATT_BOOL, 0, 0, {0, 0, 0}, 0}, +#define HA_use_alpha 7 + + {"screen-colors", "Allow object highlight and selection color", + RND_HATT_BOOL, 0, 0, {0, 0, 0}, 0}, +#define HA_screen_color 8 + + {"format", "Export file format", + RND_HATT_ENUM, 0, 0, {0, 0, 0}, rnd_drwpx_filetypes}, +#define HA_filetype 9 + + {"layers", "List of layers to export or \"GUI\" for exporting what's visible on the GUI at the moment or empty for default export layer visibility", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0}, +#define HA_layers 10 + + {"view", "If not empty, switch to view and compile before exporting", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0}, +#define HA_view 11 +}; + +#define NUM_OPTIONS (sizeof(png_attribute_list)/sizeof(png_attribute_list[0])) + +static rnd_hid_attr_val_t png_values[NUM_OPTIONS]; + +static const rnd_export_opt_t *png_get_export_options(rnd_hid_t *hid, int *n, rnd_design_t *dsg, void *appspec) +{ + const char *val = png_values[HA_pngfile].str; + + if ((dsg != NULL) && ((val == NULL) || (*val == '\0'))) + csch_derive_default_filename(dsg, sch_rnd_export_appspec_prj(appspec), &png_values[HA_pngfile], ".png"); + + if (n) + *n = NUM_OPTIONS; + return png_attribute_list; +} + +static const char *filename; +static rnd_box_t *bounds; +static double png_fill_gray_thrs; + + +static rnd_hid_attr_val_t *png_options; + +static void png_head(void) +{ + pctx->ymirror = 1; + rnd_drwpx_start(pctx); +} + +static void png_finish(FILE *f) +{ + rnd_drwpx_finish(pctx, f, png_options[HA_filetype].lng); +} + +static void png_hid_export_to_file(rnd_design_t *hl, FILE *the_file, rnd_hid_attr_val_t *options, rnd_xform_t *xform) +{ + rnd_box_t region; + rnd_hid_expose_ctx_t ctx; + double dtmp; + + png_f = the_file; + + region.X1 = hl->dwg.X1; + region.Y1 = hl->dwg.Y1; + region.X2 = hl->dwg.X2; + region.Y2 = hl->dwg.Y2; + + png_options = options; + bounds = ®ion; + + dtmp = (double)options[HA_fill_gray_threshold].lng / 100.0; + png_fill_gray_thrs = dtmp * dtmp * 3; + + xform->no_render_select = xform->no_render_hilight = !options[HA_screen_color].lng; + pctx->in_mono = options[HA_mono].lng; + png_head(); + + ctx.design = hl; + ctx.view = *bounds; + rnd_app.expose_main(&png_hid, &ctx, xform); +} + +static int png_do_export_sheet(rnd_hid_t *hid, rnd_design_t *dsg, rnd_hid_attr_val_t *options, sch_rnd_export_appspec_t *appspec, int *ovr) +{ + rnd_xform_t xform = {0}; + FILE *f; + + rnd_drwpx_init(pctx, dsg); + + filename = cschem_export_filename(dsg, options[HA_pngfile].str, NULL, appspec->fn_page_suffix, ".png"); + + if (rnd_drwpx_set_size(pctx, NULL, options[HA_dpi].lng, options[HA_xmax].lng, options[HA_ymax].lng, options[HA_xymax].lng) != 0) { + rnd_drwpx_uninit(pctx); + return -1; + } + + if (rnd_drwpx_create(pctx, options[HA_use_alpha].lng) != 0) { + rnd_message(RND_MSG_ERROR, "png_do_export(): Failed to create bitmap of %d * %d returned NULL. Aborting export.\n", pctx->w, pctx->h); + rnd_drwpx_uninit(pctx); + return -1; + } + + f = rnd_fopen_askovr(dsg, filename, "wb", ovr); + if (f == NULL) { + perror(filename); + rnd_drwpx_uninit(pctx); + return -1; + } + + sch_rnd_set_export_layers(&xform, options[HA_layers].str); + png_hid_export_to_file(dsg, f, options, &xform); + + png_finish(f); + if (f != NULL) + fclose(f); + + rnd_drwpx_uninit(pctx); + return 0; +} + +static void png_do_export(rnd_hid_t *hid, rnd_design_t *design, rnd_hid_attr_val_t *options, void *appspec_) +{ + rnd_design_t *hl = design; + csch_sheet_t *sheet = (csch_sheet_t *)hl; + void *view_cookie; + sch_rnd_export_appspec_t *appspec = (appspec_ == NULL) ? &sch_rnd_no_appspec : appspec_; + + if (!options) { + png_get_export_options(hid, 0, design, appspec); + options = png_values; + } + + if (cschem_export_compile_pre((csch_project_t *)sheet->hidlib.project, options[HA_view].str, &view_cookie) != 0) + return; + + sch_rnd_export_project_or_sheet(hid, design, options, appspec, png_do_export_sheet); + + cschem_export_compile_post((csch_project_t *)sheet->hidlib.project, &view_cookie); +} + +static int png_parse_arguments(rnd_hid_t *hid, int *argc, char ***argv) +{ + rnd_export_register_opts2(hid, png_attribute_list, sizeof(png_attribute_list) / sizeof(png_attribute_list[0]), png_cookie, 0); + return rnd_hid_parse_command_line(argc, argv); +} + +static int png_set_layer_group(rnd_hid_t *hid, rnd_design_t *design, rnd_layergrp_id_t group, const char *purpose, int purpi, rnd_layer_id_t layer, unsigned int flags, int is_empty, rnd_xform_t **xform) +{ + return 1; +} + +static void png_set_drawing_mode(rnd_hid_t *hid, rnd_composite_op_t op, rnd_bool direct, const rnd_box_t *screen) +{ + rnd_drwpx_set_drawing_mode(pctx, hid, op, direct, screen); +} + +static rnd_color_t png_last_color; +static void png_set_color(rnd_hid_gc_t gc, const rnd_color_t *color) +{ + png_last_color = *color; + rnd_drwpx_set_color(pctx, gc, color); +} + +static void png_fill_rect(rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) +{ + rnd_drwpx_fill_rect(pctx, gc, x1, y1, x2, y2); +} + +static void png_draw_line(rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) +{ + rnd_drwpx_draw_line(pctx, gc, x1, y1, x2, y2); +} + +static void png_draw_rect(rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) +{ + png_draw_line(gc, x1, y1, x2, y1); + png_draw_line(gc, x2, y1, x2, y2); + png_draw_line(gc, x2, y2, x1, y2); + png_draw_line(gc, x1, y2, x1, y1); +} + +static void png_draw_arc(rnd_hid_gc_t gc, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t width, rnd_coord_t height, rnd_angle_t start_angle, rnd_angle_t delta_angle) +{ + rnd_drwpx_draw_arc(pctx, gc, cx, cy, width, height, start_angle, delta_angle); +} + +static void png_fill_circle(rnd_hid_gc_t gc, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t radius) +{ + rnd_drwpx_fill_circle(pctx, gc, cx, cy, radius); +} + +static void png_fill_polygon_offs(rnd_hid_gc_t gc, int n_coords, rnd_coord_t *x, rnd_coord_t *y, rnd_coord_t dx, rnd_coord_t dy) +{ + /* maybe tweak fill color so that light fills remain light grey */ + if (pctx->in_mono) { + double intens2 = png_last_color.fr * png_last_color.fr + png_last_color.fg * png_last_color.fg + png_last_color.fb * png_last_color.fb; + if (intens2 >= png_fill_gray_thrs) { + rnd_color_t clr = png_last_color; + int avg = rnd_round((double)(clr.r + clr.g + clr.b) / 3.0); + pctx->in_mono = 0; + clr.r = clr.g = clr.b = avg; + rnd_drwpx_set_color(pctx, gc, &clr); + pctx->in_mono = 1; + } + } + + rnd_drwpx_fill_polygon_offs(pctx, gc, n_coords, x, y, dx, dy); +} + + +static void png_fill_polygon(rnd_hid_gc_t gc, int n_coords, rnd_coord_t *x, rnd_coord_t *y) +{ + png_fill_polygon_offs(gc, n_coords, x, y, 0, 0); +} + +#if 0 +static void png_draw_pixmap(rnd_hid_t *hid, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t sx, rnd_coord_t sy, rnd_pixmap_t *pixmap) +{ + rnd_drwpx_draw_pixmap(pctx, hid, cx, cy, sx, sy, pixmap); +} +#endif + +static int png_usage(rnd_hid_t *hid, const char *topic) +{ + fprintf(stderr, "\npng exporter command line arguments:\n\n"); + rnd_hid_usage(png_attribute_list, sizeof(png_attribute_list) / sizeof(png_attribute_list[0])); + fprintf(stderr, "\nUsage: sch-rnd [generic_options] -x png [png options] foo.pcb\n\n"); + return 0; +} + +int pplg_check_ver_export_png(int ver_needed) { return 0; } + +void pplg_uninit_export_png(void) +{ + rnd_export_remove_opts_by_cookie(png_cookie); + + if (rnd_drwpx_has_any_format()) + rnd_hid_remove_hid(&png_hid); +} + +int pplg_init_export_png(void) +{ + RND_API_CHK_VER; + + memset(&png_hid, 0, sizeof(rnd_hid_t)); + + rnd_hid_nogui_init(&png_hid); + + png_hid.struct_size = sizeof(rnd_hid_t); + png_hid.name = "png"; + png_hid.description = "GIF/JPEG/PNG export"; + png_hid.exporter = 1; + + png_hid.get_export_options = png_get_export_options; + png_hid.do_export = png_do_export; + png_hid.parse_arguments = png_parse_arguments; + png_hid.set_layer_group = png_set_layer_group; + png_hid.make_gc = rnd_drwpx_make_gc; + png_hid.destroy_gc = rnd_drwpx_destroy_gc; + png_hid.set_drawing_mode = png_set_drawing_mode; + png_hid.set_color = png_set_color; + png_hid.set_line_cap = rnd_drwpx_set_line_cap; + png_hid.set_line_width = rnd_drwpx_set_line_width; + png_hid.set_draw_xor = rnd_drwpx_set_draw_xor; + png_hid.draw_line = png_draw_line; + png_hid.draw_arc = png_draw_arc; + png_hid.draw_rect = png_draw_rect; + png_hid.fill_circle = png_fill_circle; + png_hid.fill_polygon = png_fill_polygon; + png_hid.fill_polygon_offs = png_fill_polygon_offs; + png_hid.fill_rect = png_fill_rect; +/* png_hid.draw_pixmap = png_draw_pixmap;*/ + png_hid.argument_array = png_values; + + png_hid.usage = png_usage; + + if (rnd_drwpx_has_any_format()) { + rnd_hid_register_hid(&png_hid); + rnd_hid_load_defaults(&png_hid, png_attribute_list, NUM_OPTIONS); + } + return 0; +} Index: tags/1.0.5/src/plugins/export_png/export_png.pup =================================================================== --- tags/1.0.5/src/plugins/export_png/export_png.pup (nonexistent) +++ tags/1.0.5/src/plugins/export_png/export_png.pup (revision 10414) @@ -0,0 +1,10 @@ +$class export +$short export sheets to png +$long png, jpeg and gif render +$state works +$fmt-native no +$fmt-feature-e png +$package export-gd +dep lib_exp_pixmap +default buildin +autoload 1 Index: tags/1.0.5/src/plugins/export_ps/Makefile =================================================================== --- tags/1.0.5/src/plugins/export_ps/Makefile (nonexistent) +++ tags/1.0.5/src/plugins/export_ps/Makefile (revision 10414) @@ -0,0 +1,2 @@ +all: + cd ../../sch-rnd && make mod_export_ps Index: tags/1.0.5/src/plugins/export_ps/Plug.tmpasm =================================================================== --- tags/1.0.5/src/plugins/export_ps/Plug.tmpasm (nonexistent) +++ tags/1.0.5/src/plugins/export_ps/Plug.tmpasm (revision 10414) @@ -0,0 +1,12 @@ +put /local/rnd/mod {export_ps} +put /local/rnd/mod/OBJS [@ + $(PLUGDIR)/export_ps/export_ps.o + $(PLUGDIR)/export_ps/ps.o + $(PLUGDIR)/export_ps/eps.o +@] + +switch /local/module/export_ps/controls + case {buildin} include /local/csch/tmpasm/buildin; end; + case {plugin} include /local/csch/tmpasm/plugin; end; + case {disable} include /local/csch/tmpasm/disable; end; +end Index: tags/1.0.5/src/plugins/export_ps/eps.c =================================================================== --- tags/1.0.5/src/plugins/export_ps/eps.c (nonexistent) +++ tags/1.0.5/src/plugins/export_ps/eps.c (revision 10414) @@ -0,0 +1,301 @@ +/* + This file is part of pcb-rnd and was part of gEDA/PCB but lacked proper + copyright banner at the fork. It probably has the same copyright as + gEDA/PCB as a whole in 2011. +*/ + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "export_ps.h" + + +static rnd_hid_t eps_hid; + +static rnd_eps_t pctx_, *pctx = &pctx_; + +static const rnd_export_opt_t eps_attribute_list[] = { + /* other HIDs expect this to be first. */ + +/* %start-doc options "92 Encapsulated Postscript Export" +@ftable @code +@item --eps-file +Name of the encapsulated postscript output file. Can contain a path. +@end ftable +%end-doc +*/ + {"eps-file", "Encapsulated Postscript output file", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0}, +#define HA_psfile 0 + +/* %start-doc options "92 Encapsulated Postscript Export" +@ftable @code +@item --eps-scale +Scale EPS output by the parameter @samp{num}. +@end ftable +%end-doc +*/ + {"eps-scale", "EPS scale", + RND_HATT_REAL, 0, 100, {0, 0, 1.0}, 0}, +#define HA_scale 1 + +/* %start-doc options "92 Encapsulated Postscript Export" +@ftable @code +@item --monochrome +Convert output to monochrome. +@end ftable +%end-doc +*/ + {"monochrome", "Convert to monochrome", + RND_HATT_BOOL, 0, 0, {0, 0, 0}, 0}, +#define HA_mono 2 + + {"fill-gray-threshold", "In monochrome, fill polygons with gray if color is lighter than this percentage (0 is black, 100 is white)", + RND_HATT_INTEGER, 0, 100, {80, 0, 0}, 0}, +#define HA_fill_gray_threshold 3 + + {"screen-colors", "Allow object highlight and selection color", + RND_HATT_BOOL, 0, 0, {0, 0, 0}, 0}, +#define HA_screen_color 4 + + {"layers", "List of layers to export or \"GUI\" for exporting what's visible on the GUI at the moment or empty for default export layer visibility", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0}, +#define HA_layers 5 + + {"view", "If not empty, switch to view and compile before exporting", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0}, +#define HA_view 6 +}; + +#define NUM_OPTIONS (sizeof(eps_attribute_list)/sizeof(eps_attribute_list[0])) + +static rnd_hid_attr_val_t eps_values[NUM_OPTIONS]; + +static const rnd_export_opt_t *eps_get_export_options(rnd_hid_t *hid, int *n, rnd_design_t *dsg, void *appspec) +{ + const char *val = eps_values[HA_psfile].str; + + if ((dsg != NULL) && ((val == NULL) || (*val == '\0'))) + csch_derive_default_filename(dsg, sch_rnd_export_appspec_prj(appspec), &eps_values[HA_psfile], ".eps"); + + if (n) + *n = NUM_OPTIONS; + return eps_attribute_list; +} + +static const char *filename; +static double eps_fill_gray_thrs; +static rnd_hid_attr_val_t *options_; + +void eps_hid_export_to_file(rnd_design_t *hl, FILE * the_file, rnd_hid_attr_val_t *options, rnd_xform_t *xform) +{ + rnd_box_t region, *bnds; + double dtmp; + rnd_hid_expose_ctx_t ctx; + + options_ = options; + + region.X1 = hl->dwg.X1; + region.Y1 = hl->dwg.Y1; + region.X2 = hl->dwg.X2; + region.Y2 = hl->dwg.Y2; + bnds = ®ion; + + rnd_eps_init(pctx, the_file, *bnds, options_[HA_scale].dbl, options[HA_mono].lng, 0); + + dtmp = (double)options[HA_fill_gray_threshold].lng / 100.0; + eps_fill_gray_thrs = dtmp * dtmp * 3; + + if (pctx->outf != NULL) + rnd_eps_print_header(pctx, rnd_hid_export_fn(filename), 0, 1); + + xform->no_render_select = xform->no_render_hilight = !options[HA_screen_color].lng; + + ctx.design = hl; + ctx.view = *bnds; + rnd_app.expose_main(&eps_hid, &ctx, xform); + + rnd_eps_print_footer(pctx); + + options_ = NULL; +} + +static int eps_do_export_sheet(rnd_hid_t *hid, rnd_design_t *dsg, rnd_hid_attr_val_t *options, sch_rnd_export_appspec_t *appspec, int *ovr) +{ + rnd_xform_t xform = {0}; + + filename = cschem_export_filename(dsg, options[HA_psfile].str, NULL, appspec->fn_page_suffix, ".eps"); + pctx->outf = rnd_fopen_askovr(dsg, filename, "w", ovr); + if (pctx->outf == NULL) { + perror(filename); + return -1; + } + + sch_rnd_set_export_layers(&xform, options[HA_layers].str); + eps_hid_export_to_file(dsg, pctx->outf, options, &xform); + + fclose(pctx->outf); + return 0; +} + +static void eps_do_export(rnd_hid_t *hid, rnd_design_t *design, rnd_hid_attr_val_t *options, void *appspec_) +{ + rnd_design_t *hl = design; + csch_sheet_t *sheet = (csch_sheet_t *)hl; + void *view_cookie; + sch_rnd_export_appspec_t *appspec = (appspec_ == NULL) ? &sch_rnd_no_appspec : appspec_; + + if (!options) { + eps_get_export_options(hid, 0, design, appspec); + options = eps_values; + } + + if (cschem_export_compile_pre((csch_project_t *)sheet->hidlib.project, options[HA_view].str, &view_cookie) != 0) + return; + + sch_rnd_export_project_or_sheet(hid, design, options, appspec, eps_do_export_sheet); + + cschem_export_compile_post((csch_project_t *)sheet->hidlib.project, &view_cookie); +} + +static int eps_parse_arguments(rnd_hid_t *hid, int *argc, char ***argv) +{ + rnd_export_register_opts2(hid, eps_attribute_list, sizeof(eps_attribute_list) / sizeof(eps_attribute_list[0]), ps_cookie, 0); + return rnd_hid_parse_command_line(argc, argv); +} + +static int eps_set_layer_group(rnd_hid_t *hid, rnd_design_t *design, rnd_layergrp_id_t group, const char *purpose, int purpi, rnd_layer_id_t layer, unsigned int flags, int is_empty, rnd_xform_t **xform) +{ + return 1; +} + +static void eps_set_drawing_mode(rnd_hid_t *hid, rnd_composite_op_t op, rnd_bool direct, const rnd_box_t *screen) +{ + rnd_eps_set_drawing_mode(pctx, hid, op, direct, screen); +} + +static rnd_color_t eps_last_color; +static void eps_set_color(rnd_hid_gc_t gc, const rnd_color_t *color) +{ + eps_last_color = *color; + rnd_eps_set_color(pctx, gc, color); +} + +static void eps_draw_rect(rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) +{ + rnd_eps_draw_rect(pctx, gc, x1, y1, x2, y2); +} + +static void eps_draw_line(rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) +{ + rnd_eps_draw_line(pctx, gc, x1, y1, x2, y2); +} + +static void eps_draw_arc(rnd_hid_gc_t gc, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t width, rnd_coord_t height, rnd_angle_t start_angle, rnd_angle_t delta_angle) +{ + rnd_eps_draw_arc(pctx, gc, cx, cy, width, height, start_angle, delta_angle); +} + +static void eps_fill_circle(rnd_hid_gc_t gc, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t radius) +{ + rnd_eps_fill_circle(pctx, gc, cx, cy, radius); +} + +static void eps_fill_polygon_offs(rnd_hid_gc_t gc, int n_coords, rnd_coord_t *x, rnd_coord_t *y, rnd_coord_t dx, rnd_coord_t dy) +{ + /* maybe tweak fill color so that light fills remain light grey */ + if (pctx->in_mono) { + double intens2 = eps_last_color.fr * eps_last_color.fr + eps_last_color.fg * eps_last_color.fg + eps_last_color.fb * eps_last_color.fb; + + if (intens2 >= eps_fill_gray_thrs) { + rnd_color_t clr = eps_last_color; + int avg = rnd_round((double)(clr.r + clr.g + clr.b) / 3.0); + clr.r = clr.g = clr.b = avg; + + pctx->in_mono = 0; + rnd_eps_set_color(pctx, gc, &clr); + pctx->in_mono = 1; + } + } + + rnd_eps_fill_polygon_offs(pctx, gc, n_coords, x, y, dx, dy); +} + +static void eps_fill_polygon(rnd_hid_gc_t gc, int n_coords, rnd_coord_t *x, rnd_coord_t *y) +{ + eps_fill_polygon_offs(gc, n_coords, x, y, 0, 0); +} + +static void eps_fill_rect(rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) +{ + rnd_eps_fill_rect(pctx, gc, x1, y1, x2, y2); +} + +static int eps_usage(rnd_hid_t *hid, const char *topic) +{ + fprintf(stderr, "\neps exporter command line arguments:\n\n"); + rnd_hid_usage(eps_attribute_list, sizeof(eps_attribute_list) / sizeof(eps_attribute_list[0])); + fprintf(stderr, "\nUsage: sch-rnd [generic_options] -x eps [eps options] foo.pcb\n\n"); + return 0; +} + +void hid_eps_uninit() +{ + rnd_hid_remove_hid(&eps_hid); +} + +void hid_eps_init() +{ + memset(&eps_hid, 0, sizeof(rnd_hid_t)); + + rnd_hid_nogui_init(&eps_hid); + + eps_hid.struct_size = sizeof(rnd_hid_t); + eps_hid.name = "eps"; + eps_hid.description = "Encapsulated Postscript"; + eps_hid.exporter = 1; + + eps_hid.get_export_options = eps_get_export_options; + eps_hid.do_export = eps_do_export; + eps_hid.parse_arguments = eps_parse_arguments; + eps_hid.set_layer_group = eps_set_layer_group; + eps_hid.make_gc = rnd_eps_make_gc; + eps_hid.destroy_gc = rnd_eps_destroy_gc; + eps_hid.set_drawing_mode = eps_set_drawing_mode; + eps_hid.set_color = eps_set_color; + eps_hid.set_line_cap = rnd_eps_set_line_cap; + eps_hid.set_line_width = rnd_eps_set_line_width; + eps_hid.set_draw_xor = rnd_eps_set_draw_xor; + eps_hid.draw_line = eps_draw_line; + eps_hid.draw_arc = eps_draw_arc; + eps_hid.draw_rect = eps_draw_rect; + eps_hid.fill_circle = eps_fill_circle; + eps_hid.fill_polygon = eps_fill_polygon; + eps_hid.fill_polygon_offs = eps_fill_polygon_offs; + eps_hid.fill_rect = eps_fill_rect; + eps_hid.set_crosshair = rnd_eps_set_crosshair; + eps_hid.argument_array = eps_values; + + eps_hid.usage = eps_usage; + + rnd_hid_register_hid(&eps_hid); + rnd_hid_load_defaults(&eps_hid, eps_attribute_list, NUM_OPTIONS); +} Index: tags/1.0.5/src/plugins/export_ps/export_ps.c =================================================================== --- tags/1.0.5/src/plugins/export_ps/export_ps.c (nonexistent) +++ tags/1.0.5/src/plugins/export_ps/export_ps.c (revision 10414) @@ -0,0 +1,54 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - ps export + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include + +#include + +#include +#include + +#include "export_ps.h" + +int pplg_check_ver_export_ps(int ver_needed) { return 0; } + +void pplg_uninit_export_ps(void) +{ + hid_ps_uninit(); + hid_eps_uninit(); +} + +int pplg_init_export_ps(void) +{ + RND_API_CHK_VER; + + hid_ps_init(); + hid_eps_init(); + + return 0; +} Index: tags/1.0.5/src/plugins/export_ps/export_ps.h =================================================================== --- tags/1.0.5/src/plugins/export_ps/export_ps.h (nonexistent) +++ tags/1.0.5/src/plugins/export_ps/export_ps.h (revision 10414) @@ -0,0 +1,12 @@ +/* required by lpr */ +extern rnd_hid_t ps_hid; +extern void ps_hid_export_to_file(rnd_design_t *, FILE *, rnd_hid_attr_val_t *, rnd_xform_t *, void *); +void ps_ps_init(rnd_hid_t * hid); + +/* required for ps<->eps cross call */ +extern void hid_eps_init(); +extern void hid_eps_uninit(); +extern void hid_ps_init(); +extern void hid_ps_uninit(); +extern const char *ps_cookie; + Index: tags/1.0.5/src/plugins/export_ps/export_ps.pup =================================================================== --- tags/1.0.5/src/plugins/export_ps/export_ps.pup (nonexistent) +++ tags/1.0.5/src/plugins/export_ps/export_ps.pup (revision 10414) @@ -0,0 +1,11 @@ +$class export +$short export sheets to ps/eps +$long PostScript, Encapsulated PostScript exporter +$state works +$fmt-native no +$fmt-feature-e ps +$fmt-feature-e eps +$package export-vector +dep lib_exp_text +default buildin +autoload 1 Index: tags/1.0.5/src/plugins/export_ps/ps.c =================================================================== --- tags/1.0.5/src/plugins/export_ps/ps.c (nonexistent) +++ tags/1.0.5/src/plugins/export_ps/ps.c (revision 10414) @@ -0,0 +1,516 @@ +/* + This file is part of pcb-rnd and was part of gEDA/PCB but lacked proper + copyright banner at the fork. It probably has the same copyright as + gEDA/PCB as a whole in 2011. +*/ +#include + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "export_ps.h" + +const char *ps_cookie = "ps HID"; + +static int ps_set_layer_group(rnd_hid_t *hid, rnd_design_t *design, rnd_layergrp_id_t group, const char *purpose, int purpi, rnd_layer_id_t layer, unsigned int flags, int is_empty, rnd_xform_t **xform); + +static const rnd_export_opt_t ps_attribute_list[] = { + /* other HIDs expect this to be first. */ + +/* %start-doc options "91 Postscript Export" +@ftable @code +@item --psfile +Name of the postscript output file. Can contain a path. +@end ftable +%end-doc +*/ + {"psfile", "Postscript output file", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0}, +#define HA_psfile 0 + +/* %start-doc options "91 Postscript Export" +@ftable @code +@item --fill-page +Scale output to make the sheet fit the page. +@end ftable +%end-doc +*/ + {"fill-page", "Scale drawing to fill page (default on)", + RND_HATT_BOOL, 0, 0, {1, 0, 0}, 0}, +#define HA_fillpage 1 + +/* %start-doc options "91 Postscript Export" +@ftable @code +@item --ps-color +Postscript output in color. +@end ftable +%end-doc +*/ + {"ps-color", "Prints in color", + RND_HATT_BOOL, 0, 0, {0, 0, 0}, 0}, +#define HA_color 2 + + {"fill-gray-threshold", "If ps-color is not enabled, fill polygons with grey if color is lighter than this percentage (0 is black, 100 is white)", + RND_HATT_INTEGER, 0, 100, {80, 0, 0}, 0}, +#define HA_fill_gray_threshold 3 + +/* %start-doc options "91 Postscript Export" +@ftable @code +@cindex ps-invert +@item --ps-invert +Draw objects as white-on-black. +@end ftable +%end-doc +*/ + {"ps-invert", "Draw objects as white-on-black", + RND_HATT_BOOL, 0, 0, {0, 0, 0}, 0}, +#define HA_psinvert 4 + +/* %start-doc options "91 Postscript Export" +@ftable @code +@item --media +Size of the media, the postscript is fitted to. The parameter +@code{} can be any of the standard names for paper size: @samp{A0} +to @samp{A10}, @samp{B0} to @samp{B10}, @samp{Letter}, @samp{11x17}, +@samp{Ledger}, @samp{Legal}, @samp{Executive}, @samp{A-Size}, @samp{B-size}, +@samp{C-Size}, @samp{D-size}, @samp{E-size}, @samp{US-Business_Card}, +@samp{Intl-Business_Card}. +@end ftable +%end-doc +*/ + {"media", "media type", + RND_HATT_ENUM, 0, 0, {22, 0, 0}, rnd_medias}, +#define HA_media 5 + +/* %start-doc options "91 Postscript Export" +@ftable @code +@item --scale +Scale value to compensate for printer sizing errors (1.0 = full scale). +@end ftable +%end-doc +*/ + {"scale", "Scale value to compensate for printer sizing errors (1.0 = full scale)", + RND_HATT_REAL, 0.01, 4, {0, 0, 1.00}, 0}, +#define HA_scale 6 + +/* %start-doc options "91 Postscript Export" +@ftable @code +@cindex multi-file +@item --multi-file +Produce multiple files, one per page, instead of a single multi page file. +@end ftable +%end-doc +*/ + {"multi-file", "Produce multiple files, one per page, instead of a single file", + RND_HATT_BOOL, 0, 0, {0, 0, 0.40}, 0}, +#define HA_multifile 7 + +/* %start-doc options "91 Postscript Export" +@ftable @code +@cindex show-toc +@item --show-toc +Generate Table of Contents +@end ftable +%end-doc +*/ + {"show-toc", "Print Table of Content (automatic decision unless explicitly changed)", + RND_HATT_BOOL, 0, 0, {2, 0, 0}, 0}, /* 2 means "auto" */ +#define HA_toc 8 + + {"screen-colors", "Allow object highlight and selection color", + RND_HATT_BOOL, 0, 0, {0, 0, 0}, 0}, +#define HA_screen_color 9 + + {"layers", "List of layers to export or \"GUI\" for exporting what's visible on the GUI at the moment or empty for default export layer visibility", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0}, +#define HA_layers 10 + + {"view", "If not empty, switch to view and compile before exporting", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0}, +#define HA_view 11 + +}; + +#define NUM_OPTIONS (sizeof(ps_attribute_list)/sizeof(ps_attribute_list[0])) + +/* All file-scope data is in global struct */ +static struct { + rnd_ps_t ps; + + rnd_bool multi_file; + double fill_gray_thrs; + + const char *filename; + rnd_hid_expose_ctx_t exps; + + rnd_hid_attr_val_t ps_values[NUM_OPTIONS]; + + int ovr_all; + int had_page; /* 1 if we ever wrote a page */ + + sch_rnd_export_appspec_t *appspec; +} global; + +static const rnd_export_opt_t *ps_get_export_options(rnd_hid_t *hid, int *n, rnd_design_t *dsg, void *appspec) +{ + const char *val = global.ps_values[HA_psfile].str; + + if ((dsg != NULL) && ((val == NULL) || (*val == '\0'))) + csch_derive_default_filename(dsg, sch_rnd_export_appspec_prj(appspec), &global.ps_values[HA_psfile], ".ps"); + if (n) + *n = NUM_OPTIONS; + return ps_attribute_list; +} + +static FILE *psopen(rnd_design_t *hl, const char *base, const char *which) +{ + FILE *ps_open_file; + char *buf, *suff, *buf2; + + if (base == NULL) /* cam, file name template case */ + return NULL; + + if (!global.multi_file) + return rnd_fopen_askovr(hl, base, "w", NULL); + + buf = (char *)malloc(strlen(base) + strlen(which) + 5); + + suff = (char *)strrchr(base, '.'); + if (suff) { + strcpy(buf, base); + buf2 = strrchr(buf, '.'); + sprintf(buf2, ".%s.%s", which, suff + 1); + } + else { + sprintf(buf, "%s.%s.ps", base, which); + } + ps_open_file = rnd_fopen_askovr(hl, buf, "w", &global.ovr_all); + free(buf); + return ps_open_file; +} + +/* This is used by other HIDs that use a postscript format, like lpr or eps. */ +void ps_hid_export_to_file(rnd_design_t *hl, FILE * the_file, rnd_hid_attr_val_t * options, rnd_xform_t *xform, void *appspec_) +{ + double dtmp; + int toc; + rnd_xform_t xform0 = {0}; + + if (xform == NULL) xform = &xform0; + + rnd_ps_init(&global.ps, hl, the_file, options[HA_media].lng, options[HA_fillpage].lng, options[HA_scale].dbl); + + /* generic ps config: extra conf from export params */ + global.ps.incolor = options[HA_color].lng; + global.ps.invert = options[HA_psinvert].lng; + xform->no_render_select = xform->no_render_hilight = !options[HA_screen_color].lng; + + dtmp = (double)options[HA_fill_gray_threshold].lng / 100.0; + global.fill_gray_thrs = dtmp * dtmp * 3; + + if (the_file) + rnd_ps_start_file(&global.ps, "sch-rnd release: sch-rnd " CSCH_VERSION); + + /* reset static vars */ + rnd_ps_use_gc(&global.ps, NULL); + + global.exps.design = hl; + global.exps.view.X1 = hl->dwg.X1; + global.exps.view.Y1 = hl->dwg.Y1; + global.exps.view.X2 = hl->dwg.X2; + global.exps.view.Y2 = hl->dwg.Y2; + + /* print ToC */ + switch(options[HA_toc].lng) { + case 0: toc = 0; break; /* explicit off */ + case 1: toc = 1; break; /* explicit on */ + default: toc = 0*global.appspec->exp_prj; /* auto: use toc for project export, don't use toc for single sheet export */ + } + + global.had_page = 0; + if (!global.multi_file && toc) { + rnd_ps_begin_toc(&global.ps); + rnd_app.expose_main(&ps_hid, &global.exps, xform); + rnd_ps_end_toc(&global.ps); + global.had_page = 1; + } + + /* print page(s) */ + rnd_ps_begin_pages(&global.ps); + rnd_app.expose_main(&ps_hid, &global.exps, xform); + rnd_ps_end_pages(&global.ps); +} + + +static FILE *fh; + +static int ps_do_export_sheet(rnd_hid_t *hid, rnd_design_t *dsg, rnd_hid_attr_val_t *options, sch_rnd_export_appspec_t *appspec, int *ovr) +{ + rnd_xform_t xform = {0}; + + global.appspec = appspec; + sch_rnd_set_export_layers(&xform, options[HA_layers].str); + ps_hid_export_to_file(dsg, fh, options, &xform, appspec); + return 0; +} + + +static void ps_do_export(rnd_hid_t *hid, rnd_design_t *design, rnd_hid_attr_val_t *options, void *appspec_) +{ + rnd_design_t *hl = design; + csch_sheet_t *sheet = (csch_sheet_t *)hl; + void *view_cookie; + sch_rnd_export_appspec_t *appspec = (appspec_ == NULL) ? &sch_rnd_no_appspec : appspec_; + + global.ovr_all = 0; + + if (!options) { + ps_get_export_options(hid, 0, design, appspec); + options = global.ps_values; + } + + if (cschem_export_compile_pre((csch_project_t *)sheet->hidlib.project, options[HA_view].str, &view_cookie) != 0) + return; + + global.multi_file = options[HA_multifile].lng; + global.filename = cschem_export_filename(hl, options[HA_psfile].str, NULL, NULL, ".ps"); + + if (global.multi_file) + fh = 0; + else { + const char *fn = global.filename; + fh = psopen(hl, fn, "toc"); + if (!fh) { + perror(fn); + goto error; + } + } + + + sch_rnd_export_project_or_sheet(hid, design, options, appspec, ps_do_export_sheet); + + global.multi_file = 0; + if (fh) { + rnd_ps_end_file(&global.ps); + fclose(fh); + } + + error:; + cschem_export_compile_post((csch_project_t *)sheet->hidlib.project, &view_cookie); +} + +static int ps_parse_arguments(rnd_hid_t *hid, int *argc, char ***argv) +{ + rnd_export_register_opts2(hid, ps_attribute_list, NUM_OPTIONS, ps_cookie, 0); + return rnd_hid_parse_command_line(argc, argv); +} + +static int ps_set_layer_group(rnd_hid_t *hid, rnd_design_t *design, rnd_layergrp_id_t group, const char *purpose, int purpi, rnd_layer_id_t layer, unsigned int flags, int is_empty, rnd_xform_t **xform) +{ + rnd_design_t *hl = design; + gds_t tmp_ln; + const char *name; + int newpage; + + gds_init(&tmp_ln); + TODO("project: needed for project multisheet export"); + name = "TODO:layer_name"; + + if (rnd_ps_printed_toc(&global.ps, group, name)) { + gds_uninit(&tmp_ln); + return 0; + } + + newpage = rnd_ps_is_new_page(&global.ps, group); + if (newpage) { + if ((global.ps.pagecount != 0) && global.had_page) { + rnd_fprintf(global.ps.outf, "showpage\n"); + } + if (global.multi_file) { + int nr; + const char *fn; + gds_t tmp; + + gds_init(&tmp); + fn = global.appspec->fn_page_suffix+1; + nr = rnd_ps_new_file(&global.ps, psopen(hl, global.filename, fn), fn); + gds_uninit(&tmp); + if (nr != 0) + return 0; + + rnd_ps_start_file(&global.ps, "sch-rnd release: sch-rnd " CSCH_VERSION); + } + else + global.had_page = 1; + + + { + gds_t tmp = {0}; + const char *layer_fn = "TODO_ps_filename2"; + rnd_ps_page_frame(&global.ps, 1, layer_fn, 0); + gds_uninit(&tmp); + } + + rnd_ps_page_background(&global.ps, 0, 0, 1); + } + + gds_uninit(&tmp_ln); + return 1; +} + +static void ps_set_drawing_mode(rnd_hid_t *hid, rnd_composite_op_t op, rnd_bool direct, const rnd_box_t *screen) +{ + rnd_ps_set_drawing_mode(&global.ps, hid, op, direct, screen); +} + +static rnd_color_t ps_last_color; +static void ps_set_color(rnd_hid_gc_t gc, const rnd_color_t *color) +{ + ps_last_color = *color; + rnd_ps_set_color(&global.ps, gc, color); +} + +static void ps_draw_rect(rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) +{ + rnd_ps_draw_rect(&global.ps, gc, x1, y1, x2, y2); +} + +static void ps_draw_line(rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) +{ + rnd_ps_draw_line(&global.ps, gc, x1, y1, x2, y2); +} + +static void ps_draw_arc(rnd_hid_gc_t gc, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t width, rnd_coord_t height, rnd_angle_t start_angle, rnd_angle_t delta_angle) +{ + rnd_ps_draw_arc(&global.ps, gc, cx, cy, width, height, start_angle, delta_angle); +} + +static void ps_fill_circle(rnd_hid_gc_t gc, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t radius) +{ + rnd_ps_fill_circle(&global.ps, gc, cx, cy, radius); +} + +static void ps_fill_polygon_offs(rnd_hid_gc_t gc, int n_coords, rnd_coord_t *x, rnd_coord_t *y, rnd_coord_t dx, rnd_coord_t dy) +{ + /* maybe tweak fill color so that light fills remain light grey */ + if (!global.ps.incolor) { + double intens2 = ps_last_color.fr * ps_last_color.fr + ps_last_color.fg * ps_last_color.fg + ps_last_color.fb * ps_last_color.fb; + + if (intens2 >= global.fill_gray_thrs) { + rnd_color_t clr = ps_last_color; + int avg = rnd_round((double)(clr.r + clr.g + clr.b) / 3.0); + clr.r = clr.g = clr.b = avg; + + global.ps.incolor = 1; + rnd_ps_set_color(&global.ps, gc, &clr); + global.ps.incolor = 0; + } + } + + rnd_ps_fill_polygon_offs(&global.ps, gc, n_coords, x, y, dx, dy); +} + + +static void ps_fill_polygon(rnd_hid_gc_t gc, int n_coords, rnd_coord_t *x, rnd_coord_t *y) +{ + ps_fill_polygon_offs(gc, n_coords, x, y, 0, 0); +} + +static void ps_fill_rect(rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) +{ + rnd_ps_fill_rect(&global.ps, gc, x1, y1, x2, y2); +} + + +rnd_hid_t ps_hid; + + +static int ps_inited = 0; +void ps_ps_init(rnd_hid_t * hid) +{ + if (ps_inited) + return; + + hid->get_export_options = ps_get_export_options; + hid->do_export = ps_do_export; + hid->parse_arguments = ps_parse_arguments; + hid->set_layer_group = ps_set_layer_group; + hid->make_gc = rnd_ps_make_gc; + hid->destroy_gc = rnd_ps_destroy_gc; + hid->set_drawing_mode = ps_set_drawing_mode; + hid->set_color = ps_set_color; + hid->set_line_cap = rnd_ps_set_line_cap; + hid->set_line_width = rnd_ps_set_line_width; + hid->set_draw_xor = rnd_ps_set_draw_xor; + hid->draw_line = ps_draw_line; + hid->draw_arc = ps_draw_arc; + hid->draw_rect = ps_draw_rect; + hid->fill_circle = ps_fill_circle; + hid->fill_polygon_offs = ps_fill_polygon_offs; + hid->fill_polygon = ps_fill_polygon; + hid->fill_rect = ps_fill_rect; + hid->set_crosshair = rnd_ps_set_crosshair; + + ps_inited = 1; +} + +static int ps_usage(rnd_hid_t *hid, const char *topic) +{ + fprintf(stderr, "\nps exporter command line arguments:\n\n"); + rnd_hid_usage(ps_attribute_list, sizeof(ps_attribute_list) / sizeof(ps_attribute_list[0])); + fprintf(stderr, "\nUsage: sch-rnd [generic_options] -x ps [ps options] foo.rs\n\n"); + return 0; +} + +static void plugin_ps_uninit(void) +{ + rnd_remove_actions_by_cookie(ps_cookie); + rnd_export_remove_opts_by_cookie(ps_cookie); + ps_inited = 0; +} + +void hid_ps_uninit() +{ + plugin_ps_uninit(); + rnd_hid_remove_hid(&ps_hid); +} + +void hid_ps_init() +{ + memset(&ps_hid, 0, sizeof(rnd_hid_t)); + + rnd_hid_nogui_init(&ps_hid); + ps_ps_init(&ps_hid); + + ps_hid.struct_size = sizeof(rnd_hid_t); + ps_hid.name = "ps"; + ps_hid.description = "Postscript export"; + ps_hid.exporter = 1; + ps_hid.mask_invert = 1; + ps_hid.argument_array = global.ps_values; + + ps_hid.usage = ps_usage; + + rnd_hid_register_hid(&ps_hid); + rnd_hid_load_defaults(&ps_hid, ps_attribute_list, NUM_OPTIONS); +} Index: tags/1.0.5/src/plugins/export_spice/Makefile =================================================================== --- tags/1.0.5/src/plugins/export_spice/Makefile (nonexistent) +++ tags/1.0.5/src/plugins/export_spice/Makefile (revision 10414) @@ -0,0 +1,2 @@ +all: + cd ../../sch-rnd && make mod_export_spice Index: tags/1.0.5/src/plugins/export_spice/Plug.tmpasm =================================================================== --- tags/1.0.5/src/plugins/export_spice/Plug.tmpasm (nonexistent) +++ tags/1.0.5/src/plugins/export_spice/Plug.tmpasm (revision 10414) @@ -0,0 +1,10 @@ +put /local/rnd/mod {export_spice} +put /local/rnd/mod/OBJS [@ + $(PLUGDIR)/export_spice/export_spice.o +@] + +switch /local/module/export_spice/controls + case {buildin} include /local/csch/tmpasm/buildin; end; + case {plugin} include /local/csch/tmpasm/plugin; end; + case {disable} include /local/csch/tmpasm/disable; end; +end Index: tags/1.0.5/src/plugins/export_spice/export_spice.c =================================================================== --- tags/1.0.5/src/plugins/export_spice/export_spice.c (nonexistent) +++ tags/1.0.5/src/plugins/export_spice/export_spice.c (revision 10414) @@ -0,0 +1,522 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - SPICE netlist export + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +static csch_plug_io_t espice_net; +static vtp0_t pin2port = {0}; /* cache */ +static vtp0_t pin2vect = {0}; /* cache; each item is a dynamically allocated vtp0_t of ports */ + +extern int export_spice_is_dbg(void); + + +static int spice_export_prio(const char *fn, const char *fmt, csch_plug_io_type_t type) +{ + if (type != CSCH_IOTYP_NETLIST) + return 0; + if (rnd_strcasecmp(fmt, "spice") == 0) + return 100; + if (rnd_strcasecmp(fmt, "cir") == 0) + return 98; + if (rnd_strcasecmp(fmt, "net") == 0) + return 95; + return 0; +} + +typedef struct { + csch_anet_t *net0; +} spice_ctx_t; + +static const char *spice_get_netname(spice_ctx_t *ctx, const csch_anet_t *net) +{ + if (net == ctx->net0) + return "0"; + return sch_nle_get_netname(net); +} + + +static void print_port_net(spice_ctx_t *ctx, FILE *f, const csch_aport_t *port, const char *refdes, long pinnum, long *noconn, int spc) +{ + const csch_anet_t *net; + const char *netname; + + if (spc) + fputc(' ', f); + + net = port->conn.net; + if ((net == NULL) || (net->hdr.omit)) { + rnd_message(RND_MSG_ERROR, "spice: pin '%d' in component %s is not connected anywhere\n", pinnum, refdes); + fprintf(f, "__noconn_%ld__", (*noconn)++); + return; + } + + netname = spice_get_netname(ctx, net); /* can't be NULL, auto-named to anon then */ + fprintf(f, "%s", netname); +} + +static void print_vect_nets(spice_ctx_t *ctx, FILE *f, vtp0_t *vect, const char *refdes, long pinnum, long *noconn) +{ + long n; + fprintf(f, " ["); + for(n = 0; n < vect->used; n++) + print_port_net(ctx, f, vect->array[n], refdes, pinnum, noconn, (n > 0)); + fprintf(f, "]"); +} + +static void print_port_name(spice_ctx_t *ctx, FILE *f, const csch_aport_t *port) +{ + fprintf(f, " %s", port->name); +} + +static void print_vect_names(spice_ctx_t *ctx, FILE *f, vtp0_t *vect) +{ + long n; + fprintf(f, " ["); + for(n = 0; n < vect->used; n++) + print_port_name(ctx, f, vect->array[n]); + fprintf(f, "]"); +} + + + +static void spice_export_comps(FILE *f, csch_abstract_t *abs) +{ + long noconn = 0; + spice_ctx_t ctx = {0}; + htsp_entry_t *e, *p; + int debug = export_spice_is_dbg(); + + /* find net 0 and store it in ctx */ + for(e = htsp_first(&abs->nets); e != NULL; e = htsp_next(&abs->nets, e)) { + csch_anet_t *net = e->value; + if (!net->hdr.omit) { + const char *attr = csch_attrib_get_str(&net->hdr.attr, "spice/gnd"); + if (attr != NULL) { + ctx.net0 = net; + break; + } + } + } + + /* write instances */ + for(e = htsp_first(&abs->comps); e != NULL; e = htsp_next(&abs->comps, e)) { + csch_acomp_t *comp = e->value; + const char *refdes = sch_nle_get_refdes(comp), *val, *parms; + long n; + + if ((refdes == NULL) || (comp->hdr.omit)) + continue; + + if (debug) { + const char *dev = sch_nle_get_alt_attr(&comp->hdr.attr, "device", NULL); + + fputc('\n', f); + fprintf(f, "* comp.name = %s\n", comp->name); + if (dev != NULL) + fprintf(f, "* comp.a.device = %s\n", dev); + } + + + /* map (order) ports into pin2port */ + pin2port.used = 0; + pin2vect.used = 0; + for(p = htsp_first(&comp->ports); p != NULL; p = htsp_next(&comp->ports, p)) { + const csch_aport_t *port = p->value; + void **already, **alreadyv; + const char *spinnum = sch_nle_get_pinnum(port), *spn; + char *end; + long pinnum; + int is_vect = 0; + + if (spinnum == NULL) + continue; /* pin without pin number should be ignored for simulation */ + + spn = spinnum; + if (*spn == '[') { + spn++; + is_vect = 1; + } + pinnum = strtol(spn, &end, 10); + if (is_vect ? (*end != ']') : (*end != '\0')) { + rnd_message(RND_MSG_ERROR, "spice: pin number '%s' is not an integer in component %s (ignoring pin)\n", spinnum, refdes); + continue; + } + + already = vtp0_get(&pin2port, pinnum, 0); + if ((already != NULL) && (*already != NULL)) { + rnd_message(RND_MSG_ERROR, "spice: duplicate pin '%s' in component %s (ignoring pin)\n", spinnum, refdes); + continue; + } + + alreadyv = vtp0_get(&pin2vect, pinnum, 0); + + if (is_vect) { + vtp0_t *vect; + if ((alreadyv == NULL) || (*alreadyv == NULL)) { + vect = calloc(sizeof(vtp0_t), 1); + vtp0_set(&pin2vect, pinnum, (void *)vect); + } + else + vect = *alreadyv; + vtp0_append(vect, (void *)port); + } + else + vtp0_set(&pin2port, pinnum, (void *)port); + } + + val = sch_nle_get_alt_attr(&comp->hdr.attr, "display/value", "value", NULL); + parms = sch_nle_get_alt_attr(&comp->hdr.attr, "display/spice/params", "spice/params", NULL); + + /* debug print port names and values */ + if (debug) { + fprintf(f, "* port_names ="); + for(n = 1; n < RND_MAX(pin2port.used, pin2vect.used); n++) { + const csch_aport_t *port = NULL; + vtp0_t *vect = NULL; + + if (n < pin2port.used) port = pin2port.array[n]; + if (n < pin2vect.used) vect = pin2vect.array[n]; + + if (vect != NULL) + print_vect_names(&ctx, f, vect); + else if (port != NULL) + print_port_name(&ctx, f, port); + } + fputc('\n', f); + + + if (val != NULL) + fprintf(f, "* comp.a.value = %s\n", val); + if (parms != NULL) + fprintf(f, "* comp.a.spice/params = %s\n", parms); + } + + /* print the instance */ + fprintf(f, "%s", refdes); + for(n = 1; n < RND_MAX(pin2port.used, pin2vect.used); n++) { + const csch_aport_t *port = NULL; + vtp0_t *vect = NULL; + + if (n < pin2port.used) port = pin2port.array[n]; + if (n < pin2vect.used) vect = pin2vect.array[n]; + + if ((port != NULL) && (vect != NULL)) { + const char *spinnum = sch_nle_get_pinnum(port); + rnd_message(RND_MSG_ERROR, "spice: pin '%s' in component %s can not be both scalar and vector; going for the vector\n", spinnum, refdes); + port = NULL; + } + + if ((port == NULL) && (vect == NULL)) { + rnd_message(RND_MSG_ERROR, "spice: missing pin '%d' in component %s (broken export)\n", n, refdes); + fprintf(f, " _missing"); + continue; + } + + if (vect != NULL) + print_vect_nets(&ctx, f, vect, refdes, n, &noconn); + else if (port != NULL) + print_port_net(&ctx, f, port, refdes, n, &noconn, 1); + else + abort(); /* can't get here, we've already checked that we have either port or vect */ + } + + /* free all vectors */ + for(n = 1; n < pin2vect.used; n++) { + vtp0_t *vect = pin2vect.array[n]; + if (vect != NULL) { + vtp0_uninit(vect); + free(vect); + } + pin2vect.array[n] = NULL; + } + + /* print val and params */ + if (val != NULL) + fprintf(f, " %s", val); + + val = sch_nle_get_alt_attr(&comp->hdr.attr, "spice/model_card", NULL); + if (val != NULL) { + val = sch_nle_get_alt_attr(&comp->hdr.attr, "spice/model_card_uname", NULL); + if (val != NULL) + fprintf(f, " %s", val); + else + fprintf(f, " sch_rnd_error_mc_uname"); + } + else { + val = sch_nle_get_alt_attr(&comp->hdr.attr, "spice/model_card_uname", NULL); + if (val == NULL) + val = sch_nle_get_alt_attr(&comp->hdr.attr, "spice/model", NULL); + if (val != NULL) + fprintf(f, " %s", val); + } + + if (parms != NULL) + fprintf(f, " %s", parms); + + fprintf(f, "\n"); + } +} + +/* Copy model_card's headers until the first non-comment; return the first + non-white-space character of the first non-comment line */ +static const char *find_model_card_head(FILE *f, const char *model_card) +{ + const char *s; + int nl = 1; + + for(s = model_card; *s != '\0'; s++) { + if (nl && !isspace(*s)) { + /* first non-space after a newline */ + if (*s != '*') + return s; + } + + if (*s == '\n') + nl = 1; + else if (isspace(*s) && nl) + nl = 1; /* ingore leading whitespace */ + else + nl = 0; + + fputc(*s, f); + } + return NULL; +} + +static void spice_export_model_cards(FILE *f, csch_abstract_t *abs) +{ + htsp_entry_t *e; + + for(e = htsp_first(&abs->comps); e != NULL; e = htsp_next(&abs->comps, e)) { + csch_acomp_t *comp = e->value; + const char *model_card, *head; + + if (comp->hdr.omit) continue; + + model_card = sch_nle_get_alt_attr(&comp->hdr.attr, "spice/model_card", NULL); + if (model_card != NULL) { + const char *uname = sch_nle_get_alt_attr(&comp->hdr.attr, "spice/model_card_uname", NULL); + + if (uname == NULL) + uname = "schrnd_error_no_uname"; + + fprintf(f, "\n*** sch-rnd/export_spice: model card: %s ***\n", comp->name); + + head = find_model_card_head(f, model_card); + if (head == NULL) { + rnd_message(RND_MSG_ERROR, "spice model card export: model card should start with .model or .subckt (component %s)\n", comp->name); + } + else if ((rnd_strncasecmp(head, ".model", 6) == 0) && isspace(head[6])) { + head += 6; + while(isspace(*head)) head++; + while(!isspace(*head)) head++; /* skip over original name */ + while(isspace(*head)) head++; + fprintf(f, ".MODEL %s %s\n", uname, head); + } + else if ((rnd_strncasecmp(head, ".subckt", 7) == 0) && isspace(head[7])) { + head += 7; + while(isspace(*head)) head++; + while(!isspace(*head)) head++; /* skip over original name */ + while(isspace(*head)) head++; + fprintf(f, ".SUBCKT %s %s\n", uname, head); + } + } + } +} + +static void spice_export_file_headers(FILE *f, csch_abstract_t *abs) +{ + int announced = 0; + htsp_entry_t *e; + + for(e = htsp_first(&abs->comps); e != NULL; e = htsp_next(&abs->comps, e)) { + csch_acomp_t *comp = e->value; + const char *hdr; + + if (comp->hdr.omit) continue; + + hdr = sch_nle_get_alt_attr(&comp->hdr.attr, "spice/file_header", NULL); + if (hdr != NULL) { + if (!announced) { + fprintf(f, "\n*** sch-rnd/export_spice: file headers ***\n"); + announced = 1; + } + fprintf(f, "\n%s\n", hdr); + } + } +} + +static void spice_export_includes(FILE *f, csch_abstract_t *abs) +{ + htsp_entry_t *e; + int hash_inited = 0; + htsp_t fns = {0}; + + for(e = htsp_first(&abs->comps); e != NULL; e = htsp_next(&abs->comps, e)) { + csch_acomp_t *comp = e->value; + const char *inc; + + if (comp->hdr.omit) continue; + + inc = sch_nle_get_alt_attr(&comp->hdr.attr, "spice/model_include", NULL); + if (inc != NULL) { + if (!hash_inited) { + htsp_init(&fns, strhash, strkeyeq); + hash_inited = 1; + } + htsp_set(&fns, (char *)inc, NULL); + } + } + + if (hash_inited) { + htsp_entry_t *e; + + fprintf(f, "\n*** sch-rnd/export_spice: model includes ***\n"); + for(e = htsp_first(&fns); e != NULL; e = htsp_next(&fns, e)) + fprintf(f, ".INCLUDE %s\n", e->key); + + htsp_uninit(&fns); + } +} + +static void spice_export_cmds(FILE *f, csch_abstract_t *abs) +{ + int announced = 0; + htsp_entry_t *e; + + for(e = htsp_first(&abs->comps); e != NULL; e = htsp_next(&abs->comps, e)) { + csch_acomp_t *comp = e->value; + const char *hdr; + + if (comp->hdr.omit) continue; + + hdr = sch_nle_get_alt_attr(&comp->hdr.attr, "spice/command", NULL); + if (hdr != NULL) { + if (!announced) { + fprintf(f, "\n*** sch-rnd/export_spice: commands ***\n.control\n"); + announced = 1; + } + fprintf(f, "\n%s\n", hdr); + } + } + if (announced) + fprintf(f, "\n.endc\n"); +} + +extern int export_spice_omit(const char *what); + +static int spice_export_project_abst(const char *fn, const char *fmt, csch_abstract_t *abs, rnd_hid_attr_val_t *options) +{ + TODO("get hidlib as an arg") + rnd_design_t *hidlib = NULL; + FILE *f = rnd_fopen(hidlib, fn, "w"); + if (f == NULL) + return -1; + + fprintf(f, ".title sch-rnd export using export_spice\n"); + + if (!export_spice_omit("headers")) + spice_export_file_headers(f, abs); + if (!export_spice_omit("includes")) + spice_export_includes(f, abs); + if (!export_spice_omit("model_cards")) + spice_export_model_cards(f, abs); + + fprintf(f, "\n*** circuit ***\n"); + spice_export_comps(f, abs); + + if (!export_spice_omit("commands")) + spice_export_cmds(f, abs); + fprintf(f, ".end\n"); + + fclose(f); + return 0; +} + +#include "hid_impl.c" + +int pplg_check_ver_export_spice(int ver_needed) { return 0; } + +void pplg_uninit_export_spice(void) +{ + csch_plug_io_unregister(&espice_net); + rnd_export_remove_opts_by_cookie(spice_cookie); + rnd_hid_remove_hid(&spice_hid); + + vtp0_uninit(&pin2port); + vtp0_uninit(&pin2vect); +} + +int pplg_init_export_spice(void) +{ + RND_API_CHK_VER; + + espice_net.name = "export to SPICE netlist"; + espice_net.export_prio = spice_export_prio; + espice_net.export_project_abst = spice_export_project_abst; + espice_net.ext_export_project = ".cir"; + csch_plug_io_register(&espice_net); + + + rnd_hid_nogui_init(&spice_hid); + + spice_hid.struct_size = sizeof(rnd_hid_t); + spice_hid.name = "spice"; + spice_hid.description = "Exports project's SPICE netlist"; + spice_hid.exporter = 1; + + spice_hid.get_export_options = spice_get_export_options; + spice_hid.do_export = spice_do_export; + spice_hid.parse_arguments = spice_parse_arguments; + spice_hid.argument_array = spice_values; + + spice_hid.usage = spice_usage; + + rnd_hid_register_hid(&spice_hid); + rnd_hid_load_defaults(&spice_hid, spice_options, NUM_OPTIONS); + + + return 0; +} + Index: tags/1.0.5/src/plugins/export_spice/export_spice.pup =================================================================== --- tags/1.0.5/src/plugins/export_spice/export_spice.pup (nonexistent) +++ tags/1.0.5/src/plugins/export_spice/export_spice.pup (revision 10414) @@ -0,0 +1,10 @@ +$class export +$short export SPICE netlist +$long SPICE netlist exporter for circuit simulation +$state works +$fmt-native no +$fmt-feature-e spice +$package (core) +dep lib_netlist_exp +default buildin +autoload 1 Index: tags/1.0.5/src/plugins/export_spice/hid_impl.c =================================================================== --- tags/1.0.5/src/plugins/export_spice/hid_impl.c (nonexistent) +++ tags/1.0.5/src/plugins/export_spice/hid_impl.c (revision 10414) @@ -0,0 +1,137 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - SPICE netlist export + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include +#include +#include +#include +#include +#include +#include + +static const char spice_cookie[] = "SPICE export hid"; + +static const rnd_export_opt_t spice_options[] = { + {"outfile", "Name of the SPICE netlist output file", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0}, +#define HA_outfile 0 + + {"debug", "Print extra comments in the output", + RND_HATT_BOOL, 0, 0, {0, 0, 0}, 0}, +#define HA_debug 1 + + {"omit-headers", "Do not print the header section (spice/file_header symbol attributes)", + RND_HATT_BOOL, 0, 0, {0, 0, 0}, 0}, +#define HA_omit_headers 2 + + {"omit-includes", "Do not print the includes (spice/model_include symbol attributes)", + RND_HATT_BOOL, 0, 0, {0, 0, 0}, 0}, +#define HA_omit_includes 3 + + {"omit-model-cards", "Do not print the model cards (either inline of lib-copied; spice/model_card, spice/model symbol attributes)", + RND_HATT_BOOL, 0, 0, {0, 0, 0}, 0}, +#define HA_omit_model_cards 4 + + {"omit-commands", "Do not print spice commands (spice/command symbol attributes)", + RND_HATT_BOOL, 0, 0, {0, 0, 0}, 0}, +#define HA_omit_commands 5 + + {"view", "Name of the view to export (use first view when not specified)", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0}, +#define HA_view 6 +}; + +#define NUM_OPTIONS (sizeof(spice_options)/sizeof(spice_options[0])) + +rnd_hid_attr_val_t spice_values[NUM_OPTIONS]; + +int export_spice_is_dbg(void) +{ + return spice_values[HA_debug].lng; +} + +int export_spice_omit(const char *what) +{ + switch(*what) { + case 'h': return spice_values[HA_omit_headers].lng; + case 'i': return spice_values[HA_omit_includes].lng; + case 'm': return spice_values[HA_omit_model_cards].lng; + case 'c': return spice_values[HA_omit_commands].lng; + } + return 0; +} + +static const rnd_export_opt_t *spice_get_export_options(rnd_hid_t *hid, int *n, rnd_design_t *dsg, void *appspec) +{ + const char *val = spice_values[HA_outfile].str; + + if ((dsg != NULL) && ((val == NULL) || (*val == '\0'))) + csch_derive_default_filename(dsg, 1, &spice_values[HA_outfile], ".cir"); + + if (n) + *n = NUM_OPTIONS; + return spice_options; +} + +static void spice_do_export(rnd_hid_t *hid, rnd_design_t *design, rnd_hid_attr_val_t *options, void *appspec) +{ + csch_sheet_t *sheet = (csch_sheet_t *)design; + int viewid = CSCH_VIEW_DEFAULT; + + if (!options) { + spice_get_export_options(hid, 0, design, appspec); + options = spice_values; + } + + if ((options[HA_view].str != NULL) && (options[HA_view].str[0] != '\0')) { + viewid = csch_view_get_id((csch_project_t *)sheet->hidlib.project, options[HA_view].str); + if (viewid < 0) { + rnd_message(RND_MSG_ERROR, "No such view in the project: '%s'\n", options[HA_view].str); + return; + } + } + + sch_rnd_export_prj_abst((csch_project_t *)sheet->hidlib.project, sheet, viewid, "spice", options[HA_outfile].str, options); +} + +static int spice_usage(rnd_hid_t *hid, const char *topic) +{ + fprintf(stderr, "\nSPICE exporter command line arguments:\n\n"); + rnd_hid_usage(spice_options, sizeof(spice_options) / sizeof(spice_options[0])); + fprintf(stderr, "\nUsage: sch-rnd [generic_options] -x spice [options] foo.rs\n\n"); + return 0; +} + + +static int spice_parse_arguments(rnd_hid_t *hid, int *argc, char ***argv) +{ + rnd_export_register_opts2(hid, spice_options, sizeof(spice_options) / sizeof(spice_options[0]), spice_cookie, 0); + return rnd_hid_parse_command_line(argc, argv); +} + +rnd_hid_t spice_hid = {0}; Index: tags/1.0.5/src/plugins/export_svg/Makefile =================================================================== --- tags/1.0.5/src/plugins/export_svg/Makefile (nonexistent) +++ tags/1.0.5/src/plugins/export_svg/Makefile (revision 10414) @@ -0,0 +1,2 @@ +all: + cd ../../sch-rnd && make mod_export_svg Index: tags/1.0.5/src/plugins/export_svg/Plug.tmpasm =================================================================== --- tags/1.0.5/src/plugins/export_svg/Plug.tmpasm (nonexistent) +++ tags/1.0.5/src/plugins/export_svg/Plug.tmpasm (revision 10414) @@ -0,0 +1,10 @@ +put /local/rnd/mod {export_svg} +put /local/rnd/mod/OBJS [@ + $(PLUGDIR)/export_svg/export_svg.o +@] + +switch /local/module/export_svg/controls + case {buildin} include /local/csch/tmpasm/buildin; end; + case {plugin} include /local/csch/tmpasm/plugin; end; + case {disable} include /local/csch/tmpasm/disable; end; +end Index: tags/1.0.5/src/plugins/export_svg/export_svg.c =================================================================== --- tags/1.0.5/src/plugins/export_svg/export_svg.c (nonexistent) +++ tags/1.0.5/src/plugins/export_svg/export_svg.c (revision 10414) @@ -0,0 +1,312 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - svg export + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + + +static rnd_hid_t svg_hid; + +const char *svg_cookie = "export_svg"; + +static rnd_svg_t pctx_, *pctx = &pctx_; + +static const rnd_export_opt_t svg_attribute_list[] = { + {"outfile", "Graphics output file", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0}, +#define HA_svgfile 0 + + {"opacity", "Layer opacity", + RND_HATT_INTEGER, 0, 100, {100, 0, 0}, 0}, +#define HA_opacity 1 + + {"screen-colors", "Allow object highlight and selection color", + RND_HATT_BOOL, 0, 0, {0, 0, 0}, 0}, +#define HA_screen_color 2 + + {"true-size", "Attempt to preserve true size for printing", + RND_HATT_BOOL, 0, 0, {0, 0, 0}, 0}, +#define HA_true_size 3 + + {"layers", "List of layers to export or \"GUI\" for exporting what's visible on the GUI at the moment or empty for default export layer visibility", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0}, +#define HA_layers 4 + + {"view", "If not empty, switch to view and compile before exporting", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0}, +#define HA_view 5 +}; + +#define NUM_OPTIONS (sizeof(svg_attribute_list)/sizeof(svg_attribute_list[0])) + +static rnd_hid_attr_val_t svg_values[NUM_OPTIONS]; + +static char *out_filename; + +static const rnd_export_opt_t *svg_get_export_options(rnd_hid_t *hid, int *n, rnd_design_t *dsg, void *appspec) +{ + const char *val = svg_values[HA_svgfile].str; + + if ((dsg != NULL) && ((val == NULL) || (*val == '\0'))) + csch_derive_default_filename(dsg, sch_rnd_export_appspec_prj(appspec), &svg_values[HA_svgfile], ".svg"); + + if (n) + *n = NUM_OPTIONS; + return svg_attribute_list; +} + +void svg_hid_export_to_file(rnd_design_t *hl, FILE * the_file, rnd_hid_attr_val_t * options, rnd_xform_t *xform) +{ + rnd_hid_expose_ctx_t ctx; + + ctx.design = hl; + ctx.view.X1 = hl->dwg.X1; + ctx.view.Y1 = hl->dwg.Y1; + ctx.view.X2 = hl->dwg.X2; + ctx.view.Y2 = hl->dwg.Y2; + + pctx->outf = the_file; + + TODO("set flip if needed"); + rnd_svg_background(pctx); + + xform->no_render_select = xform->no_render_hilight = !options[HA_screen_color].lng; + + rnd_app.expose_main(&svg_hid, &ctx, xform); +} + +static int svg_do_export_sheet(rnd_hid_t *hid, rnd_design_t *dsg, rnd_hid_attr_val_t *options, sch_rnd_export_appspec_t *appspec, int *ovr) +{ + rnd_xform_t xform = {0}; + FILE *f = NULL; + + out_filename = cschem_export_filename(dsg, options[HA_svgfile].str, NULL, appspec->fn_page_suffix, ".svg"); + + f = rnd_fopen_askovr(dsg, out_filename, "wb", ovr); + if (f == NULL) { + int ern = errno; + rnd_message(RND_MSG_ERROR, "svg_do_export(): failed to open %s: %s\n", out_filename, strerror(ern)); + free(out_filename); + return -1; + } + free(out_filename); + + rnd_svg_init(pctx, dsg, f, options[HA_opacity].lng, 1, options[HA_true_size].lng); + if (f != NULL) + rnd_svg_header(pctx); + + sch_rnd_set_export_layers(&xform, options[HA_layers].str); + svg_hid_export_to_file(dsg, pctx->outf, options, &xform); + + if (pctx->outf != NULL) { + rnd_svg_footer(pctx); + fclose(pctx->outf); + } + pctx->outf = NULL; + rnd_svg_uninit(pctx); + + return 0; +} + + +static void svg_do_export(rnd_hid_t *hid, rnd_design_t *design, rnd_hid_attr_val_t *options, void *appspec_) +{ + rnd_design_t *hl = design; + csch_sheet_t *sheet = (csch_sheet_t *)hl; + void *view_cookie; + sch_rnd_export_appspec_t *appspec = (appspec_ == NULL) ? &sch_rnd_no_appspec : appspec_; + + pctx->comp_cnt = 0; + + if (!options) { + svg_get_export_options(hid, 0, design, appspec); + options = svg_values; + } + + if (cschem_export_compile_pre((csch_project_t *)sheet->hidlib.project, options[HA_view].str, &view_cookie) != 0) + return; + + sch_rnd_export_project_or_sheet(hid, design, options, appspec, svg_do_export_sheet); + + + cschem_export_compile_post((csch_project_t *)sheet->hidlib.project, &view_cookie); +} + +static int svg_parse_arguments(rnd_hid_t *hid, int *argc, char ***argv) +{ + rnd_export_register_opts2(hid, svg_attribute_list, sizeof(svg_attribute_list) / sizeof(svg_attribute_list[0]), svg_cookie, 0); + return rnd_hid_parse_command_line(argc, argv); +} + +static int svg_set_layer_group(rnd_hid_t *hid, rnd_design_t *design, rnd_layergrp_id_t group, const char *purpose, int purpi, rnd_layer_id_t layer, unsigned int flags, int is_empty, rnd_xform_t **xform) +{ + if (is_empty) + return 0; + + { + gds_t tmp_ln; + const char *name; + + gds_init(&tmp_ln); + TODO("do we need this at all? there's no multi-sheet svg export"); + name = "TODO:layer_name"; + rnd_svg_layer_group_begin(pctx, group, name, 0); + gds_uninit(&tmp_ln); + } + return 1; +} + +static void svg_set_drawing_mode(rnd_hid_t *hid, rnd_composite_op_t op, rnd_bool direct, const rnd_box_t *screen) +{ + rnd_svg_set_drawing_mode(pctx, hid, op, direct, screen); +} + +static void svg_set_color(rnd_hid_gc_t gc, const rnd_color_t *color) +{ + rnd_svg_set_color(pctx, gc, color); +} + +static void svg_draw_rect(rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) +{ + rnd_svg_draw_rect(pctx, gc, x1, y1, x2, y2); +} + +static void svg_fill_rect(rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) +{ + rnd_svg_fill_rect(pctx, gc, x1, y1, x2, y2); +} + +static void svg_draw_line(rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) +{ + rnd_svg_draw_line(pctx, gc, x1, y1, x2, y2); +} + +static void svg_draw_arc(rnd_hid_gc_t gc, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t width, rnd_coord_t height, rnd_angle_t start_angle, rnd_angle_t delta_angle) +{ + rnd_svg_draw_arc(pctx, gc, cx, cy, width, height, start_angle, delta_angle); +} + +static void svg_fill_circle(rnd_hid_gc_t gc, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t radius) +{ + rnd_svg_fill_circle(pctx, gc, cx, cy, radius); +} + +static void svg_fill_polygon_offs(rnd_hid_gc_t gc, int n_coords, rnd_coord_t *x, rnd_coord_t *y, rnd_coord_t dx, rnd_coord_t dy) +{ + rnd_svg_fill_polygon_offs(pctx, gc, n_coords, x, y, dx, dy); +} + +static void svg_fill_polygon(rnd_hid_gc_t gc, int n_coords, rnd_coord_t *x, rnd_coord_t *y) +{ + rnd_svg_fill_polygon_offs(pctx, gc, n_coords, x, y, 0, 0); +} + +static int svg_usage(rnd_hid_t *hid, const char *topic) +{ + fprintf(stderr, "\nsvg exporter command line arguments:\n\n"); + rnd_hid_usage(svg_attribute_list, sizeof(svg_attribute_list) / sizeof(svg_attribute_list[0])); + fprintf(stderr, "\nUsage: sch-rnd [generic_options] -x svg [svg options] foo.rs\n\n"); + return 0; +} + +int pplg_check_ver_export_svg(int ver_needed) { return 0; } + +void pplg_uninit_export_svg(void) +{ + rnd_export_remove_opts_by_cookie(svg_cookie); + rnd_hid_remove_hid(&svg_hid); +} + +int pplg_init_export_svg(void) +{ + RND_API_CHK_VER; + + memset(&svg_hid, 0, sizeof(rnd_hid_t)); + + rnd_hid_nogui_init(&svg_hid); + + svg_hid.struct_size = sizeof(rnd_hid_t); + svg_hid.name = "svg"; + svg_hid.description = "Scalable Vector Graphics export"; + svg_hid.exporter = 1; + + svg_hid.get_export_options = svg_get_export_options; + svg_hid.do_export = svg_do_export; + svg_hid.parse_arguments = svg_parse_arguments; + svg_hid.set_layer_group = svg_set_layer_group; + svg_hid.make_gc = rnd_svg_make_gc; + svg_hid.destroy_gc = rnd_svg_destroy_gc; + svg_hid.set_drawing_mode = svg_set_drawing_mode; + svg_hid.set_color = svg_set_color; + svg_hid.set_line_cap = rnd_svg_set_line_cap; + svg_hid.set_line_width = rnd_svg_set_line_width; + svg_hid.set_draw_xor = rnd_svg_set_draw_xor; + svg_hid.draw_line = svg_draw_line; + svg_hid.draw_arc = svg_draw_arc; + svg_hid.draw_rect = svg_draw_rect; + svg_hid.fill_circle = svg_fill_circle; + svg_hid.fill_polygon = svg_fill_polygon; + svg_hid.fill_polygon_offs = svg_fill_polygon_offs; + svg_hid.fill_rect = svg_fill_rect; + svg_hid.set_crosshair = rnd_svg_set_crosshair; + svg_hid.argument_array = svg_values; + + svg_hid.usage = svg_usage; + + rnd_hid_register_hid(&svg_hid); + rnd_hid_load_defaults(&svg_hid, svg_attribute_list, NUM_OPTIONS); + + return 0; +} Index: tags/1.0.5/src/plugins/export_svg/export_svg.pup =================================================================== --- tags/1.0.5/src/plugins/export_svg/export_svg.pup (nonexistent) +++ tags/1.0.5/src/plugins/export_svg/export_svg.pup (revision 10414) @@ -0,0 +1,10 @@ +$class export +$short export sheets to svg +$long Scalable Vector Graphics exporter +$state works +$fmt-native no +$fmt-feature-e svg +$package export-vector +dep lib_exp_text +default buildin +autoload 1 Index: tags/1.0.5/src/plugins/export_tedax/Makefile =================================================================== --- tags/1.0.5/src/plugins/export_tedax/Makefile (nonexistent) +++ tags/1.0.5/src/plugins/export_tedax/Makefile (revision 10414) @@ -0,0 +1,2 @@ +all: + cd ../../sch-rnd && make mod_export_tedax Index: tags/1.0.5/src/plugins/export_tedax/Plug.tmpasm =================================================================== --- tags/1.0.5/src/plugins/export_tedax/Plug.tmpasm (nonexistent) +++ tags/1.0.5/src/plugins/export_tedax/Plug.tmpasm (revision 10414) @@ -0,0 +1,10 @@ +put /local/rnd/mod {export_tedax} +put /local/rnd/mod/OBJS [@ + $(PLUGDIR)/export_tedax/export_tedax.o +@] + +switch /local/module/export_tedax/controls + case {buildin} include /local/csch/tmpasm/buildin; end; + case {plugin} include /local/csch/tmpasm/plugin; end; + case {disable} include /local/csch/tmpasm/disable; end; +end Index: tags/1.0.5/src/plugins/export_tedax/export_tedax.c =================================================================== --- tags/1.0.5/src/plugins/export_tedax/export_tedax.c (nonexistent) +++ tags/1.0.5/src/plugins/export_tedax/export_tedax.c (revision 10414) @@ -0,0 +1,276 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - tEDAx netlist export + * Copyright (C) 2020, 2023 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +static csch_plug_io_t etdx_net; + +static int tdx_export_prio(const char *fn, const char *fmt, csch_plug_io_type_t type) +{ + if (type != CSCH_IOTYP_NETLIST) + return 0; + if ((rnd_strcasecmp(fmt, "tedax") == 0) || (rnd_strcasecmp(fmt, "tdx") == 0)) + return 100; + if (rnd_strcasecmp(fmt, "net") == 0) + return 90; + return 0; +} + +static void tdx_fprint_escape(FILE *f, const char *val) +{ + if ((val == NULL) || (*val == '\0')) { + fputc('-', f); + return; + } + for(; *val != '\0'; val++) { + switch(*val) { + case '\\': fputc('\\', f); fputc('\\', f); break; + case '\n': fputc('\\', f); fputc('n', f); break; + case '\r': fputc('\\', f); fputc('r', f); break; + case '\t': fputc('\\', f); fputc('t', f); break; + case ' ': fputc('\\', f); fputc(' ', f); break; + default: + fputc(*val, f); + } + } +} + +static void export_attr(FILE *f, const char *cmd, const char *key, const char *val, const char *val2) +{ + if ((key == NULL) || (val == NULL)) + return; + fprintf(f, "%s ", cmd); + tdx_fprint_escape(f, key); + fputc(' ', f); + tdx_fprint_escape(f, val); + if (val2 != NULL) { + fputc(' ', f); + tdx_fprint_escape(f, val2); + } + fputc('\n', f); +} + +/* Export comptag and nettag for attributes that have export_name */ +static void export_custom_attrs(FILE *f, const char *name, csch_ahdr_t *obj, const char *cmd) +{ + htsp_entry_t *e; + for(e = htsp_first(&obj->attr); e != NULL; e = htsp_next(&obj->attr, e)) { + csch_attrib_t *a = e->value; + if ((a->export_name != NULL) && (a->val != NULL)) + export_attr(f, cmd, name, a->export_name, a->val); + } +} + +static void tdx_export_comps(FILE *f, csch_abstract_t *abs) +{ + htsp_entry_t *e, *p; + for(e = htsp_first(&abs->comps); e != NULL; e = htsp_next(&abs->comps, e)) { + csch_acomp_t *comp = e->value; + const char *refdes = sch_nle_get_refdes(comp); + + if (refdes == NULL) + continue; + + if (comp->hdr.omit) + continue; + + export_attr(f, "footprint", refdes, sch_nle_get_alt_attr(&comp->hdr.attr, "display/footprint", "footprint", NULL), NULL); + export_attr(f, "value", refdes, sch_nle_get_alt_attr(&comp->hdr.attr, "display/value", "value", NULL), NULL); + export_attr(f, "device", refdes, sch_nle_get_alt_attr(&comp->hdr.attr, "display/device", "device", NULL), NULL); + export_custom_attrs(f, refdes, &comp->hdr, "comptag"); + for(p = htsp_first(&comp->ports); p != NULL; p = htsp_next(&comp->ports, p)) { + const csch_aport_t *port = p->value; + const char *pinnum = sch_nle_get_pinnum(port); + const char *pinname = sch_nle_get_alt_attr(&port->hdr.attr, "display/pinname", "name", NULL); + + if (pinname == NULL) + continue; + + if (strpbrk(pinnum, " \t") != NULL) { /* space separated list of pinnums */ + char *s, *next, *tmp = rnd_strdup(pinnum); + for(s = tmp; s != NULL; s = next) { + next = strpbrk(s, " \t"); + if (next != NULL) { + *next = '\0'; + next++; + } + while(isspace(*s)) s++; + if (*s == '\0') break; + export_attr(f, "pinname", refdes, s, pinname); + } + free(tmp); + } + else + export_attr(f, "pinname", refdes, pinnum, pinname); + } + } +} + +static void tdx_export_nets(FILE *f, csch_abstract_t *abs) +{ + htsp_entry_t *e; + long n; + char *s, *next; + gds_t tmp = {0}; + + for(e = htsp_first(&abs->nets); e != NULL; e = htsp_next(&abs->nets, e)) { + csch_anet_t *net = e->value; + const char *netname = sch_nle_get_netname(net); + + if (net->hdr.omit) continue; + + for(n = 0; n < net->conns.used; n++) { + csch_aport_t *port = net->conns.array[n]; + const char *refdes = NULL, *pinnum; + + if (port->hdr.type != CSCH_ATYPE_PORT) { + rnd_message(RND_MSG_ERROR, "tdx: invalid connection (object type)\n"); + continue; + } + + pinnum = sch_nle_get_pinnum(port); + if (pinnum == NULL) { + rnd_message(RND_MSG_ERROR, "tdx: can't determine port's pin number\n"); + continue; + } + + if (port->parent != NULL) { + refdes = sch_nle_get_refdes(port->parent); + if (port->parent->hdr.omit) + continue; /* omit component */ + } + if (refdes == NULL) { + /* This is not an error: no refdes means: do not export (e.g. gnd) */ +/* rnd_message(RND_MSG_ERROR, "tdx: can't determine port's parent component refdes\n");*/ + continue; + } + + /* split up pinnum at space and create one or more conn lines connecting + each pin to the given net */ + tmp.used = 0; + gds_append_str(&tmp, pinnum); + for(s = tmp.array; s != NULL; s = next) { + /* strip leading whitespace and seps */ + while(isspace(*s)) s++; + if (*s == '\0') + break; + + /* split string at next sep */ + next = strpbrk(s, " \t\r\n"); + if (next != NULL) { + *next = '\0'; + next++; + } + fprintf(f, "conn "); + tdx_fprint_escape(f, netname); + fputc(' ', f); + tdx_fprint_escape(f, refdes); + fputc(' ', f); + tdx_fprint_escape(f, s); + fputc('\n', f); + } + } + export_custom_attrs(f, netname, &net->hdr, "nettag"); + } + gds_uninit(&tmp); +} + + +static int tdx_export_project_abst(const char *fn, const char *fmt, csch_abstract_t *abs, rnd_hid_attr_val_t *options) +{ + TODO("get hidlib as an arg") + rnd_design_t *hidlib = NULL; + FILE *f = rnd_fopen(hidlib, fn, "w"); + if (f == NULL) + return -1; + + fprintf(f, "tEDAx v1\n"); + fprintf(f, "begin netlist v1 "); + tdx_fprint_escape(f, ""); + fprintf(f, "\n"); + + tdx_export_comps(f, abs); + tdx_export_nets(f, abs); + + fprintf(f, "end netlist\n\n"); + fclose(f); + return 0; +} + +#include "hid_impl.c" + +int pplg_check_ver_export_tedax(int ver_needed) { return 0; } + +void pplg_uninit_export_tedax(void) +{ + csch_plug_io_unregister(&etdx_net); + rnd_export_remove_opts_by_cookie(tedax_cookie); + rnd_hid_remove_hid(&tedax_hid); +} + +int pplg_init_export_tedax(void) +{ + RND_API_CHK_VER; + + etdx_net.name = "export to tEDAx"; + etdx_net.export_prio = tdx_export_prio; + etdx_net.export_project_abst = tdx_export_project_abst; + etdx_net.ext_export_project = ".tdx"; + csch_plug_io_register(&etdx_net); + + + rnd_hid_nogui_init(&tedax_hid); + + tedax_hid.struct_size = sizeof(rnd_hid_t); + tedax_hid.name = "tedax"; + tedax_hid.description = "Exports project's tEDAx netlist"; + tedax_hid.exporter = 1; + + tedax_hid.get_export_options = tedax_get_export_options; + tedax_hid.do_export = tedax_do_export; + tedax_hid.parse_arguments = tedax_parse_arguments; + tedax_hid.argument_array = tedax_values; + + tedax_hid.usage = tedax_usage; + + rnd_hid_register_hid(&tedax_hid); + rnd_hid_load_defaults(&tedax_hid, tedax_options, NUM_OPTIONS); + + + return 0; +} + Index: tags/1.0.5/src/plugins/export_tedax/export_tedax.pup =================================================================== --- tags/1.0.5/src/plugins/export_tedax/export_tedax.pup (nonexistent) +++ tags/1.0.5/src/plugins/export_tedax/export_tedax.pup (revision 10414) @@ -0,0 +1,10 @@ +$class export +$short export tEDAx netlist +$long export netlist as a tEDAx netlist block +$state works +$fmt-native no +$fmt-feature-e tEDAx netlist +$package (core) +dep lib_netlist_exp +default buildin +autoload 1 Index: tags/1.0.5/src/plugins/export_tedax/hid_impl.c =================================================================== --- tags/1.0.5/src/plugins/export_tedax/hid_impl.c (nonexistent) +++ tags/1.0.5/src/plugins/export_tedax/hid_impl.c (revision 10414) @@ -0,0 +1,99 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - tEDAx netlist export + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include +#include +#include +#include +#include +#include +#include + +static const char tedax_cookie[] = "tEDAx export hid"; + +static const rnd_export_opt_t tedax_options[] = { + {"outfile", "Name of the tEDAx netlist output file", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0}, +#define HA_outfile 0 + + {"view", "Name of the view to export (use first view when not specified)", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0}, +#define HA_view 1 +}; + +#define NUM_OPTIONS (sizeof(tedax_options)/sizeof(tedax_options[0])) + +static rnd_hid_attr_val_t tedax_values[NUM_OPTIONS]; + +static const rnd_export_opt_t *tedax_get_export_options(rnd_hid_t *hid, int *n, rnd_design_t *dsg, void *appspec) +{ + const char *val = tedax_values[HA_outfile].str; + + if ((dsg != NULL) && ((val == NULL) || (*val == '\0'))) + csch_derive_default_filename(dsg, 1, &tedax_values[HA_outfile], ".tdx"); + + if (n) + *n = NUM_OPTIONS; + return tedax_options; +} + +static void tedax_do_export(rnd_hid_t *hid, rnd_design_t *design, rnd_hid_attr_val_t *options, void *appspec) +{ + csch_sheet_t *sheet = (csch_sheet_t *)design; + int viewid = CSCH_VIEW_DEFAULT; + + if (!options) { + tedax_get_export_options(hid, 0, design, appspec); + options = tedax_values; + } + + if ((options[HA_view].str != NULL) && (options[HA_view].str[0] != '\0')) { + viewid = csch_view_get_id((csch_project_t *)sheet->hidlib.project, options[HA_view].str); + if (viewid < 0) { + rnd_message(RND_MSG_ERROR, "No such view in the project: '%s'\n", options[HA_view].str); + return; + } + } + + sch_rnd_export_prj_abst((csch_project_t *)sheet->hidlib.project, sheet, viewid, "tedax", options[HA_outfile].str, options); +} + +static int tedax_usage(rnd_hid_t *hid, const char *topic) +{ + fprintf(stderr, "\ntEDAx exporter command line arguments:\n\n"); + rnd_hid_usage(tedax_options, sizeof(tedax_options) / sizeof(tedax_options[0])); + fprintf(stderr, "\nUsage: sch-rnd [generic_options] -x tedax [options] foo.rs\n\n"); + return 0; +} + + +static int tedax_parse_arguments(rnd_hid_t *hid, int *argc, char ***argv) +{ + rnd_export_register_opts2(hid, tedax_options, sizeof(tedax_options) / sizeof(tedax_options[0]), tedax_cookie, 0); + return rnd_hid_parse_command_line(argc, argv); +} + +rnd_hid_t tedax_hid = {0}; Index: tags/1.0.5/src/plugins/export_tedax_footprint/Makefile =================================================================== --- tags/1.0.5/src/plugins/export_tedax_footprint/Makefile (nonexistent) +++ tags/1.0.5/src/plugins/export_tedax_footprint/Makefile (revision 10414) @@ -0,0 +1,2 @@ +all: + cd ../../sch-rnd && make mod_export_tedax_footprint Index: tags/1.0.5/src/plugins/export_tedax_footprint/Plug.tmpasm =================================================================== --- tags/1.0.5/src/plugins/export_tedax_footprint/Plug.tmpasm (nonexistent) +++ tags/1.0.5/src/plugins/export_tedax_footprint/Plug.tmpasm (revision 10414) @@ -0,0 +1,10 @@ +put /local/rnd/mod {export_tedax_footprint} +put /local/rnd/mod/OBJS [@ + $(PLUGDIR)/export_tedax_footprint/export_tedax_footprint.o +@] + +switch /local/module/export_tedax_footprint/controls + case {buildin} include /local/csch/tmpasm/buildin; end; + case {plugin} include /local/csch/tmpasm/plugin; end; + case {disable} include /local/csch/tmpasm/disable; end; +end Index: tags/1.0.5/src/plugins/export_tedax_footprint/export_tedax_footprint.c =================================================================== --- tags/1.0.5/src/plugins/export_tedax_footprint/export_tedax_footprint.c (nonexistent) +++ tags/1.0.5/src/plugins/export_tedax_footprint/export_tedax_footprint.c (revision 10414) @@ -0,0 +1,340 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - tedax_footprint export + * Copyright (C) 2024 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + + +static rnd_hid_t tedax_footprint_hid; + +const char *tedax_footprint_cookie = "export_tedax_footprint"; + +typedef struct tedax_footprint_s { + FILE *outf; +} tedax_footprint_t; + +static tedax_footprint_t tctx_, *tctx = &tctx_; + +static const rnd_export_opt_t tedax_footprint_attribute_list[] = { + {"outfile", "Graphics output file", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0}, +#define HA_tedax_footprintfile 0 + + {"layers", "List of layers to export or \"GUI\" for exporting what's visible on the GUI at the moment or empty for default export layer visibility", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0}, +#define HA_layers 1 + + {"view", "If not empty, switch to view and compile before exporting", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0}, +#define HA_view 2 +}; + +#define NUM_OPTIONS (sizeof(tedax_footprint_attribute_list)/sizeof(tedax_footprint_attribute_list[0])) + +#define OLAYER "secondary silk" +#define TR(v) (((double)P2C(v)/1000.0)) +#define TRX(v) (((double)P2C(v)/1000.0)) +#define TRY(v) (((double)P2C(v)/1000.0)) + +static rnd_hid_attr_val_t tedax_footprint_values[NUM_OPTIONS]; + +static char *out_filename; + +static const rnd_export_opt_t *tedax_footprint_get_export_options(rnd_hid_t *hid, int *n, rnd_design_t *dsg, void *appspec) +{ + const char *val = tedax_footprint_values[HA_tedax_footprintfile].str; + + if ((dsg != NULL) && ((val == NULL) || (*val == '\0'))) + csch_derive_default_filename(dsg, sch_rnd_export_appspec_prj(appspec), &tedax_footprint_values[HA_tedax_footprintfile], ".tdx"); + + if (n) + *n = NUM_OPTIONS; + return tedax_footprint_attribute_list; +} + +void tedax_footprint_hid_export_to_file(rnd_design_t *hl, FILE * the_file, rnd_hid_attr_val_t * options, rnd_xform_t *xform) +{ + rnd_hid_expose_ctx_t ctx; + + ctx.design = hl; + ctx.view.X1 = hl->dwg.X1; + ctx.view.Y1 = hl->dwg.Y1; + ctx.view.X2 = hl->dwg.X2; + ctx.view.Y2 = hl->dwg.Y2; + + tctx->outf = the_file; + + rnd_app.expose_main(&tedax_footprint_hid, &ctx, xform); +} + +static int tedax_footprint_do_export_sheet(rnd_hid_t *hid, rnd_design_t *dsg, rnd_hid_attr_val_t *options, sch_rnd_export_appspec_t *appspec, int *ovr) +{ + rnd_xform_t xform = {0}; + FILE *f = NULL; + + out_filename = cschem_export_filename(dsg, options[HA_tedax_footprintfile].str, NULL, appspec->fn_page_suffix, ".tedax_footprint"); + + f = rnd_fopen_askovr(dsg, out_filename, "w", ovr); + if (f == NULL) { + int ern = errno; + rnd_message(RND_MSG_ERROR, "tedax_footprint_do_export(): failed to open %s: %s\n", out_filename, strerror(ern)); + free(out_filename); + return -1; + } + free(out_filename); + + tctx->outf = f; + fprintf(f, "tEDAx v1\nbegin footprint v1 schematic\n"); + + sch_rnd_set_export_layers(&xform, options[HA_layers].str); + tedax_footprint_hid_export_to_file(dsg, tctx->outf, options, &xform); + + fprintf(tctx->outf, "end footprint\n"); + fclose(tctx->outf); + + tctx->outf = NULL; + return 0; +} + + +static void tedax_footprint_do_export(rnd_hid_t *hid, rnd_design_t *design, rnd_hid_attr_val_t *options, void *appspec_) +{ + rnd_design_t *hl = design; + csch_sheet_t *sheet = (csch_sheet_t *)hl; + void *view_cookie; + sch_rnd_export_appspec_t *appspec = (appspec_ == NULL) ? &sch_rnd_no_appspec : appspec_; + + if (!options) { + tedax_footprint_get_export_options(hid, 0, design, appspec); + options = tedax_footprint_values; + } + + if (cschem_export_compile_pre((csch_project_t *)sheet->hidlib.project, options[HA_view].str, &view_cookie) != 0) + return; + + sch_rnd_export_project_or_sheet(hid, design, options, appspec, tedax_footprint_do_export_sheet); + + + cschem_export_compile_post((csch_project_t *)sheet->hidlib.project, &view_cookie); +} + +static int tedax_footprint_parse_arguments(rnd_hid_t *hid, int *argc, char ***argv) +{ + rnd_export_register_opts2(hid, tedax_footprint_attribute_list, sizeof(tedax_footprint_attribute_list) / sizeof(tedax_footprint_attribute_list[0]), tedax_footprint_cookie, 0); + return rnd_hid_parse_command_line(argc, argv); +} + +static int tedax_footprint_set_layer_group(rnd_hid_t *hid, rnd_design_t *design, rnd_layergrp_id_t group, const char *purpose, int purpi, rnd_layer_id_t layer, unsigned int flags, int is_empty, rnd_xform_t **xform) +{ + if (is_empty) + return 0; + + return 1; +} + +static void tedax_footprint_set_drawing_mode(rnd_hid_t *hid, rnd_composite_op_t op, rnd_bool direct, const rnd_box_t *screen) +{ +} + +struct rnd_hid_gc_s { + int width; +}; + +rnd_hid_gc_t rnd_tedax_footprint_make_gc(rnd_hid_t *hid) +{ + rnd_hid_gc_t rv = (rnd_hid_gc_t)calloc(sizeof(struct rnd_hid_gc_s), 1); + rv->width = 1; + return rv; +} + +void rnd_tedax_footprint_destroy_gc(rnd_hid_gc_t gc) +{ + free(gc); +} + +static void tedax_footprint_set_color(rnd_hid_gc_t gc, const rnd_color_t *color) +{ +} + +void rnd_tedax_footprint_set_draw_xor(rnd_hid_gc_t gc, int xor_) +{ +} + +void rnd_tedax_footprint_set_crosshair(rnd_hid_t *hid, rnd_coord_t x, rnd_coord_t y, rnd_set_crosshair_t a) +{ +} + +void rnd_tedax_footprint_set_line_cap(rnd_hid_gc_t gc, rnd_cap_style_t style) +{ +} + +void rnd_tedax_footprint_set_line_width(rnd_hid_gc_t gc, rnd_coord_t width) +{ + gc->width = width; +} + + +static void tedax_footprint_draw_rect(rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) +{ + fprintf(tctx->outf, "line " OLAYER " - %f %f %f %f %f 0\n", TRX(x1), TRY(y1), TRX(x2), TRY(y1), TR(gc->width)); + fprintf(tctx->outf, "line " OLAYER " - %f %f %f %f %f 0\n", TRX(x2), TRY(y1), TRX(x2), TRY(y2), TR(gc->width)); + fprintf(tctx->outf, "line " OLAYER " - %f %f %f %f %f 0\n", TRX(x2), TRY(y2), TRX(x1), TRY(y2), TR(gc->width)); + fprintf(tctx->outf, "line " OLAYER " - %f %f %f %f %f 0\n", TRX(x2), TRY(y1), TRX(x1), TRY(y1), TR(gc->width)); +} + +static void tedax_footprint_fill_rect(rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) +{ + fprintf(tctx->outf, "polygon " OLAYER " - 0 4 %f %f %f %f %f %f %f %f\n", + TRX(x1), TRY(y1), TRX(x2), TRY(y1), TRX(x2), TRY(y2), TRX(x1), TRY(y2)); +} + +static void tedax_footprint_draw_line(rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) +{ + fprintf(tctx->outf, "line " OLAYER " - %f %f %f %f %f 0\n", + TRX(x1), TRY(y1), TRX(x2), TRY(y2), TR(gc->width)); +} + +static void tedax_footprint_draw_arc(rnd_hid_gc_t gc, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t width, rnd_coord_t height, rnd_angle_t start_angle, rnd_angle_t delta_angle) +{ + rnd_coord_t radius = (width+height)/2.0; + double oradius = TR(radius); + if (oradius < 0.1) + return; + + fprintf(tctx->outf, "arc " OLAYER " - %f %f %f %f %f %f 0\n", + TRX(cx), TRY(cy), oradius, start_angle, delta_angle, TR(gc->width)); +} + +static void tedax_footprint_fill_circle(rnd_hid_gc_t gc, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t radius) +{ + fprintf(tctx->outf, "arc " OLAYER " - %f %f %f 0 360 0.1 0\n", + TRX(cx), TRY(cy), TR(radius)); +} + +static void tedax_footprint_fill_polygon_offs(rnd_hid_gc_t gc, int n_coords, rnd_coord_t *x, rnd_coord_t *y, rnd_coord_t dx, rnd_coord_t dy) +{ + int n; + + /* respect line length limit: with a pair of %.2f we can export about 60 coords */ + if (n_coords > 60) { + rnd_message(RND_MSG_ERROR, "tedax_footprint_fill_polygon_offs(): can't export polygon: too many corners\n"); + return; + } + + fprintf(tctx->outf, "polygon " OLAYER " - 0 %d", n_coords); + for(n = 0; n < n_coords; n++) + fprintf(tctx->outf, " %.2f %.2f", TRX(x[n]), TRY(y[n])); + fprintf(tctx->outf, "\n"); +} + +static void tedax_footprint_fill_polygon(rnd_hid_gc_t gc, int n_coords, rnd_coord_t *x, rnd_coord_t *y) +{ + tedax_footprint_fill_polygon_offs(gc, n_coords, x, y, 0, 0); +} + +static int tedax_footprint_usage(rnd_hid_t *hid, const char *topic) +{ + fprintf(stderr, "\ntedax_footprint exporter command line arguments:\n\n"); + rnd_hid_usage(tedax_footprint_attribute_list, sizeof(tedax_footprint_attribute_list) / sizeof(tedax_footprint_attribute_list[0])); + fprintf(stderr, "\nUsage: sch-rnd [generic_options] -x tedax_footprint [tedax_footprint options] foo.rs\n\n"); + return 0; +} + +int pplg_check_ver_export_tedax_footprint(int ver_needed) { return 0; } + +void pplg_uninit_export_tedax_footprint(void) +{ + rnd_export_remove_opts_by_cookie(tedax_footprint_cookie); + rnd_hid_remove_hid(&tedax_footprint_hid); +} + +int pplg_init_export_tedax_footprint(void) +{ + RND_API_CHK_VER; + + memset(&tedax_footprint_hid, 0, sizeof(rnd_hid_t)); + + rnd_hid_nogui_init(&tedax_footprint_hid); + + tedax_footprint_hid.struct_size = sizeof(rnd_hid_t); + tedax_footprint_hid.name = "tedax_footprint"; + tedax_footprint_hid.description = "Export drawing as a tEDAx footprint on silk"; + tedax_footprint_hid.exporter = 1; + + tedax_footprint_hid.get_export_options = tedax_footprint_get_export_options; + tedax_footprint_hid.do_export = tedax_footprint_do_export; + tedax_footprint_hid.parse_arguments = tedax_footprint_parse_arguments; + tedax_footprint_hid.set_layer_group = tedax_footprint_set_layer_group; + tedax_footprint_hid.make_gc = rnd_tedax_footprint_make_gc; + tedax_footprint_hid.destroy_gc = rnd_tedax_footprint_destroy_gc; + tedax_footprint_hid.set_drawing_mode = tedax_footprint_set_drawing_mode; + tedax_footprint_hid.set_color = tedax_footprint_set_color; + tedax_footprint_hid.set_line_cap = rnd_tedax_footprint_set_line_cap; + tedax_footprint_hid.set_line_width = rnd_tedax_footprint_set_line_width; + tedax_footprint_hid.set_draw_xor = rnd_tedax_footprint_set_draw_xor; + tedax_footprint_hid.draw_line = tedax_footprint_draw_line; + tedax_footprint_hid.draw_arc = tedax_footprint_draw_arc; + tedax_footprint_hid.draw_rect = tedax_footprint_draw_rect; + tedax_footprint_hid.fill_circle = tedax_footprint_fill_circle; + tedax_footprint_hid.fill_polygon = tedax_footprint_fill_polygon; + tedax_footprint_hid.fill_polygon_offs = tedax_footprint_fill_polygon_offs; + tedax_footprint_hid.fill_rect = tedax_footprint_fill_rect; + tedax_footprint_hid.set_crosshair = rnd_tedax_footprint_set_crosshair; + tedax_footprint_hid.argument_array = tedax_footprint_values; + + tedax_footprint_hid.usage = tedax_footprint_usage; + + rnd_hid_register_hid(&tedax_footprint_hid); + rnd_hid_load_defaults(&tedax_footprint_hid, tedax_footprint_attribute_list, NUM_OPTIONS); + + return 0; +} Index: tags/1.0.5/src/plugins/export_tedax_footprint/export_tedax_footprint.pup =================================================================== --- tags/1.0.5/src/plugins/export_tedax_footprint/export_tedax_footprint.pup (nonexistent) +++ tags/1.0.5/src/plugins/export_tedax_footprint/export_tedax_footprint.pup (revision 10414) @@ -0,0 +1,9 @@ +$class export +$short export sheet to tEDAx silk fp +$long export sheet to tEDAx silk footprint for use on a PCB +$state works +$fmt-native no +$fmt-feature-e tdx +$package export-vector +default buildin +autoload 1 Index: tags/1.0.5/src/plugins/funcmap/Makefile =================================================================== --- tags/1.0.5/src/plugins/funcmap/Makefile (nonexistent) +++ tags/1.0.5/src/plugins/funcmap/Makefile (revision 10414) @@ -0,0 +1,2 @@ +all: + cd ../../sch-rnd && make mod_funcmap Index: tags/1.0.5/src/plugins/funcmap/Plug.tmpasm =================================================================== --- tags/1.0.5/src/plugins/funcmap/Plug.tmpasm (nonexistent) +++ tags/1.0.5/src/plugins/funcmap/Plug.tmpasm (revision 10414) @@ -0,0 +1,14 @@ +put /local/rnd/mod {funcmap} +put /local/rnd/mod/OBJS [@ + $(PLUGDIR)/funcmap/funcmap.o +@] + +put /local/rnd/mod/CONFFILE {funcmap.conf} +put /local/rnd/mod/CONF {$(PLUGDIR)/funcmap/funcmap_conf.h} +put /local/rnd/mod/CONFVAR {funcmap_conf_internal} + +switch /local/module/funcmap/controls + case {buildin} include /local/csch/tmpasm/buildin; end; + case {plugin} include /local/csch/tmpasm/plugin; end; + case {disable} include /local/csch/tmpasm/disable; end; +end Index: tags/1.0.5/src/plugins/funcmap/compiler.c =================================================================== --- tags/1.0.5/src/plugins/funcmap/compiler.c (nonexistent) +++ tags/1.0.5/src/plugins/funcmap/compiler.c (revision 10414) @@ -0,0 +1,196 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - alternate function mapper + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust Fund in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/*** compiler hooks ***/ + +static const char *funcmap_lookup_portfunc(const char *funcmap_name, csch_attribs_t *comp_attrs, const char *port_func, long port_func_len) +{ + csch_attrib_t *ports = csch_attrib_get(comp_attrs, "funcmap/ports"); + long n; + + if (ports == NULL) + return NULL; + + if (ports->arr.used == 0) { + rnd_message(RND_MSG_ERROR, "Funcmap '%s': funcmap/ports shall be a non-empty array\n", funcmap_name); + return NULL; + } + + + if (port_func_len <= 0) + port_func_len = strlen(port_func); + + for(n = 0; n < ports->arr.used; n++) { + const char *fnc = ports->arr.array[n]; + while(isspace(*fnc)) fnc++; + if (strncmp(fnc, port_func, port_func_len) == 0) { + fnc += port_func_len; + while(isspace(*fnc)) fnc++; + if ((fnc[0] == '-') && (fnc[1] == '>')) { + fnc += 2; + while(isspace(*fnc)) fnc++; + return fnc; + } + } + } + + return NULL; +} + +static void apply_port_instructions(const char *funcmap_name, csch_hook_call_ctx_t *cctx, csch_aport_t *port, const char *instr) +{ + const char *curr, *next; + + for(curr = instr; curr != NULL; curr = next) { + long len = -1; + char *key, *val, *s, *sep; + csch_source_arg_t *src; + + while(isspace(*curr)) curr++; + if (*curr == '\0') + break; + + next = strchr(curr, ';'); + if (next != NULL) { + len = next - curr; + next++; + } + + funcmap_tmp_gds2.used = 0; + if (len > 0) + gds_append_len(&funcmap_tmp_gds2, curr, len); + else + gds_append_str(&funcmap_tmp_gds2, curr); + + key = funcmap_tmp_gds2.array; + sep = strchr(key, '='); + if (sep == NULL) { + rnd_message(RND_MSG_ERROR, "Funcmap '%s': invalid instruction: missing '=' in '%s'\n", funcmap_name, key); + continue; + } + + *sep = '\0'; + val = sep+1; + for(s = sep-1; (s > key) && isspace(*s); s--) + *s = '\0'; + while(isspace(*val)) val++; + + if (*key == '\0') { + rnd_message(RND_MSG_ERROR, "Funcmap '%s': invalid instruction: missing key in '%s'\n", funcmap_name, instr); + continue; + } + + src = csch_attrib_src_pa(&port->hdr, "funcmap", "funcmap", "apply funcmap instructions"); + csch_attrib_set(&port->hdr.attr, cctx->view_eng->eprio + CSCH_PRI_PLUGIN_NORMAL, key, val, src, NULL); + } +} + + +/* this can be global because of single-thread compilation and the sequence + of compilation that guarantees compile_port() is called on all ports of + a component after compile_port1(). */ +static csch_attribs_t *comp_attrs; +static const char *comp_funcmap_name; + +fgw_error_t funcmap_compile_comp1(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + anymap_ctx_t *actx; + csch_acomp_t *comp; + csch_attrib_t *afuncmap; + csch_project_t *prj; + + comp_attrs = NULL; + comp_funcmap_name = NULL; + + CSCH_HOOK_CONVARG(1, FGW_AOBJ, devmap_comp_update, comp = fgw_aobj(&argv[1])); + assert(comp->hdr.type == CSCH_ATYPE_COMP); + + afuncmap = csch_attrib_get(&comp->hdr.attr, "funcmap"); + if (afuncmap == NULL) + return 0; + + prj = comp->hdr.abst->prj; + actx = csch_p4_get_by_project(&p4_funcmap, prj); + + comp_attrs = anymap_get_from_any_lib(actx, comp, afuncmap, argv[0].val.argv0.user_call_ctx); + if (comp_attrs == NULL) { + rnd_message(RND_MSG_ERROR, "Can't find funcmap %s for component %s\n", (afuncmap->val == NULL ? "" : afuncmap->val), comp->name); + return -1; + } + + comp_funcmap_name = afuncmap->val; + + return 0; +} + +fgw_error_t funcmap_compile_port(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + csch_hook_call_ctx_t *cctx = argv[0].val.argv0.user_call_ctx; + csch_source_arg_t *src; + csch_acomp_t *comp; + csch_aport_t *port; + const char *func = NULL, *instr; + long port_len; + + CSCH_HOOK_CONVARG(1, FGW_AOBJ, funcmap_comp_update, port = fgw_aobj(&argv[1])); + assert(port->hdr.type == CSCH_ATYPE_PORT); + comp = port->parent; + if ((comp == NULL) || (comp->hdr.type != CSCH_ATYPE_COMP)) + return 0; /* ignore sheet ports */ + + + if (comp_attrs == NULL) + return 0; /* component has no funcmap attribute or lookup failed */ + + /* if component has a funcmap but port has no funcmap/name, assign the + default automatically: port name */ + func = csch_attrib_get_str(&port->hdr.attr, "funcmap/name"); + if (func == NULL) { + func = port->name; + src = csch_attrib_src_pa(&port->hdr, "funcmap", "funcmap", "no funcmap/name, fall back on port name"); + csch_attrib_set(&port->hdr.attr, cctx->view_eng->eprio + CSCH_PRI_PLUGIN_NORMAL, "funcmap/name", func, src, NULL); + } + + + port_len = strlen(port->name); + funcmap_tmp_gds.used = 0; + gds_append_len(&funcmap_tmp_gds, port->name, port_len); + gds_append(&funcmap_tmp_gds, '/'); + gds_append_str(&funcmap_tmp_gds, func); + + instr = funcmap_lookup_portfunc(comp_funcmap_name, comp_attrs, funcmap_tmp_gds.array, funcmap_tmp_gds.used); + if (instr == NULL) { + if ((func != port->name) && (strcmp(func, port->name) != 0)) + rnd_message(RND_MSG_ERROR, "funcmap: port %s-%s has invalid function '%s' assigned\n", comp->name, port->name, func); + return -1; + } + + apply_port_instructions(funcmap_tmp_gds.array, cctx, port, instr); + + return 0; +} Index: tags/1.0.5/src/plugins/funcmap/dlg_funcmap.c =================================================================== --- tags/1.0.5/src/plugins/funcmap/dlg_funcmap.c (nonexistent) +++ tags/1.0.5/src/plugins/funcmap/dlg_funcmap.c (revision 10414) @@ -0,0 +1,1030 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - alternate function mapper + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust Fund in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/* Locally implemented dialog boxes */ + +#include +#include +#include +#include +#include +#include + +/*** Common ***/ +/* Resolve component and fetch the funcmap attrib subtree (typically from + local lib). Returns 0 on success. */ +RND_INLINE int funcmap_fetch(csch_project_t *prj, const char *comp_name, csch_acomp_t **comp_out, csch_attribs_t **fmattrs_out) +{ + csch_abstract_t *abst = prj->abst; + csch_acomp_t *comp; + csch_attrib_t *afuncmap; + + if (comp_out != NULL) + *comp_out = NULL; + + if (fmattrs_out != NULL) + *fmattrs_out = NULL; + + if (abst == NULL) + return -1; + + comp = csch_acomp_get(abst, comp_name); + if (comp == NULL) + return -1; + + afuncmap = csch_attrib_get(&comp->hdr.attr, "funcmap"); + if (afuncmap == NULL) + return -1; + + if (comp_out != NULL) + *comp_out = comp; + + if (fmattrs_out != NULL) { + anymap_ctx_t *actx; + csch_hook_call_ctx_t cctx = {0}; + + cctx.project = prj; + actx = csch_p4_get_by_project(&p4_funcmap, prj); + *fmattrs_out = anymap_get_from_any_lib(actx, comp, afuncmap, &cctx); + if (*fmattrs_out == NULL) + return -1; + } + + return 0; +} + +static const char *funcmap_get_selected(csch_acomp_t *comp, const char *port_name) +{ + csch_aport_t *port = htsp_get(&comp->ports, port_name); + + if (port == NULL) + return NULL; + + return csch_attrib_get_str(&port->hdr.attr, "funcmap/name"); +} + +/* Undoably modify the "funcmap/name" attribute of comp-port_name in + source terminals. Values in existing terminal attributes are modified + or if there is no attribute and new_val is not NULL, the attribute is + created on one of the terminals. If new_val is NULL, the attribute is + removed */ +static int funcmap_set_on_port(csch_acomp_t *comp, const char *port_name, const char *new_val) +{ + csch_aport_t *port = htsp_get(&comp->ports, port_name); + csch_cgrp_t *fallback = NULL; + int done = 0; + long n; + + if (port == NULL) + return -1; + + /* find terminal object(s) to set the attribute in; change the attribute + in all terminals where it already exist */ + for(n = 0; n < port->hdr.srcs.used; n++) { + csch_cgrp_t *term = port->hdr.srcs.array[n]; + csch_attrib_t *a; + if (!csch_obj_is_grp(&term->hdr)) continue; + if (term->role != CSCH_ROLE_TERMINAL) continue; + if (fallback == NULL) fallback = term; + + /* if this terminal has a funcmap/name attribute, change it */ + a = csch_attrib_get(&term->attr, "funcmap/name"); + if (a != NULL) { + if (new_val != NULL) { + if ((a->val == NULL) || (strcmp(a->val, new_val) != 0)) { + csch_source_arg_t *source = csch_attrib_src_c(NULL, 0, 0, "funcmap action (modify existing attr)"); + csch_attr_modify_str(term->hdr.sheet, term, CSCH_ATP_USER_DEFAULT, "funcmap/name", new_val, source, 1); + } + } + else + csch_attr_modify_del(term->hdr.sheet, term, "funcmap/name", 1); + done = 1; + } + } + + + if (!done && (new_val != NULL)) { + /* no terminal group had the attribute; set it on the fallback terminal */ + if (fallback == NULL) { + rnd_message(RND_MSG_ERROR, "funcmap_set_on_port(): can't set attribute on port %s-%s: terminal not found on the drawing\n", comp->name, port_name); + return -1; + } + else { + csch_source_arg_t *source = csch_attrib_src_c(NULL, 0, 0, "funcmap action (create new attr)"); + csch_attr_modify_str(fallback->hdr.sheet, fallback, CSCH_ATP_USER_DEFAULT, "funcmap/name", new_val, source, 1); + } + } + + return 0; +} + +static void funcmap_step(csch_acomp_t *comp, const char *port_name, csch_attribs_t *fmattrs, const char *curr, int dir) +{ + vts0_t funcs = {0}; + long n, curridx = -1, setidx = -1; + + if (funcmap_get_port_funcs(&funcs, fmattrs, port_name, curr, &curridx) < 0) + goto quit; + + if (curridx < 0) { + if (dir > 0) + setidx = 0; + else + setidx = funcs.used-1; + } + else { + if (dir > 0) { + setidx = curridx + 1; + if (setidx >= funcs.used) + setidx = 0; + } + else { + setidx = curridx - 1; + if (setidx < 0) + setidx = funcs.used-1; + } + } + + if (setidx >= 0) + funcmap_set_on_port(comp, port_name, funcs.array[setidx]); + + quit:; + for(n = 0; n < funcs.used; n++) + free(funcs.array[n]); + vts0_uninit(&funcs); +} + +static const char csch_acts_FuncmapChange[] = + "FuncmapChange(previous|next|remove, component, port)\n" + "FuncmapChange(set, component, port, [newfunc])\n" + "FuncmapChange(setgrp, component, grpname)\n"; +static const char csch_acth_FuncmapChange[] = "Change the alternate function of a component-port. The setgrp command activates a group by setting all affected ports to that group's funcionality. All arguments are case-sensitive."; +/* DOC: funcmapchange.html */ +static fgw_error_t csch_act_FuncmapChange(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + csch_sheet_t *sheet = CSCH_ACT_SHEET; + csch_project_t *prj = (csch_project_t *)sheet->hidlib.project; + const char *cmd, *comp_name, *port_name, *grp_name, *new_func = NULL; + const char *curr; + csch_acomp_t *comp; + csch_attribs_t *fmattrs; + + RND_ACT_CONVARG(1, FGW_STR, FuncmapChange, cmd = argv[1].val.str); + RND_ACT_CONVARG(2, FGW_STR, FuncmapChange, comp_name = argv[2].val.str); + RND_ACT_CONVARG(3, FGW_STR, FuncmapChange, grp_name = port_name = argv[3].val.str); + RND_ACT_MAY_CONVARG(4, FGW_STR, FuncmapChange, new_func = argv[4].val.str); + + RND_ACT_IRES(-1); + + if (funcmap_fetch(prj, comp_name, &comp, &fmattrs) != 0) { + rnd_message(RND_MSG_ERROR, "FuncmapChange: failed to fetch component funcmap attr from the abstract model: '%s'\n", comp_name); + return 0; + } + + + if (rnd_strcasecmp(cmd, "previous") == 0) { + curr = funcmap_get_selected(comp, port_name); + funcmap_step(comp, port_name, fmattrs, curr, -1); + } + else if (rnd_strcasecmp(cmd, "next") == 0) { + curr = funcmap_get_selected(comp, port_name); + funcmap_step(comp, port_name, fmattrs, curr, +1); + } + else if (rnd_strcasecmp(cmd, "remove") == 0) { + funcmap_set_on_port(comp, port_name, NULL); + } + else if (rnd_strcasecmp(cmd, "set") == 0) { + if (new_func == NULL) { + /* invoke the GUI */ + rnd_actionva(&sheet->hidlib, "FuncmapPortDialog", "object", comp->name, port_name, NULL); + } + else { + if (funcmap_has_func(comp, port_name, fmattrs, new_func)) + funcmap_set_on_port(comp, port_name, new_func); + else + rnd_message(RND_MSG_ERROR, "Port %s-%s doesn't have alternate functio '%s'\n", comp->name, port_name, new_func); + } + } + else if (rnd_strcasecmp(cmd, "setgrp") == 0) { + funcmap_set_func_grp(comp, fmattrs, grp_name); + } + else { + rnd_message(RND_MSG_ERROR, "FuncmapChange: invalid first attribute\n"); + return 0; + } + + + RND_ACT_IRES(0); + return 0; +} + +static int funcmap_print_table(FILE *f, csch_project_t *prj, const char *comp_name, const char *sort_by) +{ + csch_acomp_t *comp; + csch_attribs_t *fmattrs; + htsp_t func2col, port2cell; + int c, grpcol, sort_by_col = -1; + long r; + vtp0_t rows = {0}; /* contains: vts0_t *in_cells */ + vts0_t hdr = {0}, *hdrs = &hdr; + vtl0_t colw = {0}; + + /* build the table */ + if (funcmap_fetch(prj, comp_name, &comp, &fmattrs) != 0) + return -1; + + + /* map header */ + vts0_append(&hdr, rnd_strdup("")); + funcmap_comp_gen_hdr_(&hdr, htsp_get(fmattrs, "funcmap/weak_groups")); + funcmap_comp_gen_hdr_(&hdr, htsp_get(fmattrs, "funcmap/strong_groups")); + vts0_append(&hdr, rnd_strdup("")); + + /* set up sort-by */ + if (sort_by != NULL) { + for(c = 0; c < hdr.used; c++) { + if (strcmp(hdr.array[c], sort_by) == 0) { + sort_by_col = c; + break; + } + } + if (sort_by_col < 0) + rnd_message(RND_MSG_ERROR, "funcmap_print_table(): can't sort by '%s': no such column\n(Printing the table unsorted)\n", sort_by); + } + + /* map table */ + funcmap_comp2dlg_hashgrps(&func2col, fmattrs, &grpcol); + funcmap_comp2dlg_hashcells(&func2col, &port2cell, htsp_get(fmattrs, "funcmap/ports"), grpcol); + vtl0_enlarge(&colw, grpcol+1); + + funcmap_sort_rows(&rows, &port2cell, sort_by_col); + + vtp0_insert_len(&rows, 0, (void **)&hdrs, 1); + + /* calculate col widths */ + for(r = 0; r < rows.used; r++) { + long n; + vts0_t *in_cells = rows.array[r]; + const char *selected, *key; + + key = in_cells->array[0]; + selected = funcmap_get_selected(comp, key); + for(n = 0; n <= grpcol; n++) { + int len; + + if ((in_cells->used > n) & (in_cells->array[n] != NULL)) { + if ((n > 0) && (selected != NULL) && (strcmp(in_cells->array[n], selected) == 0)) + len = strlen(in_cells->array[n]) + 4; + else + len = strlen(in_cells->array[n]); + } + else + len = 1; + if (len > colw.array[n]) + colw.array[n] = len; + } + } + + /* print table */ + for(r = 0; r < rows.used; r++) { + long n; + vts0_t *in_cells = rows.array[r]; + const char *selected, *key; + + key = in_cells->array[0]; + selected = funcmap_get_selected(comp, key); + for(n = 0; n <= grpcol; n++) { + int len; + + if (n != 0) + fprintf(f, " "); + + if ((in_cells->used > n) & (in_cells->array[n] != NULL)) { + if ((n > 0) && (selected != NULL) && (strcmp(in_cells->array[n], selected) == 0)) + len = fprintf(f, "[[%s]]", in_cells->array[n]); + else + len = fprintf(f, "%s", in_cells->array[n]); + } + else + len = fprintf(f, "-"); + + if (n != grpcol) { + while(len < colw.array[n]) { + fprintf(f, " "); + len++; + } + } + + } + printf("\n"); + } + + vtl0_uninit(&colw); + vtp0_uninit(&rows); + funcmap_hashgrps_free(&func2col); + funcmap_hashcells_free(&port2cell); + + for(c = 0; c < hdr.used; c++) + free(hdr.array[c]); + vts0_uninit(&hdr); + + return 0; +} + + +static const char csch_acts_FuncmapPrintTable[] = "FuncmapPrintTable(component, [column])"; +static const char csch_acth_FuncmapPrintTable[] = "Print a table of all alternative port functions for a component If column is specified, sort the table by the named column."; +/* DOC: funcmapprinttable.html */ +static fgw_error_t csch_act_FuncmapPrintTable(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + csch_sheet_t *sheet = CSCH_ACT_SHEET; + csch_project_t *prj = (csch_project_t *)sheet->hidlib.project; + const char *comp_name, *sort_by = NULL; + + RND_ACT_CONVARG(1, FGW_STR, FuncmapPrintTable, comp_name = argv[1].val.str); + RND_ACT_MAY_CONVARG(2, FGW_STR, FuncmapPrintTable, sort_by = argv[2].val.str); + + RND_ACT_IRES(funcmap_print_table(stdout, prj, comp_name, sort_by)); + return 0; +} + +/*** Funcmap for a port ***/ +typedef struct funcmap_port_ctx_s funcmap_port_ctx_t; + +struct funcmap_port_ctx_s { + RND_DAD_DECL_NOINIT(dlg) + csch_sheet_t *sheet; + const char *comp_name, *port_name; + int wenum; + vts0_t funcs; +}; + + +static void pcb_dlg_funcmap_port(csch_sheet_t *sheet, const char *comp_name, const char *port_name) +{ + funcmap_port_ctx_t *ctx, ctx_ = {0}; + rnd_hid_dad_buttons_t clbtn[] = {{"Cancel", 0}, {"Set and Close", 1}, {NULL, 0}}; + const char *curr; + char *title; + int okay; + long curridx = -1, n; + csch_acomp_t *comp; + csch_attribs_t *fmattrs; + csch_project_t *prj = (csch_project_t *)sheet->hidlib.project; + rnd_hid_attr_val_t hv; + + /* set up a full feature context, just in case we need to go non-modal later */ + ctx = &ctx_; + ctx->sheet = sheet; + ctx->comp_name = comp_name; + ctx->port_name = port_name; + + /* fetch component and funcmap */ + if (funcmap_fetch(prj, comp_name, &comp, &fmattrs) != 0) { + rnd_message(RND_MSG_ERROR, "FuncmapPortDialog: failed to fetch component %s funcmap\n", comp_name); + return; + } + + curr = funcmap_get_selected(comp, port_name); + if (funcmap_get_port_funcs(&ctx->funcs, fmattrs, port_name, curr, &curridx) != 0) { + rnd_message(RND_MSG_ERROR, "FuncmapPortDialog: failed to list port functions\n"); + return; + } + + + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_ENUM(ctx->dlg, ctx->funcs.array); + ctx->wenum = RND_DAD_CURRENT(ctx->dlg); + + RND_DAD_BEGIN_VBOX(ctx->dlg); /* spring */ + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_END(ctx->dlg); + + RND_DAD_BUTTON_CLOSES(ctx->dlg, clbtn); + RND_DAD_END(ctx->dlg); + + title = rnd_concat("Alternate function mapping of port ", ctx->comp_name, "-", ctx->port_name, NULL); + RND_DAD_DEFSIZE(ctx->dlg, 200, 100); + RND_DAD_NEW("funcmap_port_dlg", ctx->dlg, title, ctx, rnd_true, NULL); /* type=local/modal */ + free(title); + + hv.lng = curridx; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wenum, &hv); + + okay = RND_DAD_RUN(ctx->dlg); + if (okay) { + int idx = ctx->dlg[ctx->wenum].val.lng; + if ((idx >= 0) && (idx < ctx->funcs.used)) { + const char *new_val = ctx->funcs.array[idx]; + rnd_actionva(&ctx->sheet->hidlib, "FuncmapChange", "set", ctx->comp_name, ctx->port_name, new_val, NULL); + } + } + RND_DAD_FREE(ctx->dlg); + + for(n = 0; n < ctx->funcs.used; n++) + free(ctx->funcs.array[n]); + vts0_uninit(&ctx->funcs); +} + +static csch_cgrp_t *get_term_from_obj(csch_chdr_t *obj) +{ + for(;obj != NULL;obj = &obj->parent->hdr) { + if (csch_obj_is_grp(obj)) { + csch_cgrp_t *grp = (csch_cgrp_t *)obj; + if (grp->role == CSCH_ROLE_TERMINAL) + return grp; + } + } + + return NULL; +} + + +static const char csch_acts_FuncmapPortDialog[] = "FuncmapPortDialog(object, component, port)"; +static const char csch_acth_FuncmapPortDialog[] = "Open the modal dialog for changing the alternate function of a port. "; +static fgw_error_t csch_act_FuncmapPortDialog(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + csch_sheet_t *sheet = CSCH_ACT_SHEET; + csch_project_t *prj = (csch_project_t *)sheet->hidlib.project; + const char *comp_name = NULL, *port_name = NULL; + int scope = F_Object; + + RND_ACT_CONVARG(1, FGW_KEYWORD, FuncmapPortDialog, scope = fgw_keyword(&argv[1])); + RND_ACT_MAY_CONVARG(2, FGW_STR, FuncmapPortDialog, comp_name = argv[2].val.str); + RND_ACT_MAY_CONVARG(3, FGW_STR, FuncmapPortDialog, port_name = argv[3].val.str); + + RND_ACT_IRES(-1); + + if (scope != F_Object) { + rnd_message(RND_MSG_ERROR, "FuncmapPortDialog: invalid first argument\n"); + return 0; + } + + if ((comp_name != NULL) || (port_name != NULL)) { + if ((comp_name == NULL) || (port_name == NULL)) { + rnd_message(RND_MSG_ERROR, "FuncmapPortDialog: if either comp_name or port_name is specified, both need to be specified\n"); + return 0; + } + } + + if (comp_name == NULL) { + /* need to pick one on the GUI */ + csch_coord_t x, y; + csch_chdr_t *obj; + csch_cgrp_t *term; + + if (sch_rnd_get_coords("Click on a terminal for funcmaps", &x, &y, 0) != 0) + return 0; + + obj = sch_rnd_search_first_gui_inspect(sheet, C2P(x), C2P(y)); + if (obj == NULL) { + rnd_message(RND_MSG_ERROR, "FuncmapPortDialog(): no object under cursor\n"); + return 0; + } + + term = get_term_from_obj(obj); + if (term == NULL) { + rnd_message(RND_MSG_ERROR, "FuncmapPortDialog(): not a terminal\n"); + return 0; + } + + if (term->aid.used == 1) { + csch_aport_t *port = htip_get(&prj->abst->aid2obj, term->aid.array[0]); + if (port == NULL) { + rnd_message(RND_MSG_ERROR, "FuncmapPortDialog(): no port found for this terminal; is the project compiled?\n"); + return 0; + } + port_name = port->name; + comp_name = port->parent->name; + } + else { + rnd_message(RND_MSG_ERROR, "FuncmapPortDialog(): there is no direct mapping from this terminal to a single abstract port\n"); + return 0; + } + } + + + pcb_dlg_funcmap_port(sheet, comp_name, port_name); + + RND_ACT_IRES(0); + return 0; +} + + +/*** Funcmap for components ***/ +typedef struct funcmap_comp_ctx_s funcmap_comp_ctx_t; + +#define MAXGRP 128 + +struct funcmap_comp_ctx_s { + RND_DAD_DECL_NOINIT(dlg) + csch_sheet_t *sheet; + char *comp_name; + vts0_t hdr; + int sort_by; /* column ID */ + int wtable, wsort, wact_grp; + gdl_elem_t link; +}; + +static gdl_list_t funcmap_comps; + +/* Modal dialog to choose a column */ +static int funcmap_comp_choose_column(funcmap_comp_ctx_t *ctx) +{ + rnd_hid_dad_buttons_t clbtn[] = {{"Cancel", 0}, {"Select and Close", 1}, {NULL, 0}}; + int okay, wenum, res = -1; + rnd_hid_attr_val_t hv; + RND_DAD_DECL(dlg); + + RND_DAD_BEGIN_VBOX(dlg); + RND_DAD_COMPFLAG(dlg, RND_HATF_EXPFILL); + RND_DAD_ENUM(dlg, ctx->hdr.array); + wenum = RND_DAD_CURRENT(dlg); + + RND_DAD_BEGIN_VBOX(dlg); /* spring */ + RND_DAD_COMPFLAG(dlg, RND_HATF_EXPFILL); + RND_DAD_END(dlg); + + RND_DAD_BUTTON_CLOSES(dlg, clbtn); + RND_DAD_END(dlg); + + RND_DAD_DEFSIZE(dlg, 200, 100); + RND_DAD_NEW("funcmap_column_dlg", dlg, "Alternate function mapping: choose column", ctx, rnd_true, NULL); /* type=local/modal */ + + hv.lng = ctx->sort_by; + rnd_gui->attr_dlg_set_value(dlg_hid_ctx, wenum, &hv); + + okay = RND_DAD_RUN(dlg); + if (okay) + res = dlg[wenum].val.lng; + RND_DAD_FREE(dlg); + return res; +} + + +static void funcmap_comp_clear_hdr(funcmap_comp_ctx_t *ctx) +{ + int n; + for(n = 0; n < ctx->hdr.used; n++) + free(ctx->hdr.array[n]); + ctx->hdr.used = 0; +} + +static void funcmap_comp_close_cb(void *caller_data, rnd_hid_attr_ev_t ev) +{ + funcmap_comp_ctx_t *ctx = caller_data; + + RND_DAD_FREE(ctx->dlg); + free(ctx->comp_name); + gdl_remove(&funcmap_comps, ctx, link); + funcmap_comp_clear_hdr(ctx); + vts0_uninit(&ctx->hdr); + free(ctx); +} + +static int get_selected_col(rnd_hid_row_t *r) +{ + int n; + + for(n = 1; n < r->cols; n++) { + const char *c = r->cell[n]; + if ((c != NULL) && (c[0] == '[') && (c[1] == '[')) + return n; + } + + return -1; +} + +static void funcmap_comp2dlg_act_grp(funcmap_comp_ctx_t *ctx) +{ + rnd_hid_attr_val_t hv; + rnd_hid_attribute_t *attr = &ctx->dlg[ctx->wtable]; + int btn_set = 0; + rnd_hid_row_t *r; + + r = rnd_dad_tree_get_selected(attr); + if (r != NULL) { + int col = get_selected_col(r); + if (col >= 0) { + char *lab = rnd_concat("act. ", ctx->hdr.array[col], NULL); + hv.str = lab; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wact_grp, &hv); + free(lab); + btn_set = 1; + } + } + + if (!btn_set) { + hv.str = "set. grp."; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wact_grp, &hv); + } +} + +static void funcmap_comp2dlg(funcmap_comp_ctx_t *ctx) +{ + rnd_hid_attr_val_t hv; + rnd_hid_attribute_t *attr; + rnd_hid_tree_t *tree; + rnd_hid_row_t *r; + char *cursor_path = NULL; + csch_acomp_t *comp; + csch_attribs_t *fmattrs; + htsp_t func2col, port2cell; + int grpcol; + + attr = &ctx->dlg[ctx->wtable]; + tree = attr->wdata; + + /* remember cursor */ + r = rnd_dad_tree_get_selected(attr); + if (r != NULL) + cursor_path = rnd_strdup(r->cell[0]); + + /* remove existing items */ + rnd_dad_tree_clear(tree); + + /* build the table */ + if (funcmap_fetch((csch_project_t *)ctx->sheet->hidlib.project, ctx->comp_name, &comp, &fmattrs) != 0) + return; + funcmap_comp2dlg_hashgrps(&func2col, fmattrs, &grpcol); + funcmap_comp2dlg_hashcells(&func2col, &port2cell, htsp_get(fmattrs, "funcmap/ports"), grpcol); + + /*** fill in the GUI ***/ + { + long r; + vtp0_t rows = {0}; /* contains: vts0_t *in_cells */ + + funcmap_sort_rows(&rows, &port2cell, ctx->sort_by); + + for(r = 0; r < rows.used; r++) { + long n; + vts0_t *in_cells = rows.array[r]; + char *cells[MAXGRP+3]; + const char *selected, *key; + + key = in_cells->array[0]; + selected = funcmap_get_selected(comp, key); + for(n = 0; n <= grpcol; n++) { + if ((in_cells->used > n) & (in_cells->array[n] != NULL)) { + if ((n > 0) && (selected != NULL) && (strcmp(in_cells->array[n], selected) == 0)) { + char *tmp = rnd_concat("[[", in_cells->array[n], "]]", NULL); + free(in_cells->array[n]); + in_cells->array[n] = tmp; + } + cells[n] = in_cells->array[n]; + in_cells->array[n] = NULL; + } + else + cells[n] = rnd_strdup("-"); + } + cells[n] = NULL; + rnd_dad_tree_append(attr, NULL, cells); + } + + vtp0_uninit(&rows); + } + + /* restore cursor */ + if (cursor_path != NULL) { + hv.str = cursor_path; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wtable, &hv); + free(cursor_path); + } + + /*** set buttons ***/ + if (ctx->sort_by >= 0) + hv.str = ctx->hdr.array[ctx->sort_by]; + else + hv.str = ""; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wsort, &hv); + + funcmap_comp2dlg_act_grp(ctx); + + /*** clean up temp ***/ + funcmap_hashgrps_free(&func2col); + funcmap_hashcells_free(&port2cell); +} + +static void funcmap_comp_gen_hdr(funcmap_comp_ctx_t *ctx) +{ + csch_acomp_t *comp; + csch_attribs_t *fmattrs; + + funcmap_comp_clear_hdr(ctx); + + if (funcmap_fetch((csch_project_t *)ctx->sheet->hidlib.project, ctx->comp_name, &comp, &fmattrs) != 0) + return; + + vts0_append(&ctx->hdr, rnd_strdup("")); + + funcmap_comp_gen_hdr_(&ctx->hdr, htsp_get(fmattrs, "funcmap/weak_groups")); + funcmap_comp_gen_hdr_(&ctx->hdr, htsp_get(fmattrs, "funcmap/strong_groups")); + + vts0_append(&ctx->hdr, rnd_strdup("")); +} + +static void funcmap_comp_any_change(funcmap_comp_ctx_t *ctx, const char *cmd) +{ + rnd_hid_attribute_t *attr = &ctx->dlg[ctx->wtable]; + rnd_hid_row_t *r = rnd_dad_tree_get_selected(attr); + + if (r == NULL) { + rnd_message(RND_MSG_ERROR, "Select a port from the above list first\n"); + return; + } + + rnd_actionva(&ctx->sheet->hidlib, "FuncmapChange", cmd, ctx->comp_name, r->cell[0], NULL); + rnd_actionva(&ctx->sheet->hidlib, "CompileProject", NULL); + funcmap_comp2dlg(ctx); +} + +/* Step function left or right, by the ordering of the GUI columns (which + typically differs from the ordering of functionality for a specific + port in the file, so FuncmapChange() would step differently) */ +static void funcmap_comp_gui_step(funcmap_comp_ctx_t *ctx, int dir) +{ + rnd_hid_attribute_t *attr = &ctx->dlg[ctx->wtable]; + rnd_hid_row_t *r = rnd_dad_tree_get_selected(attr); + const char *new_val = NULL; + int curridx, newidx, collen = ctx->hdr.used; + + if (r == NULL) { + rnd_message(RND_MSG_ERROR, "Select a port from the above list first\n"); + return; + } + + curridx = get_selected_col(r); + + if (curridx < 0) { + if (dir > 0) + newidx = collen-1; + else + newidx = 1; + } + else + newidx = curridx + dir; + + for(;;) { + if (newidx >= collen) + newidx = 1; + else if (newidx < 1) + newidx = collen-1; + + if (newidx == curridx) + break; + + new_val = r->cell[newidx]; + if ((new_val[0] != '-') || (new_val[1] != '\0')) + break; + + newidx += dir; + } + + if (newidx != curridx) { + rnd_actionva(&ctx->sheet->hidlib, "FuncmapChange", "set", ctx->comp_name, r->cell[0], new_val, NULL); + rnd_actionva(&ctx->sheet->hidlib, "CompileProject", NULL); + funcmap_comp2dlg(ctx); + } +} + + +static void funcmap_comp_left_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + funcmap_comp_ctx_t *ctx = caller_data; + funcmap_comp_gui_step(ctx, -1); +} + +static void funcmap_comp_right_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + funcmap_comp_ctx_t *ctx = caller_data; + funcmap_comp_gui_step(ctx, +1); +} + +static void funcmap_comp_del_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + funcmap_comp_ctx_t *ctx = caller_data; + funcmap_comp_any_change(ctx, "remove"); +} + +static void funcmap_comp_refresh_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + funcmap_comp_ctx_t *ctx = caller_data; + funcmap_comp2dlg(ctx); +} + +static void funcmap_comp_change_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + funcmap_comp_ctx_t *ctx = caller_data; + funcmap_comp_any_change(ctx, "set"); +} + +static void funcmap_comp_act_grp_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr_btn) +{ + funcmap_comp_ctx_t *ctx = caller_data; + rnd_hid_attribute_t *attr = &ctx->dlg[ctx->wtable]; + rnd_hid_row_t *r = rnd_dad_tree_get_selected(attr); + int curridx; + + if (r == NULL) { + rnd_message(RND_MSG_ERROR, "Select a port from the above list first\n"); + return; + } + + curridx = get_selected_col(r); + if (curridx < 0) { + rnd_message(RND_MSG_ERROR, "Internal error: can't find selected column\n"); + return; + } + + rnd_actionva(&ctx->sheet->hidlib, "FuncmapChange", "setgrp", ctx->comp_name, ctx->hdr.array[curridx], NULL); + rnd_actionva(&ctx->sheet->hidlib, "CompileProject", NULL); + funcmap_comp2dlg(ctx); +} + +static void funcmap_comp_sort_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + funcmap_comp_ctx_t *ctx = caller_data; + int col = funcmap_comp_choose_column(ctx); + + if (col >= 0) { + ctx->sort_by = col; + funcmap_comp2dlg(ctx); + } +} + +static void funcmap_comp_select_cb(rnd_hid_attribute_t *attrib, void *hid_ctx, rnd_hid_row_t *row) +{ + rnd_hid_tree_t *tree = attrib->wdata; + funcmap_comp_ctx_t *ctx = tree->user_ctx; + funcmap_comp2dlg_act_grp(ctx); +} + + +static void pcb_dlg_funcmap_comp(csch_sheet_t *sheet, csch_acomp_t *comp) +{ + funcmap_comp_ctx_t *ctx; + rnd_hid_dad_buttons_t clbtn[] = {{"Close", 0}, {NULL, 0}}; + char *title; + + ctx = calloc(sizeof(funcmap_comp_ctx_t), 1); + ctx->sheet = sheet; + ctx->comp_name = rnd_strdup(comp->name); + ctx->sort_by = -1; + + funcmap_comp_gen_hdr(ctx); + + gdl_append(&funcmap_comps, ctx, link); + + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_TREE(ctx->dlg, MAXGRP, 0, (const char **)ctx->hdr.array); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL | RND_HATF_SCROLL); + RND_DAD_TREE_SET_CB(ctx->dlg, selected_cb, funcmap_comp_select_cb); + RND_DAD_TREE_SET_CB(ctx->dlg, ctx, ctx); + ctx->wtable = RND_DAD_CURRENT(ctx->dlg); + + /* bottom row of buttons */ + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "sort:"); + RND_DAD_BUTTON(ctx->dlg, ""); + ctx->wsort = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_CHANGE_CB(ctx->dlg, funcmap_comp_sort_cb); + RND_DAD_HELP(ctx->dlg, "Choose a column to sort entries by."); + + RND_DAD_BEGIN_VBOX(ctx->dlg); /* sep */ + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_FRAME); + RND_DAD_END(ctx->dlg); + + RND_DAD_BUTTON(ctx->dlg, "<--"); + RND_DAD_CHANGE_CB(ctx->dlg, funcmap_comp_left_cb); + RND_DAD_HELP(ctx->dlg, "Choose the previous function of the port selected."); + RND_DAD_BUTTON(ctx->dlg, "-->"); + RND_DAD_CHANGE_CB(ctx->dlg, funcmap_comp_right_cb); + RND_DAD_HELP(ctx->dlg, "Choose the next function of the port selected."); + RND_DAD_BUTTON(ctx->dlg, "del"); + RND_DAD_CHANGE_CB(ctx->dlg, funcmap_comp_del_cb); + RND_DAD_HELP(ctx->dlg, "Remove the function chocice of the port selected.\nThe funcmap/name attribute is removed from all terminals contributing to this port.\nIn turn the port functionality falls back to its default (primary function)."); + RND_DAD_BUTTON(ctx->dlg, "change"); + RND_DAD_CHANGE_CB(ctx->dlg, funcmap_comp_change_cb); + RND_DAD_HELP(ctx->dlg, "Select port functionality from a list of available functions."); + RND_DAD_BUTTON(ctx->dlg, "act. grp."); + RND_DAD_CHANGE_CB(ctx->dlg, funcmap_comp_act_grp_cb); + ctx->wact_grp = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_HELP(ctx->dlg, "Activate group.\nTake the current row's selected function and select the same function for all other ports in the same functionality group.\nFor example select MISO from the SPI group for a port then click this button to get all other SPI ports of the same SPI group also activated."); + RND_DAD_BUTTON(ctx->dlg, "refresh"); + RND_DAD_CHANGE_CB(ctx->dlg, funcmap_comp_refresh_cb); + RND_DAD_HELP(ctx->dlg, "The dialog is not refreshed automatically. Click this button to refresh the dialog after a compilation."); + + + RND_DAD_BEGIN_VBOX(ctx->dlg); /* spring */ + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_END(ctx->dlg); + + RND_DAD_BUTTON_CLOSES(ctx->dlg, clbtn); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + + title = rnd_concat("Alternate function mapping of component ", ctx->comp_name, NULL); + RND_DAD_DEFSIZE(ctx->dlg, 500, 400); + RND_DAD_NEW("funcmap_comp_dlg", ctx->dlg, title, ctx, rnd_false, funcmap_comp_close_cb); /* type=local */ + free(title); + + funcmap_comp2dlg(ctx); +} + +static csch_cgrp_t *get_sym_from_obj(csch_chdr_t *obj) +{ + + for(;obj != NULL;obj = &obj->parent->hdr) { + if (csch_obj_is_grp(obj)) { + csch_cgrp_t *grp = (csch_cgrp_t *)obj; + if (grp->role == CSCH_ROLE_SYMBOL) + return grp; + } + } + + return NULL; +} + +static const char csch_acts_FuncmapComponentDialog[] = "FuncmapComponentDialog(object)\n"; +static const char csch_acth_FuncmapComponentDialog[] = "Open the alternate function mapping dialog for a component"; +static fgw_error_t csch_act_FuncmapComponentDialog(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + csch_sheet_t *sheet = CSCH_ACT_SHEET; + csch_project_t *prj = (csch_project_t *)sheet->hidlib.project; + csch_acomp_t *comp = NULL; + int scope = F_Object; + + RND_ACT_MAY_CONVARG(1, FGW_KEYWORD, FuncmapComponentDialog, scope = fgw_keyword(&argv[1])); + + RND_ACT_IRES(-1); + if (prj->abst == NULL) { + rnd_message(RND_MSG_ERROR, "FuncmapComponentDialog(): abstract model is not available - compile first\n"); + return 0; + } + + switch(scope) { + case F_Object: + { + csch_coord_t x, y; + csch_chdr_t *obj; + csch_cgrp_t *sym; + + if (sch_rnd_get_coords("Click on a symbol for funcmaps", &x, &y, 0) != 0) + break; + + obj = sch_rnd_search_obj_at(sheet, x, y, sch_rnd_slop); + if (obj == NULL) { + rnd_message(RND_MSG_ERROR, "FuncmapComponentDialog(): no object under cursor\n"); + break; + } + + sym = get_sym_from_obj(obj); + if (sym == NULL) { + rnd_message(RND_MSG_ERROR, "FuncmapComponentDialog(): not a symbol\n"); + return 0; + } + + if (sym->aid.used == 1) + comp = htip_get(&prj->abst->aid2obj, sym->aid.array[0]); + else + rnd_message(RND_MSG_ERROR, "FuncmapComponentDialog(): there is no direct mapping from this symbol to a single abstract component\n"); + } + break; + } + + if (comp == NULL) { + rnd_message(RND_MSG_ERROR, "FuncmapComponentDialog(): can not find the corresponding component\n"); + return 0; + } + + pcb_dlg_funcmap_comp(sheet, comp); + RND_ACT_IRES(0); + return 0; +} Index: tags/1.0.5/src/plugins/funcmap/fmdrc.c =================================================================== --- tags/1.0.5/src/plugins/funcmap/fmdrc.c (nonexistent) +++ tags/1.0.5/src/plugins/funcmap/fmdrc.c (revision 10414) @@ -0,0 +1,161 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - alternate function mapper + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust Fund in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/* DRC checks */ + +#include +#include + +#define SINGLE '>' +#define MULTI ',' + +RND_INLINE void funcmap_drc_comp(csch_drc_t *drc, csch_project_t *prj, csch_acomp_t *comp) +{ +/* csch_abstract_t *abst = prj->abst;*/ + csch_attribs_t *fmattrs; + htsp_t func2col, grps; + csch_attrib_t *grplst; + int grpcol, c, f; + htsp_entry_t *e; + vts0_t hdr = {0}; + + if (funcmap_fetch(prj, comp->name, &comp, &fmattrs) != 0) + return; + + /* collect only strong groups as we are going to verify only those */ + htsp_init(&func2col, strhash, strkeyeq); + htsp_init(&grps, strhash, strkeyeq); + grpcol = 1; + grplst = htsp_get(fmattrs, "funcmap/strong_groups"); + funcmap_comp2dlg_hashgrp(&func2col, grplst, &grpcol); + funcmap_map_grps(&grps, fmattrs, grplst); + vts0_append(&hdr, rnd_strdup("")); + funcmap_comp_gen_hdr_(&hdr, htsp_get(fmattrs, "funcmap/strong_groups")); + vts0_append(&hdr, rnd_strdup("")); + +/* rnd_trace("drc1 collect:\n");*/ + for(e = htsp_first(&comp->ports); e != NULL; e = htsp_next(&comp->ports, e)) { + csch_aport_t *port = e->value; + const char *port_name = e->key; + const char *func; + vtl0_t *cols; + + func = csch_attrib_get_str(&port->hdr.attr, "funcmap/name"); + if (func == NULL) + continue; + + cols = htsp_get(&func2col, func); + if (cols == NULL) + continue; + + for(c = 0; c < cols->used; c++) { + const char *grp_name; + vts0_t *grp_funcs; + + f = cols->array[c]; + if ((f < 0) || (f >= hdr.used)) continue; + grp_name = hdr.array[f]; + if (grp_name == NULL) continue; + grp_funcs = htsp_get(&grps, grp_name); /* all functions of the group we are in */ +/* rnd_trace(" port=%s func=%s in %s %p\n", port_name, func, grp_name, grp_funcs);*/ + + /* mark the function we used up by modifying their string in the grp + hash-list (these are strdupd) */ + for(f = 0; f < grp_funcs->used; f++) { + char *grp_func = grp_funcs->array[f]; + if (strcmp(grp_func, func) == 0) { + *grp_func = (cols->used == 1) ? SINGLE : MULTI; +/* rnd_trace(" '%s'\n", grp_func);*/ + } + } + } + } + +/* rnd_trace("drc2 verify:\n");*/ + /* Verify that each strong group has either 0 or all functions used, exactly once */ + for(e = htsp_first(&grps); e != NULL; e = htsp_next(&grps, e)) { + const char *grp_name = e->key; + vts0_t *grp_funcs = e->value; + int has_single = 0, has_multi = 0, has_unbound = 0; + + for(f = 0; f < grp_funcs->used; f++) { + const char *func = grp_funcs->array[f]; + switch(*func) { + case SINGLE: has_single++; break; + case MULTI: has_multi++; break; + default: has_unbound++; break; + } + } + +/* rnd_trace(" grp %s: %d %d %d\n", grp_name, has_single, has_multi, has_unbound);*/ + if (has_unbound && has_single) { + /* some ports in this group are selected in a way we know this + port is to be used (has_single), while other ports are unselected + (has_unbound). The reason for ignoring multi: attiny24 has SCK used + by both USI and SPI; using SCK for SPI would trigger a violation on + USI. Instead, ignore SCK in both unless it is unbound. */ + csch_drc_violation_t *v = csch_drc_violation_alloc_append(drc); + csch_drc_abst_ref_t *r; + v->title = rnd_strdup("funcmap/strong_grp_partial"); + v->desc = rnd_strdup_printf("Strong function group %s with some functions assigned to ports while other functions not assigned", grp_name); + r = csch_drc_abst_ref_alloc_append(v); + r->comp_name = rnd_strdup(comp->name); + } + } + + + funcmap_map_grps_uninit(&grps); + funcmap_hashgrps_free(&func2col); + for(c = 0; c < hdr.used; c++) + free(hdr.array[c]); + vts0_uninit(&hdr); +} + +static void funcmap_drc_ev(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + csch_sheet_t *sheet = (csch_sheet_t *)hidlib; + csch_project_t *prj = (csch_project_t *)sheet->hidlib.project; + csch_abstract_t *abst = prj->abst; + csch_drc_t *drc; + htsp_entry_t *e; + + if (funcmap_conf.plugins.funcmap.drc_disable) + return; + + if ((argc < 1) || (argv[1].type != RND_EVARG_PTR) || (abst == NULL)) + return; + + drc = argv[1].d.p; + if (drc == NULL) + return; + + for(e = htsp_first(&abst->comps); e != NULL; e = htsp_next(&abst->comps, e)) + funcmap_drc_comp(drc, prj, e->value); + + drc->ran++; +} Index: tags/1.0.5/src/plugins/funcmap/fmparse.c =================================================================== --- tags/1.0.5/src/plugins/funcmap/fmparse.c (nonexistent) +++ tags/1.0.5/src/plugins/funcmap/fmparse.c (revision 10414) @@ -0,0 +1,529 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - alternate function mapper + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust Fund in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/* Helper functions to parse funcmap list attributes */ + +#include + +/* Make a list of functions for a port and/or return the index of a function + on the list. If dst is NULL, no list is created; if find_func is NULL no + search for the given fuinction is done. If find_func is not NULL, + out_idx is set to the index of the function on the list or -1 if not found */ +static int funcmap_get_port_funcs(vts0_t *dst, csch_attribs_t *fmattrs, const char *port_name, const char *find_func, long *out_idx) +{ + long n, pnlen, find_func_len, idx = 0; + csch_attrib_t *lst = htsp_get(fmattrs, "funcmap/ports"); + + if (lst == NULL) + return -1; + + if (find_func != NULL) { + find_func_len = strlen(find_func); + *out_idx = -1; + } + + pnlen = strlen(port_name); + for(n = 0; n < lst->arr.used; n++) { + const char *line = lst->arr.array[n]; + char *sep, *func; + + while(isspace(*line)) line++; + + sep = strchr(line, '/'); /* find port name (left of /) */ + if (sep != NULL) { + int len = sep - line; + + if ((pnlen != len) || (memcmp(line, port_name, pnlen) != 0)) + continue; /* ignore lines not for this port */ + + /* fetch functionality supported by this port (right side of /) */ + func = sep+1; + sep = strpbrk(func, " \t\r\n>"); + if (sep != NULL) { + char *func_dup; + if ((*sep == '>') && (sep > line) && (sep[-1] == '-')) /* found -> */ + sep--; + len = sep - func; + if (dst != NULL) { + func_dup = rnd_strndup(func, len); + vts0_append(dst, func_dup); + } + if ((find_func != NULL) && (find_func_len == len) && (strncmp(find_func, func, len) == 0)) { + *out_idx = idx; + find_func = NULL; + } + idx++; + } + } + } + + return 0; +} + +static int funcmap_has_func(csch_acomp_t *comp, const char *port_name, csch_attribs_t *fmattrs, const char *func) +{ + long idx; + + funcmap_get_port_funcs(NULL, fmattrs, port_name, func, &idx); + + return (idx >= 0); +} + +static void funcmap_comp2dlg_hashgrp(htsp_t *func2col, csch_attrib_t *lst, int *grpcol) +{ + long n; + + + if (lst == NULL) + return; + + for(n = 0; n < lst->arr.used; n++) { + const char *line = lst->arr.array[n]; + char *sep, *func, *next, *fname; + + while(isspace(*line)) line++; + + sep = strchr(line, '>'); + if (sep == NULL) + continue; + if ((*sep != '>') || (sep <= line) || (sep[-1] != '-')) + continue; /* not -> */ + + for(func = sep+1; func != NULL; func = next) { + vtl0_t *cols; + + while((*func == ',') || isspace(*func)) func++; + if (*func == '\0') break; + next = strpbrk(func, " \t,"); + + if (next != NULL) + fname = rnd_strndup(func, next-func); + else + fname = rnd_strdup(func); + cols = htsp_get(func2col, fname); + if (cols == NULL) { + cols = calloc(sizeof(vtl0_t), 1); + htsp_set(func2col, fname, cols); + } + else + free(fname); + + vtl0_append(cols, *grpcol); + } + + (*grpcol)++; + } +} + +static void funcmap_comp2dlg_hashgrps(htsp_t *func2col, csch_attribs_t *fmattrs, int *grpcol) +{ + htsp_init(func2col, strhash, strkeyeq); + + *grpcol = 1; + funcmap_comp2dlg_hashgrp(func2col, htsp_get(fmattrs, "funcmap/weak_groups"), grpcol); + funcmap_comp2dlg_hashgrp(func2col, htsp_get(fmattrs, "funcmap/strong_groups"), grpcol); +} + +static void funcmap_hashgrps_free(htsp_t *func2col) +{ + htsp_entry_t *e; + + for(e = htsp_first(func2col); e != NULL; e = htsp_next(func2col, e)) { + vtl0_t *cols = e->value; + vtl0_uninit(cols); + free(cols); + free(e->key); + } + htsp_uninit(func2col); +} + + +static void funcmap_comp2dlg_hashcells(htsp_t *func2col, htsp_t *port2cell, csch_attrib_t *lst, int nogrp) +{ + long n; + gds_t tmp = {0}; + + htsp_init(port2cell, strhash, strkeyeq); + + if (lst == NULL) + return; + + for(n = 0; n < lst->arr.used; n++) { + const char *line = lst->arr.array[n]; + char *sep, *func; + vts0_t *cells; + + while(isspace(*line)) line++; + + + sep = strchr(line, '/'); /* find port name (left of /) */ + if (sep != NULL) { + int len = sep - line; + vtl0_t *cols; + + /* ensure cells for this port */ + tmp.used = 0; + gds_append_len(&tmp, line, len); + cells = htsp_get(port2cell, tmp.array); + if (cells == NULL) { + cells = calloc(sizeof(vts0_t), 1); + htsp_set(port2cell, tmp.array, cells); + tmp.array = NULL; + tmp.used = tmp.alloced = 0; + } + + /* fetch functionality supported by this port (right side of /) */ + func = sep+1; + sep = strpbrk(func, " \t\r\n>"); + if (sep != NULL) { + if ((*sep == '>') && (sep > line) && (sep[-1] == '-')) /* found -> */ + sep--; + len = sep - func; + tmp.used = 0; + gds_append_len(&tmp, func, len); + func = tmp.array; + + cols = htsp_get(func2col, func); + + if ((cols == NULL) || (cols->used == 0)) { + if ((nogrp >= cells->used) || (cells->array[nogrp] == NULL)) { + vts0_set(cells, nogrp, func); + tmp.array = NULL; + tmp.alloced = 0; + } + } + else if (cols->used == 1) { /* the function is assigned to a single col - avoid extra strdup */ + if ((cols->array[0] >= cells->used) || (cells->array[cols->array[0]] == NULL)) { + vts0_set(cells, cols->array[0], func); + tmp.array = NULL; + tmp.alloced = 0; + } + } + else { /* the function is assigned to more than one cols */ + int m; + for(m = 0; m < cols->used; m++) { + if ((cols->array[m] >= cells->used) || (cells->array[cols->array[m]] == NULL)) + vts0_set(cells, cols->array[m], rnd_strdup(func)); + } + } + tmp.used = 0; + } + } + } + + gds_uninit(&tmp); +} + +static void funcmap_hashcells_free(htsp_t *port2cell) +{ + htsp_entry_t *e; + + for(e = htsp_first(port2cell); e != NULL; e = htsp_next(port2cell, e)) { + long n; + vts0_t *cells = e->value; + + free(e->key); + for(n = 0; n < cells->used; n++) + free(cells->array[n]); + vts0_uninit(cells); + free(cells); + } + htsp_uninit(port2cell); +} + +static int funcmap_row_cmp(const void *r1, const void *r2) +{ + const vts0_t **in_cells1 = (const vts0_t **)r1, **in_cells2 = (const vts0_t **)r2; + const char *k1 = (*in_cells1)->array[0], *k2 = (*in_cells2)->array[0]; + + if ((k1 == NULL) && (k2 != NULL)) return +1; + if ((k2 == NULL) && (k1 != NULL)) return -1; + if ((k1 == NULL) && (k2 == NULL)) return +1; + return strcmp(k1, k2); +} + +/* Append table rows (each a vts0_t *in_cells) in dst and sort dst by the + table column sort_by_col (if it's >= 0). The caller needs to call + vtp0_free() on dst (vector content doesn't need to be free'd) */ +static void funcmap_sort_rows(vtp0_t *dst, htsp_t *port2cell, int sort_by_col) +{ + long r; + htsp_entry_t *e; + + for(e = htsp_first(port2cell); e != NULL; e = htsp_next(port2cell, e)) { + vts0_t *in_cells = e->value; + char *key = rnd_strdup(e->key); + + in_cells->array[0] = key; /* remember key as first col (room allocated already) */ + + if (sort_by_col > 0) /* get sort-by column to be the first temporarily */ + rnd_swap(char *, in_cells->array[0], in_cells->array[sort_by_col]); + + vtp0_append(dst, in_cells); + } + + if (sort_by_col >= 0) + qsort(dst->array, dst->used, sizeof(vts0_t *), funcmap_row_cmp); + + /* undo the swap we did for the sort */ + for(r = 0; r < dst->used; r++) { + vts0_t *in_cells = dst->array[r]; + + if (sort_by_col > 0) + rnd_swap(char *, in_cells->array[0], in_cells->array[sort_by_col]); + } +} + +static void funcmap_comp_gen_hdr_(vts0_t *dst, csch_attrib_t *lst) +{ + long n; + + if (lst == NULL) + return; + + for(n = 0; n < lst->arr.used; n++) { + const char *line = lst->arr.array[n]; + char *sep, *tmp; + + while(isspace(*line)) line++; + sep = strpbrk(line, " \t\r\n>"); + if (sep != NULL) { + int len; + + if ((*sep == '>') && (sep > line) && (sep[-1] == '-')) /* found -> */ + sep--; + + len = sep - line; + tmp = rnd_strndup(line, len); + vts0_append(dst, tmp); + } + } +} + + +/*** set group ***/ + +/* split up a list of functions and add them in the hash */ +static int funcmap_set_func_grp_want_found(htsp_t *dst, const char *grp_name, int grp_name_len, const char *funcs, int for_search) +{ + const char *curr, *next; + vts0_t *lst; + + if (!for_search) { + char *key = rnd_strndup(grp_name, grp_name_len); + lst = calloc(sizeof(vts0_t), 1); + htsp_set(dst, key, lst); + } + + /* skip whitespace and -> */ + while(isspace(*funcs)) funcs++; + if ((funcs[0] == '-') && (funcs[1] == '>')) + funcs+=2; + + + for(curr = funcs; curr != NULL; curr = next) { + char *fname; + + while((*curr == ',') || isspace(*curr)) curr++; + if (*curr == '\0') break; + next = strpbrk(curr, " \t,"); + + if (next != NULL) + fname = rnd_strndup(curr, next-curr); + else + fname = rnd_strdup(curr); + + if (for_search) { + if (htsp_has(dst, fname)) + free(fname); + else + htsp_set(dst, fname, dst); + } + else + vts0_append(lst, fname); + } + + return 1; +} + +static int funcmap_func_grp_seek_or_list_(htsp_t *dst, csch_attribs_t *fmattrs, const char *grp_name, int grp_name_len, csch_attrib_t *grp_lst) +{ + long n; + + for(n = 0; n < grp_lst->arr.used; n++) { + const char *sep, *line = grp_lst->arr.array[n]; + + while(isspace(*line)) line++; + + sep = strpbrk(line, " \t\r\n>"); + if (sep != NULL) { + int len; + + if ((*sep == '>') && (sep > line) && (sep[-1] == '-')) /* found -> */ + sep--; + + len = sep - line; + if (grp_name != NULL) { /* search for a specific group */ + if ((grp_name_len == len) && (strncmp(line, grp_name, len) == 0)) + return funcmap_set_func_grp_want_found(dst, NULL, 0, sep+1, 1); + } + else { + /* list groups */ + funcmap_set_func_grp_want_found(dst, line, len, sep+1, 0); + } + } + } + + return 0; +} + +/* Returns 1 if grp_name is found and hash table is filled in */ +static int funcmap_set_func_grp_want(htsp_t *dst, csch_attribs_t *fmattrs, const char *grp_name, int grp_name_len, csch_attrib_t *grp_lst) +{ + return funcmap_func_grp_seek_or_list_(dst, fmattrs, grp_name, grp_name_len, grp_lst); +} + + +/* Create a list of functions per group in dst. Key is the name of the group, + value is a vts0_t with all strings allocated. Use funcmap_map_grps_uninit() + to free all fields. */ +static int funcmap_map_grps(htsp_t *dst, csch_attribs_t *fmattrs, csch_attrib_t *grp_lst) +{ + return funcmap_func_grp_seek_or_list_(dst, fmattrs, NULL, 0, grp_lst); +} + +/* Free all fields of dst (but not dst itself) */ +static void funcmap_map_grps_uninit(htsp_t *dst) +{ + htsp_entry_t *e; + for(e = htsp_first(dst); e != NULL; e = htsp_next(dst, e)) { + vts0_t *funcs = e->value; + long n; + + free(e->key); + for(n = 0; n < funcs->used; n++) + free(funcs->array[n]); + vts0_uninit(funcs); + free(funcs); + } + htsp_uninit(dst); +} + + +static int funcmap_set_on_port(csch_acomp_t *comp, const char *port_name, const char *new_val); + +/* change the functionality of all ports that belong to a group to activate + the group */ +static int funcmap_set_func_grp(csch_acomp_t *comp, csch_attribs_t *fmattrs, const char *grp_name) +{ + int res = 0; + long n; + gds_t func_name = {0}; + csch_attrib_t *lst = htsp_get(fmattrs, "funcmap/ports"); + htsp_t wanted; + int grp_name_len; + htsp_entry_t *e; + + if (lst == NULL) + return -1; + + for(n = 0; n < comp->hdr.srcs.used; n++) { + csch_cgrp_t *sym = comp->hdr.srcs.array[n]; + uundo_freeze_serial(&sym->hdr.sheet->undo); + } + + + /* create a hash table of functions for this group */ + grp_name_len = strlen(grp_name); + htsp_init(&wanted, strhash, strkeyeq); + (void)( /* get the first group with matching name */ + funcmap_set_func_grp_want(&wanted, fmattrs, grp_name, grp_name_len, htsp_get(fmattrs, "funcmap/weak_groups")) + || + funcmap_set_func_grp_want(&wanted, fmattrs, grp_name, grp_name_len, htsp_get(fmattrs, "funcmap/strong_groups")) + ); + + for(n = 0; n < lst->arr.used; n++) { + const char *line = lst->arr.array[n]; + char *sep, *func; + + while(isspace(*line)) line++; + + sep = strchr(line, '/'); /* find port name (left of /) */ + if (sep != NULL) { + int r, func_len, port_len = sep - line; + + /* fetch functionality supported by this port (right side of /) */ + func = sep+1; + sep = strpbrk(func, " \t\r\n>"); + if (sep != NULL) { + if ((*sep == '>') && (sep > line) && (sep[-1] == '-')) /* found -> */ + sep--; + func_len = sep - func; + func_name.used = 0; + gds_append_len(&func_name, func, func_len); + + /* check if function is in the hash of functions we want to have */ + e = htsp_popentry(&wanted, func_name.array); + if (e != NULL) { + const char *port_name; + + /* copy port name to temp storage so it can be truncated */ + func_name.used = 0; + gds_append_len(&func_name, line, port_len); + port_name = func_name.array; + + r = funcmap_set_on_port(comp, port_name, e->key); + if (r != 0) { + rnd_message(RND_MSG_ERROR, "Failed to set port '%s' functionality to '%s' for group '%s'\n", port_name, e->key, grp_name); + res = 1; + } + + /* set port functionality */ + free(e->key); + } + } + } + } + + for(e = htsp_first(&wanted); e != NULL; e = htsp_next(&wanted, e)) { + rnd_message(RND_MSG_ERROR, "Failed to find a port for functionality '%s' in group '%s'\n", e->key, grp_name); + res = 1; + free(e->key); + } + htsp_uninit(&wanted); + gds_uninit(&func_name); + + + for(n = 0; n < comp->hdr.srcs.used; n++) { + csch_cgrp_t *sym = comp->hdr.srcs.array[n]; + uundo_unfreeze_serial(&sym->hdr.sheet->undo); + uundo_inc_serial(&sym->hdr.sheet->undo); + } + + return res; +} Index: tags/1.0.5/src/plugins/funcmap/funcmap.c =================================================================== --- tags/1.0.5/src/plugins/funcmap/funcmap.c (nonexistent) +++ tags/1.0.5/src/plugins/funcmap/funcmap.c (revision 10414) @@ -0,0 +1,296 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - (pin alternate) function map + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust Fund in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "funcmap_conf.h" +#include "conf_internal.c" + +static conf_funcmap_t funcmap_conf; +static csch_p4cfg_t p4_funcmap; +static csch_lib_backend_t be_funcmap_lht; +static gds_t funcmap_tmp_gds, funcmap_tmp_gds2; + +#define funcmap_get_anymap(sheet) \ + ((anymap_ctx_t *)csch_p4_get_by_sheet(&p4_funcmap, sheet)) + +typedef anymap_obj_t funcmap_t; + +static const char funcmap_cookie[] = "funcmap"; +static csch_lib_master_t *devmaster; + +#include "parse.c" +#include "loclib.c" +#include "libs.c" +#include "preview.c" +#include "fmparse.c" +#include "compiler.c" +#include "dlg_funcmap.c" +#include "fmdrc.c" + +static int on_load(fgw_obj_t *obj, const char *filename, const char *opts) +{ + fgw_func_reg(obj, "compile_component1", funcmap_compile_comp1); + fgw_func_reg(obj, "compile_port", funcmap_compile_port); + + return 0; +} + +static const fgw_eng_t fgw_funcmap_eng = { + "funcmap", + csch_c_call_script, + NULL, + on_load, + NULL /* on_unload */ +}; + +const char csch_acts_quick_attr_funcmap[] = "quick_attr_funcmap(objptr)"; +const char csch_acth_quick_attr_funcmap[] = "Quick Attribute Edit for funcmap using the funcmap library"; +fgw_error_t csch_act_quick_attr_funcmap(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_design_t *hidlib = RND_ACT_DESIGN; + csch_sheet_t *sheet = (csch_sheet_t *)hidlib; + csch_cgrp_t *grp; + fgw_arg_t ares, args[4]; + int ret; + + QUICK_ATTR_GET_GRP(grp, "quick_attr_funcmap"); + + args[1].type = FGW_STR; + args[1].val.cstr = "funcmap"; + args[2].type = FGW_STR; + args[2].val.cstr = "sheet"; + args[3].type = FGW_STR; + args[3].val.cstr = "modal"; + + ret = rnd_actionv_bin(&sheet->hidlib, "librarydialog", &ares, 4, args); + if ((ret == 0) && ((ares.type & FGW_STR) == FGW_STR)) { + csch_source_arg_t *src; + char *path = ares.val.str, *sep = NULL; + + if ((path != NULL) && (*path != '\0')) + sep = strrchr(path, '/'); + if (sep != NULL) { + char *end = strrchr(sep+1, '.'); + if ((end != NULL) && (rnd_strcasecmp(end, ".funcmap") == 0)) + *end = '\0'; + + src = csch_attrib_src_p("funcmap", "manually picked from the funcmap lib"); + csch_attr_modify_str(sheet, grp, -CSCH_ATP_USER_DEFAULT, "funcmap", sep+1, src, 1); +/* rnd_trace("new funcmap val: '%s'\n", sep+1);*/ + } + } + fgw_arg_free(&rnd_fgw, &ares); + + + RND_ACT_IRES(1); + return 0; +} + + +static const char csch_acts_FuncmaplibRehash[] = "FuncmaplibRehash()"; +static const char csch_acth_FuncmaplibRehash[] = "Rebuild the in-memory tree of funcmaps"; +static fgw_error_t csch_act_FuncmaplibRehash(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + csch_sheet_t *sheet = CSCH_ACT_SHEET; + csch_lib_master_t *master = csch_lib_get_master("funcmap", 1); + + csch_lib_clear_sheet_lib(sheet, master->uid); + csch_lib_add_all(sheet, master, &funcmap_conf.plugins.funcmap.search_paths, 1); + rnd_event(&sheet->hidlib, CSCH_EVENT_LIBRARY_CHANGED, NULL); + RND_ACT_IRES(0); + return 0; +} + +static const char csch_acts_FuncmaplibCleanLocal[] = "FuncmaplibCleanLocal()"; +static const char csch_acth_FuncmaplibCleanLocal[] = "Remove all local-lib funcmaps from the current sheet; they are re-loaded from external libs into the local lib upon the next compilation. Useful to refresh local lib from disk."; +static fgw_error_t csch_act_FuncmaplibCleanLocal(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + csch_sheet_t *sheet = CSCH_ACT_SHEET; + long cnt = 0, n, i; + csch_lib_root_t *libroot; + csch_lib_master_t *master = csch_lib_get_master("funcmap", 0); + csch_cgrp_t *root_grp; + + libroot = sheet->local_libs.array[master->uid]; + for(n = 0; n < libroot->roots.used; n++) { + csch_lib_t *root = libroot->roots.array[n]; + if (strcmp(root->name, "") == 0) { + for(i = root->children.used-1; i >= 0; i--) { + csch_lib_t *le = root->children.array[i]; + csch_lib_remove(le); + cnt++; + } + break; + } + } + + /* remove from indirect */ + root_grp = csch_loclib_get_root(sheet, master, NULL, 0, NULL); + if (root_grp != NULL) + csch_cgrp_clear(root_grp); + + rnd_message(RND_MSG_INFO, "Removed %ld funcmap(s) from the local lib of the sheet\n", cnt); + + rnd_event(&sheet->hidlib, CSCH_EVENT_LIBRARY_CHANGED, NULL); + RND_ACT_IRES(0); + return 0; +} + + +static void funcmap_sheet_postload_ev(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + csch_sheet_t *sheet = (csch_sheet_t *)hidlib; + csch_lib_add_all(sheet, devmaster, &funcmap_conf.plugins.funcmap.search_paths, 0); + csch_lib_add_local(sheet, devmaster); +} + +static rnd_action_t funcmap_action_list[] = { + {"quick_attr_funcmap", csch_act_quick_attr_funcmap, csch_acth_quick_attr_funcmap, csch_acts_quick_attr_funcmap}, + {"FuncmaplibRehash", csch_act_FuncmaplibRehash, csch_acth_FuncmaplibRehash, csch_acts_FuncmaplibRehash}, + {"FuncmaplibCleanLocal", csch_act_FuncmaplibCleanLocal, csch_acth_FuncmaplibCleanLocal, csch_acts_FuncmaplibCleanLocal}, + {"FuncmapComponentDialog", csch_act_FuncmapComponentDialog, csch_acth_FuncmapComponentDialog, csch_acts_FuncmapComponentDialog}, + {"FuncmapPortDialog", csch_act_FuncmapPortDialog, csch_acth_FuncmapPortDialog, csch_acts_FuncmapPortDialog}, + {"FuncmapChange", csch_act_FuncmapChange, csch_acth_FuncmapChange, csch_acts_FuncmapChange}, + {"FuncmapPrintTable", csch_act_FuncmapPrintTable, csch_acth_FuncmapPrintTable, csch_acts_FuncmapPrintTable} +}; + +/*** p4 ***/ + + +static void funcmap_p4_project_init(csch_p4cfg_t *p4, csch_project_t *prj) +{ + /* initialize view-local cache */ + anymap_ctx_t *ctx = calloc(sizeof(anymap_ctx_t), 1); + ctx->name = ctx->attr_key = "funcmap"; + ctx->eng_src_name = "funcmap"; + ctx->be = &be_funcmap_lht; + ctx->sheet_init = funcmap_sheet_init; + ldch_init(&ctx->maps); + ctx->maps.load_name_to_real_name = funcmap_lib_lookup; + ctx->low_parser = ldch_lht_reg_low_parser(&ctx->maps); + ctx->high_parser = ldch_reg_high_parser(&ctx->maps, "funcmap"); + ctx->high_parser->parse = funcmap_parse; + ctx->high_parser->free_payload = funcmap_free_payload; + + csch_p4_set_by_project(p4, prj, ctx); +} + +static void funcmap_p4_project_uninit(csch_p4cfg_t *p4, csch_project_t *prj) +{ + anymap_ctx_t *ctx = csch_p4_get_by_project(p4, prj); + ldch_uninit(&ctx->maps); + vtp0_uninit(&ctx->ssyms); + free(ctx); +} + + +/*** plugin ***/ + +int pplg_check_ver_funcmap(int ver_needed) { return 0; } + +void pplg_uninit_funcmap(void) +{ + rnd_event_unbind_allcookie(funcmap_cookie); + rnd_remove_actions_by_cookie(funcmap_cookie); + rnd_conf_plug_unreg("plugins/funcmap/", funcmap_conf_internal, funcmap_cookie); + csch_p4_unreg_plugin(&p4_funcmap); + gds_uninit(&funcmap_tmp_gds); + gds_uninit(&funcmap_tmp_gds2); +} + +int pplg_init_funcmap(void) +{ + RND_API_CHK_VER; + + fgw_eng_reg(&fgw_funcmap_eng); + + RND_REGISTER_ACTIONS(funcmap_action_list, funcmap_cookie); + + devmaster = csch_lib_get_master("funcmap", 1); + be_funcmap_lht.name = "funcmap"; + be_funcmap_lht.realpath = funcmap_lht_realpath; + be_funcmap_lht.map = funcmap_lht_map; + be_funcmap_lht.map_local = funcmap_lht_map_local; + be_funcmap_lht.load = funcmap_lht_load; + be_funcmap_lht.preview_text = funcmap_lht_preview_text; + be_funcmap_lht.free = anymap_lht_free; + be_funcmap_lht.loc_refresh_from_ext = funcmap_loc_refresh_from_ext; + be_funcmap_lht.loc_list = funcmap_loc_list; + + + csch_lib_backend_reg(devmaster, &be_funcmap_lht); + + rnd_event_bind(CSCH_EVENT_SHEET_POSTLOAD, funcmap_sheet_postload_ev, NULL, funcmap_cookie); + rnd_event_bind(CSCH_EVENT_DRC_RUN, funcmap_drc_ev, NULL, funcmap_cookie); + + rnd_conf_plug_reg(funcmap_conf, funcmap_conf_internal, funcmap_cookie); +#define conf_reg(field,isarray,type_name,cpath,cname,desc,flags) \ + rnd_conf_reg_field(funcmap_conf, field,isarray,type_name,cpath,cname,desc,flags); +#include "funcmap_conf_fields.h" + + p4_funcmap.project_init = funcmap_p4_project_init; + p4_funcmap.project_uninit = funcmap_p4_project_uninit; + + csch_p4_reg_plugin(&p4_funcmap); + + return 0; +} + Index: tags/1.0.5/src/plugins/funcmap/funcmap.conf =================================================================== --- tags/1.0.5/src/plugins/funcmap/funcmap.conf (nonexistent) +++ tags/1.0.5/src/plugins/funcmap/funcmap.conf (revision 10414) @@ -0,0 +1,15 @@ +li:pcb-rnd-conf-v1 { + ha:append { + ha:plugins { + ha:funcmap { + drc_disable = 0 + li:search_paths = { + ?../../library/funcmap + ?$(rc.path.design)/funcmap + ?~/.sch-rnd/funcmap/ + ?$(rc.path.share)/funcmap + } + } + } + } +} Index: tags/1.0.5/src/plugins/funcmap/funcmap.pup =================================================================== --- tags/1.0.5/src/plugins/funcmap/funcmap.pup (nonexistent) +++ tags/1.0.5/src/plugins/funcmap/funcmap.pup (revision 10414) @@ -0,0 +1,8 @@ +$class engine +$short alternate port functions +$long Handles alternate functionality of device ports (e.g. MCU pins) +$state WIP +$package (core) +default buildin +dep lib_anymap +autoload 1 Index: tags/1.0.5/src/plugins/funcmap/funcmap_conf.h =================================================================== --- tags/1.0.5/src/plugins/funcmap/funcmap_conf.h (nonexistent) +++ tags/1.0.5/src/plugins/funcmap/funcmap_conf.h (revision 10414) @@ -0,0 +1,15 @@ +#ifndef SCH_RND_FUNCMAP_CONF_H +#define SCH_RND_FUNCMAP_CONF_H + +#include + +typedef struct { + const struct { + const struct { + RND_CFT_BOOLEAN drc_disable; /* if set: do not run the funcmap Design Rule Checker; funcmap DRC checks foralternative pin functionality grouping violations */ + RND_CFT_LIST search_paths; /* ordered list of paths that are each recursively searched for funcmap files */ + } funcmap; + } plugins; +} conf_funcmap_t; + +#endif Index: tags/1.0.5/src/plugins/funcmap/libs.c =================================================================== --- tags/1.0.5/src/plugins/funcmap/libs.c (nonexistent) +++ tags/1.0.5/src/plugins/funcmap/libs.c (revision 10414) @@ -0,0 +1,95 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - (pin alternate) function map + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust Fund in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/*** funcmap library handling ***/ + +static char *funcmap_lib_lookup(ldch_ctx_t *ctx, const char *load_name, ldch_low_parser_t *low, ldch_high_parser_t *high, void *low_call_ctx, void *high_call_ctx) +{ +/* csch_hook_call_ctx_t *cctx = high_call_ctx; for cctx->project */ +/* fgw_obj_t *obj = ctx->user_data;*/ + csch_lib_t *le; + + /* if full path is known */ + if (strchr(load_name, '/') != NULL) + return rnd_strdup(load_name); + + TODO("we shouldn't search master, only sheet's funcmap libs, but the" + "abstract model doesn't have sheets"); + le = csch_lib_search_master(devmaster, load_name, CSCH_SLIB_STATIC); + if (le == NULL) { + char *load_name2 = rnd_concat(load_name, ".funcmap", NULL); + le = csch_lib_search_master(devmaster, load_name2, CSCH_SLIB_STATIC); + free(load_name2); + } +/* rnd_trace("funcmap lookup: %s -> %p\n", load_name, le);*/ + + return le == NULL ? NULL : rnd_strdup(le->realpath); +} + +/* effectively a test-parse */ +csch_lib_type_t funcmap_lht_file_type(rnd_design_t *hl, const char *fn) +{ + FILE *f; + int n; + csch_lib_type_t res = CSCH_SLIB_invalid; + + f = rnd_fopen(hl, fn, "r"); + if (f == NULL) + return res; + + for(n = 0; n < 16; n++) { + char *s, line[1024]; + s = fgets(line, sizeof(line), f); + if (s == NULL) break; + if (strstr(s, "ha:funcmap.v") == 0) { + res = CSCH_SLIB_STATIC; + break; + } + } + fclose(f); + return res; +} + + +static char *funcmap_lht_realpath(rnd_design_t *hl, const char *root) +{ + /* accept only non-prefixed paths for now */ + if (strchr(root, '@') != NULL) + return NULL; + + return csch_lib_fs_realpath(hl, root); +} + +static int funcmap_lht_map(rnd_design_t *hl, csch_lib_t *root_dir) +{ + gds_t tmp = {0}; + gds_append_str(&tmp, root_dir->realpath); + csch_lib_fs_map(hl, &be_funcmap_lht, root_dir, &tmp, funcmap_lht_file_type); + gds_uninit(&tmp); + return 0; +} Index: tags/1.0.5/src/plugins/funcmap/loclib.c =================================================================== --- tags/1.0.5/src/plugins/funcmap/loclib.c (nonexistent) +++ tags/1.0.5/src/plugins/funcmap/loclib.c (revision 10414) @@ -0,0 +1,77 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - (pin alternate) function map + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust Fund in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/*** local lib support ***/ + +static int funcmap_lht_map_local(rnd_design_t *hl, csch_lib_t *root_dir, const csch_cgrp_t *indirect) +{ + csch_sheet_t *sheet = (csch_sheet_t *)hl; + anymap_ctx_t *actx = funcmap_get_anymap(sheet); + const csch_cgrp_t *root_grp; + + /* do not automatically create a local funcmap dir (we are at opening a sheet) */ + root_grp = csch_loclib_get_root(sheet, devmaster, NULL, 0, NULL); + if (root_grp != NULL) + anymap_sheet_init_(actx, hl, root_dir, root_grp); + + return 0; +} + +static void funcmap_sheet_init(anymap_ctx_t *actx, csch_sheet_t *sheet, csch_lib_t **root_dir_out, int alloc) +{ + csch_lib_t *root_dir = NULL; + int alloced; + csch_cgrp_t *root_grp; + csch_source_arg_t *src; + + src = csch_attrib_src_p("funcmap", NULL); + if (csch_loclib_get_roots(&root_dir, &root_grp, devmaster, sheet, src, alloc, &alloced) == 0) + anymap_sheet_init_(actx, &sheet->hidlib, root_dir, root_grp); + + if (root_dir_out != NULL) + *root_dir_out = root_dir; +} + +static int funcmap_lht_load(csch_sheet_t *sheet, void *dst_, csch_lib_t *src, const char *params) +{ + /* real loading happens through funcmap_lib_lookup(); this is called from the + lib window (will be needed for the preview) */ + return -1; +} + +static int funcmap_loc_list(csch_sheet_t *sheet, csch_lib_t *src) +{ + return anymap_loc_list(sheet, src, "funcmap"); +} + +static int funcmap_loc_refresh_from_ext(csch_sheet_t *sheet, csch_lib_t *src) +{ + anymap_ctx_t *actx = funcmap_get_anymap(sheet); + return anymap_loc_refresh_from_ext(actx, sheet, src); +} + Index: tags/1.0.5/src/plugins/funcmap/parse.c =================================================================== --- tags/1.0.5/src/plugins/funcmap/parse.c (nonexistent) +++ tags/1.0.5/src/plugins/funcmap/parse.c (revision 10414) @@ -0,0 +1,68 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - alternate function mapper + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust Fund in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/*** funcmap parser ***/ + +static void parse_error(void *ectx, lht_node_t *n, const char *msg) +{ + rnd_message(RND_MSG_ERROR, "funcmap: parse error '%s' near %ld:%ld\n", msg, n->line, n->col); +} + +static ldch_data_t *funcmap_parse(ldch_high_parser_t *parser, void *call_ctx, ldch_file_t *file) +{ + ldch_data_t *data; + funcmap_t *funcmap; + lht_doc_t *doc = ldch_lht_get_doc(file); + + if ((doc->root == NULL) && rnd_is_dir(NULL, file->real_name)) + return NULL; /* happens on refresh on a dir */ + + if ((doc->root == NULL) || (doc->root->type != LHT_HASH) || (strcmp(doc->root->name, "funcmap.v1") != 0)) { + rnd_message(RND_MSG_ERROR, "funcmap: invalid root node in '%s'; expected 'ha:funcmap.v1'\n", file->real_name); + return NULL; + } + + data = ldch_data_alloc(file, parser, sizeof(funcmap_t)); + funcmap = (funcmap_t *)&data->payload; + csch_attrib_init(&funcmap->comp_attribs); + if (csch_lht_parse_attribs(&funcmap->comp_attribs, lht_dom_hash_get(doc->root, "comp_attribs"), parse_error, NULL) != 0) { + rnd_message(RND_MSG_ERROR, "funcmap: failed to load any component attributes from '%s''\n", file->real_name); + ldch_data_free(parser->ctx, data); + return NULL; + } + + return data; +} + +static void funcmap_free_payload(ldch_data_t *data) +{ + funcmap_t *funcmap = (funcmap_t *)&data->payload; + + csch_attrib_uninit(&funcmap->comp_attribs); +} + Index: tags/1.0.5/src/plugins/funcmap/preview.c =================================================================== --- tags/1.0.5/src/plugins/funcmap/preview.c (nonexistent) +++ tags/1.0.5/src/plugins/funcmap/preview.c (revision 10414) @@ -0,0 +1,33 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - (pin alternate) function map + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust Fund in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +static char *funcmap_lht_preview_text(csch_sheet_t *sheet, csch_lib_t *src, const char *parametric) +{ + anymap_ctx_t *actx = funcmap_get_anymap(sheet); + return anymap_lht_preview_text(actx, sheet, src, parametric); +} Index: tags/1.0.5/src/plugins/gui/Makefile =================================================================== --- tags/1.0.5/src/plugins/gui/Makefile (nonexistent) +++ tags/1.0.5/src/plugins/gui/Makefile (revision 10414) @@ -0,0 +1,2 @@ +all: + cd ../../sch-rnd && make mod_gui Index: tags/1.0.5/src/plugins/gui/Plug.tmpasm =================================================================== --- tags/1.0.5/src/plugins/gui/Plug.tmpasm (nonexistent) +++ tags/1.0.5/src/plugins/gui/Plug.tmpasm (revision 10414) @@ -0,0 +1,15 @@ +put /local/rnd/mod {gui} +put /local/rnd/mod/OBJS [@ + $(PLUGDIR)/gui/act.o + $(PLUGDIR)/gui/layersel.o + $(PLUGDIR)/gui/sheetsel.o + $(PLUGDIR)/gui/sch_rnd_gui.o + $(PLUGDIR)/gui/status.o +@] + +switch /local/module/gui/controls + case {buildin} include /local/csch/tmpasm/buildin; end; + case {plugin} include /local/csch/tmpasm/plugin; end; + case {disable} include /local/csch/tmpasm/disable; end; +end + Index: tags/1.0.5/src/plugins/gui/act.c =================================================================== --- tags/1.0.5/src/plugins/gui/act.c (nonexistent) +++ tags/1.0.5/src/plugins/gui/act.c (revision 10414) @@ -0,0 +1,76 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - GUI + * Copyright (C) 2020,2023 Tibor 'Igor2' Palinkas + * copied from pcb-rnd, interactive printed circuit board design + * Copyright (C) 2017..2019 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "act.h" + +const char csch_acts_Zoom_[] = + rnd_gui_acts_zoom + "Zoom(selected)\n"; +const char csch_acth_Zoom[] = "GUI zoom"; +/* DOC: zoom.html */ +fgw_error_t csch_act_Zoom(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_design_t *hidlib = RND_ACT_DESIGN; + csch_sheet_t *sheet = (csch_sheet_t *)hidlib; + const char *csch_acts_Zoom = csch_acts_Zoom_; + rnd_acts_Zoom = csch_acts_Zoom_; + + RND_GUI_NOGUI(); + + if (argc == 2) { + const char *vp; + + RND_ACT_CONVARG(1, FGW_STR, Zoom, vp = argv[1].val.str); + + if (rnd_strcasecmp(vp, "selected") == 0) { + rnd_box_t sb; + if (sch_rnd_get_selection_bbox_gui(&sb, sheet) > 0) + rnd_gui->zoom_win(rnd_gui, sb.X1, sb.Y1, sb.X2, sb.Y2, 1); + else + rnd_message(RND_MSG_ERROR, "Can't zoom to selection: nothing selected\n"); + return 0; + } + } + + return rnd_gui_act_zoom(res, argc, argv); +} Index: tags/1.0.5/src/plugins/gui/act.h =================================================================== --- tags/1.0.5/src/plugins/gui/act.h (nonexistent) +++ tags/1.0.5/src/plugins/gui/act.h (revision 10414) @@ -0,0 +1,7 @@ +extern const char csch_acts_Popup[]; +extern const char csch_acth_Popup[]; +fgw_error_t csch_act_Popup(fgw_arg_t *res, int argc, fgw_arg_t *argv); + +extern const char csch_acts_Zoom_[]; +extern const char csch_acth_Zoom[]; +fgw_error_t csch_act_Zoom(fgw_arg_t *res, int argc, fgw_arg_t *argv); Index: tags/1.0.5/src/plugins/gui/autocomp.c =================================================================== --- tags/1.0.5/src/plugins/gui/autocomp.c (nonexistent) +++ tags/1.0.5/src/plugins/gui/autocomp.c (revision 10414) @@ -0,0 +1,110 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - GUI + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#define ACOMP_TIMER_RES_MS 250 + + +static void autocomp_update_bar(csch_sheet_t *sheet) +{ + rnd_hid_attr_val_t hv; + + if (!status.active) + return; + + if (sheet->acp_starting == 0) + hv.dbl = 0; + else + hv.dbl = (double)sheet->acp_remain / (double)sheet->acp_starting; + rnd_gui->attr_dlg_set_value(status.rdsub.dlg_hid_ctx, status.wcomp_bar, &hv); +} + +static void autocomp_compile(rnd_design_t *hl) +{ + rnd_actionva(hl, "CompileProject", NULL); + autocomp_update_bar((csch_sheet_t *)hl); +} + +static void autocomp_tick(rnd_hidval_t user_data) +{ + csch_sheet_t *sheet; + + if (!status.acomp_timer_want) { + status.acomp_timer_active = 0; + return; + } + status.acomp_timer = rnd_gui->add_timer(rnd_gui, autocomp_tick, ACOMP_TIMER_RES_MS, user_data); + status.acomp_timer_active = 1; + + sheet = (csch_sheet_t *)rnd_multi_get_current(); + +/*rnd_trace("acomp tick: %ld / %ld\n", sheet->acp_remain, sheet->acp_starting);*/ + + if (sheet != NULL) { + if (sheet->acp_remain > 0) { + sheet->acp_remain -= ACOMP_TIMER_RES_MS; + if (sheet->acp_remain <= 0) { + sheet->acp_remain = 0; + autocomp_compile(&sheet->hidlib); + } + else + autocomp_update_bar(sheet); + } + } +} + +static void autocomp_restart_timer(rnd_design_t *hl) +{ + csch_sheet_t *sheet = (csch_sheet_t *)hl; + + if ((csch_project_t *)sheet->hidlib.project == &sch_rnd_buffer_prj) + return; /* do not compile buffers */ + + sheet->acp_remain = sheet->acp_starting = conf_core.editor.autocomp_time; + + /* immediate compile */ + if (sheet->acp_remain <= 0) { + sheet->acp_remain = 0; + autocomp_compile(hl); + return; + } + + /* start timer if it's not running */ + if (!status.acomp_timer_active) { + rnd_hidval_t hv = {0}; + rnd_gui->add_timer(rnd_gui, autocomp_tick, ACOMP_TIMER_RES_MS, hv); + status.acomp_timer_want = 1; + status.acomp_timer_active = 1; + } + + autocomp_update_bar(sheet); +} + +static void autocomp_stop_timer(rnd_design_t *hl) +{ + status.acomp_timer_want = 0; +} Index: tags/1.0.5/src/plugins/gui/edit_act.c =================================================================== --- tags/1.0.5/src/plugins/gui/edit_act.c (nonexistent) +++ tags/1.0.5/src/plugins/gui/edit_act.c (revision 10414) @@ -0,0 +1,262 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - GUI + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * (loosely based on camv-rnd's implementation) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include +#include +#include + +#include +#include +#include +#include +#include + +RND_INLINE + int cmd_auto_obj_or_buff(int cmd) +{ + rnd_toolid_t buff; + + if (cmd != F_Auto) return cmd; + + buff = rnd_tool_lookup("buffer"); + if (rnd_conf.editor.mode == buff) + return F_Buffer; + return F_Object; +} + +#define CMD_IDPATH(idx, aname, dst) \ + do { \ + csch_oidpath_t *oidp; \ + fgw_arg_t atmp; \ + memcpy(&atmp, &argv[idx], sizeof(fgw_arg_t)); \ + atmp.type &= ~FGW_DYN; \ + if (fgw_arg_conv(&rnd_fgw, &atmp, FGW_IDPATH) != 0) { \ + rnd_message(RND_MSG_ERROR, #aname ": invalid idpath\n"); \ + RND_ACT_FAIL(aname); \ + return FGW_ERR_ARG_CONV; \ + } \ + oidp = fgw_idpath(&atmp); \ + if (oidp != NULL) { \ + csch_sheet_t *sheet = (csch_sheet_t *)RND_ACT_DESIGN; \ + dst = csch_oidpath_resolve(sheet, oidp); \ + if ((FGW_BASE_TYPE(argv[idx].type) == FGW_STR) && ((argv[idx].val.str[0] != '0') || (argv[idx].val.str[1] != 'x'))) { \ + csch_oidpath_free(oidp); \ + free(oidp); \ + fgw_ptr_unreg(&rnd_fgw, &atmp, RND_PTR_DOMAIN_IDPATH); \ + } \ + } \ + else \ + dst = NULL; \ + } while(0) \ + + +static const char csch_acts_Rotate90[] = "Rotate90([object|buffer|auto], [steps])\nRotate90(idpath, steps, idp, x, y)"; +static const char csch_acth_Rotate90[] = "Rotate object or buffer CCW in 90 degree steps. Default target is auto. Default steps is 1."; +static fgw_error_t csch_act_Rotate90(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_design_t *hidlib = RND_ACT_DESIGN; + csch_sheet_t *sheet = (csch_sheet_t *)hidlib; + int rv = -1, cmd = F_Auto, steps = 1; + + RND_ACT_MAY_CONVARG(1, FGW_KEYWORD, Rotate90, cmd = fgw_keyword(&argv[1])); + RND_ACT_MAY_CONVARG(2, FGW_INT, Rotate90, steps = argv[2].val.nat_int); + + cmd = cmd_auto_obj_or_buff(cmd); + + switch(cmd) { + case F_Idpath: + { + csch_coord_t x, y; + csch_chdr_t *obj; + + CMD_IDPATH(3, Rotate90, obj); + RND_ACT_CONVARG(4, FGW_COORD, Rotate90, x = fgw_coord(&(argv[4]))); + RND_ACT_CONVARG(5, FGW_COORD, Rotate90, y = fgw_coord(&(argv[5]))); + if (obj != NULL) { + csch_rotate90(sheet, obj, x, y, steps, 1); + rv = 0; + } + break; + } + case F_Object: + { + csch_coord_t x, y; + csch_chdr_t *obj; + + if (sch_rnd_get_coords("Click on object to rotate", &x, &y, 0) != 0) + break; + + obj = sch_rnd_search_obj_at(sheet, x, y, sch_rnd_slop); + if (obj != NULL) + csch_rotate90(sheet, obj, x, y, steps, 1); + rv = 0; + } + break; + case F_Buffer: + { + csch_sheet_t *buff = SCH_RND_PASTEBUFFER; + csch_cgrp_t *grp = &buff->direct; + htip_entry_t *e; + for(e = htip_first(&grp->id2obj); e != NULL; e = htip_next(&grp->id2obj, e)) + csch_rotate90(buff, e->value, 0, 0, steps, 0); + rv = 0; + } + break; + default: + rnd_message(RND_MSG_ERROR, "Invalid first arg for Rotate90()\n"); + break; + } + RND_ACT_IRES(rv); + return 0; +} + +static const char csch_acts_Rotate[] = "Rotate([object|buffer|auto], [deg|ask])\n"; +static const char csch_acth_Rotate[] = "Rotate object or buffer CCW in def degrees. Default target is auto. Default deg is ask (which prompts for a value)."; +static fgw_error_t csch_act_Rotate(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_design_t *hidlib = RND_ACT_DESIGN; + int rv = -1, cmd = F_Auto, ask = 0; + double deg; + + RND_ACT_MAY_CONVARG(1, FGW_KEYWORD, Rotate, cmd = fgw_keyword(&argv[1])); + + if (argc < 3) + ask = 1; + else if (((argv[2].type & FGW_STR) == FGW_STR) && ((argv[2].val.str[0] == 'a') || (argv[2].val.str[0] == 'A'))) + ask = 1; + + if (ask) { + char *end, *degs = rnd_hid_prompt_for(hidlib, "Degrees to rotate:", "15", "Rotation angle"); + if (degs == NULL) /* cancel - not yet implemented */ + return 0; + deg = strtod(degs, &end); + if (*end != '\0') { + rnd_message(RND_MSG_ERROR, "Invalid numeric value (at '%s')\n", end); + free(degs); + return 0; + } + free(degs); + } + else + RND_ACT_MAY_CONVARG(2, FGW_DOUBLE, Rotate, deg = argv[2].val.nat_double); + + cmd = cmd_auto_obj_or_buff(cmd); + + switch(cmd) { + case F_Object: + { + csch_sheet_t *sheet = (csch_sheet_t *)hidlib; + csch_coord_t x, y; + csch_chdr_t *obj; + + if (sch_rnd_get_coords("Click on object to rotate", &x, &y, 0) != 0) + break; + + obj = sch_rnd_search_obj_at(sheet, x, y, sch_rnd_slop); + if (obj != NULL) + csch_rotate(sheet, obj, x, y, deg, 1); + rv = 0; + } + break; + case F_Buffer: + { + csch_sheet_t *buff = SCH_RND_PASTEBUFFER; + csch_cgrp_t *grp = &buff->direct; + htip_entry_t *e; + for(e = htip_first(&grp->id2obj); e != NULL; e = htip_next(&grp->id2obj, e)) + csch_rotate(buff, e->value, 0, 0, deg, 0); + rv = 0; + } + break; + default: + rnd_message(RND_MSG_ERROR, "Invalid first arg for Rotate()\n"); + break; + } + RND_ACT_IRES(rv); + return 0; +} + +static const char csch_acts_Mirror[] = "Mirror([object|buffer|auto], [horizontal|vertical])\n"; +static const char csch_acth_Mirror[] = "Mirror object or buffer. Default target is auto. Default direction is horizontal."; +static fgw_error_t csch_act_Mirror(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_design_t *hidlib = RND_ACT_DESIGN; + int rv = -1, cmd = F_Auto, dir = F_Horizontal, mirx = 0, miry = 0; + + RND_ACT_MAY_CONVARG(1, FGW_KEYWORD, Mirror, cmd = fgw_keyword(&argv[1])); + RND_ACT_MAY_CONVARG(2, FGW_KEYWORD, Mirror, dir = fgw_keyword(&argv[2])); + + switch(dir) { + case F_Horizontal: mirx = 1; break; + case F_Vertical: miry = 1; break; + default: + rnd_message(RND_MSG_ERROR, "Invalid second arg for Mirror()\n"); + RND_ACT_IRES(-1); + return 0; + } + + cmd = cmd_auto_obj_or_buff(cmd); + + switch(cmd) { + case F_Object: + { + csch_sheet_t *sheet = (csch_sheet_t *)hidlib; + csch_chdr_t *obj; + csch_coord_t x, y; + + if (sch_rnd_get_coords("Click on object to mirror", &x, &y, 0) != 0) + break; + + obj = sch_rnd_search_obj_at(sheet, x, y, sch_rnd_slop); + if (obj != NULL) + csch_mirror(sheet, obj, x, y, mirx, miry, 1); + rv = 0; + } + break; + case F_Buffer: + { + csch_sheet_t *buff = SCH_RND_PASTEBUFFER; + csch_cgrp_t *grp = &buff->direct; + htip_entry_t *e; + for(e = htip_first(&grp->id2obj); e != NULL; e = htip_next(&grp->id2obj, e)) + csch_mirror(buff, e->value, 0, 0, mirx, miry, 0); + rv = 0; + } + break; + default: + rnd_message(RND_MSG_ERROR, "Invalid first arg for Mirror()\n"); + break; + } + RND_ACT_IRES(rv); + return 0; +} + +#define EDIT_ACTS \ + {"Rotate90", csch_act_Rotate90, csch_acth_Rotate90, csch_acts_Rotate90}, \ + {"Rotate", csch_act_Rotate, csch_acth_Rotate, csch_acts_Rotate}, \ + {"Mirror", csch_act_Mirror, csch_acth_Mirror, csch_acts_Mirror}, \ + Index: tags/1.0.5/src/plugins/gui/gui.pup =================================================================== --- tags/1.0.5/src/plugins/gui/gui.pup (nonexistent) +++ tags/1.0.5/src/plugins/gui/gui.pup (revision 10414) @@ -0,0 +1,8 @@ +$class gui +$short Graphical User Interface +$long sch-rnd-specific GUI elements +$package lib-gui +$state works +dep lib_hid_common +default buildin +autoload 1 Index: tags/1.0.5/src/plugins/gui/infobar.c =================================================================== --- tags/1.0.5/src/plugins/gui/infobar.c (nonexistent) +++ tags/1.0.5/src/plugins/gui/infobar.c (revision 10414) @@ -0,0 +1,120 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - GUI + * Copyright (C) 2019, 2022 Tibor 'Igor2' Palinkas + * Copied from pcb-rnd by the original author. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include + +#include +#include + +static rnd_hidval_t infobar_timer; +static int infobar_timer_active = 0; +static double last_interval = -2; +static int infobar_gui_inited = 0; + +static void infobar_check(rnd_design_t *dsg) +{ + csch_sheet_t *sheet = (csch_sheet_t *)dsg; + + if ((dsg != NULL) && (dsg->fullpath != NULL) && !sheet->saving) { + double last_chg = rnd_file_mtime(NULL, dsg->fullpath); + if (last_chg > sheet->infobar_last_date) { + sheet->infobar_last_date = last_chg; + rnd_actionva(dsg, "InfoBarFileChanged", "open", NULL); + } + } +} + +static void pcb_infobar_brdchg_ev(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + csch_sheet_t *sheet = (csch_sheet_t *)hidlib; + rnd_actionva(hidlib, "InfoBarFileChanged", "close", NULL); + if ((hidlib != NULL) && (hidlib->fullpath != NULL)) { + if (sheet->infobar_last_date <= 0) + sheet->infobar_last_date = rnd_file_mtime(NULL, hidlib->fullpath); + infobar_check(hidlib); + } + else if (sheet != NULL) + sheet->infobar_last_date = -1; +} + + +static void infobar_tick(rnd_hidval_t user_data) +{ + rnd_design_t *dsg = rnd_multi_get_current(); + + if (conf_core.rc.file_changed_interval > 0) { + infobar_timer = rnd_gui->add_timer(rnd_gui, infobar_tick, (conf_core.rc.file_changed_interval * 1000.0), user_data); + last_interval = conf_core.rc.file_changed_interval; + infobar_timer_active = 1; + } + else + infobar_timer_active = 0; + + if (infobar_timer_active) { /* check for file change */ + infobar_check(dsg); + + } +} + +static void pcb_infobar_update_conf(rnd_conf_native_t *cfg, int arr_idx, void *user_data) +{ + if ((!infobar_gui_inited) || (last_interval == conf_core.rc.file_changed_interval)) + return; + if ((infobar_timer_active) && (rnd_gui != NULL) && (rnd_gui->stop_timer != NULL)) { + rnd_gui->stop_timer(rnd_gui, infobar_timer); + infobar_timer_active = 0; + } + infobar_tick(infobar_timer); +} + + +static void pcb_infobar_gui_init_ev(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + infobar_gui_inited = 1; + pcb_infobar_brdchg_ev(hidlib, NULL, 0, NULL); /* this may have happened ebfore plugin init if file was specified on the CLI and is already loaded - pick up file data from memory */ + if (!infobar_timer_active) + infobar_tick(infobar_timer); +} + +static void pcb_infobar_postsave_ev(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + if ((hidlib != NULL) && (hidlib->fullpath != NULL)) { + csch_sheet_t *sheet = (csch_sheet_t *)hidlib; + sheet->infobar_last_date = rnd_file_mtime(NULL, hidlib->fullpath); + rnd_actionva(hidlib, "InfoBarFileChanged", "close", NULL); + } +} + +static void pcb_infobar_postload_ev(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + if ((hidlib != NULL) && (hidlib->fullpath != NULL)) { + csch_sheet_t *sheet = (csch_sheet_t *)hidlib; + sheet->infobar_last_date = rnd_file_mtime(NULL, hidlib->fullpath); + rnd_actionva(hidlib, "InfoBarFileChanged", "close", NULL); + } +} + Index: tags/1.0.5/src/plugins/gui/layersel.c =================================================================== --- tags/1.0.5/src/plugins/gui/layersel.c (nonexistent) +++ tags/1.0.5/src/plugins/gui/layersel.c (revision 10414) @@ -0,0 +1,157 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - GUI + * Copyright (C) 2020,2023 Tibor 'Igor2' Palinkas + * (loosely based on camv-rnd's implementation) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include + +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include + +#include + +#include "layersel.h" + +typedef struct layersel_ctx_s layersel_ctx_t; + +typedef struct { + int wvis, wlab; + int lid; + layersel_ctx_t *ls; +} ls_layer_t; + + +struct layersel_ctx_s { + rnd_hid_dad_subdialog_t sub; + int sub_inited; + int lock_vis, lock_sel; + int selected; /* layer idx (lid) of the currently selected layer */ + ls_layer_t layers[CSCH_DSPLY_max]; +}; + +static layersel_ctx_t layersel; + +static void lys_update_vis(ls_layer_t *lys) +{ + rnd_hid_attr_val_t hv; + hv.lng = !!csch_layer_vis[lys->lid]; + rnd_gui->attr_dlg_set_value(lys->ls->sub.dlg_hid_ctx, lys->wvis, &hv); +} + +static void layer_vis_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + ls_layer_t *lys = attr->user_data; + if (lys == NULL) + return; + + lys->ls->lock_vis++; + csch_layer_vis[lys->lid] = !csch_layer_vis[lys->lid]; + lys->ls->lock_vis--; + + lys_update_vis(lys); + sch_rnd_redraw(NULL); +} + +static void layer_right_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + TODO("set popup layer to: (ls_layer_t *)attr->user_data"); + rnd_actionl("Popup", "layer", NULL); +} + +static void layersel_create_layer(layersel_ctx_t *ls, ls_layer_t *lys, const char *name) +{ + RND_DAD_BEGIN_HBOX(ls->sub.dlg); + RND_DAD_BOOL(ls->sub.dlg); + lys->wvis = RND_DAD_CURRENT(ls->sub.dlg); + RND_DAD_SET_ATTR_FIELD(ls->sub.dlg, user_data, lys); + RND_DAD_CHANGE_CB(ls->sub.dlg, layer_vis_cb); + RND_DAD_LABEL(ls->sub.dlg, name); + lys->wlab = RND_DAD_CURRENT(ls->sub.dlg); + RND_DAD_SET_ATTR_FIELD(ls->sub.dlg, user_data, lys); + RND_DAD_CHANGE_CB(ls->sub.dlg, layer_vis_cb); + RND_DAD_RIGHT_CB(ls->sub.dlg, layer_right_cb); + RND_DAD_END(ls->sub.dlg); +} + +static void layersel_docked_create(layersel_ctx_t *ls) +{ + int n, i; /* must be signed */ + + RND_DAD_BEGIN_VBOX(ls->sub.dlg); + RND_DAD_COMPFLAG(ls->sub.dlg, RND_HATF_EXPFILL | RND_HATF_SCROLL); + + for(i = 0, n = 0; n < CSCH_DSPLY_max; n++) { + ls_layer_t *lys = &ls->layers[n]; + lys->lid = n; + lys->ls = ls; + layersel_create_layer(ls, lys, csch_dsply_name(n)); + i++; + } + RND_DAD_END(ls->sub.dlg); + RND_DAD_DEFSIZE(ls->sub.dlg, 210, 200); + RND_DAD_MINSIZE(ls->sub.dlg, 100, 100); +} + +static void layersel_update_vis(layersel_ctx_t *ls) +{ + int n; + for(n = 0; n < CSCH_DSPLY_max; n++) + lys_update_vis(&ls->layers[n]); +} + +static void layersel_build(void) +{ + layersel_docked_create(&layersel); + if (rnd_hid_dock_enter(&layersel.sub, RND_HID_DOCK_LEFT, "layersel") == 0) { + layersel.sub_inited = 1; + layersel_update_vis(&layersel); + } +} + +void sch_rnd_layersel_gui_init_ev(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + if ((RND_HAVE_GUI_ATTR_DLG) && (rnd_gui->get_menu_cfg != NULL)) { + layersel_build(); + } +} + +void sch_rnd_layersel_vis_chg_ev(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + if ((!layersel.sub_inited) || (layersel.lock_vis > 0)) + return; + layersel_update_vis(&layersel); +} Index: tags/1.0.5/src/plugins/gui/layersel.h =================================================================== --- tags/1.0.5/src/plugins/gui/layersel.h (nonexistent) +++ tags/1.0.5/src/plugins/gui/layersel.h (revision 10414) @@ -0,0 +1,5 @@ +void sch_rnd_layersel_gui_init_ev(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]); +void sch_rnd_layersel_vis_chg_ev(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]); + + + Index: tags/1.0.5/src/plugins/gui/sch_rnd_gui.c =================================================================== --- tags/1.0.5/src/plugins/gui/sch_rnd_gui.c (nonexistent) +++ tags/1.0.5/src/plugins/gui/sch_rnd_gui.c (revision 10414) @@ -0,0 +1,560 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - GUI + * Copyright (C) 2020,2022 Tibor 'Igor2' Palinkas + * (copied from camv-rnd by the author) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "layersel.h" +#include "sheetsel.h" +#include "act.h" +#include "status.h" + +#include "infobar.c" +#include "title.c" + +static const char *layersel_cookie = "sch_rnd_gui/layersel"; +static const char *sheetsel_cookie = "sch_rnd_gui/sheetsel"; +static const char *status_cookie = "sch_rnd_gui/status"; +static const char *infobar_cookie = "sch_rnd_gui/infobar"; +static const char *sch_rnd_gui_cookie = "sch_rnd_gui"; +static const char *title_cookie = "lib_hid_pcbui/title"; + +static void sch_dwg_area_edit_ev(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + csch_sheet_t *sheet = (csch_sheet_t *)hidlib; + + if (sheet->bbox_changed) { + rnd_coord_t x1, y1, x2, y2; + rnd_coord_t min_x = sch_rnd_sheet_attr_crd(sheet, "drawing_min_width", 0); + rnd_coord_t min_y = sch_rnd_sheet_attr_crd(sheet, "drawing_min_height", 0); + + sheet->bbox_changed = 0; + + + x1 = C2P(sheet->bbox.x1); + y1 = C2P(sheet->bbox.y1); + x2 = C2P(RND_MAX(min_x, sheet->bbox.x2)); + y2 = C2P(RND_MAX(min_y, sheet->bbox.y2)); + + if ((sheet->hidlib.dwg.X1 == x1) && (sheet->hidlib.dwg.Y1 == y1) && (sheet->hidlib.dwg.X2 == x2) && (sheet->hidlib.dwg.Y2 == y2)) + return; + + sch_rnd_sheet_warn_size(sheet, sheet->bbox.x1, sheet->bbox.y1, RND_MAX(min_x, sheet->bbox.x2), RND_MAX(min_y, sheet->bbox.y2)); + + sheet->hidlib.dwg.X1 = x1; + sheet->hidlib.dwg.Y1 = y1; + sheet->hidlib.dwg.X2 = x2; + sheet->hidlib.dwg.Y2 = y2; + } +} + + +#define NOGUI() \ +do { \ + if ((rnd_gui == NULL) || (!rnd_gui->gui)) { \ + RND_ACT_IRES(1); \ + return 0; \ + } \ + RND_ACT_IRES(0); \ +} while(0) + +extern csch_chdr_t *csch_obj_clicked; + +const char csch_acts_Popup[] = "Popup(MenuName, [obj-type])"; +const char csch_acth_Popup[] = "Bring up the popup menu specified by MenuName, optionally modified with the object type under the cursor.\n"; +fgw_error_t csch_act_Popup(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_design_t *hidlib = RND_ACT_DESIGN; + csch_sheet_t *sheet = (csch_sheet_t *)hidlib; + char name[256], name2[256], wnname[256]; + const char *tn = NULL, *a0, *a1 = NULL, *misc = "misc"; + int r = 1; + enum { + CTX_NONE, + CTX_OBJ_TYPE + } ctx_sens = CTX_NONE; + + NOGUI(); + + if (argc != 2 && argc != 3) + RND_ACT_FAIL(Popup); + + RND_ACT_CONVARG(1, FGW_STR, Popup, a0 = argv[1].val.str); + RND_ACT_MAY_CONVARG(2, FGW_STR, Popup, a1 = argv[2].val.str); + + *name = '\0'; + *name2 = '\0'; + + if (argc == 3) { + if (strcmp(a1, "obj-type") == 0) ctx_sens = CTX_OBJ_TYPE; + } + + if (strlen(a0) < sizeof(name) - 32) { + switch(ctx_sens) { + case CTX_OBJ_TYPE: + { + rnd_coord_t x, y; + csch_chdr_t *obj; + + rnd_hid_get_coords("context sensitive popup: select object", &x, &y, 0); + x = rnd_grid_fit(x, hidlib->grid, hidlib->grid_ox); + y = rnd_grid_fit(y, hidlib->grid, hidlib->grid_oy); + obj = sch_rnd_search_first_gui_inspect(sheet, x, y); + if (obj == NULL) { + if (rnd_point_in_box(&hidlib->dwg, x, y)) { + if (sheet->is_symbol) + strcpy(name, "/popups/symbol-as-sheet"); + else + strcpy(name, "/popups/sheet"); + misc = "none"; + } + else + tn = "none"; + } + else if (csch_obj_is_grp(obj)) { + csch_cgrp_t *grp = (csch_cgrp_t *)obj; + if (grp->srole != NULL) { + tn = ((csch_cgrp_t *)obj)->srole; + misc = "unknown-grp"; + } + else { + const char *purp = csch_attrib_get_str(&grp->attr, "purpose"); + if (purp == NULL) + purp = "unknown"; + rnd_snprintf(name, sizeof(name2), "/popups/%s-user-grp-%s", a0, purp); + misc = "user-grp-unknown"; + } + } + else { + if (obj->parent->role == CSCH_ROLE_WIRE_NET) { + sprintf(wnname, "wire-net-%s", csch_ctype_name(obj->type)); + tn = wnname; + misc = "wire-net"; + } + else + tn = csch_ctype_name(obj->type); + } + + if (*name == '\0') + rnd_snprintf(name, sizeof(name), "/popups/%s-%s", a0, tn); + rnd_snprintf(name2, sizeof(name2), "/popups/%s-%s", a0, misc); + csch_obj_clicked = obj; + } + break; + case CTX_NONE: + sprintf(name, "/popups/%s", a0); + break; + + } + } + +rnd_trace("popup: name=%s name2=%s\n", name, name2); + if (*name != '\0') + r = rnd_gui->open_popup(rnd_gui, name); + if ((r != 0) && (*name2 != '\0')) + r = rnd_gui->open_popup(rnd_gui, name2); + + RND_ACT_IRES(r); + return 0; +} + +static char *dup_cwd(void) +{ + char tmp[RND_PATH_MAX + 1]; + return rnd_strdup(rnd_get_wd(tmp)); +} + +static const char csch_acts_Load[] = "Load()\n" "Load(Project|Sheet)"; +static const char csch_acth_Load[] = "Load a project or a schematics sheet from a user-selected file."; +static fgw_error_t csch_act_Load(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + static char *last_project = NULL, *last_layer = NULL; + const char *function = "Sheet"; + char *name = NULL; + rnd_design_t *hl = RND_ACT_DESIGN; + static const char *flt_any[] = {"*", "*.*", NULL}; + + if (last_layer == NULL) last_layer = dup_cwd(); + if (last_project == NULL) last_project = dup_cwd(); + +TODO("loadfrom action"); +#if 0 + /* Called with both function and file name -> no gui */ + if (argc > 2) + return RND_ACT_CALL_C(csch_act_LoadFrom, res, argc, argv); +#else + if (argc > 2) + return -1; +#endif + + RND_ACT_MAY_CONVARG(1, FGW_STR, Load, function = argv[1].val.str); + + if (rnd_strcasecmp(function, "Sheet") == 0) { + int n, di, rem; + static const char *pat_lht[] = {"*.rs", "*.lht", NULL}; + static const char *pat_tdx[] = {"*.tdx", NULL}; + char name_tmp[32][32]; + char ext_tmp[32][32]; + char *pat_tmp[32][2]; + rnd_hid_fsd_filter_t flt[32]; + static const rnd_hid_fsd_filter_t flt1[] = { + {"lihata", "lihata", pat_lht}, + {"tEDAx", "tEDAx", pat_tdx}, + }; + static const rnd_hid_fsd_filter_t flt2[] = { + {"all", NULL, flt_any}, + {NULL, NULL, NULL} + }; + + di = sizeof(flt1)/sizeof(flt1[0]); + rem = sizeof(flt)/sizeof(flt[0]) - di - sizeof(flt2)/sizeof(flt2[0]); + memcpy(flt, flt1, sizeof(flt1)); + + for(n = 0; (n < csch_ios.used) && (rem > 0); n++) { + char *sep, *ext; + int namelen; + csch_plug_io_t *io = csch_ios.array[n]; + + if (io->load_sheet == NULL) continue; + + /* generate name */ + sep = strchr(io->name, ' '); + if (sep != NULL) { + namelen = sep - io->name; + if (namelen > 31) + namelen = 31; + } + else + namelen = 31; + strncpy(name_tmp[di], io->name, namelen); + (name_tmp[di])[namelen] = '\0'; + + if (strcmp(name_tmp[di], "lihata") == 0) continue; + if (strcmp(name_tmp[di], "tEDAx") == 0) continue; + + /* generate pattern */ + ext = ext_tmp[di]; + ext[0] = '*'; ext[1] = '.'; + strncpy(ext+2, io->ext_save_sheet, 29); + ext[31] = '\0'; + (pat_tmp[di])[0] = ext; + (pat_tmp[di])[1] = NULL; + + flt[di].name = name_tmp[di]; + flt[di].mime = name_tmp[di]; + flt[di].pat = (const char **)pat_tmp[di]; + + rem--; + di++; + } + memcpy(flt+di, flt2, sizeof(flt2)); + + name = rnd_hid_fileselect(rnd_gui, "Load sheet", "Import a sheet from file", last_layer, ".rs", flt, "sheet", RND_HID_FSD_READ, NULL); + } + else if (rnd_strcasecmp(function, "Project") == 0) { + static const char *pat_prj[] = {"project.lht", NULL}; + static const rnd_hid_fsd_filter_t flt[] = { + {"Project", "Project", pat_prj}, + {"all", NULL, flt_any}, + {NULL, NULL, NULL} + }; + name = rnd_hid_fileselect(rnd_gui, "Load a project file", "load project (all layers) from file", last_project, ".lht", flt, "project", RND_HID_FSD_READ, NULL); + } + else { + rnd_message(RND_MSG_ERROR, "Invalid subcommand for Load(): '%s'\n", function); + RND_ACT_IRES(1); + return 0; + } + + if (name != NULL) { + if (rnd_conf.rc.verbose) + fprintf(stderr, "Load: Calling LoadFrom(%s, %s)\n", function, name); + rnd_actionva(hl, "LoadFrom", function, name, NULL); + free(name); + } + + RND_ACT_IRES(0); + return 0; +} + +static int save_as(rnd_design_t *hl, int what, int as, const char *name) +{ + csch_sheet_t *sheet = (csch_sheet_t *)hl; + const char *prev_fn, *whats, *prev_loadfn; + char *free_me = NULL, *free_me2 = NULL; + int need_fsd, save_res = -1; + int append_rs = 0; + + if ((hl->fullpath != NULL) && (hl->fullpath[0] == '<')) { + as = 1; /* force save-as on */ + append_rs = 1; + } + + /* figure previous file name and whether we need to invoke FSD */ + if (as) { + if (name == NULL) { + prev_fn = sheet->hidlib.fullpath; + if (prev_fn == NULL) + prev_fn = free_me = dup_cwd(); + prev_loadfn = sheet->hidlib.loadname; + if (prev_loadfn == NULL) + prev_loadfn = prev_fn; + need_fsd = 1; + } + else { + prev_fn = name; + need_fsd = 0; + } + } + else { + prev_fn = name = sheet->hidlib.fullpath; + if (name == NULL) { + prev_fn = free_me = dup_cwd(); + need_fsd = 1; + } + else + need_fsd = 0; + + prev_loadfn = sheet->hidlib.loadname; + if (prev_loadfn == NULL) + prev_loadfn = prev_fn; + } + + if (append_rs) + prev_loadfn = free_me2 = rnd_concat(prev_loadfn, ".rs", NULL); + + /* invoke FSD if needed */ + switch(what) { + case F_Sheet: + if (need_fsd) + name = rnd_hid_fileselect(rnd_gui, "Save sheet", "Save a sheet to file", prev_loadfn, ".rs", NULL, "sheet", 0, NULL); + whats = "sheet"; + break; + case F_Project: + if (need_fsd) + name = rnd_hid_fileselect(rnd_gui, "Save a project file", "save project (all layers) to file", prev_loadfn, ".lht", NULL, "project", 0, NULL); + whats = "project"; + break; + default: + rnd_message(RND_MSG_ERROR, "Invalid first argument for Save() or SaveAs()\n"); + goto error; + } + + if (name != NULL) { /* NULL means cancel */ + if (rnd_conf.rc.verbose) + fprintf(stderr, "Save: Calling SaveTo(%s, %s)\n", whats, name); + save_res = rnd_actionva(hl, "SaveTo", whats, name, NULL); + } + else if (rnd_conf.rc.verbose) + fprintf(stderr, "Save: SaveTo(%s, ...) cancelled\n", whats); + + free(free_me); + free(free_me2); + return save_res; + + error:; + free(free_me); + free(free_me2); + return 1; +} + +static const char csch_acts_Save[] = "Save()\n" "Save(Project|Sheet)"; +static const char csch_acth_Save[] = "Save a project or a schmeatics sheet trying to preserve original file name."; +static const char csch_acts_SaveAs[] = "SaveAs(Project|Sheet, [filename])"; +static const char csch_acth_SaveAs[] = "Save a project or a schmeatics sheet using a new file name."; +static fgw_error_t csch_act_Save(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_design_t *hl = RND_ACT_DESIGN; + const char *actname = argv[0].val.func->name; + int as = (actname[4] == 'a') || (actname[4] == 'A'); + int what = F_Sheet; + const char *name = NULL; + + if (as) { + RND_ACT_MAY_CONVARG(1, FGW_KEYWORD, SaveAs, what = fgw_keyword(&argv[1])); + RND_ACT_MAY_CONVARG(2, FGW_STR, SaveAs, name = argv[2].val.cstr); + } + else + RND_ACT_MAY_CONVARG(1, FGW_KEYWORD, SaveAs, what = fgw_keyword(&argv[1])); + + RND_ACT_IRES(save_as(hl, what, as, name)); + return 0; +} + +static const char csch_acts_SwitchRelative[] = "SwitchRelative(steps)\n"; +static const char csch_acth_SwitchRelative[] = "Switch to a different sheet by traversing integer steps on the linked list of sheets loaded"; +static fgw_error_t csch_act_SwitchRelative(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + int step; + + RND_ACT_MAY_CONVARG(1, FGW_INT, SwitchRelative, step = argv[1].val.nat_int); + sch_rnd_multi_switch_to_delta(NULL, step); + RND_ACT_IRES(0); + return 0; +} + +const char csch_acts_ExportProjectDialog[] = "ExportDialog()\n"; +const char csch_acth_ExportProjectDialog[] = "Open the export dialog for exporting the project (all sheets of the project)."; +fgw_error_t csch_act_ExportProjectDialog(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + static sch_rnd_export_appspec_t appspec = {0}; + + appspec.exp_prj = 1; + rnd_dlg_export("Export project to file(s)", 1, 0, RND_ACT_DESIGN, &appspec); + return 0; +} + + +#include "edit_act.c" + +static rnd_action_t sch_rnd_gui_action_list[] = { + {"Load", csch_act_Load, csch_acth_Load, csch_acts_Load}, + {"Save", csch_act_Save, csch_acth_Save, csch_acts_Save}, + {"SaveAs", csch_act_Save, csch_acth_SaveAs, csch_acts_SaveAs}, + {"Zoom", csch_act_Zoom, csch_acth_Zoom, csch_acts_Zoom_}, + {"ZoomTo", csch_act_Zoom, csch_acth_Zoom, csch_acts_Zoom_}, + {"SwitchRelative", csch_act_SwitchRelative, csch_acth_SwitchRelative, csch_acts_SwitchRelative}, + EDIT_ACTS + {"Popup", csch_act_Popup, csch_acth_Popup, csch_acts_Popup}, + {"StatusSetText", csch_act_StatusSetText, csch_acth_StatusSetText, csch_acts_StatusSetText}, + {"ExportProjectDialog", csch_act_ExportProjectDialog, csch_acth_ExportProjectDialog, csch_acts_ExportProjectDialog}, +}; + +int pplg_check_ver_gui(int ver_needed) { return 0; } + +void pplg_uninit_gui(void) +{ + rnd_toolbar_uninit(); + rnd_event_unbind_allcookie(infobar_cookie); + rnd_event_unbind_allcookie(layersel_cookie); + rnd_event_unbind_allcookie(sheetsel_cookie); + rnd_event_unbind_allcookie(status_cookie); + rnd_event_unbind_allcookie(title_cookie); + rnd_remove_actions_by_cookie(sch_rnd_gui_cookie); + rnd_conf_hid_unreg(status_cookie); + rnd_conf_hid_unreg(infobar_cookie); +} + +static void gui_conf_val_change_post(rnd_conf_native_t *cfg, int arr_idx, void *user_data) +{ + if (strncmp(cfg->hash_path, "editor/style/tool", 17) == 0) { + /* re-activate current tool to get this applied */ + rnd_tool_chg_mode(rnd_multi_get_current()); + } +} + +static rnd_conf_hid_id_t install_events(const char *cookie, const char *paths[], rnd_conf_hid_callbacks_t cb[], void (*update_cb)(rnd_conf_native_t*,int,void*)) +{ + const char **rp; + rnd_conf_native_t *nat; + int n; + rnd_conf_hid_id_t conf_id; + static rnd_conf_hid_callbacks_t global_cb = {0}; + + global_cb.val_change_post = gui_conf_val_change_post; + + conf_id = rnd_conf_hid_reg(cookie, &global_cb); + for(rp = paths, n = 0; *rp != NULL; rp++, n++) { + memset(&cb[n], 0, sizeof(cb[0])); + cb[n].val_change_post = update_cb; + nat = rnd_conf_get_field(*rp); + if (nat != NULL) + rnd_conf_hid_set_cb(nat, conf_id, &cb[n]); + } + + return conf_id; +} + +int pplg_init_gui(void) +{ + const char *st_paths[] = {"editor/line_refraction", "editor/line_cont", "editor/rubber_band_mode", "editor/rubber_band_ortho", "editor/grid", NULL}; + const char *ibpaths[] = { "rc/file_changed_interval", NULL }; + static rnd_conf_hid_callbacks_t st_cb[sizeof(st_paths)/sizeof(st_paths[0])]; + static rnd_conf_hid_callbacks_t ibcb[sizeof(ibpaths)/sizeof(ibpaths[0])]; + + RND_API_CHK_VER; + + rnd_event_bind(RND_EVENT_GUI_INIT, sch_rnd_sheetsel_gui_init_ev, NULL, sheetsel_cookie); + rnd_event_bind(RND_EVENT_GUI_INIT, sch_rnd_layersel_gui_init_ev, NULL, layersel_cookie); + rnd_event_bind(RND_EVENT_GUI_INIT, sch_status_gui_init_ev, NULL, layersel_cookie); + rnd_event_bind(RND_EVENT_USER_INPUT_KEY, sch_status_st_update_ev, NULL, status_cookie); + rnd_event_bind(RND_EVENT_DESIGN_SET_CURRENT, sch_status_st_update_ev, NULL, status_cookie); + rnd_event_bind(CSCH_EVENT_SHEET_POSTLOAD, sch_status_postload_ev, NULL, status_cookie); + rnd_event_bind(RND_EVENT_CROSSHAIR_MOVE, sch_status_rd_update_ev, NULL, status_cookie); + rnd_event_bind(CSCH_EVENT_SHEET_EDITED, sch_status_rd_edit_ev, NULL, status_cookie); + rnd_event_bind(CSCH_EVENT_PRJ_STANCE_CHANGED, sch_status_rd_edit_ev, NULL, status_cookie); + rnd_event_bind(CSCH_EVENT_SHEET_EDITED, sch_dwg_area_edit_ev, NULL, status_cookie); + rnd_event_bind(RND_EVENT_GUI_INIT, pcb_infobar_gui_init_ev, NULL, infobar_cookie); + rnd_event_bind(RND_EVENT_DESIGN_SET_CURRENT, pcb_infobar_brdchg_ev, NULL, infobar_cookie); + rnd_event_bind(CSCH_EVENT_SHEET_POSTSAVE, pcb_infobar_postsave_ev, NULL, infobar_cookie); + rnd_event_bind(CSCH_EVENT_SHEET_POSTLOAD, pcb_infobar_postload_ev, NULL, infobar_cookie); + rnd_event_bind(CSCH_EVENT_PRJ_VIEW_ACTIVATED, sch_status_view_activated_ev, NULL, infobar_cookie); + rnd_event_bind(RND_EVENT_DESIGN_SET_CURRENT, sch_title_board_changed_ev, NULL, title_cookie); + rnd_event_bind(RND_EVENT_DESIGN_SET_CURRENT, sch_sheetsel_board_changed_ev, NULL, sheetsel_cookie); + rnd_event_bind(RND_EVENT_DESIGN_FN_CHANGED, sch_title_board_changed_ev, NULL, title_cookie); + rnd_event_bind(RND_EVENT_DESIGN_META_CHANGED, sch_title_meta_changed_ev, NULL, title_cookie); + rnd_event_bind(RND_EVENT_DESIGN_META_CHANGED, sch_sheetsel_meta_changed_ev, NULL, title_cookie); + rnd_event_bind(RND_EVENT_GUI_INIT, sch_title_gui_init_ev, NULL, title_cookie); + rnd_event_bind(RND_EVENT_LOAD_POST, sch_sheetsel_load_post_ev, NULL, sheetsel_cookie); + rnd_event_bind(RND_EVENT_DESIGN_FN_CHANGED, sch_sheetsel_fn_changed_ev, NULL, sheetsel_cookie); + rnd_event_bind(CSCH_EVENT_SHEET_POSTUNLOAD, sch_sheetsel_unload_post_ev, NULL, sheetsel_cookie); + rnd_event_bind(CSCH_EVENT_LAYERVIS_CHANGED, sch_rnd_layersel_vis_chg_ev, NULL, layersel_cookie); + + RND_REGISTER_ACTIONS(sch_rnd_gui_action_list, sch_rnd_gui_cookie); + + install_events(status_cookie, st_paths, st_cb, sch_status_st_update_conf); + install_events(infobar_cookie, ibpaths, ibcb, pcb_infobar_update_conf); + + rnd_toolbar_init(); + return 0; +} Index: tags/1.0.5/src/plugins/gui/sheetsel.c =================================================================== --- tags/1.0.5/src/plugins/gui/sheetsel.c (nonexistent) +++ tags/1.0.5/src/plugins/gui/sheetsel.c (revision 10414) @@ -0,0 +1,261 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - GUI + * Copyright (C) 2022,2023,2024 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022, Entrust in 2023,2024) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include + +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include "sheetsel.h" + +const char sheetsel_tooltip[] = + "A list of all projects/sheets currently open\n" + "\nProject marks:\n" + " [e] explicit (project.lht lists sheet files)\n" + " [i] implicit (no sheet list in project.lht)\n" + " P! partial (not all root sheets are loaded)\n" + "\nSheet marks:\n" + " * unsaved changes\n" + " [R] root sheet (directly compiled)\n" + " [a] aux sheet (referenced from hierarchy)\n" + " [u] unlisted sheet (in the same dir)\n" + " [E] external (unlisted, loaded for hierarchy)\n" + " [?] unknown/undecided sheet state\n"; + +typedef struct sheetsel_ctx_s sheetsel_ctx_t; +struct sheetsel_ctx_s { + rnd_hid_dad_subdialog_t sub; + int sub_inited, lock; + int wtree; +}; + +static sheetsel_ctx_t sheetsel; + +static const char *sheet_marks(csch_project_t *prj, csch_sheet_t *sheet) +{ + switch(sheet->stype) { + case CSCH_SHTY_unknown: return " [?]"; + case CSCH_SHTY_AUX: return " [a]"; + case CSCH_SHTY_ROOT: return " [R]"; + case CSCH_SHTY_UNLISTED: return " [u]"; + case CSCH_SHTY_EXTERNAL: return " [E]"; + } + return " [??]"; +} + +static void sheetsel_prj2dlg(sheetsel_ctx_t *ss) +{ + rnd_hid_attribute_t *attr = &ss->sub.dlg[ss->wtree]; + rnd_hid_tree_t *tree = attr->wdata; + rnd_hid_row_t *r, *rprj; + htsp_entry_t *e; + char *cell[2], *changed; + + /* remove existing items */ + rnd_dad_tree_clear(tree); + + /* add all items */ + cell[1] = NULL; + for(e = htsp_first(&rnd_projects); e != NULL; e = htsp_next(&rnd_projects, e)) { + long n; + csch_project_t *prj = e->value; + char *end; + gds_t tmp = {0}; + const char *bn = rnd_parent_dir_name(e->key); + + gds_append_str(&tmp, bn); + if (tmp.array != NULL) { + end = strchr(tmp.array, '/'); + if (end != NULL) + tmp.used = end - tmp.array; + } + else + rnd_message(RND_MSG_ERROR, "Internal error: empty project name (please report this bug)\n"); + + if ((prj->hdr.fullpath == NULL) || ((prj->num_root_sheets == 0) && (prj->num_aux_sheets == 0))) + gds_append_str(&tmp, " [i]"); + else + gds_append_str(&tmp, " [e]"); + + if (csch_project_is_partial(prj)) + gds_append_str(&tmp, " P!"); + + cell[0] = tmp.array; + rprj = rnd_dad_tree_append(attr, NULL, cell); + rprj->user_data = NULL; + + for(n = 0; n < prj->hdr.designs.used; n++) { + csch_sheet_t *sheet = prj->hdr.designs.array[n]; + const char *marks; + + if (sheet->hidlib.loadname != NULL) { + bn = strrchr(sheet->hidlib.loadname, '/'); + if (bn != NULL) + bn++; + else + bn = sheet->hidlib.loadname; + } + else + bn = ""; + + changed = (sheet->changed ? "*" : NULL); + if (prj->hdr.fullpath == NULL) + marks = " [u]"; + else + marks = sheet_marks(prj, sheet); + + cell[0] = rnd_concat(bn, marks, changed, NULL); + r = rnd_dad_tree_append_under(attr, rprj, cell); + r->user_data = sheet; + } + } + + rnd_dad_tree_expcoll(attr, NULL, 1, 1); + +} + +static void sheetsel_select_current(sheetsel_ctx_t *ss) +{ + rnd_hid_attribute_t *attr = &ss->sub.dlg[ss->wtree]; + rnd_hid_tree_t *tree = attr->wdata; + rnd_design_t *curr = rnd_multi_get_current(); + rnd_hid_row_t *r, *actr = NULL; + htsp_entry_t *e; + + for(e = htsp_first(&tree->paths); e != NULL; e = htsp_next(&tree->paths, e)) { + r = e->value; + if (r->user_data == curr) + actr = e->value; + } + + /* set cursor to currently active sheet */ + if (actr != NULL) { + rnd_hid_attr_val_t hv; + hv.str = actr->path; + rnd_gui->attr_dlg_set_value(ss->sub.dlg_hid_ctx, ss->wtree, &hv); + } +} + + +static void sheetsel_select_cb(rnd_hid_attribute_t *attrib, void *hid_ctx, rnd_hid_row_t *row) +{ + rnd_hid_tree_t *tree = attrib->wdata; + sheetsel_ctx_t *ctx = tree->user_ctx; + + if ((row == NULL) || (row->user_data == NULL)) + return; + + ctx->lock++; + sch_rnd_multi_switch_to(row->user_data); + ctx->lock--; +} + +static void sheetsel_docked_create(sheetsel_ctx_t *ss) +{ + RND_DAD_BEGIN_VBOX(ss->sub.dlg); + RND_DAD_COMPFLAG(ss->sub.dlg, RND_HATF_EXPFILL); + + RND_DAD_TREE(ss->sub.dlg, 1, 1, NULL); + RND_DAD_COMPFLAG(ss->sub.dlg, RND_HATF_EXPFILL | RND_HATF_SCROLL | RND_HATF_TREE_NO_AUTOEXP); + RND_DAD_TREE_SET_CB(ss->sub.dlg, selected_cb, sheetsel_select_cb); + RND_DAD_TREE_SET_CB(ss->sub.dlg, ctx, ss); + ss->wtree = RND_DAD_CURRENT(ss->sub.dlg); + RND_DAD_HELP(ss->sub.dlg, sheetsel_tooltip); + + RND_DAD_END(ss->sub.dlg); + RND_DAD_DEFSIZE(ss->sub.dlg, 210, 200); + RND_DAD_MINSIZE(ss->sub.dlg, 100, 100); +} + + +static void sheetsel_build(void) +{ + sheetsel_docked_create(&sheetsel); + if (rnd_hid_dock_enter(&sheetsel.sub, RND_HID_DOCK_LEFT, "sheetsel") == 0) { + sheetsel.sub_inited = 1; + sheetsel_prj2dlg(&sheetsel); + sheetsel_select_current(&sheetsel); + } +} + +void sch_rnd_sheetsel_gui_init_ev(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + if ((RND_HAVE_GUI_ATTR_DLG) && (rnd_gui->get_menu_cfg != NULL)) + sheetsel_build(); +} + +void sch_sheetsel_board_changed_ev(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + if (sheetsel.sub_inited && !sheetsel.lock) + sheetsel_select_current(&sheetsel); +} + +void sch_sheetsel_load_post_ev(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + if (sheetsel.sub_inited && !sheetsel.lock) { + sheetsel_prj2dlg(&sheetsel); + sheetsel_select_current(&sheetsel); + } +} + +void sch_sheetsel_unload_post_ev(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + sch_sheetsel_load_post_ev(hidlib, user_data, argc, argv); +} + +void sch_sheetsel_meta_changed_ev(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + sch_sheetsel_load_post_ev(hidlib, user_data, argc, argv); +} + +void sch_sheetsel_fn_changed_ev(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + if (sheetsel.sub_inited && !sheetsel.lock) { + sheetsel_prj2dlg(&sheetsel); + sheetsel_select_current(&sheetsel); + } +} + Index: tags/1.0.5/src/plugins/gui/sheetsel.h =================================================================== --- tags/1.0.5/src/plugins/gui/sheetsel.h (nonexistent) +++ tags/1.0.5/src/plugins/gui/sheetsel.h (revision 10414) @@ -0,0 +1,6 @@ +void sch_rnd_sheetsel_gui_init_ev(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]); +void sch_sheetsel_board_changed_ev(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]); +void sch_sheetsel_load_post_ev(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]); +void sch_sheetsel_unload_post_ev(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]); +void sch_sheetsel_meta_changed_ev(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]); +void sch_sheetsel_fn_changed_ev(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]); Index: tags/1.0.5/src/plugins/gui/status.c =================================================================== --- tags/1.0.5/src/plugins/gui/status.c (nonexistent) +++ tags/1.0.5/src/plugins/gui/status.c (revision 10414) @@ -0,0 +1,340 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - GUI + * Copyright (C) 2021,2022 Tibor 'Igor2' Palinkas + * (originally copied from camv-rnd by the author) + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "sch-rnd/conf_core.h" +#include "sch-rnd/crosshair.h" +#include "sch-rnd/draw.h" +#include "sch-rnd/buffer.h" +#include "sch-rnd/multi.h" + +typedef struct { + int active; + rnd_hid_dad_subdialog_t stsub, rdsub; /* st is for the bottom status line, rd is for the top readouts */ + int stsub_inited, rdsub_inited; + int wst, wsttxt, wcomp_chk, wcomp_btn, wcomp_bar; + int st_has_text; + int wrdunit, wrd[3]; + int wviewbtn; + gds_t buf; /* save on allocation */ + int lock; + rnd_hidval_t acomp_timer; + unsigned acomp_timer_active:1; + unsigned acomp_timer_want:1; +} status_ctx_t; + +static status_ctx_t status; + +#include "autocomp.c" + +static void status_st_sch2dlg(rnd_design_t *dsg) +{ + rnd_hid_cfg_keys_t *kst = rnd_gui->key_state; + static rnd_hid_attr_val_t hv; + char kbd[128]; + const char *cnt, *refr, *rubber; + csch_coord_t grid = (dsg != NULL) ? dsg->grid : 0; + + if (!status.stsub_inited) + return; + + status.buf.used = 0; + + cnt = conf_core.editor.line_cont ? "C," : ""; + refr = conf_core.editor.line_refraction ? "|_" : "_|"; + if (conf_core.editor.rubber_band_mode) + rubber = conf_core.editor.rubber_band_ortho ? ",RL" : ",R"; + else + rubber = " "; + + if (kst != NULL) { + if (kst->seq_len_action > 0) { + int len; + memcpy(kbd, "(last: ", 7); + len = rnd_hid_cfg_keys_seq(kst, kbd+7, sizeof(kbd)-9); + memcpy(kbd+len+7, ")", 2); + } + else + rnd_hid_cfg_keys_seq(kst, kbd, sizeof(kbd)); + } + else + *kbd = '\0'; + + rnd_append_printf(&status.buf, "grid=%$rc line=%s%s%s kbd=%s", + P2C(grid), + cnt, refr, rubber, + kbd); + hv.str = status.buf.array; + rnd_gui->attr_dlg_set_value(status.stsub.dlg_hid_ctx, status.wst, &hv); +} + +static void status_rd_sch2dlg(void) +{ + static rnd_hid_attr_val_t hv; + + if ((status.lock) || (!status.rdsub_inited)) + return; + + /* coordinate readout (right side box) */ + status.buf.used = 0; + hv.str = status.buf.array; + + rnd_append_printf(&status.buf, "%$rc", P2C(sch_rnd_crosshair_x)); + rnd_gui->attr_dlg_set_value(status.rdsub.dlg_hid_ctx, status.wrd[0], &hv); + status.buf.used = 0; + rnd_append_printf(&status.buf, "%$rc", P2C(sch_rnd_crosshair_y)); + rnd_gui->attr_dlg_set_value(status.rdsub.dlg_hid_ctx, status.wrd[1], &hv); + + if (status.rdsub.dlg[status.wcomp_chk].val.lng) { + rnd_gui->attr_dlg_widget_hide(status.rdsub.dlg_hid_ctx, status.wcomp_btn, 1); + rnd_gui->attr_dlg_widget_hide(status.rdsub.dlg_hid_ctx, status.wcomp_bar, 0); + } + else { + rnd_gui->attr_dlg_widget_hide(status.rdsub.dlg_hid_ctx, status.wcomp_btn, 0); + rnd_gui->attr_dlg_widget_hide(status.rdsub.dlg_hid_ctx, status.wcomp_bar, 1); + } +} + +void status_activate_view(rnd_design_t *hidlib) +{ + rnd_hid_attr_val_t hv; + csch_sheet_t *sheet = (csch_sheet_t *)hidlib; + csch_project_t *prj; + csch_view_t *v; + + if (!status.active && (sheet != NULL)) + return; + + prj = (csch_project_t *)sheet->hidlib.project; + if (prj->curr < prj->views.used) { + v = prj->views.array[prj->curr]; + hv.str = v->fgw_ctx.name; + } + else + hv.str = "N/A"; + rnd_gui->attr_dlg_set_value(status.rdsub.dlg_hid_ctx, status.wviewbtn, &hv); +} + +static void status_docked_create_st(void) +{ + RND_DAD_BEGIN_VBOX(status.stsub.dlg); + RND_DAD_COMPFLAG(status.stsub.dlg, RND_HATF_EXPFILL | RND_HATF_TIGHT); + RND_DAD_LABEL(status.stsub.dlg, ""); + RND_DAD_COMPFLAG(status.stsub.dlg, RND_HATF_HIDE); + status.wsttxt = RND_DAD_CURRENT(status.stsub.dlg); + RND_DAD_LABEL(status.stsub.dlg, ""); + status.wst = RND_DAD_CURRENT(status.stsub.dlg); + RND_DAD_END(status.stsub.dlg); +} + +/* append an expand-vbox to eat up excess space for center-align */ +static void vpad(rnd_hid_dad_subdialog_t *sub) +{ + RND_DAD_BEGIN_VBOX(sub->dlg); + RND_DAD_COMPFLAG(sub->dlg, RND_HATF_EXPFILL | RND_HATF_TIGHT); + RND_DAD_END(sub->dlg); +} + +static void autocomp_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + status_rd_sch2dlg(); + if (status.rdsub.dlg[status.wcomp_chk].val.lng) + autocomp_restart_timer(rnd_multi_get_current()); + else + autocomp_stop_timer(rnd_multi_get_current()); +} + +static void btn_compile_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + rnd_actionva(rnd_multi_get_current(), "CompileProject", NULL); + rnd_gui->invalidate_all(rnd_gui); + TODO("fetch return value and print error or succes (info) - rather do it in the action: there are other places this is called from as well"); +} + + +static void btn_viewchg_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + rnd_actionva(rnd_gui->get_dad_design(hid_ctx), "ViewDialog", NULL); +} + +static void btn_support_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + rnd_actionva(rnd_gui->get_dad_design(hid_ctx), "irc", NULL); +} + +static void status_docked_create_rd(rnd_design_t *hidlib) +{ + int n; + const char **support_icon = rnd_dlg_xpm_by_name("online_help"); + + RND_DAD_BEGIN_HBOX(status.rdsub.dlg); + RND_DAD_COMPFLAG(status.rdsub.dlg, RND_HATF_TIGHT); + + /* compile block */ + RND_DAD_BEGIN_VBOX(status.rdsub.dlg); + RND_DAD_COMPFLAG(status.rdsub.dlg, RND_HATF_FRAME | RND_HATF_TIGHT); + RND_DAD_BEGIN_HBOX(status.rdsub.dlg); + RND_DAD_BOOL(status.rdsub.dlg); + RND_DAD_HELP(status.rdsub.dlg, "Enable timed auto-compile:\nautomatically compile current view after a short delay after\nchanges to the sheet"); + status.wcomp_chk = RND_DAD_CURRENT(status.rdsub.dlg); + RND_DAD_CHANGE_CB(status.rdsub.dlg, autocomp_cb); + RND_DAD_BUTTON(status.rdsub.dlg, "Compile"); + RND_DAD_HELP(status.rdsub.dlg, "Recompile the abstract model\nusing all sheets of the current project"); + RND_DAD_CHANGE_CB(status.rdsub.dlg, btn_compile_cb); + status.wcomp_btn = RND_DAD_CURRENT(status.rdsub.dlg); + RND_DAD_PROGRESS(status.rdsub.dlg); + RND_DAD_COMPFLAG(status.rdsub.dlg, RND_HATF_PRG_SMALL); + status.wcomp_bar = RND_DAD_CURRENT(status.rdsub.dlg); + + RND_DAD_END(status.rdsub.dlg); + RND_DAD_BEGIN_HBOX(status.rdsub.dlg); + RND_DAD_COMPFLAG(status.rdsub.dlg, RND_HATF_EXPFILL); + RND_DAD_BUTTON(status.rdsub.dlg, ""); + RND_DAD_COMPFLAG(status.rdsub.dlg, RND_HATF_EXPFILL); + RND_DAD_HELP(status.rdsub.dlg, "Which of the project configured views is used for compilation\nand in turn for rendering display/ attributes"); + RND_DAD_CHANGE_CB(status.rdsub.dlg, btn_viewchg_cb); + status.wviewbtn = RND_DAD_CURRENT(status.rdsub.dlg); + RND_DAD_END(status.rdsub.dlg); + RND_DAD_END(status.rdsub.dlg); + + RND_DAD_PICBUTTON(status.rdsub.dlg, support_icon); + RND_DAD_CHANGE_CB(status.rdsub.dlg, btn_support_cb); + RND_DAD_BEGIN_VBOX(status.rdsub.dlg); + RND_DAD_COMPFLAG(status.rdsub.dlg, RND_HATF_EXPFILL | RND_HATF_FRAME | RND_HATF_TIGHT); + vpad(&status.rdsub); + for(n = 0; n < 3; n++) { + RND_DAD_LABEL(status.rdsub.dlg, ""); + status.wrd[n] = RND_DAD_CURRENT(status.rdsub.dlg); + } + RND_DAD_END(status.rdsub.dlg); + RND_DAD_END(status.rdsub.dlg); +} + +static void status_rd_init() +{ + if (conf_core.editor.autocomp) { + rnd_hid_attr_val_t hv; + hv.lng = 1; + rnd_gui->attr_dlg_set_value(status.rdsub.dlg_hid_ctx, status.wcomp_chk, &hv); + autocomp_cb(NULL, NULL, NULL); + } +} + +void sch_status_gui_init_ev(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + if ((RND_HAVE_GUI_ATTR_DLG) && (rnd_gui->get_menu_cfg != NULL)) { + status_docked_create_st(); + if (rnd_hid_dock_enter(&status.stsub, RND_HID_DOCK_BOTTOM, "status") == 0) { + status.stsub_inited = 1; + status_st_sch2dlg(hidlib); + } + + status_docked_create_rd(hidlib); + if (rnd_hid_dock_enter(&status.rdsub, RND_HID_DOCK_TOP_RIGHT, "readout") == 0) { + status.rdsub_inited = 1; + status_rd_init(); + status_rd_sch2dlg(); + } + status.active = 1; + status_activate_view(hidlib); + } +} + +void sch_status_st_update_conf(rnd_conf_native_t *cfg, int arr_idx, void *user_data) +{ + status_st_sch2dlg(rnd_multi_get_current()); +} + +void sch_status_st_update_ev(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + status_st_sch2dlg(rnd_multi_get_current()); +} + +void sch_status_rd_update_ev(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + status_rd_sch2dlg(); +} + +void sch_status_rd_edit_ev(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + if (status.active && status.rdsub.dlg[status.wcomp_chk].val.lng) + autocomp_restart_timer(hidlib); +} + +void sch_status_view_activated_ev(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + status_activate_view(hidlib); +} + +void sch_status_postload_ev(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + if (status.active && status.rdsub.dlg[status.wcomp_chk].val.lng) + autocomp_restart_timer(hidlib); +} + +const char csch_acts_StatusSetText[] = "StatusSetText([text])\n"; +const char csch_acth_StatusSetText[] = "Replace status printout with text temporarily; turn status printout back on if text is not provided."; +fgw_error_t csch_act_StatusSetText(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *text = NULL; + + if (argc > 2) + RND_ACT_FAIL(StatusSetText); + + RND_ACT_MAY_CONVARG(1, FGW_STR, StatusSetText, text = argv[1].val.str); + + if (text != NULL) { + rnd_hid_attr_val_t hv; + hv.str = text; + rnd_gui->attr_dlg_set_value(status.stsub.dlg_hid_ctx, status.wsttxt, &hv); + rnd_gui->attr_dlg_widget_hide(status.stsub.dlg_hid_ctx, status.wsttxt, 0); + rnd_gui->attr_dlg_widget_hide(status.stsub.dlg_hid_ctx, status.wst, 1); + status.st_has_text = 1; + } + else { + status.st_has_text = 0; + rnd_gui->attr_dlg_widget_hide(status.stsub.dlg_hid_ctx, status.wst, 0); + rnd_gui->attr_dlg_widget_hide(status.stsub.dlg_hid_ctx, status.wsttxt, 1); + } + + RND_ACT_IRES(0); + return 0; +} Index: tags/1.0.5/src/plugins/gui/status.h =================================================================== --- tags/1.0.5/src/plugins/gui/status.h (nonexistent) +++ tags/1.0.5/src/plugins/gui/status.h (revision 10414) @@ -0,0 +1,12 @@ +void sch_status_gui_init_ev(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]); +void sch_status_st_update_conf(rnd_conf_native_t *cfg, int arr_idx, void *user_data); +void sch_status_st_update_ev(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]); +void sch_status_rd_update_ev(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]); +void sch_status_rd_edit_ev(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]); +void sch_status_view_activated_ev(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]); +void sch_status_postload_ev(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]); + +extern const char csch_acts_StatusSetText[]; +extern const char csch_acth_StatusSetText[]; +extern fgw_error_t csch_act_StatusSetText(fgw_arg_t *res, int argc, fgw_arg_t *argv); + Index: tags/1.0.5/src/plugins/gui/title.c =================================================================== --- tags/1.0.5/src/plugins/gui/title.c (nonexistent) +++ tags/1.0.5/src/plugins/gui/title.c (revision 10414) @@ -0,0 +1,83 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - GUI + * Copyright (C) 2019,2022 Tibor 'Igor2' Palinkas - in pcb-rnd + * Copyright (C) 2022 Tibor 'Igor2' Palinkas - tuned for sch-rnd + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include + +#include + +#include + +static gds_t title_buf; +static int gui_inited = 0, brd_changed; + +static void update_title(rnd_design_t *hl, int changed, int is_symbol) +{ + const char *filename, *name; + + if ((rnd_gui == NULL) || (rnd_gui->set_top_title == NULL) || (!gui_inited)) + return; + + /* change title only if current sheet's changed */ + if (rnd_multi_get_current() != hl) + return; + + if ((hl->name == NULL) || (*hl->name == '\0')) + name = "Unnamed"; + else + name = hl->name; + + if ((hl->fullpath == NULL) || (*hl->fullpath == '\0')) + filename = ""; + else + filename = hl->fullpath; + + title_buf.used = 0; + rnd_append_printf(&title_buf, "%s%s (%s) - %s - sch-rnd", changed ? "*" : "", name, filename, is_symbol ? "symbol" : "sheet"); + rnd_gui->set_top_title(rnd_gui, title_buf.array); +} + +static void sch_title_board_changed_ev(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + csch_sheet_t *pcb = (csch_sheet_t *)hidlib; + brd_changed = 0; + update_title(hidlib, pcb->changed, pcb->is_symbol); +} + +static void sch_title_meta_changed_ev(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + csch_sheet_t *pcb = (csch_sheet_t *)hidlib; + brd_changed = pcb->changed; + update_title(hidlib, pcb->changed, pcb->is_symbol); +} + +static void sch_title_gui_init_ev(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + csch_sheet_t *pcb = (csch_sheet_t *)hidlib; + gui_inited = 1; + update_title(hidlib, pcb->changed, pcb->is_symbol); +} + Index: tags/1.0.5/src/plugins/hlibrary_fs/Makefile =================================================================== --- tags/1.0.5/src/plugins/hlibrary_fs/Makefile (nonexistent) +++ tags/1.0.5/src/plugins/hlibrary_fs/Makefile (revision 10414) @@ -0,0 +1,2 @@ +all: + cd ../../sch-rnd && make mod_hlibrary_fs Index: tags/1.0.5/src/plugins/hlibrary_fs/Plug.tmpasm =================================================================== --- tags/1.0.5/src/plugins/hlibrary_fs/Plug.tmpasm (nonexistent) +++ tags/1.0.5/src/plugins/hlibrary_fs/Plug.tmpasm (revision 10414) @@ -0,0 +1,10 @@ +put /local/rnd/mod {hlibrary_fs} +put /local/rnd/mod/OBJS [@ + $(PLUGDIR)/hlibrary_fs/hlibrary_fs.o +@] + +switch /local/module/hlibrary_fs/controls + case {buildin} include /local/csch/tmpasm/buildin; end; + case {plugin} include /local/csch/tmpasm/plugin; end; + case {disable} include /local/csch/tmpasm/disable; end; +end Index: tags/1.0.5/src/plugins/hlibrary_fs/hlibrary_fs.c =================================================================== --- tags/1.0.5/src/plugins/hlibrary_fs/hlibrary_fs.c (nonexistent) +++ tags/1.0.5/src/plugins/hlibrary_fs/hlibrary_fs.c (revision 10414) @@ -0,0 +1,132 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - library of hierarchic child sheets (from the local file system) + * Copyright (C) 2024 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust in 2024) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +static csch_lib_backend_t be_hlibrary_fs; + +static char *hlibrary_fs_realpath(rnd_design_t *hl, const char *root) +{ + /* accept only non-prefixed paths */ + if (strchr(root, '@') != NULL) + return NULL; + + return csch_lib_fs_realpath(hl, root); +} + +csch_lib_type_t hlibrary_fs_file_type(rnd_design_t *hl, const char *fn) +{ + int res; + + res = csch_test_parse_fn(hl, fn, CSCH_IOTYP_SHEET); + if (res == 1) + return CSCH_SLIB_STATIC; + + return CSCH_SLIB_invalid; +} + +static int hlibrary_fs_map(rnd_design_t *hl, csch_lib_t *root_dir) +{ + gds_t tmp = {0}; + gds_append_str(&tmp, root_dir->realpath); + csch_lib_fs_map(hl, &be_hlibrary_fs, root_dir, &tmp, hlibrary_fs_file_type); + gds_uninit(&tmp); + return 0; +} + +static int hlibrary_fs_load(csch_sheet_t *sheet, void *dst_, csch_lib_t *src, const char *params) +{ + csch_sheet_t *dst = dst_; + csch_cgrp_t *grp = NULL; + + switch(src->type) { + case CSCH_SLIB_PARAMETRIC: + rnd_message(RND_MSG_ERROR, "hlibrary_fs_load(): can't handle parametric\n"); + return -1; + + case CSCH_SLIB_STATIC: + TODO("call the loader?"); +/* grp = csch_load_grp(dst, src->realpath, NULL);*/ + return -1; + break; + + case CSCH_SLIB_invalid: + case CSCH_SLIB_DIR: + return -1; + } + + if (grp == NULL) + return -1; + + grp->sym_prefer_loclib = 1; + csch_cgrp_render_all(dst, &dst->direct); + csch_cobj_update(dst, &dst->direct.hdr, 1); + + return 0; +} + +static void hlibrary_fs_free(csch_lib_t *src) +{ +} + + +int pplg_check_ver_hlibrary_fs(int ver_needed) { return 0; } + +void pplg_uninit_hlibrary_fs(void) +{ + +} + +int pplg_init_hlibrary_fs(void) +{ + RND_API_CHK_VER; + + be_hlibrary_fs.name = "hlibrary_fs"; + be_hlibrary_fs.realpath = hlibrary_fs_realpath; + be_hlibrary_fs.map = hlibrary_fs_map; + be_hlibrary_fs.load = hlibrary_fs_load; /* loads a group into dst sheet */ + be_hlibrary_fs.free = hlibrary_fs_free; + + csch_lib_backend_reg(csch_lib_get_master("hlibrary", 1), &be_hlibrary_fs); + + return 0; +} + Index: tags/1.0.5/src/plugins/hlibrary_fs/hlibrary_fs.pup =================================================================== --- tags/1.0.5/src/plugins/hlibrary_fs/hlibrary_fs.pup (nonexistent) +++ tags/1.0.5/src/plugins/hlibrary_fs/hlibrary_fs.pup (revision 10414) @@ -0,0 +1,7 @@ +$class symlib +$short hierarchic sheets (file system) +$long access libraries of hierarchic child sheets stored on the local file system +$state works +$package (core) +default buildin +autoload 1 Index: tags/1.0.5/src/plugins/io_altium/Makefile =================================================================== --- tags/1.0.5/src/plugins/io_altium/Makefile (nonexistent) +++ tags/1.0.5/src/plugins/io_altium/Makefile (revision 10414) @@ -0,0 +1,14 @@ +all: binlen2txt + cd ../../sch-rnd && make mod_io_altium + +include ../../../Makefile.conf +include $(LIBRND_MAK) + +L_CFLAGS=-g -I$(LIBRND_INCDIR) -I$(LIBRND_INCDIR)/librnd/src_3rd +L_LDLIBS=-lrnd-3rd + +binlen2txt: binlen2txt.o + $(CC) -o binlen2txt binlen2txt.o $(L_LDFLAGS) $(L_LDLIBS) + +binlen2txt.o: binlen2txt.c + $(CC) -c -o binlen2txt.o $(L_CFLAGS) binlen2txt.c Index: tags/1.0.5/src/plugins/io_altium/Plug.tmpasm =================================================================== --- tags/1.0.5/src/plugins/io_altium/Plug.tmpasm (nonexistent) +++ tags/1.0.5/src/plugins/io_altium/Plug.tmpasm (revision 10414) @@ -0,0 +1,20 @@ +put /local/rnd/mod {io_altium} +put /local/rnd/mod/OBJS [@ + $(PLUGDIR)/io_altium/io_altium.o + $(PLUGDIR)/io_altium/read.o + $(PLUGDIR)/io_altium/pcbdoc_ascii.o + $(PLUGDIR)/io_altium/altium_kw_sphash.o +@] + +put /local/rnd/mod/CONFFILE {io_altium.conf} +put /local/rnd/mod/CONF {$(PLUGDIR)/io_altium/io_altium_conf.h} +put /local/rnd/mod/CONFVAR {io_altium_conf_internal} + +put /local/rnd/mod/SPHASH {$(PLUGDIR)/io_altium/altium_kw.sphash} +put /local/rnd/mod/SPHASH_ARGS {--prefix altium_kw --multi -i} + +switch /local/module/io_altium/controls + case {buildin} include /local/csch/tmpasm/buildin; end; + case {plugin} include /local/csch/tmpasm/plugin; end; + case {disable} include /local/csch/tmpasm/disable; end; +end Index: tags/1.0.5/src/plugins/io_altium/altium_kw.sphash =================================================================== --- tags/1.0.5/src/plugins/io_altium/altium_kw.sphash (nonexistent) +++ tags/1.0.5/src/plugins/io_altium/altium_kw.sphash (revision 10414) @@ -0,0 +1,92 @@ +record + misc + header + 1 + 2 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 + 17 + 18 + 22 + 25 + 27 + 28 + 29 + 31 + 32 + 33 + 34 + 39 + 41 + 43 + 209 +field + alignment + areacolor + arrowkind + borderon + cornerxradius + corneryradius + cornerxradius_frac + corneryradius_frac + corner.x + corner.y + corner.x_frac + corner.y_frac + currentpartid + custommarginwidth + customx + customy + designator + distancefromtop + electrical + endangle + header + height + iotype + ishidden + issolid + justification + linewidth + locationcount + location.x + location.y + location.x_frac + location.y_frac + name + orientation + ownerpartdisplaymode + ownerpartid + ownerindex + pinconglomerate + pinlength + pinlength_frac + radius + radius_frac + secondaryradius + secondaryradius_frac + side + sheetstyle + showborder + startangle + style + symbol_inner + symbol_inneredge + symbol_outer + symbol_outeredge + text + usecustomsheet + width + xsize + ysize Index: tags/1.0.5/src/plugins/io_altium/binlen2txt.c =================================================================== --- tags/1.0.5/src/plugins/io_altium/binlen2txt.c (nonexistent) +++ tags/1.0.5/src/plugins/io_altium/binlen2txt.c (revision 10414) @@ -0,0 +1,91 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - altium format support + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/* Extract lines from an almost-ascii-doc extracted from a cdf; the file + contains of lines, each starting with a 4 byte long binary length field + followed by a nul-terminated string */ + +#include + +#include "binlen2txt.h" + +int binlen2txt_readline(vts0_t *dst, int (*read_cb)(void *ctx, void *dst, long len), void *ctx) +{ + unsigned long len; + unsigned char raw_len[4]; + + if (read_cb(ctx, raw_len, 4) != 0) + return -1; + + /* length is 4 bytes LSB */ + len = ((unsigned long)raw_len[3]) << 24 | ((unsigned long)raw_len[2]) << 16 | ((unsigned long)raw_len[1]) << 8 | ((unsigned long)raw_len[0]); + + dst->used = 0; + vts0_enlarge(dst, len); + if (dst->alloced < len) + return -1; + + if (read_cb(ctx, dst->array, len) != 0) + return -1; + + dst->array[len] = '\0'; + + return 0; +} + + + +#ifndef BINLEN_NO_MAIN + +static int read_cb(void *ctx, void *dst, long len) +{ + if (fread(dst, len, 1, (FILE *)ctx) == 1) + return 0; + return -1; +} + +int main(int argc, char *argv[]) +{ + vts0_t lin = {0}; + FILE *f; + + if (argc > 1) { + f = fopen(argv[1], "r"); + if (f == NULL) { + fprintf(stderr, "Error: failed to open '%s' for read\n", argv[1]); + return 1; + } + } + else + f = stdin; + + while(binlen2txt_readline(&lin, read_cb, f) == 0) + printf("%s\n", lin.array); + vts0_uninit(&lin); +} +#endif Index: tags/1.0.5/src/plugins/io_altium/binlen2txt.h =================================================================== --- tags/1.0.5/src/plugins/io_altium/binlen2txt.h (nonexistent) +++ tags/1.0.5/src/plugins/io_altium/binlen2txt.h (revision 10414) @@ -0,0 +1,9 @@ +#include + + +/* Read the next line into dst (overwriting the string there); + read_cb() is caller provided low level reader, should return + 0 on success (all bytes read). */ +int binlen2txt_readline(vts0_t *dst, int (*read_cb)(void *ctx, void *dst, long len), void *ctx); + + Index: tags/1.0.5/src/plugins/io_altium/io_altium.c =================================================================== --- tags/1.0.5/src/plugins/io_altium/io_altium.c (nonexistent) +++ tags/1.0.5/src/plugins/io_altium/io_altium.c (revision 10414) @@ -0,0 +1,90 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - altium format support + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + + +#include +#include +#include +#include +#include +#include "read.h" + +#include "io_altium_conf.h" +#include "conf_internal.c" + +conf_io_altium_t io_altium_conf; +static char altium_cookie[] = "io_altium"; + +static csch_plug_io_t altium_bin, altium_ascii; + +static int io_altium_common_load_prio(const char *fn, const char *fmt, csch_plug_io_type_t type) +{ + if (fmt != NULL) { + if (!strstr(fmt, "altium") && !strstr(fmt, "schdoc")) + return 0; + } + if (type == CSCH_IOTYP_SHEET) + return 90; + return 0; +} + +int pplg_check_ver_io_altium(int ver_needed) { return 0; } + +void pplg_uninit_io_altium(void) +{ + csch_plug_io_unregister(&altium_bin); + csch_plug_io_unregister(&altium_ascii); + rnd_conf_plug_unreg("plugins/io_altium/", io_altium_conf_internal, altium_cookie); +} + +int pplg_init_io_altium(void) +{ + RND_API_CHK_VER; + + altium_bin.name = "altium schematics sheet from schdoc (cdf)"; + altium_bin.load_prio = io_altium_common_load_prio; + altium_bin.load_sheet = io_altium_bin_load_sheet; + altium_bin.test_parse = io_altium_bin_test_parse; + + altium_bin.ext_save_sheet = "SchDoc"; + csch_plug_io_register(&altium_bin); + + altium_ascii.name = "altium schematics sheet from schdoc (ASCII)"; + altium_ascii.load_prio = io_altium_common_load_prio; + altium_ascii.load_sheet = io_altium_ascii_load_sheet; + altium_ascii.test_parse = io_altium_ascii_test_parse; + + altium_ascii.ext_save_sheet = "SchDoc"; + csch_plug_io_register(&altium_ascii); + + rnd_conf_plug_reg(io_altium_conf, io_altium_conf_internal, altium_cookie); +#define conf_reg(field,isarray,type_name,cpath,cname,desc,flags) \ + rnd_conf_reg_field(io_altium_conf, field,isarray,type_name,cpath,cname,desc,flags); +#include "io_altium_conf_fields.h" + + return 0; +} + Index: tags/1.0.5/src/plugins/io_altium/io_altium.conf =================================================================== --- tags/1.0.5/src/plugins/io_altium/io_altium.conf (nonexistent) +++ tags/1.0.5/src/plugins/io_altium/io_altium.conf (revision 10414) @@ -0,0 +1,19 @@ +li:pcb-rnd-conf-v1 { + ha:overwrite { + ha:plugins { + ha:io_altium { + coord_mult = 400 + auto_normalize = 1 + emulate_text_ang_180 = 1 + rename_redundant_pins = 1 + li:postproc_sheet_load { + {(@.a.Designator != "")}; {propset(@, rename/a/Designator, name)} + {(@.type == TEXT) && (@.text == "%../A.Designator%")}; {propset(@, p/text/text, "%../A.name%")} + {(@.a.Package != "")}; {propset(@, rename/a/Package, footprint)} + {(@.type == TEXT) && (@.text == "%../A.Package%")}; {propset(@, p/text/text, "%../A.footprint%")} + {(@.a.PinUniqueId != "")}; {propset(@, rename/a/PinUniqueId, -PinUniqueId)} + } + } + } + } +} Index: tags/1.0.5/src/plugins/io_altium/io_altium.pup =================================================================== --- tags/1.0.5/src/plugins/io_altium/io_altium.pup (nonexistent) +++ tags/1.0.5/src/plugins/io_altium/io_altium.pup (revision 10414) @@ -0,0 +1,10 @@ +$class io +$short altium schematics +$long Load schematics from altium schdoc +$state works +$fmt-feature-r altium schematics +$package io-alien +dep lib_alien +dep lib_ucdf +default buildin +autoload 1 Index: tags/1.0.5/src/plugins/io_altium/io_altium_conf.h =================================================================== --- tags/1.0.5/src/plugins/io_altium/io_altium_conf.h (nonexistent) +++ tags/1.0.5/src/plugins/io_altium/io_altium_conf.h (revision 10414) @@ -0,0 +1,20 @@ +#ifndef SCH_RND_IO_ALTIUM_CONF_H +#define SCH_RND_IO_ALTIUM_CONF_H + +#include + +typedef struct { + const struct { + const struct { + RND_CFT_REAL coord_mult; /* all altium coordinates are multiplied by this value to get sch-rnd coords */ + RND_CFT_BOOLEAN emulate_text_ang_180; /* altium displays text objects with angle==180 with an extra 180 degree rotation; it's a display hack sch-rnd doesn't have; when this emulation is enabled, the loader adds a +180 degree rotation in such text (changing data!) to match the behavior */ + RND_CFT_BOOLEAN auto_normalize; /* move all objects so that starting coords are near 0;0 */ + RND_CFT_LIST postproc_sheet_load; /* pattern;action pairs for object transformations after a succesful load; mostly used for attribute editing */ + RND_CFT_BOOLEAN rename_redundant_pins; /* if pin names are not unique within a symbol, rename all instances */ + } io_altium; + } plugins; +} conf_io_altium_t; + +extern conf_io_altium_t io_altium_conf; + +#endif Index: tags/1.0.5/src/plugins/io_altium/pcbdoc_ascii.c =================================================================== --- tags/1.0.5/src/plugins/io_altium/pcbdoc_ascii.c (nonexistent) +++ tags/1.0.5/src/plugins/io_altium/pcbdoc_ascii.c (revision 10414) @@ -0,0 +1,285 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * altium plugin - pcbdoc low level read: parse ASCII into a tree in mem + * pcb-rnd Copyright (C) 2021 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include + +#include +#include + +#include + +#include "pcbdoc_ascii.h" + +#define block_size 65536L + +/* optional trace */ +#if 0 +# define tprintf printf +#else + static int tprintf(const char *fmt, ...) { return 0; } +#endif + +TODO("move these to pcb-rnd rnd_inclib") +int pcbdoc_ascii_load_blocks(altium_tree_t *tree, FILE *f, long max) +{ + long curr = 0, next; + + for(;;) { + int c; + altium_block_t *blk; + + /* seek at potential end-of-block */ + next = curr + block_size; + if (next > max-1) + next = max-1; + fseek(f, next, SEEK_SET); + + /* seek first record separator (or eof) */ + for(;;) { + c = fgetc(f); + if (c == EOF) + break; + next++; + if ((c == '\r') || (c == '\n')) + break; + } + + if (c != EOF) { + /* seek end of record separator section (typica: \r\n) */ + for(;;) { + c = fgetc(f); + if (c == EOF) + break; + if ((c != '\r') && (c != '\n')) + break; + next++; + } + } + + if (next == curr) + break; + + /* by now "next" points to the first character of the next block */ + blk = malloc(sizeof(altium_block_t) + (next-curr) + 2); + if (blk == NULL) { + fprintf(stderr, "pcbdoc_ascii_load_blocks: failed to alloc memory\n"); + return -1; + } + memset(&blk->link, 0, sizeof(blk->link)); + blk->size = next-curr; + fseek(f, curr, SEEK_SET); + if (fread(&blk->raw, blk->size, 1, f) != 1) { + free(blk); + fprintf(stderr, "pcbdoc_ascii_load_blocks: can't read that many: %ld from %ld (%ld; max is %ld)\n", blk->size, curr, curr+blk->size, max); + return -1; + } + if (c == EOF) { + int last = blk->raw[blk->size-1]; + if ((last != '\r') && (last != '\n')) { + blk->raw[blk->size] = '\n'; + blk->size++; + } + } + blk->raw[blk->size] = '\0'; + gdl_append(&tree->blocks, blk, link); +/* printf("curr=%ld next=%ld\n", curr, next);*/ + curr = next; + } + + return 0; +} + +TODO("these two 'new' functions should use stack-slabs from umalloc") +altium_record_t *pcbdoc_ascii_new_rec(altium_tree_t *tree, const char *type_s, int type) +{ + altium_record_t *rec = calloc(sizeof(altium_record_t), 1); + + if (type == altium_kw_AUTO) { + type = altium_kw_sphash(type_s); + if ((type < altium_kw_record_SPHASH_MINVAL) || (type > altium_kw_record_SPHASH_MAXVAL)) + type = altium_kw_record_misc; + } + + rec->type = type; + rec->type_s = type_s; + + gdl_append(&tree->rec[type], rec, link); + + return rec; +} + +altium_field_t *pcbdoc_ascii_new_field(altium_tree_t *tree, altium_record_t *rec, const char *key, int kw, const char *val) +{ + altium_field_t *field = calloc(sizeof(altium_field_t), 1); + + if (kw == altium_kw_AUTO) { + kw = altium_kw_sphash(key); + if ((kw < altium_kw_field_SPHASH_MINVAL) || (kw > altium_kw_field_SPHASH_MAXVAL)) + kw = altium_kw_record_SPHASH_INVALID; + } + + field->type = kw; + field->key = key; + field->val_type = ALTIUM_FT_STR; + field->val.str = val; + + gdl_append(&rec->fields, field, link); + + return field; +} + +int pcbdoc_ascii_parse_fields(altium_tree_t *tree, altium_record_t *rec, const char *fn, long line, char **fields) +{ + int nl = 0; + char *s, *key, *val, *end; + + s = *fields; + + for(;;) { + /* ignore leading seps and newlines, exit if ran out of the string */ + while(*s == '|') s++; + if (*s == '\0') + break; + + /* find sep */ + end = strpbrk(s, "|\r\n"); + if (end == NULL) { + fprintf(stderr, "Unterminated field in %s:%ld\n", fn, line); + *fields = s; + return -1; + } + if (*end != '|') + nl = 1; + *end = '\0'; + + key = s; + val = strchr(s, '='); + if (val != NULL) { + *val = '\0'; + val++; + } + else + val = end; + + tprintf(" %s=%s\n", key, val); + pcbdoc_ascii_new_field(tree, rec, key, altium_kw_AUTO, val); + s = end+1; + if (nl) + break; + } + + *fields = s; + return 0; +} + +int pcbdoc_ascii_parse_blocks(altium_tree_t *tree, const char *fn) +{ + altium_block_t *blk; + long line = 1, idx = 0; + + for(blk = gdl_first(&tree->blocks); blk != NULL; blk = gdl_next(&tree->blocks, blk)) { + char *s = blk->raw, *end; + int is_hdr; + + tprintf("---blk---\n"); + + for(;;) { /* parse each line within the block */ + altium_record_t *rec; + + /* ignore leading seps and newlines, exit if ran out of the string */ + while((*s == '|') || (*s == '\r') || (*s == '\n')) s++; + if (*s == '\0') + break; + + /* parse the record header */ + if ((strncmp(s, "RECORD=", 7) != 0) && (strncmp(s, "HEADER=", 7) != 0)) { + fprintf(stderr, "First field must be record or header in %s:%ld\n", fn, line); + return -1; + } + is_hdr = (s[0] == 'H'); + if (!is_hdr) + s+=7; + end = strpbrk(s, "|\r\n"); + if (end == NULL) { + fprintf(stderr, "Unterminated record in %s:%ld\n", fn, line); + return -1; + } + *end = '\0'; + tprintf("rec='%s' idx=%ld\n", s, idx); + if (is_hdr) + rec = pcbdoc_ascii_new_rec(tree, s, altium_kw_record_header); + else + rec = pcbdoc_ascii_new_rec(tree, s, altium_kw_AUTO); + s = end+1; + + if (pcbdoc_ascii_parse_fields(tree, rec, fn, line, &s) != 0) + return -1; + + if (is_hdr) + pcbdoc_ascii_new_field(tree, rec, "header", altium_kw_field_header, blk->raw+8); + + + if (!is_hdr) { + rec->idx = idx; + idx++; + } + else + rec->idx = -1; + } + } + + return 0; +} + +void altium_tree_free(altium_tree_t *tree) +{ + altium_block_t *blk; + altium_record_t *rec; + int n; + + for(blk = gdl_first(&tree->blocks); blk != NULL; blk = gdl_first(&tree->blocks)) { + gdl_remove(&tree->blocks, blk, link); + free(blk); + } + + for(n = 0; n < altium_kw_record_SPHASH_MAXVAL+1; n++) { + for(rec = gdl_first(&tree->rec[n]); rec != NULL; rec = gdl_first(&tree->rec[n])) { + altium_field_t *field; + + for(field = gdl_first(&rec->fields); field != NULL; field = gdl_first(&rec->fields)) { + gdl_remove(&rec->fields, field, link); + free(field); + } + gdl_remove(&tree->rec[n], rec, link); + free(rec); + } + } +} + + +#include "schdoc.c" Index: tags/1.0.5/src/plugins/io_altium/pcbdoc_ascii.h =================================================================== --- tags/1.0.5/src/plugins/io_altium/pcbdoc_ascii.h (nonexistent) +++ tags/1.0.5/src/plugins/io_altium/pcbdoc_ascii.h (revision 10414) @@ -0,0 +1,80 @@ +#include +#include +#include +#include "altium_kw_sphash.h" + +typedef struct altium_field_s { + altium_kw_field_keys_t type; /* derived from ->key */ + const char *key; + enum { ALTIUM_FT_STR, ALTIUM_FT_CRD, ALTIUM_FT_DBL, ALTIUM_FT_LNG } val_type; + union { + const char *str; + rnd_coord_t crd; + double dbl; + long lng; /* also used for bool */ + } val; + gdl_elem_t link; /* in parent record */ +} altium_field_t; + +typedef struct altium_record_s { + altium_kw_record_keys_t type; /* derived from ->type_s */ + const char *type_s; + long idx; /* 0-based index of RECORDs within the file - SchDoc references by this */ + void *user_data; + gdl_list_t fields; + gdl_elem_t link; /* in tree records */ +} altium_record_t; + +typedef struct altium_block_s { + gdl_elem_t link; /* in tree blocks */ + long size; /* allocated size of raw */ + char raw[1]; /* bytes read from the file */ +} altium_block_t; + +typedef struct altium_tree_s { + gdl_list_t rec[altium_kw_record_SPHASH_MAXVAL+1]; /* ordered list of records per type */ + gdl_list_t blocks; +} altium_tree_t; + +#define altium_kw_AUTO (-2) +altium_record_t *pcbdoc_ascii_new_rec(altium_tree_t *tree, const char *type_s, int type); +altium_field_t *pcbdoc_ascii_new_field(altium_tree_t *tree, altium_record_t *rec, const char *key, int kw, const char *val); + +/* Parse '|' separated fields and allocate new altium_field_t's for them and + put them under rec. Return 0 on success. Stop at \n, 'fields' points to + the next char after the \n */ +int pcbdoc_ascii_parse_fields(altium_tree_t *tree, altium_record_t *rec, const char *fn, long line, char **fields); + +int pcbdoc_ascii_parse_blocks(altium_tree_t *tree, const char *fn); + +int pcbdoc_ascii_load_blocks(altium_tree_t *tree, FILE *f, long max); + + +void altium_tree_free(altium_tree_t *tree); + + +#include +#include +#include + +typedef struct io_altium_rctx_s { + altium_tree_t tree; + const char *fn; + htip_t id2rec; + csch_alien_read_ctx_t alien; + unsigned silent:1; +} io_altium_rctx_t; + +#define error_(ctx, rec, args) \ + do { \ + if (!ctx->silent) { \ + altium_record_t *__rec__ = rec; \ + if (__rec__ != NULL) \ + rnd_message(RND_MSG_ERROR, "altium parse error at %s rec #%ld:\n", (ctx)->fn, (long)((__rec__)->idx)); \ + else \ + rnd_message(RND_MSG_ERROR, "altium parse error at %s:\n", (ctx)->fn); \ + rnd_msg_error args; \ + } \ + } while(0) + +#define error(node, args) error_(rctx, node, args) Index: tags/1.0.5/src/plugins/io_altium/read.c =================================================================== --- tags/1.0.5/src/plugins/io_altium/read.c (nonexistent) +++ tags/1.0.5/src/plugins/io_altium/read.c (revision 10414) @@ -0,0 +1,188 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - altium file format support + * Copyright (C) 2022, 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022 and Entrust in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include +#include + +#include +#include +#include + +#include "pcbdoc_ascii.h" +#include "schdoc.h" + +#include "read.h" + +#define BINLEN_NO_MAIN +#include "binlen2txt.c" + +/* optional trace */ +#if 1 +# include +# define tprintf printf +#else + static int tprintf(const char *fmt, ...) { return 0; } +#endif + +/**** binary ****/ + +static int read_cb(void *ctx, void *dst, long len) +{ + long res = ucdf_fread((ucdf_file_t *)ctx, dst, len); + return (res == len) ? 0 : -1; +} + +static int alti_load_bin_sheet(io_altium_rctx_t *rctx, ucdf_ctx_t *uctx, ucdf_file_t *fp) +{ + vts0_t tmp = {0}; + + while(binlen2txt_readline(&tmp, read_cb, fp) == 0) { + long slen; + altium_block_t *blk = malloc(sizeof(altium_block_t) + tmp.used + 2); + + memset(&blk->link, 0, sizeof(blk->link)); + blk->size = tmp.used; + memcpy(blk->raw, tmp.array, tmp.used); + + slen = strlen(blk->raw); + blk->raw[slen] = '\n'; + blk->raw[slen+1] = '\0'; + gdl_append(&rctx->tree.blocks, blk, link); + } + + + vts0_uninit(&tmp); + return pcbdoc_ascii_parse_blocks(&rctx->tree, rctx->fn); +} + +int io_altium_bin_load_sheet(FILE *f, const char *fn, const char *fmt, csch_sheet_t *dst) +{ + int res, found = 0; + ucdf_ctx_t uctx = {0}; + ucdf_direntry_t *de; + io_altium_rctx_t rctx = {0}; + + res = ucdf_open(&uctx, fn); + if (res != 0) + return -1; + + rctx.fn = fn; + + /* look at each main directory and see if we can parse them */ + for(de = uctx.root->children; de != NULL; de = de->next) { +/* tprintf("de name='%s'\n", de->name);*/ + if ((de->type == UCDF_DE_FILE) && (strcmp(de->name, "FileHeader") == 0)) { + ucdf_file_t fp; + + res = ucdf_fopen(&uctx, &fp, de); + if (res != 0) { + error_((&rctx), NULL, ("io_altium_load_sheet(): failed to open FileHeader\n")); + break; + } + + found = (alti_load_bin_sheet(&rctx, &uctx, &fp) == 0); + break; + } + } + + ucdf_close(&uctx); + + if (!found) { + error_((&rctx), NULL, ("io_altium_bin_load_sheet(): failed to find or parse sheet file\n")); + res = -1; + } + else + res = altium_parse_sheet(&rctx, dst); + + altium_tree_free(&rctx.tree); + + return res; +} + +int io_altium_bin_test_parse(FILE *f, const char *fn, const char *fmt, csch_plug_io_type_t type) +{ + return ucdf_test_parse(fn); +} + + +/**** ascii ****/ + +int io_altium_ascii_load_sheet(FILE *f_nope, const char *fn, const char *fmt, csch_sheet_t *dst) +{ + FILE *f; + int res; + long filesize; + io_altium_rctx_t rctx = {0}; + + rctx.fn = fn; + + filesize = rnd_file_size(NULL, fn); + if (filesize <= 0) + return -1; + + f = rnd_fopen(NULL, fn, "rb"); + if (f == NULL) + return -1; + + res = pcbdoc_ascii_load_blocks(&rctx.tree, f, filesize); + fclose(f); + + if (res != 0) + return -1; + + res = pcbdoc_ascii_parse_blocks(&rctx.tree, fn); + + if (res == 0) + res = altium_parse_sheet(&rctx, dst); + + altium_tree_free(&rctx.tree); + + return res; +} + + +int io_altium_ascii_test_parse(FILE *f, const char *fn, const char *fmt, csch_plug_io_type_t type) +{ + char line[256], *s; + + /* first line should comply to the low level file format */ + fgets(line, sizeof(line), f); + + s = line; + if (*s == '|') s++; + + /* every line must start with a RECORD or HEADER field, the first one too */ + if ((strncmp(s,"RECORD=", 7) != 0) && (strncmp(s,"HEADER=", 7) != 0)) + return -1; + + /* there must be a field separator */ + if (strchr(s, '|') == NULL) + return -1; + + return 0; +} Index: tags/1.0.5/src/plugins/io_altium/read.h =================================================================== --- tags/1.0.5/src/plugins/io_altium/read.h (nonexistent) +++ tags/1.0.5/src/plugins/io_altium/read.h (revision 10414) @@ -0,0 +1,6 @@ +#include +int io_altium_bin_load_sheet(FILE *f, const char *fn, const char *fmt, csch_sheet_t *dst); +int io_altium_bin_test_parse(FILE *f, const char *fn, const char *fmt, csch_plug_io_type_t type); + +int io_altium_ascii_load_sheet(FILE *f, const char *fn, const char *fmt, csch_sheet_t *dst); +int io_altium_ascii_test_parse(FILE *f, const char *fn, const char *fmt, csch_plug_io_type_t type); Index: tags/1.0.5/src/plugins/io_altium/schdoc.c =================================================================== --- tags/1.0.5/src/plugins/io_altium/schdoc.c (nonexistent) +++ tags/1.0.5/src/plugins/io_altium/schdoc.c (revision 10414) @@ -0,0 +1,2439 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - altium file format support + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "io_altium_conf.h" + +#include "schdoc.h" + +TODO("At the moment this is #included from pcbdoc_ascii.c; this would change once that code is moved to pcb-rnd's inclib") + +/* for records that have been executed and intentionally did not create a group; + for example slotted symbols for the inactive pins */ +static const csch_cgrp_t NOGRP_, *NOGRP = &NOGRP_; + +/* Record types: + 1: symbol placement (from lib) + 2: pin + 4: text object + 5: bezier + 6: line + 7: polygon + 8: ellipse + 9: arc modified to pie + 10: round rect + 11: elliptic arc + 12: arc + 13: line (single segment, with same fields as rectangle) + 14: rectangle + 15: sheet ref box (green box) + 16: port in sheet entry (yellow arrows within 15) + 17: GND/vcc + 18: port on sheet: hexagon net label + 22: NC + 25: netlabel + 27: wire + 29: junction? + 28: note: multiline text in a rectangle (white background, no frame) + 31: font id + 34: attribute text + 39: sheet template object + 41: attribute text + 43: warning sign + 44: empty? + 45: footprint/model + 46: empty? + 47: DESIMP? + 48: empty? + 209: note (multiline text in a box, yellow background, frame) +*/ + +/* When a number is specified as an integer part and a fraction, the fracion + needs to be divided by this number */ +#define FRAC_DIV 100000 + +/* Decide if a color is dark; color is in #rgb */ +static int alti_is_dark(unsigned long clr) +{ + double r, g, b, dist; + + r = clr & 0xFF; + g = (clr & 0xFF00) >> 8; + b = (clr & 0xFF0000) >> 16; + + if ((r < 64) || (g < 64) || (b < 64)) + return 1; + + dist = r*r + g*g + b*b; + return (dist < 0xC000); +} + +/* Return 1 if instantiation of object shall be skipped because it's for + a different slot than what parent symbol is instantiated for. 1 if opartid + is present and it differs from parent symbols "currentpartid" attrib. */ +static int alti_slot_skip(csch_cgrp_t *parent, const char *opartid, const char *opartdisp) +{ + const char *cpid; + + if (opartid == NULL) + return 0; + + /* ownerpartid==-1 means always visible */ + if ((opartid[0] == '-') && (opartid[1] == '1') && (opartid[2] == '\0')) + return 0; + + /* deal with ownerpartdisplaymode == 0 only */ + if ((opartdisp != NULL) && (*opartdisp != '0')) + return 1; + + /* find symbol parent */ + while(parent->role != CSCH_ROLE_SYMBOL) { + parent = parent->hdr.parent; + if (parent == NULL) + return 0; /* not in symbol */ + } + + cpid = csch_attrib_get_str(&parent->attr, "-currentpartid"); + if (cpid == NULL) + return 0; + + return (strcmp(cpid, opartid) != 0); +} + +static int alti_coord_equ_x(io_altium_rctx_t *rctx, double x1, double x2) +{ + return csch_alien_coord_x(&rctx->alien, x1) == csch_alien_coord_x(&rctx->alien, x2); +} + +static int alti_coord_equ_y(io_altium_rctx_t *rctx, double y1, double y2) +{ + return csch_alien_coord_x(&rctx->alien, y1) == csch_alien_coord_x(&rctx->alien, y2); +} + +static double conv_double_field_(io_altium_rctx_t *rctx, altium_record_t *rec, altium_field_t *field) +{ + char *end; + double res; + + switch(field->val_type) { + case ALTIUM_FT_DBL: return field->val.dbl; + case ALTIUM_FT_LNG: return field->val.lng; + case ALTIUM_FT_CRD: return field->val.crd; + case ALTIUM_FT_STR: + res = strtod(field->val.str, &end); + if (*end != '\0') { + error(rec, ("io_altium: failed to convert floating point value '%s'\n", field->val)); + return 0; + } + return res; + } + abort(); +} + +#define conv_double_field(fld) conv_double_field_(rctx, rec, fld) + +static long conv_long_field_(io_altium_rctx_t *rctx, altium_record_t *rec, altium_field_t *field) +{ + char *end; + long res; + + switch(field->val_type) { + case ALTIUM_FT_DBL: return field->val.dbl; + case ALTIUM_FT_LNG: return field->val.lng; + case ALTIUM_FT_CRD: return field->val.crd; + case ALTIUM_FT_STR: + res = strtol(field->val.str, &end, 10); + if (*end != '\0') { + error(rec, ("io_altium: failed to convert integer value '%s'\n", field->val.str)); + return 0; + } + return res; + } + abort(); +} + +#define conv_long_field(fld) conv_long_field_(rctx, rec, fld) + +csch_cgrp_t *altium_get_parent(io_altium_rctx_t *rctx, altium_record_t *rec, long pidx, int is_solid, char **stroke, char **fill) +{ + + if (pidx >= 0) { + altium_record_t *parent_rec = htip_get(&rctx->id2rec, pidx); + if (parent_rec == NULL) { + error(rec, ("altium_get_parent(): invalid ownerindex %ld\n", pidx)); + return NULL; + } + if (parent_rec->user_data == NULL) + error(rec, ("altium_get_parent(): invalid group behind ownerindex %ld\n", pidx)); + *stroke = "sym-decor"; + *fill = is_solid ? *stroke : "sym-decor-fill"; + return parent_rec->user_data; + } + + *stroke = "sheet-decor"; + *fill = is_solid ? *stroke : "sheet-decor-fill"; + return &rctx->alien.sheet->direct; +} + + +static int altium_parse_arc(io_altium_rctx_t *rctx, altium_record_t *rec, int is_pie, int is_elliptic, int full_circle) +{ + altium_field_t *field; + long ri = -1, rf = 0, r2i = -1, r2f = 0; + double r, r2, sa = 0, ea = 0, da, cx = -1, cy = -1, cxf = 0, cyf = 0; + csch_chdr_t *arc; + csch_cgrp_t *parent; + long pidx = -1; + char *stroke, *fill; + const char *opartid = NULL, *opartdsp = NULL; + + if (full_circle) { + sa = 0; + ea = 360; + } + + for(field = gdl_first(&rec->fields); field != NULL; field = gdl_next(&rec->fields, field)) { + switch(field->type) { + case altium_kw_field_ownerindex: pidx = conv_long_field(field); break; + case altium_kw_field_ownerpartid: opartid = field->val.str; break; + case altium_kw_field_ownerpartdisplaymode: opartdsp = field->val.str; break; + case altium_kw_field_location_x: cx = conv_long_field(field); break; + case altium_kw_field_location_y: cy = conv_long_field(field); break; + case altium_kw_field_location_x_frac: cxf = conv_long_field(field); break; + case altium_kw_field_location_y_frac: cyf = conv_long_field(field); break; + case altium_kw_field_radius: ri = conv_long_field(field); break; + case altium_kw_field_radius_frac: rf = conv_long_field(field); break; + case altium_kw_field_secondaryradius: r2i = conv_long_field(field); break; + case altium_kw_field_secondaryradius_frac: r2f = conv_long_field(field); break; + case altium_kw_field_startangle: sa = conv_double_field(field); break; + case altium_kw_field_endangle: ea = conv_double_field(field); break; + default: break; + } + } + + cx += cxf / FRAC_DIV; + cy += cyf / FRAC_DIV; + + parent = altium_get_parent(rctx, rec, pidx, 0, &stroke, &fill); + if (parent == NOGRP) + return 0; + if (parent == NULL) + return -1; + + if (alti_slot_skip(parent, opartid, opartdsp)) + return 0; + + if ((ea >= 360) && (sa < 0)) + sa = 0; + if ((cx < 0) || (cy < 0) || (ri < 0)) { + error(rec, ("altium_parse_arc(): missing coords or radius\n")); + return -1; + } + + if (is_elliptic && (r2i < 0)) { + error(rec, ("altium_parse_arc(): missing secondary radius for elliptical arc\n")); + return -1; + } + + r = ri + (double)rf/FRAC_DIV; + r2 = r2i + (double)r2f/FRAC_DIV; + + if (ea < sa) + da = 360 - sa + ea; + else + da = ea - sa; + + if (is_elliptic && (fabs(r-r2) > 0.1)) { + double sar = sa / RND_RAD_TO_DEG; + double dar = da / RND_RAD_TO_DEG; + arc = csch_alien_mkearc(&rctx->alien, parent, cx, cy, r, r2, sar, dar, stroke, NULL); + } + else if (is_pie) { + arc = csch_alien_mkpoly(&rctx->alien, parent, stroke, fill); + if (arc != NULL) { + double ear = ea / RND_RAD_TO_DEG; + double sar = sa / RND_RAD_TO_DEG; + csch_alien_append_poly_arc(&rctx->alien, arc, cx, cy, r, sa, da); + csch_alien_append_poly_line(&rctx->alien, arc, cx + r*cos(ear), cx + r*sin(ear), cx, cy); + csch_alien_append_poly_line(&rctx->alien, arc, cx, cy, cx + r*cos(sar), cx + r*sin(sar)); + } + } + else + arc = csch_alien_mkarc(&rctx->alien, parent, cx, cy, r, sa, da, stroke); + + + if (arc == NULL) { + error(rec, ("altium_parse_arc(): failed to create arc\n")); + return -1; + } + + return 0; +} + +static int altium_parse_arcs(io_altium_rctx_t *rctx) +{ + altium_record_t *rec; + + /* normal arcs */ + for(rec = gdl_first(&rctx->tree.rec[altium_kw_record_12]); rec != NULL; rec = gdl_next(&rctx->tree.rec[altium_kw_record_12], rec)) + if (altium_parse_arc(rctx, rec, 0, 0, 0) != 0) + return -1; + + /* elliptic arcs */ + for(rec = gdl_first(&rctx->tree.rec[altium_kw_record_11]); rec != NULL; rec = gdl_next(&rctx->tree.rec[altium_kw_record_11], rec)) + if (altium_parse_arc(rctx, rec, 0, 1, 0) != 0) + return -1; + + /* pies */ + for(rec = gdl_first(&rctx->tree.rec[altium_kw_record_9]); rec != NULL; rec = gdl_next(&rctx->tree.rec[altium_kw_record_9], rec)) + if (altium_parse_arc(rctx, rec, 1, 0, 0) != 0) + return -1; + + /* elliptical circles */ + for(rec = gdl_first(&rctx->tree.rec[altium_kw_record_8]); rec != NULL; rec = gdl_next(&rctx->tree.rec[altium_kw_record_8], rec)) + if (altium_parse_arc(rctx, rec, 0, 1, 1) != 0) + return -1; + + return 0; +} + +/* Read X1, Y1 ... Xn, Yn integer fields into dst in x,y packing */ +static int altium_get_multi_xy(io_altium_rctx_t *rctx, vtd0_t *dst, altium_record_t *rec, long *parent_idx, long *aclr) +{ + altium_field_t *field; + + *parent_idx = -1; + *aclr = -1; + dst->used = 0; + + for(field = gdl_first(&rec->fields); field != NULL; field = gdl_next(&rec->fields, field)) { + if (field->type == altium_kw_field_ownerindex) { + *parent_idx = conv_long_field(field); + } + else if (field->type == altium_kw_field_areacolor) { + *aclr = conv_long_field(field); + } + else if (((field->key[0] == 'X') || (field->key[0] == 'Y')) && isdigit(field->key[1])) { + long idx; + char *end; + + idx = strtol(field->key+1, &end, 10) - 1; + idx = idx << 1; + if (field->key[0] == 'Y') idx++; + vtd0_enlarge(dst, idx); + + if (strcmp(end, "_FRAC") == 0) { /* fraction part */ + dst->array[idx] += (double)conv_long_field(field) / FRAC_DIV; + } + else if (*end == '\0') { /* integer part */ + dst->array[idx] = conv_long_field(field); + } + else { + error(rec, ("altium_get_multi_xy(): invalid index: %s\n", field->key)); + return -1; + } + } + } + return 0; +} + +static int altium_parse_bezier(io_altium_rctx_t *rctx, altium_record_t *rec, vtd0_t *xy) +{ + altium_field_t *field; + csch_cgrp_t *parent; + long n, pidx = -1, aclr = -1; + char *stroke, *fill; + const char *opartid = NULL, *opartdsp = NULL; + + for(field = gdl_first(&rec->fields); field != NULL; field = gdl_next(&rec->fields, field)) { + switch(field->type) { + case altium_kw_field_ownerindex: pidx = conv_long_field(field); break; + case altium_kw_field_ownerpartid: opartid = field->val.str; break; + case altium_kw_field_ownerpartdisplaymode: opartdsp = field->val.str; break; + default: break; + } + } + + parent = altium_get_parent(rctx, rec, pidx, 0, &stroke, &fill); + if (parent == NOGRP) + return 0; + if (parent == NULL) + return -1; + + if (alti_slot_skip(parent, opartid, opartdsp)) + return 0; + + if (altium_get_multi_xy(rctx, xy, rec, &pidx, &aclr) != 0) { + error(rec, ("altium_parse_lines(): missing coordinate for line\n")); + return -1; + } + + for(n = 0; n+7 < xy->used; n += 6) + csch_alien_mkbezier(&rctx->alien, parent, + xy->array[n+0], xy->array[n+1], + xy->array[n+2], xy->array[n+3], + xy->array[n+4], xy->array[n+5], + xy->array[n+6], xy->array[n+7], + stroke); + + return 0; +} + +static int altium_parse_beziers(io_altium_rctx_t *rctx) +{ + altium_record_t *rec; + vtd0_t xy = {0}; + + /* normal arcs */ + for(rec = gdl_first(&rctx->tree.rec[altium_kw_record_5]); rec != NULL; rec = gdl_next(&rctx->tree.rec[altium_kw_record_5], rec)) + if (altium_parse_bezier(rctx, rec, &xy) != 0) + return -1; + + vtd0_uninit(&xy); + + return 0; +} + + +static int altium_create_lines(io_altium_rctx_t *rctx, altium_record_t *rec, vtd0_t *xy, int is_wire, int is_poly, int rect_fields) +{ + long n, pidx, aclr = -1; + csch_chdr_t *poly; + csch_cgrp_t *parent; + char *stroke, *fill; + const char *opartid = NULL, *opartdsp = NULL; + int is_solid = 0; + + if (rect_fields) { + altium_field_t *field; + + pidx = -1; + xy->used = 0; + vtd0_enlarge(xy, 3); + xy->array[0] = xy->array[1] = xy->array[2] = xy->array[3] = -1; + + for(field = gdl_first(&rec->fields); field != NULL; field = gdl_next(&rec->fields, field)) { + switch(field->type) { + case altium_kw_field_ownerindex: pidx = conv_long_field(field); + case altium_kw_field_ownerpartid: opartid = field->val.str; break; + case altium_kw_field_ownerpartdisplaymode: opartdsp = field->val.str; break; + case altium_kw_field_location_x: xy->array[0] = conv_long_field(field); break; + case altium_kw_field_location_y: xy->array[1] = conv_long_field(field); break; + case altium_kw_field_location_x_frac: xy->array[0] += ((double)conv_long_field(field)) / FRAC_DIV; break; + case altium_kw_field_location_y_frac: xy->array[1] += ((double)conv_long_field(field)) / FRAC_DIV; break; + case altium_kw_field_corner_x: xy->array[2] = conv_long_field(field); break; + case altium_kw_field_corner_y: xy->array[3] = conv_long_field(field); break; + case altium_kw_field_corner_x_frac: xy->array[2] += (double)conv_long_field(field) / FRAC_DIV; break; + case altium_kw_field_corner_y_frac: xy->array[3] += (double)conv_long_field(field) / FRAC_DIV; break; + case altium_kw_field_issolid: is_solid = field->val.str[0] == 'T'; break; + case altium_kw_field_areacolor: aclr = conv_long_field(field); break; + default: break; + } + } + } + else if (altium_get_multi_xy(rctx, xy, rec, &pidx, &aclr) != 0) { + error(rec, ("altium_parse_lines(): missing coordinate for line\n")); + return -1; + } + + if (aclr > 0) + is_solid = alti_is_dark(aclr); + + parent = altium_get_parent(rctx, rec, pidx, is_solid, &stroke, &fill); + if (parent == NOGRP) + return 0; + if (parent == NULL) + return -1; + + if (alti_slot_skip(parent, opartid, opartdsp)) + return 0; + + if (is_poly) + poly = csch_alien_mkpoly(&rctx->alien, parent, stroke, fill); + + for(n = 2; n < xy->used; n += 2) { + csch_chdr_t *lin; + double x1 = xy->array[n-2], y1 = xy->array[n-1]; + double x2 = xy->array[n], y2 = xy->array[n+1]; + + if (is_poly) { + csch_alien_append_poly_line(&rctx->alien, poly, x1, y1, x2, y2); + lin = poly; + } + else if (is_wire) + lin = csch_alien_mknet(&rctx->alien, parent, x1, y1, x2, y2); + else + lin = csch_alien_mkline(&rctx->alien, parent, x1, y1, x2, y2, stroke); + + if (lin == NULL) { + if (!alti_coord_equ_x(rctx, x1, x2) || !alti_coord_equ_y(rctx, y1, y2)) { + /* it's an error only if line is not 0-long */ + error(rec, ("altium_parse_lines(): failed to create line\n")); + return -1; + } + } + } + + if (is_poly) { + double x1 = xy->array[xy->used-2], y1 = xy->array[xy->used-1]; + double x2 = xy->array[0], y2 = xy->array[1]; + + csch_alien_append_poly_line(&rctx->alien, poly, x1, y1, x2, y2); + } + + + return 0; +} + +static int altium_parse_lines(io_altium_rctx_t *rctx) +{ + altium_record_t *rec; + altium_field_t *field; + vtd0_t xy = {0}; + + + /* decoration lines */ + for(rec = gdl_first(&rctx->tree.rec[altium_kw_record_6]); rec != NULL; rec = gdl_next(&rctx->tree.rec[altium_kw_record_6], rec)) { + for(field = gdl_first(&rec->fields); field != NULL; field = gdl_next(&rec->fields, field)) { + switch(field->type) { + case altium_kw_field_linewidth: break; + default: break; + } + } + if (altium_create_lines(rctx, rec, &xy, 0, 0, 0) != 0) + return -1; + } + + /* decoration lines */ + for(rec = gdl_first(&rctx->tree.rec[altium_kw_record_13]); rec != NULL; rec = gdl_next(&rctx->tree.rec[altium_kw_record_13], rec)) { + for(field = gdl_first(&rec->fields); field != NULL; field = gdl_next(&rec->fields, field)) { + switch(field->type) { + case altium_kw_field_linewidth: break; + default: break; + } + } + if (altium_create_lines(rctx, rec, &xy, 0, 0, 1) != 0) + return -1; + } + + /* net lines */ + for(rec = gdl_first(&rctx->tree.rec[altium_kw_record_27]); rec != NULL; rec = gdl_next(&rctx->tree.rec[altium_kw_record_27], rec)) { + for(field = gdl_first(&rec->fields); field != NULL; field = gdl_next(&rec->fields, field)) { + switch(field->type) { + case altium_kw_field_linewidth: break; + default: break; + } + } + if (altium_create_lines(rctx, rec, &xy, 1, 0, 0) != 0) + return -1; + } + + vtd0_uninit(&xy); + return 0; +} + +static int altium_parse_polys(io_altium_rctx_t *rctx) +{ + altium_record_t *rec; + altium_field_t *field; + vtd0_t xy = {0}; + + + /* decoration lines */ + for(rec = gdl_first(&rctx->tree.rec[altium_kw_record_7]); rec != NULL; rec = gdl_next(&rctx->tree.rec[altium_kw_record_7], rec)) { + for(field = gdl_first(&rec->fields); field != NULL; field = gdl_next(&rec->fields, field)) { + switch(field->type) { + case altium_kw_field_linewidth: break; + default: break; + } + } + if (altium_create_lines(rctx, rec, &xy, 0, 1, 0) != 0) + return -1; + } + + vtd0_uninit(&xy); + return 0; +} + +static int altium_parse_rect(io_altium_rctx_t *rctx, altium_record_t *rec, int is_round) +{ + altium_field_t *field; + long pidx = -1, aclr = -1; + double x1 = 0, y1 = 0, x2 = 0, y2 = 0, x1f = 0, y1f = 0, x2f = 0, y2f = 0; + double xr = 0, yr = 0, xrf = 0, yrf = 0; + csch_chdr_t *poly; + csch_cgrp_t *parent; + char *stroke, *fill; + int is_solid = 0; + const char *opartid = NULL, *opartdsp = NULL; + + for(field = gdl_first(&rec->fields); field != NULL; field = gdl_next(&rec->fields, field)) { + switch(field->type) { + case altium_kw_field_ownerindex: pidx = conv_long_field(field); break; + case altium_kw_field_ownerpartid: opartid = field->val.str; break; + case altium_kw_field_ownerpartdisplaymode: opartdsp = field->val.str; break; + case altium_kw_field_location_x: x1 = conv_long_field(field); break; + case altium_kw_field_location_y: y1 = conv_long_field(field); break; + case altium_kw_field_location_x_frac: x1f = conv_long_field(field); break; + case altium_kw_field_location_y_frac: y1f = conv_long_field(field); break; + case altium_kw_field_corner_x: x2 = conv_long_field(field); break; + case altium_kw_field_corner_y: y2 = conv_long_field(field); break; + case altium_kw_field_corner_x_frac: x2f = conv_long_field(field); break; + case altium_kw_field_corner_y_frac: y2f = conv_long_field(field); break; + case altium_kw_field_cornerxradius: xr = conv_long_field(field); break; + case altium_kw_field_corneryradius: yr = conv_long_field(field); break; + case altium_kw_field_cornerxradius_frac: xrf = conv_long_field(field); break; + case altium_kw_field_corneryradius_frac: yrf = conv_long_field(field); break; + case altium_kw_field_issolid: is_solid = field->val.str[0] == 'T'; break; + case altium_kw_field_areacolor: aclr = conv_long_field(field); break; + + default: break; + } + } + + if (aclr > 0) + is_solid = alti_is_dark(aclr); + + parent = altium_get_parent(rctx, rec, pidx, is_solid, &stroke, &fill); + if (parent == NOGRP) + return 0; + if (parent == NULL) + return -1; + + if (alti_slot_skip(parent, opartid, opartdsp)) + return 0; + + if (is_round) { + if ((xr < 0) || (yr < 0)) { + error(rec, ("altium_parse_rect(): missing cornerxradius or corneryradius\n")); + return -1; + } + if ((xr != yr)) { + error(rec, ("altium_parse_rect(): cornerxradius != corneryradius; elliptic corner rounding not yet supported, using circular instead\n")); + xr = yr = (xr+yr)/2; + } + } + else { + if ((xr > 0) || (yr > 0)) + error(rec, ("altium_parse_rect(): cornerxradius or corneryradius present in non-round rect (ignoring these fields)\n")); + } + + x1 += x1f / FRAC_DIV; + y1 += y1f / FRAC_DIV; + x2 += x2f / FRAC_DIV; + y2 += y2f / FRAC_DIV; + xr += xrf / FRAC_DIV; + yr += yrf / FRAC_DIV; + + poly = csch_alien_mkpoly(&rctx->alien, parent, stroke, fill); + if (poly == NULL) { + error(rec, ("altium_parse_rect(): failed to create poly\n")); + return -1; + } + + if (is_round) { + csch_alien_append_poly_line(&rctx->alien, poly, x1+xr, y1, x2-xr, y1); + csch_alien_append_poly_arc(&rctx->alien, poly, x2-xr, y1+yr, xr, -90, 90); + csch_alien_append_poly_line(&rctx->alien, poly, x2, y1+yr, x2, y2-yr); + csch_alien_append_poly_arc(&rctx->alien, poly, x2-xr, y2-yr, xr, 0, 90); + csch_alien_append_poly_line(&rctx->alien, poly, x2-xr, y2, x1+xr, y2); + csch_alien_append_poly_arc(&rctx->alien, poly, x1+xr, y2-yr, xr, 90, 90); + csch_alien_append_poly_line(&rctx->alien, poly, x1, y2-yr, x1, y1+yr); + csch_alien_append_poly_arc(&rctx->alien, poly, x1+xr, y1+yr, xr, 180, 90); + } + else { + csch_alien_append_poly_line(&rctx->alien, poly, x1, y1, x2, y1); + csch_alien_append_poly_line(&rctx->alien, poly, x2, y1, x2, y2); + csch_alien_append_poly_line(&rctx->alien, poly, x2, y2, x1, y2); + csch_alien_append_poly_line(&rctx->alien, poly, x1, y2, x1, y1); + } + + return 0; +} + +static int altium_parse_shref_rect(io_altium_rctx_t *rctx, altium_record_t *rec) +{ + altium_field_t *field; + csch_source_arg_t *src; + long pidx = -1, xs = -1, ys = -1; + long line = rec->idx+1; + double x1 = -1, y1 = -1, x2 = -1, y2 = -1, x1f = 0, y1f = 0; + csch_chdr_t *poly; + csch_cgrp_t *parent, *sym; + char *stroke = "sym-decor", *fill = "sym-decor-fill", *dummy; + int is_solid = 0; + + for(field = gdl_first(&rec->fields); field != NULL; field = gdl_next(&rec->fields, field)) { + switch(field->type) { + case altium_kw_field_ownerindex: pidx = conv_long_field(field); break; +/* case altium_kw_field_ownerpartid: opartid = field->val.str; break;*/ +/* case altium_kw_field_ownerpartdisplaymode: opartdsp = field->val.str; break;*/ + case altium_kw_field_location_x: x1 = conv_long_field(field); break; + case altium_kw_field_location_y: y1 = conv_long_field(field); break; + case altium_kw_field_location_x_frac: x1f = conv_long_field(field); break; + case altium_kw_field_location_y_frac: y1f = conv_long_field(field); break; + case altium_kw_field_xsize: xs = conv_long_field(field); break; + case altium_kw_field_ysize: ys = conv_long_field(field); break; + default: break; + } + } + + if ((x1 < 0) || (y1 < 0) || (xs < 0) || (ys < 0)) { + error(rec, ("altium_parse_shref_rect(): missing location.x or location.y or xsize or ysize\n")); + return -1; + } + + parent = altium_get_parent(rctx, rec, pidx, is_solid, &dummy, &dummy); + if (parent == NOGRP) + return 0; + if (parent == NULL) + return -1; + + x1 += x1f / FRAC_DIV; + y1 += y1f / FRAC_DIV; + x2 = x1 + xs; + y2 = y1 - ys; + + sym = csch_cgrp_alloc(rctx->alien.sheet, parent, csch_oid_new(rctx->alien.sheet, parent)); + if (sym == NULL) { + error(rec, ("altium_parse_shref_rect(): Failed to allocate symbol for rail or nc\n")); + return -1; + } + + src = csch_attrib_src_c(rctx->fn, line, 0, NULL); + csch_attrib_set(&sym->attr, CSCH_ATP_USER_DEFAULT, "role", "symbol", src, NULL); + sym->role = CSCH_ROLE_SYMBOL; + TODO("hierarchic: mark this sym as subsheet ref"); + rec->user_data = sym; + htip_set(&rctx->id2rec, rec->idx, rec); + + + sym->x = csch_alien_coord_x(&rctx->alien, x1); + sym->y = csch_alien_coord_y(&rctx->alien, y1); + sym->xform.x = xs; sym->xform.y = ys; /* fields are abused to remember xs and ys */ + + poly = csch_alien_mkpoly(&rctx->alien, sym, stroke, fill); + if (poly == NULL) { + error(rec, ("altium_parse_shref_rect(): failed to create poly\n")); + return -1; + } + + /* the whole sym is moved */ + x2 -= x1; + y2 -= y1; + + csch_alien_append_poly_line(&rctx->alien, poly, 0, 0, x2, 0); + csch_alien_append_poly_line(&rctx->alien, poly, x2, 0, x2, y2); + csch_alien_append_poly_line(&rctx->alien, poly, x2, y2, 0, y2); + csch_alien_append_poly_line(&rctx->alien, poly, 0, y2, 0, 0); + + return 0; +} + + +static int altium_parse_rects(io_altium_rctx_t *rctx) +{ + altium_record_t *rec; + + for(rec = gdl_first(&rctx->tree.rec[altium_kw_record_14]); rec != NULL; rec = gdl_next(&rctx->tree.rec[altium_kw_record_14], rec)) + if (altium_parse_rect(rctx, rec, 0) != 0) + return -1; + + for(rec = gdl_first(&rctx->tree.rec[altium_kw_record_10]); rec != NULL; rec = gdl_next(&rctx->tree.rec[altium_kw_record_10], rec)) + if (altium_parse_rect(rctx, rec, 1) != 0) + return -1; + + + for(rec = gdl_first(&rctx->tree.rec[altium_kw_record_15]); rec != NULL; rec = gdl_next(&rctx->tree.rec[altium_kw_record_15], rec)) + if (altium_parse_shref_rect(rctx, rec) != 0) + return -1; + + return 0; +} + +static int altium_parse_attrib(io_altium_rctx_t *rctx, altium_record_t *rec, int is_round, const char *force_key, int abs_coord) +{ + altium_field_t *field; + int ishidden = 0, orientation = 0; + double x = -1, y = -1, xf = 0, yf = 0; + long pidx = -1; + csch_cgrp_t *parent; + char *stroke, *fill, keytmp[128]; + const char *key = force_key, *val = ""; + csch_source_arg_t *src; + const char *opartid = NULL, *opartdsp = NULL; + + for(field = gdl_first(&rec->fields); field != NULL; field = gdl_next(&rec->fields, field)) { + switch(field->type) { + case altium_kw_field_ownerindex: pidx = conv_long_field(field); break; + case altium_kw_field_ownerpartid: opartid = field->val.str; break; + case altium_kw_field_ownerpartdisplaymode: opartdsp = field->val.str; break; + case altium_kw_field_orientation: orientation = conv_long_field(field); break; + case altium_kw_field_location_x: x = conv_long_field(field); break; + case altium_kw_field_location_y: y = conv_long_field(field); break; + case altium_kw_field_location_x_frac: xf = conv_long_field(field); break; + case altium_kw_field_location_y_frac: yf = conv_long_field(field); break; + case altium_kw_field_name: key = field->val.str; break; + case altium_kw_field_text: val = field->val.str; break; + case altium_kw_field_ishidden: ishidden = field->val.str[0] == 'T'; break; + default: break; + } + } + + if (key == NULL) { + key = keytmp; + rnd_snprintf(keytmp, sizeof(keytmp), "not_named_in_record_%ld", rec->idx); + } + + x += xf / FRAC_DIV; + y += yf / FRAC_DIV; + + parent = altium_get_parent(rctx, rec, pidx, 0, &stroke, &fill); + if (parent == NOGRP) + return 0; + if (parent == NULL) + return 0; + + if (alti_slot_skip(parent, opartid, opartdsp)) + return 0; + + src = csch_attrib_src_c(rctx->fn, rec->idx+1, 0, NULL); + csch_attrib_set(&parent->attr, CSCH_ATP_USER_DEFAULT, key, val, src, NULL); + + if (!ishidden) { + if ((x >= 0) && (y >= 0)) { + csch_text_t *text; + int n; + + /* Altium seems to have a next layer of indirection: if key points to + a Foo attribute but the value of that attribute is =Bar, then + the value of Bar is printed. sch-rnd doesn't have this indirection so + the closest thing we can do is to resolve it here and hardwire + a reference to the final indirection (at the time of parsing the file) */ + for(n = 0; n < 8; n++) { /* allow at most 8 hops to avoid infinite loop */ + const char *val = csch_attrib_get_str(&parent->attr, key); + if ((val == NULL) || (*val != '=')) + break; + key = val+1; + } + + if (abs_coord) { + x -= parent->x / rctx->alien.coord_factor; + y -= parent->y / rctx->alien.coord_factor; + } + + text = (csch_text_t *)csch_alien_mktext(&rctx->alien, parent, x, y, stroke); + text->text = rnd_strdup_printf("%%../A.%s%%", key); + text->dyntext = 1; + text->hdr.floater = 1; + if (orientation == 1) + text->spec_rot = 90; + } + else + error(rec, ("altium_parse_attrib(): can't create visible attrib text with no coords\n")); + } + + return 0; +} + + +static int altium_parse_attribs(io_altium_rctx_t *rctx) +{ + altium_record_t *rec; + + for(rec = gdl_first(&rctx->tree.rec[altium_kw_record_41]); rec != NULL; rec = gdl_next(&rctx->tree.rec[altium_kw_record_41], rec)) + if (altium_parse_attrib(rctx, rec, 0, NULL, 0) != 0) + return -1; + + + for(rec = gdl_first(&rctx->tree.rec[altium_kw_record_34]); rec != NULL; rec = gdl_next(&rctx->tree.rec[altium_kw_record_34], rec)) + if (altium_parse_attrib(rctx, rec, 0, NULL, 0) != 0) + return -1; + +TODO("hierarchical: probably need to use different keys here"); + + for(rec = gdl_first(&rctx->tree.rec[altium_kw_record_32]); rec != NULL; rec = gdl_next(&rctx->tree.rec[altium_kw_record_32], rec)) + if (altium_parse_attrib(rctx, rec, 0, "sheet_name", 1) != 0) + return -1; + + for(rec = gdl_first(&rctx->tree.rec[altium_kw_record_33]); rec != NULL; rec = gdl_next(&rctx->tree.rec[altium_kw_record_33], rec)) + if (altium_parse_attrib(rctx, rec, 0, "file_name", 1) != 0) + return -1; + + return 0; +} + +static int altium_parse_sign(io_altium_rctx_t *rctx, altium_record_t *rec) +{ + csch_sheet_t *sheet = rctx->alien.sheet; + altium_field_t *field; + double x = -1, y = -1, xf = 0, yf = 0; + long pidx = -1; + csch_cgrp_t *parent, *grp; + const char *opartid, *opartdsp, *name; + char *stroke, *fill; + csch_text_t *text; + + for(field = gdl_first(&rec->fields); field != NULL; field = gdl_next(&rec->fields, field)) { + switch(field->type) { + case altium_kw_field_ownerindex: pidx = conv_long_field(field); break; + case altium_kw_field_ownerpartid: opartid = field->val.str; break; + case altium_kw_field_ownerpartdisplaymode: opartdsp = field->val.str; break; + case altium_kw_field_location_x: x = conv_long_field(field); break; + case altium_kw_field_location_y: y = conv_long_field(field); break; + case altium_kw_field_location_x_frac: xf = conv_long_field(field); break; + case altium_kw_field_location_y_frac: yf = conv_long_field(field); break; + case altium_kw_field_name: name = field->val.str; break; + default: break; + } + } + + if (name == NULL) { + error(rec, ("altium_parse_sign(): sign with no name\n")); + return -1; + } + + x += xf / FRAC_DIV; + y += yf / FRAC_DIV; + + parent = altium_get_parent(rctx, rec, pidx, 0, &stroke, &fill); + if (parent == NOGRP) + return 0; + if (parent == NULL) + return 0; + + if (alti_slot_skip(parent, opartid, opartdsp)) + return 0; + + grp = csch_cgrp_alloc(sheet, parent, csch_oid_new(sheet, &sheet->direct)); + if (grp == NULL) { + error(rec, ("altium_parse_sign(): Failed to allocate group for sign\n")); + return -1; + } + + + grp->x = csch_alien_coord_x(&rctx->alien, x); + grp->y = csch_alien_coord_y(&rctx->alien, y); + + if (strcmp(name, "DIFFPAIR") == 0) { + char *stroke = "sheet-decor"; + int x = 5, y = 5; + + csch_alien_mkline(&rctx->alien, grp, 0, 0, x+1, y, stroke); + + csch_alien_mkline(&rctx->alien, grp, x+1, y+1, x+3, y+1, stroke); + csch_alien_mkline(&rctx->alien, grp, x+3, y+1, x+4, y+2, stroke); + csch_alien_mkline(&rctx->alien, grp, x+4, y+2, x+6, y+2, stroke); + csch_alien_mkline(&rctx->alien, grp, x+6, y+2, x+7, y+1, stroke); + csch_alien_mkline(&rctx->alien, grp, x+7, y+1, x+9, y+1, stroke); + + csch_alien_mkline(&rctx->alien, grp, x+1, y-1, x+3, y-1, stroke); + csch_alien_mkline(&rctx->alien, grp, x+3, y-1, x+4, y-2, stroke); + csch_alien_mkline(&rctx->alien, grp, x+4, y-2, x+6, y-2, stroke); + csch_alien_mkline(&rctx->alien, grp, x+6, y-2, x+7, y-1, stroke); + csch_alien_mkline(&rctx->alien, grp, x+7, y-1, x+9, y-1, stroke); + + } + else { + text = (csch_text_t *)csch_alien_mktext(&rctx->alien, grp, 0, 0, "term-primary"); + text->text = rnd_strdup(name); + } + + rec->user_data = grp; + + return 0; +} + +static int altium_parse_sheet_template(io_altium_rctx_t *rctx, altium_record_t *rec) +{ + rec->user_data = &rctx->alien.sheet->direct; + return 0; +} + +static int altium_parse_signs(io_altium_rctx_t *rctx) +{ + altium_record_t *rec; + + for(rec = gdl_first(&rctx->tree.rec[altium_kw_record_43]); rec != NULL; rec = gdl_next(&rctx->tree.rec[altium_kw_record_43], rec)) { + if (altium_parse_sign(rctx, rec) != 0) + return -1; + htip_set(&rctx->id2rec, rec->idx, rec); + } + for(rec = gdl_first(&rctx->tree.rec[altium_kw_record_39]); rec != NULL; rec = gdl_next(&rctx->tree.rec[altium_kw_record_39], rec)) { + if (altium_parse_sheet_template(rctx, rec) != 0) + return -1; + htip_set(&rctx->id2rec, rec->idx, rec); + } + return 0; +} + +static int altium_parse_net_labels(io_altium_rctx_t *rctx) +{ + altium_record_t *rec; + altium_field_t *field; + csch_line_t *wire, *term = NULL; + csch_text_t *text; + csch_source_arg_t *src; + csch_sheet_t *sheet = rctx->alien.sheet; + csch_rtree_it_t it; + csch_rtree_box_t bbox; + + for(rec = gdl_first(&rctx->tree.rec[altium_kw_record_25]); rec != NULL; rec = gdl_next(&rctx->tree.rec[altium_kw_record_25], rec)) { + double x = -1, y = -1, xf = 0, yf = 0; + int ori = 0; + const char *name = NULL; + csch_coord_t x0, y0; + + for(field = gdl_first(&rec->fields); field != NULL; field = gdl_next(&rec->fields, field)) { + switch(field->type) { + case altium_kw_field_location_x: x = conv_long_field(field); break; + case altium_kw_field_location_y: y = conv_long_field(field); break; + case altium_kw_field_location_x_frac: xf = conv_long_field(field); break; + case altium_kw_field_location_y_frac: yf = conv_long_field(field); break; + case altium_kw_field_orientation: ori = conv_long_field(field); break; + case altium_kw_field_text: name = field->val.str; break; + default: break; + } + } + + if ((x < 0) || (y < 0)) { + error(rec, ("altium_parse_net_labels(): missing location.x or location.y\n")); + return -1; + } + if (name == NULL) { + error(rec, ("altium_parse_net_labels(): missing text field for net name\n")); + return -1; + } + + x += xf / FRAC_DIV; + y += yf / FRAC_DIV; + + /* find a wire the label is put on */ + wire = NULL; + x0 = csch_alien_coord_x(&rctx->alien, x); + y0 = csch_alien_coord_y(&rctx->alien, y); + bbox.x1 = x0 - 1; + bbox.y1 = y0 - 1; + bbox.x2 = bbox.x1 + 2; + bbox.y2 = bbox.y1 + 2; + for(wire = csch_rtree_first(&it, &sheet->dsply[CSCH_DSPLY_WIRE], &bbox); wire != NULL; wire = csch_rtree_next(&it)) + if ((wire->hdr.type == CSCH_CTYPE_LINE) && (wire->hdr.parent->role == CSCH_ROLE_WIRE_NET)) + break; + + if (wire == NULL) { + csch_comm_str_t pen; + + /* net labels may be placed on terminals... */ + for(term = csch_rtree_first(&it, &sheet->dsply[CSCH_DSPLY_HUBTERM], &bbox); wire != NULL; wire = csch_rtree_next(&it)) + if ((term->hdr.type == CSCH_CTYPE_LINE) && (term->hdr.parent->role == CSCH_ROLE_TERMINAL)) + break; + + if (term == NULL) { + error(rec, ("altium_parse_net_labels(): label '%s' not on wire line or terminal line - ignoring this label\n", name)); + return 0; + } + + + /* when placed on terminal, the closest thing we can do is a short stub + wirenet that should not intersect with anything else */ + pen = csch_comm_str(rctx->alien.sheet, "wire", 1); + wire = (csch_line_t *)csch_wirenet_draw(rctx->alien.sheet, pen, x0, y0, x0+100, y0+100); + } + + if (wire != NULL) { + text = (csch_text_t *)csch_alien_mktext(&rctx->alien, wire->hdr.parent, x, y, "wire"); + text->text = rnd_strdup("%../A.name%"); + text->dyntext = 1; + text->hdr.floater = 1; + text->spec_rot = ori * 90; + src = csch_attrib_src_c(rctx->fn, rec->idx+1, 0, NULL); + csch_attrib_set(&wire->hdr.parent->attr, CSCH_ATP_USER_DEFAULT, "name", name, src, NULL); + } + } + + return 0; +} + +typedef struct { int x, y; } alti_sheet_size_t; +static alti_sheet_size_t alti_sheet_sizes[] = { + {1150, 760}, + {1550, 1110}, + {2230, 1570}, + {3150, 2230}, + {4460, 3150}, + {950, 750}, + {1500, 950}, + {2000, 1500}, + {3200, 2000}, + {4200, 3200}, + {1100, 850}, + {1400, 850}, + {1700, 1100}, + {990, 790}, + {1540, 990}, + {2060, 1560}, + {3260, 2060}, + {4280, 3280} +}; /* size sourc: https://github.com/gsuberland/altium_js */ + + +static int altium_parse_sheet_conf(io_altium_rctx_t *rctx) +{ + altium_record_t *rec; + altium_field_t *field; + long csx = -1, csy = -1, sx, sy, marg = -1; + int bon = 0, sstyle = 0, cus = 0; + + rec = gdl_first(&rctx->tree.rec[altium_kw_record_31]); + if (rec == NULL) + return 0; + + if (gdl_next(&rctx->tree.rec[altium_kw_record_31], rec) != NULL) + error(rec, ("altium_parse_sheet_conf(): multiple RECORD=31 lines are not accepted\n")); + + for(field = gdl_first(&rec->fields); field != NULL; field = gdl_next(&rec->fields, field)) { + switch(field->type) { + case altium_kw_field_customx: csx = conv_long_field(field); break; + case altium_kw_field_customy: csy = conv_long_field(field); break; + case altium_kw_field_sheetstyle: sstyle = conv_long_field(field); break; + case altium_kw_field_usecustomsheet: cus = field->val.str[0] == 'T'; break; + case altium_kw_field_borderon: bon = field->val.str[0] == 'T'; break; + case altium_kw_field_custommarginwidth: marg = conv_long_field(field); break; + default: break; + } + } + + if (cus) { + if ((csx < 0) || (csy < 0)) { + error(rec, ("altium_parse_sheet_conf(): missing CUSTOMX or CUSTOMY when USECUSTOMSHEET is T\n")); + return -1; + } + sx = csx; + sy = csy; + } + else { + if (sstyle < 0) { + error(rec, ("altium_parse_sheet_conf(): missing SHEETSTYLE when USECUSTOMSHEET is false\n")); + return -1; + } + if ((sstyle < 0) || (sstyle >= sizeof(alti_sheet_sizes)/sizeof(alti_sheet_sizes[0]))) { + error(rec, ("altium_parse_sheet_conf(): unknown SHEETSTYLE value: %d\n", sstyle)); + return -1; + } + sx = alti_sheet_sizes[sstyle].x; + sy = alti_sheet_sizes[sstyle].y; + } + + if (bon) { + if ((sx > 0) && (sy > 0)) { + csch_chdr_t *poly = csch_alien_mkpoly(&rctx->alien, &rctx->alien.sheet->direct, "titlebox-frame", NULL); + csch_alien_append_poly_line(&rctx->alien, poly, 0, 0, sx, 0); + csch_alien_append_poly_line(&rctx->alien, poly, sx, 0, sx, sy); + csch_alien_append_poly_line(&rctx->alien, poly, sx, sy, 0, sy); + csch_alien_append_poly_line(&rctx->alien, poly, 0, sy, 0, 0); + + if (marg > 0) { + csch_chdr_t *poly = csch_alien_mkpoly(&rctx->alien, &rctx->alien.sheet->direct, "titlebox-frame", NULL); + csch_alien_append_poly_line(&rctx->alien, poly, -marg, -marg, sx+marg, -marg); + csch_alien_append_poly_line(&rctx->alien, poly, sx+marg, -marg, sx+marg, sy+marg); + csch_alien_append_poly_line(&rctx->alien, poly, sx+marg, sy+marg, -marg, sy+marg); + csch_alien_append_poly_line(&rctx->alien, poly, -marg, sy+marg, -marg, -marg); + } + } + else + error(rec, ("altium_parse_sheet_conf(): invalid border size\n")); + } + + return 0; +} + + +static int altium_parse_rail_nc(io_altium_rctx_t *rctx, altium_record_t *rec, int is_rail) +{ + csch_sheet_t *sheet = rctx->alien.sheet; + csch_cgrp_t *sym, *pin; + csch_source_arg_t *src; + altium_field_t *field; + long line = rec->idx+1, fonth = 3000; + long plen = 10; + double rlen = 10.0, rrad = 2.5, tall = 0, x = -1, y = -1, xf = 0, yf = 0, dx, dy; + int ori = 0, style = 0; + const char *railname = NULL; + + for(field = gdl_first(&rec->fields); field != NULL; field = gdl_next(&rec->fields, field)) { + switch(field->type) { + case altium_kw_field_text: railname = field->val.str; break; + case altium_kw_field_location_x: x = conv_long_field(field); break; + case altium_kw_field_location_y: y = conv_long_field(field); break; + case altium_kw_field_location_x_frac: xf = conv_long_field(field); break; + case altium_kw_field_location_y_frac: yf = conv_long_field(field); break; + case altium_kw_field_orientation: ori = conv_long_field(field); break; + case altium_kw_field_style: style = conv_long_field(field); break; + default: break; + } + } + + if ((x < 0) || (y < 0)) { + error(rec, ("altium_parse_rail_nc(): rail object without coords\n")); + return -1; + } + + if (ori > 3) { + error(rec, ("altium_parse_rail_nc(): rail object with invalid orientation %d (should be 0..3)\n", ori)); + return -1; + } + + if (is_rail && (railname == NULL)) { + error(rec, ("altium_parse_rail_nc(): rail object without text\n")); + return -1; + } + + if (is_rail && (style < 0)) { + error(rec, ("altium_parse_rail_nc(): rail object without style\n")); + return -1; + } + + x += xf / FRAC_DIV; + y += yf / FRAC_DIV; + + sym = csch_cgrp_alloc(sheet, &sheet->direct, csch_oid_new(sheet, &sheet->direct)); + if (sym == NULL) { + error(rec, ("altium_parse_rail_nc(): Failed to allocate symbol for rail or nc\n")); + return -1; + } + + dx = dy = 0; + switch(ori) { + case 0: dx = +1; break; + case 1: dy = +1; break; + case 2: dx = -1; break; + case 3: dy = -1; break; + } + + + src = csch_attrib_src_c(rctx->fn, line, 0, NULL); + csch_attrib_set(&sym->attr, CSCH_ATP_USER_DEFAULT, "role", "symbol", src, NULL); + sym->role = CSCH_ROLE_SYMBOL; + src = csch_attrib_src_c(rctx->fn, line, 0, NULL); + csch_attrib_set(&sym->attr, CSCH_ATP_USER_DEFAULT, "rail", railname, src, NULL); + + + + if (is_rail) { + double plinelen = plen; + + /* tune the pin line for decoration */ + switch(style) { + case 0: plinelen -= rrad*2; break; + case 3: plinelen -= rrad; break; + case 6: plinelen -= rlen/2; break; + } + + src = csch_attrib_src_c(rctx->fn, line, 0, NULL); + pin = (csch_cgrp_t *)csch_alien_mkpin_line(&rctx->alien, src, sym, x, y, x+dx*plinelen, y+dy*plinelen); + + src = csch_attrib_src_c(rctx->fn, line, 0, NULL); + csch_attrib_set(&pin->attr, CSCH_ATP_USER_DEFAULT, "name", "1", src, NULL); + + + switch(style) { + case 4: /* Gnd */ + tall = rlen/5*3; + csch_alien_mkline(&rctx->alien, sym, + x+dx*plen - dy*rlen/3 + dx*rlen/5, y+dy*plen - dx*rlen/3 + dy*rlen/5, + x+dx*plen + dy*rlen/3 + dx*rlen/5, y+dy*plen + dx*rlen/3 + dy*rlen/5, + "sym-decor"); + csch_alien_mkline(&rctx->alien, sym, + x+dx*plen - dy*rlen/6 + dx*rlen/5*2, y+dy*plen - dx*rlen/6 + dy*rlen/5*2, + x+dx*plen + dy*rlen/6 + dx*rlen/5*2, y+dy*plen + dx*rlen/6 + dy*rlen/5*2, + "sym-decor"); + csch_alien_mkline(&rctx->alien, sym, + x+dx*plen - dy*rlen/12 + dx*rlen/5*3, y+dy*plen - dx*rlen/12 + dy*rlen/5*3, + x+dx*plen + dy*rlen/12 + dx*rlen/5*3, y+dy*plen + dx*rlen/12 + dy*rlen/5*3, + "sym-decor"); + /* fal thru */ + case 2: /* bar */ + csch_alien_mkline(&rctx->alien, sym, + x+dx*plen - dy*rlen/2, y+dy*plen - dx*rlen/2, + x+dx*plen + dy*rlen/2, y+dy*plen + dx*rlen/2, + "sym-decor"); + break; + + case 6: /* earth */ + csch_alien_mkline(&rctx->alien, sym, + x+dx*plinelen - dy*rlen/2, y+dy*plinelen - dx*rlen/2, + x+dx*plinelen + dy*rlen/2, y+dy*plinelen + dx*rlen/2, + "sym-decor"); + + csch_alien_mkline(&rctx->alien, sym, + x+dx*plinelen - dy*rlen/2, y+dy*plinelen - dx*rlen/2, + x+dx*plen - dy*rlen/2 + dy*rlen/3, y+dy*plen - dx*rlen/2 + dx*rlen/3, + "sym-decor"); + + csch_alien_mkline(&rctx->alien, sym, + x+dx*plinelen, y+dy*plinelen, + x+dx*plen + dy*rlen/3, y+dy*plen + dx*rlen/3, + "sym-decor"); + + csch_alien_mkline(&rctx->alien, sym, + x+dx*plinelen + dy*rlen/2, y+dy*plinelen + dx*rlen/2, + x+dx*plen + dy*rlen/2 + dy*rlen/3, y+dy*plen + dx*rlen/2 + dx*rlen/3, + "sym-decor"); + break; + + case 0: /* circle */ + csch_alien_mkarc(&rctx->alien, sym, + x+dx*plen-dx*rrad, y+dy*plen-dy*rrad, rrad, 0, 360, + "sym-decor"); + break; + + case 3: /* wave */ + csch_alien_mkarc(&rctx->alien, sym, + x+dx*plinelen + dy*rrad, y+dy*plinelen, rrad, 180, 180, + "sym-decor"); + csch_alien_mkarc(&rctx->alien, sym, + x+dx*plinelen - dy*rrad, y+dy*plinelen, rrad, 0, 180, + "sym-decor"); + break; + + case 1: /* triangle */ + csch_alien_mkline(&rctx->alien, sym, + x+dx*plen - dy*rlen/8, y+dy*plen - dx*rlen/4, + x+dx*plen + dy*rlen/8, y+dy*plen + dx*rlen/4, + "sym-decor"); + + csch_alien_mkline(&rctx->alien, sym, + x+dx*plen - dy*rlen/8, y+dy*plen - dx*rlen/4, + x+dx*plen, y+dy*plen + dy*rlen/4, + "sym-decor"); + + csch_alien_mkline(&rctx->alien, sym, + x+dx*plen + dy*rlen/8, y+dy*plen - dx*rlen/4, + x+dx*plen, y+dy*plen + dy*rlen/4, + "sym-decor"); + break; + + case 5: /* sig-gnd: big triangle */ + csch_alien_mkline(&rctx->alien, sym, + x+dx*plen - dy*rlen/4, y+dy*plen - dx*rlen/4, + x+dx*plen + dy*rlen/4, y+dy*plen + dx*rlen/4, + "sym-decor"); + + csch_alien_mkline(&rctx->alien, sym, + x+dx*plen - dy*rlen/4, y+dy*plen - dx*rlen/4, + x+dx*plen, y+dy*plen + dy*rlen/4, + "sym-decor"); + + csch_alien_mkline(&rctx->alien, sym, + x+dx*plen + dy*rlen/4, y+dy*plen - dx*rlen/4, + x+dx*plen, y+dy*plen + dy*rlen/4, + "sym-decor"); + break; + + default: + error(rec, ("altium_parse_rail_nc(): invalid style %d\n", style)); + } + } + else { + double xlen = rlen * 0.8; + + /* support the no-connet 'X' only for now */ + x -= dy * plen + dx * plen; + y -= dy * plen + dx * plen; + + csch_alien_mkline(&rctx->alien, sym, + x+plen - xlen/2, y+plen - xlen/2, + x+plen + xlen/2, y+plen + xlen/2, + "sym-decor"); + + csch_alien_mkline(&rctx->alien, sym, + x+plen + xlen/2, y+plen - xlen/2, + x+plen - xlen/2, y+plen + xlen/2, + "sym-decor"); + } + + if (railname != NULL) { + csch_text_t *text; + long tcx, tcy, tcx2, ext; + int has_bbox = 0, align; + + switch(ori) { + case 1: /* vertical pin, text is horizontal, centered */ + case 3: + ext = strlen(railname); + tcx = x+dx*plen - dy*rlen*ext/4; + tcx2 = x+dx*plen + dy*rlen*ext/4; + if (tcx > tcx2) { + tcy = tcx; + tcx = tcx2; + tcx2 = tcy; + } + if (dy < 0) + tcy = y+dy*plen*2 - tall - dx*rlen/2; + else + tcy = y+dy*plen + tall - dx*rlen/2; + has_bbox = 1; + align = CSCH_HALIGN_CENTER; + break; + case 0: /* horizontal text, left aligned */ + tcx = x+dx*plen + fonth/rctx->alien.coord_factor/5 + tall; + tcy = y+dy*plen - fonth/rctx->alien.coord_factor/2; + align = CSCH_HALIGN_START; + break; + case 2: /* horizontal text, right aligned */ + tcx2 = x+dx*plen - fonth/rctx->alien.coord_factor/10 - tall; + tcx = x+dx*plen - fonth/rctx->alien.coord_factor*strlen(railname) - tall; + tcy = y+dy*plen - fonth/rctx->alien.coord_factor/2; + has_bbox = 1; + align = CSCH_HALIGN_END; + break; + } + + text = (csch_text_t *)csch_alien_mktext(&rctx->alien, sym, tcx, tcy, "sym-primary"); + text->text = rnd_strdup(railname); + text->dyntext = 1; + text->has_bbox = has_bbox; + text->spec2.x = csch_alien_coord_x(&rctx->alien, tcx2); + text->spec2.y = text->spec1.y+fonth; + text->halign = align; + } + + /* create the connect arrya attrib to make the actual connection */ + if (is_rail && (railname != NULL)) { + vts0_t val = {0}; + gds_t tmp = {0}; + + gds_append_str(&tmp, "1:"); + gds_append_str(&tmp, railname); + val.array = &tmp.array; + val.used = val.alloced = 1; + + src = csch_attrib_src_c(rctx->fn, line, 0, NULL); + csch_attrib_set_arr(&sym->attr, CSCH_ATP_USER_DEFAULT, "connect", &val, src, NULL); + } + return 0; +} + + +static int altium_parse_rails_ncs(io_altium_rctx_t *rctx) +{ + altium_record_t *rec; + + for(rec = gdl_first(&rctx->tree.rec[altium_kw_record_17]); rec != NULL; rec = gdl_next(&rctx->tree.rec[altium_kw_record_17], rec)) + if (altium_parse_rail_nc(rctx, rec, 1) != 0) + return -1; + + for(rec = gdl_first(&rctx->tree.rec[altium_kw_record_22]); rec != NULL; rec = gdl_next(&rctx->tree.rec[altium_kw_record_22], rec)) + if (altium_parse_rail_nc(rctx, rec, 0) != 0) + return -1; + + return 0; +} + +static csch_chdr_t *alti_mkportbox(io_altium_rctx_t *rctx, csch_cgrp_t *parent, double rx1, double ry1, double rx2, double ry2, double left, double right) +{ + csch_chdr_t *poly = csch_alien_mkpoly(&rctx->alien, parent, "sym-decor", "sym-decor-fill"); + + csch_alien_append_poly_line(&rctx->alien, poly, rx1+left, ry1, rx2-right, ry1); + csch_alien_append_poly_line(&rctx->alien, poly, rx2-right, ry1, rx2, 0); + csch_alien_append_poly_line(&rctx->alien, poly, rx2, 0, rx2-right, ry2); + csch_alien_append_poly_line(&rctx->alien, poly, rx2-right, ry2, rx1+left, ry2); + csch_alien_append_poly_line(&rctx->alien, poly, rx1+left, ry2, rx1, 0); + csch_alien_append_poly_line(&rctx->alien, poly, rx1, 0, rx1+left, ry1); + + return poly; +} + + +static int altium_parse_port(io_altium_rctx_t *rctx, altium_record_t *rec) +{ + csch_sheet_t *sheet = rctx->alien.sheet; + csch_cgrp_t *sym; + csch_source_arg_t *src; + altium_field_t *field; + long line = rec->idx+1, fonth = 3000, width, height; + double x = -1, y = -1, xf = 0, yf = 0, x1, y1, x2, y2, rx1, ry1, rx2, ry2, rot, textrot, textdx, textdy, left, right, ox, tmx1, tmx2; + int iotype = 3, style = 0, alignment = 0; + const char *name = NULL; + + for(field = gdl_first(&rec->fields); field != NULL; field = gdl_next(&rec->fields, field)) { + switch(field->type) { + case altium_kw_field_name: name = field->val.str; break; + case altium_kw_field_location_x: x = conv_long_field(field); break; + case altium_kw_field_location_y: y = conv_long_field(field); break; + case altium_kw_field_location_x_frac: xf = conv_long_field(field); break; + case altium_kw_field_location_y_frac: yf = conv_long_field(field); break; + case altium_kw_field_iotype: iotype = conv_long_field(field); break; + case altium_kw_field_style: style = conv_long_field(field); break; + case altium_kw_field_width: width = conv_long_field(field); break; + case altium_kw_field_height: height = conv_long_field(field); break; + case altium_kw_field_alignment: alignment = conv_long_field(field); break; + default: break; + } + } + + if ((x < 0) || (y < 0)) { + error(rec, ("altium_parse_port(): port without coords\n")); + return -1; + } + + if (name == NULL) { + error(rec, ("altium_parse_port(): port without name\n")); + return -1; + } + + x += xf / FRAC_DIV; + y += yf / FRAC_DIV; + + sym = csch_cgrp_alloc(sheet, &sheet->direct, csch_oid_new(sheet, &sheet->direct)); + if (sym == NULL) { + error(rec, ("altium_parse_port(): Failed to allocate symbol for rail or nc\n")); + return -1; + } + + rot = textrot = textdx = textdy = 0; + ox = 0; + tmx1 = 1; + tmx2 = -1; + switch(style) { + case 3: rot = 180; textrot = 180; ox = -width; textdx = width; textdy = height; tmx1 = -1; tmx2 = -3; break; + case 6: rot = 90; break; +TODO("figure the other directions"); + } + + /* mark target coord for debug */ + /* csch_alien_mkarc(&rctx->alien, &rctx->alien.sheet->direct, x, y, 1, 0, 360, "sheet-decor"); */ + + + x1 = ox; + y1 = 0; + x2 = ox + width; + y2 = -height; + + rx1 = ox; + ry1 = 0 + height/2; + rx2 = x2; + ry2 = y2 + height/2; + + src = csch_attrib_src_c(rctx->fn, line, 0, NULL); + csch_attrib_set(&sym->attr, CSCH_ATP_USER_DEFAULT, "role", "symbol", src, NULL); + sym->role = CSCH_ROLE_SYMBOL; + src = csch_attrib_src_c(rctx->fn, line, 0, NULL); + csch_attrib_set(&sym->attr, CSCH_ATP_USER_DEFAULT, "rail", name, src, NULL); + + + src = csch_attrib_src_c(rctx->fn, line, 0, NULL); + csch_alien_mkpin_line(&rctx->alien, src, sym, x1, 0, x1+1, 0); + + if (style == 3) { + src = csch_attrib_src_c(rctx->fn, line, 0, NULL); + csch_alien_mkpin_line(&rctx->alien, src, sym, x2, 0, x2-1, 0); + } + + left = right = 0; + switch(iotype) { + case 0: + case 1: + case 2: + left = height/2; + break; + case 3: + left = height/2; + right = height/2; + break; + } + + alti_mkportbox(rctx, sym, rx1, ry1, rx2, ry2, left, right); + + { + csch_text_t *text; + long tcx = rx1 + textdx + height/2 * tmx1, tcy = (y1+y2)/2 + textdy, tcx2 = rx2 + textdx + height/2 * tmx2; + + text = (csch_text_t *)csch_alien_mktext(&rctx->alien, sym, tcx, tcy, "sym-primary"); + text->text = rnd_strdup(name); + text->dyntext = 1; + text->has_bbox = 1; + text->spec2.x = csch_alien_coord_x(&rctx->alien, tcx2); + text->spec2.y = text->spec1.y+fonth; + text->spec_rot = textrot; + switch(alignment) { + case 0: text->halign = CSCH_HALIGN_CENTER; break; + case 1: text->halign = CSCH_HALIGN_START; break; + } + } + + sym->x = csch_alien_coord_x(&rctx->alien, x); + sym->y = csch_alien_coord_y(&rctx->alien, y); + sym->spec_rot = rot; + + return 0; +} + +static int altium_parse_shref_port(io_altium_rctx_t *rctx, altium_record_t *rec) +{ + csch_cgrp_t *parent, *pin; + csch_source_arg_t *src; + altium_field_t *field; + long line = rec->idx+1, pidx = -1; + const char *name = NULL, *arrowkind = NULL; + char *dummy; + long side = 0, distancefromtop = -1, style = 0, step = 10, iotype = -1; + double x1, y1, x2, y2, x, y, plen = 15, left = 5, right = 5; + double fonth = 3000.0, fh = fonth/rctx->alien.coord_factor/2.0, tcx, tcy; + csch_text_t *text; + + for(field = gdl_first(&rec->fields); field != NULL; field = gdl_next(&rec->fields, field)) { + switch(field->type) { + case altium_kw_field_name: name = field->val.str; break; + case altium_kw_field_ownerindex: pidx = conv_long_field(field); break; +/* case altium_kw_field_ownerpartid: opartid = field->val.str; break;*/ +/* case altium_kw_field_ownerpartdisplaymode: opartdsp = field->val.str; break;*/ + case altium_kw_field_arrowkind: arrowkind = field->val.str; break; + case altium_kw_field_side: side = conv_long_field(field); break; + case altium_kw_field_style: style = conv_long_field(field); break; + case altium_kw_field_iotype: iotype = conv_long_field(field); break; + case altium_kw_field_distancefromtop: distancefromtop = conv_long_field(field); break; + default: break; + } + } + + parent = altium_get_parent(rctx, rec, pidx, 0, &dummy, &dummy); + if (parent == NOGRP) + return 0; + if (parent == NULL) + return -1; + + x1 = 0; y1 = 0; + x2 = x1 + parent->xform.x; y2 = y1 - parent->xform.y; /* fields are abused to remember sx and sy */ + + + switch(side) { + case 0: /* left */ + x = x1; y = y1; + y -= distancefromtop * step; + break; + case 1: /* right */ + x = x2; y = y1; + y -= distancefromtop * step; + break; + case 2: /* top */ + x = x1; y = y1; + x += distancefromtop * step; + break; + case 3: /* bottom */ + x = x1; y = y2; + x += distancefromtop * step; + break; + default: + error(rec, ("altium_parse_shref_port(): invalid side: %d\n", side)); + return -1; + } + + switch(style) { + case 0: /* none, horiz */ left = right = 0; break; + case 1: /* left */ left = 0; break; + case 2: /* right */ right = 0; break; + case 3: /* left and right */ break; + case 4: /* none, vert */ left = right = 0; break; + case 5: /* top */ left = 0; break; + case 6: /* bottom */ right = 0; break; + case 7: /* top and bottom */ break; + } + + switch(iotype) { + case 1: /* output */ right = 0; break; + case 2: /* input */ left = 0; break; + case 3: /* bidir */ break; + } + + tcx = plen+5; + tcy = -fh; + + if (arrowkind != NULL) { + if (strcmp(arrowkind, "Arrow Tail") == 0) { + right = -5; + plen -= 5; + } + else if (strcmp(arrowkind, "Triangle") == 0) { + plen = 10; + } + /* arrow not yet supported */ + } + + src = csch_attrib_src_c(rctx->fn, line, 0, NULL); + pin = (csch_cgrp_t *)csch_alien_mkpin_line(&rctx->alien, src, parent, 0, 0, 2, 0); + pin->x = csch_alien_coord_x(&rctx->alien, x); + pin->y = csch_alien_coord_y(&rctx->alien, y); + alti_mkportbox(rctx, pin, 0, +4, plen, -4, left, right); + + + text = (csch_text_t *)csch_alien_mktext(&rctx->alien, pin, tcx, tcy, "sym-primary"); + text->text = rnd_strdup(name); + + switch(side) { + case 0: break; + case 1: pin->mirx = 1; break; + case 2: pin->spec_rot = -90; pin->mirx = 1; break; + case 3: pin->spec_rot = 90; break; + } + + return 0; +} + +static int altium_parse_ports(io_altium_rctx_t *rctx) +{ + altium_record_t *rec; + + for(rec = gdl_first(&rctx->tree.rec[altium_kw_record_18]); rec != NULL; rec = gdl_next(&rctx->tree.rec[altium_kw_record_18], rec)) + if (altium_parse_port(rctx, rec) != 0) + return -1; + + for(rec = gdl_first(&rctx->tree.rec[altium_kw_record_16]); rec != NULL; rec = gdl_next(&rctx->tree.rec[altium_kw_record_16], rec)) + if (altium_parse_shref_port(rctx, rec) != 0) + return -1; + + return 0; +} + +static void TEXT_JUST(io_altium_rctx_t *rctx, altium_record_t *rec, csch_text_t *text, int just) +{ + csch_coord_t fh = 3000; + +/* 1=bottom center + 2=bottom right + 3=center left + 4=center center + 5=center right + 6=top left + 7=top center + 8=top right */ + + /* horizontal component */ + switch(just) { + case 0: case 3: case 6: break; /* left */ + case 1: case 4: case 7: break; /* center: can't do without bbox based */ + case 2: case 5: case 8: text->spec_mirx = 1; break; /* right */ + default: + error(rec, ("altium_parse_note(): invalid justification value %d\n", just)); + } + + switch(just) { + case 0: case 1: case 2: break; /* bottom */ + case 3: case 4: case 5: text->spec1.y -= fh/2; break; /* center */ + case 6: case 7: case 8: text->spec1.y -= fh; break; /* top */ + } + +} + +static int altium_parse_note(io_altium_rctx_t *rctx, altium_record_t *rec, int has_frame, int fold_corner, int allow_multiline) +{ + altium_field_t *field; + csch_cgrp_t *parent; + long x1 = 0, y1 = 0, x2 = -1, y2 = -1, aclr = -1, rad = 5, fonth = 3000, pidx = -1; + int is_solid = 0, just = 0, ori = 0; + char *stroke, *fill, *textstr = NULL; + const char *opartid = NULL, *opartdsp = NULL; + + for(field = gdl_first(&rec->fields); field != NULL; field = gdl_next(&rec->fields, field)) { + switch(field->type) { + case altium_kw_field_ownerindex: pidx = conv_long_field(field); break; + case altium_kw_field_ownerpartid: opartid = field->val.str; break; + case altium_kw_field_ownerpartdisplaymode: opartdsp = field->val.str; break; + case altium_kw_field_text: textstr = (char *)field->val.str; break; + case altium_kw_field_location_x: x1 = conv_long_field(field); break; + case altium_kw_field_location_y: y1 = conv_long_field(field); break; + case altium_kw_field_corner_x: x2 = conv_long_field(field); break; + case altium_kw_field_corner_y: y2 = conv_long_field(field); break; + case altium_kw_field_areacolor: aclr = conv_long_field(field); break; + case altium_kw_field_showborder: if (field->val.str[0] == 'T') has_frame = 1; break; + case altium_kw_field_issolid: is_solid = field->val.str[0] == 'T'; break; + case altium_kw_field_justification: just = conv_long_field(field); break; + case altium_kw_field_orientation: ori = conv_long_field(field); break; + + default: break; + } + } + + if (allow_multiline && ((x2 < 0) || (y2 < 0))) { + error(rec, ("altium_parse_note(): note rectangle without coords (end)\n")); + return -1; + } + + if (aclr > 0) + is_solid = alti_is_dark(aclr); + + parent = altium_get_parent(rctx, rec, pidx, is_solid, &stroke, &fill); + if (parent == NOGRP) + return 0; + if (parent == NULL) + return -1; + + if (alti_slot_skip(parent, opartid, opartdsp)) + return 0; + + if (has_frame) { + csch_chdr_t *poly = csch_alien_mkpoly(&rctx->alien, parent, stroke, fill); + + if (poly == NULL) { + error(rec, ("altium_parse_note(): failed to create poly\n")); + return -1; + } + + if (fold_corner) { + csch_alien_append_poly_line(&rctx->alien, poly, x1, y1, x2-rad, y1); + csch_alien_append_poly_line(&rctx->alien, poly, x2-rad, y1, x2, y1+rad); + csch_alien_append_poly_line(&rctx->alien, poly, x2, y1+rad, x2, y2); + csch_alien_append_poly_line(&rctx->alien, poly, x2, y2, x1, y2); + csch_alien_append_poly_line(&rctx->alien, poly, x1, y2, x1, y1); + } + else { + csch_alien_append_poly_line(&rctx->alien, poly, x1, y1, x2, y1); + csch_alien_append_poly_line(&rctx->alien, poly, x2, y1, x2, y2); + csch_alien_append_poly_line(&rctx->alien, poly, x2, y2, x1, y2); + csch_alien_append_poly_line(&rctx->alien, poly, x1, y2, x1, y1); + } + } + + if (textstr != NULL) { + csch_text_t *text; + + if (allow_multiline) { + char *curr, *next = NULL; + long step = fonth/rctx->alien.coord_factor*1.2, y; + + TODO("multiline: rewrite this when we have multi-line text support - but keep ~ escaping: ~1 is newline, ~~1 is escaped ~1"); + for(y = y2-step, curr = textstr; curr != NULL; y-=step, curr = next) { + char *srch = curr; + int has_escaped = 0; + + /* search next non-escaped ~1 for newline */ + for(;;) { + next = strchr(srch, '~'); /* handle only ~1 for now */ + if ((next == NULL) || (next[1] != '~')) + break; + srch = next+2; + has_escaped = 1; + } + + if (next != NULL) { + *next = '\0'; + next += 2; + } + if (*curr != '\0') { + text = (csch_text_t *)csch_alien_mktext(&rctx->alien, parent, x1, y, "sheet-decor"); + text->text = rnd_strdup(curr); + if (has_escaped) { /* remove duplicate ~ from escaped ~~1 */ + char *si, *so; + for(si = so = text->text; *si != '\0'; si++,so++) { + if ((si[0] == '~') && (si[1] == '~')) + si++; + if (si != so) + *so = *si; + } + *so = '\0'; + } + TEXT_JUST(rctx, rec, text, just); + } + } + } + else { + text = (csch_text_t *)csch_alien_mktext(&rctx->alien, parent, x1, y1, "sheet-decor"); + text->text = rnd_strdup(textstr); + text->spec_rot = ori * 90; + TEXT_JUST(rctx, rec, text, just); + } + } + + return 0; +} + +static int altium_parse_notes(io_altium_rctx_t *rctx) +{ + altium_record_t *rec; + + for(rec = gdl_first(&rctx->tree.rec[altium_kw_record_4]); rec != NULL; rec = gdl_next(&rctx->tree.rec[altium_kw_record_4], rec)) + if (altium_parse_note(rctx, rec, 0, 0, 0) != 0) + return -1; + + for(rec = gdl_first(&rctx->tree.rec[altium_kw_record_28]); rec != NULL; rec = gdl_next(&rctx->tree.rec[altium_kw_record_28], rec)) + if (altium_parse_note(rctx, rec, 1, 0, 1) != 0) + return -1; + + for(rec = gdl_first(&rctx->tree.rec[altium_kw_record_209]); rec != NULL; rec = gdl_next(&rctx->tree.rec[altium_kw_record_209], rec)) + if (altium_parse_note(rctx, rec, 1, 1, 1) != 0) + return -1; + + + return 0; +} + + +static int altium_parse_junction(io_altium_rctx_t *rctx, altium_record_t *rec) +{ + csch_sheet_t *sheet = rctx->alien.sheet; + altium_field_t *field; + long x = -1, y = -1; + csch_rtree_it_t it; + csch_rtree_box_t bbox; + csch_chdr_t *wire, *wires[128]; + int n, numw = 0; + + for(field = gdl_first(&rec->fields); field != NULL; field = gdl_next(&rec->fields, field)) { + switch(field->type) { + case altium_kw_field_location_x: x = conv_long_field(field); break; + case altium_kw_field_location_y: y = conv_long_field(field); break; + default: break; + } + } + + if ((x < 0) || (y < 0)) { + error(rec, ("altium_parse_junction(): missing coords\n")); + return -1; + } + + + wire = NULL; + bbox.x1 = csch_alien_coord_x(&rctx->alien, x); + bbox.y1 = csch_alien_coord_y(&rctx->alien, y); + bbox.x2 = bbox.x1 + 1; + bbox.y2 = bbox.y1 + 1; + for(wire = csch_rtree_first(&it, &sheet->dsply[CSCH_DSPLY_WIRE], &bbox); wire != NULL; wire = csch_rtree_next(&it)) { + if ((wire->type == CSCH_CTYPE_LINE) && (wire->parent->role == CSCH_ROLE_WIRE_NET)) { + int skip = 0; + + /* add only unique wirenets */ + for(n = 0; n < numw; n++) { + if (wires[n]->parent == wire->parent) { + skip = 1; + break; + } + } + + if (!skip) { + wires[numw] = wire; + numw++; + if (numw >= (sizeof(wires)/sizeof(wires[0]))) { + error(rec, ("altium_parse_junction(): too many wires at %ld %ld\n", x, y)); + return -1; + } + } + } + } + + /* debug drawing of junction locations */ + if (0) { + csch_alien_mkarc(&rctx->alien, &rctx->alien.sheet->direct, x, y, 6, 0, 360, "sheet-decor"); + if (numw > 1) + csch_alien_mkarc(&rctx->alien, &rctx->alien.sheet->direct, x, y, 8, 0, 360, "sheet-decor"); + } + + /* merge wirenets to get junctions; only if there are at least two different + wirenets found at the junction location (else ignore the junction) */ + if (numw < 2) + return 0; + + wires[0]->parent->role = 0; /* disable side effects during the merge */ + for(n = 1; n < numw; n++) { + wires[0]->parent->role = 0; + csch_op_merge_into(sheet, wires[0]->parent, wires[n]->parent); + wires[0]->parent->role = CSCH_ROLE_WIRE_NET; + } + wires[0]->parent->role = CSCH_ROLE_WIRE_NET; + csch_wirenet_recalc_junctions(sheet, wires[0]->parent); + + return 0; +} + +static int altium_parse_junctions(io_altium_rctx_t *rctx) +{ + altium_record_t *rec; + + for(rec = gdl_first(&rctx->tree.rec[altium_kw_record_29]); rec != NULL; rec = gdl_next(&rctx->tree.rec[altium_kw_record_29], rec)) + if (altium_parse_junction(rctx, rec) != 0) + return -1; + + return 0; +} + +static void *altium_prealloc_sym(io_altium_rctx_t *rctx, altium_record_t *rec) +{ + csch_cgrp_t *parent = &rctx->alien.sheet->direct; + csch_cgrp_t *sym; + altium_field_t *field; + csch_source_arg_t *src; + + src = csch_attrib_src_c(rctx->fn, rec->idx+1, 0, NULL); + sym = csch_cgrp_alloc(rctx->alien.sheet, parent, csch_oid_new(rctx->alien.sheet, parent)); + csch_cobj_attrib_set(rctx->alien.sheet, sym, CSCH_ATP_HARDWIRED, "role", "symbol", src); + sym->role = CSCH_ROLE_SYMBOL; + + for(field = gdl_first(&rec->fields); field != NULL; field = gdl_next(&rec->fields, field)) { + switch(field->type) { + case altium_kw_field_currentpartid: + src = csch_attrib_src_c(rctx->fn, rec->idx+1, 0, NULL); + csch_cobj_attrib_set(rctx->alien.sheet, sym, CSCH_ATP_HARDWIRED, "-currentpartid", field->val.str, src); + break; + default: break; + } + } + return sym; +} + +#define allocdst() \ +do { \ + if (*dst == NULL) { \ + *dst = csch_cgrp_alloc(rctx->alien.sheet, pin, csch_oid_new(rctx->alien.sheet, pin)); \ + if (*dst == NULL) { \ + error(rec, ("alti_pin_gfx_inside(): Failed to allocate group for pin gfx\n")); \ + return 0; \ + } \ + } \ +} while(0) + +#define diamond(top, mid, bot) \ +do { \ + csch_alien_mkline(&rctx->alien, *dst, 0, 0, -2, -2, pen); \ + csch_alien_mkline(&rctx->alien, *dst, -2, -2, -4, 0, pen); \ + csch_alien_mkline(&rctx->alien, *dst, -4, -0, -2, +2, pen); \ + csch_alien_mkline(&rctx->alien, *dst, -2, +2, 0, 0, pen); \ + if (bot) \ + csch_alien_mkline(&rctx->alien, *dst, +0.5, -2, -4.5, -2, pen); \ + if (mid) \ + csch_alien_mkline(&rctx->alien, *dst, +0.5, 0, -4.5, 0, pen); \ + if (top) \ + csch_alien_mkline(&rctx->alien, *dst, +0.5, +2, -4.5, +2, pen); \ +} while(0) + +/* Return horizontal size of graphics in altium coords. Graphics is drawn in *dst. */ +static int alti_pin_gfx_inside(io_altium_rctx_t *rctx, altium_record_t *rec, csch_cgrp_t *pin, csch_cgrp_t **dst, long inr, long ine, int textrot) +{ + const char *pen = "term-decor"; + int ox = 0; + + *dst = NULL; + + switch(ine) { + case 3: /* clock */ + allocdst(); + csch_alien_mkline(&rctx->alien, *dst, +2, +2, -2, 0, pen); + csch_alien_mkline(&rctx->alien, *dst, +2, -2, -2, 0, pen); + ox = 2; + break; + } + + switch(inr) { + case -1: + case 0: + return ox; + + case 8: /* postponed */ + allocdst(); + csch_alien_mkline(&rctx->alien, *dst, 0, 0+1, 0, +3+1, pen); + csch_alien_mkline(&rctx->alien, *dst, 0, +3+1, -3, +3+1, pen); + return 5+ox; + + + case 9: /* open collector */ + allocdst(); + diamond(0, 0, 1); + return 5+ox; + + case 10: /* hiz */ + allocdst(); + csch_alien_mkline(&rctx->alien, *dst, 0, +1.5, -3, +1.5, pen); + csch_alien_mkline(&rctx->alien, *dst, 0, +1.5, -1.5, -2, pen); + csch_alien_mkline(&rctx->alien, *dst, -3, +1.5, -1.5, -2, pen); + return 5+ox; + + case 11: /* high current */ + allocdst(); + csch_alien_mkline(&rctx->alien, *dst, 0, 0, -3.5, +1.5, pen); + csch_alien_mkline(&rctx->alien, *dst, 0, 0, -3.5, -1.5, pen); + csch_alien_mkline(&rctx->alien, *dst, -3.5, +1.5, -3.5, -1.5, pen); + return 5+ox; + + case 12: /* pulse */ + allocdst(); + csch_alien_mkline(&rctx->alien, *dst, 0, 0, -2, 0, pen); + csch_alien_mkline(&rctx->alien, *dst, -2, 0, -2, +2, pen); + csch_alien_mkline(&rctx->alien, *dst, -2, +2, -4, +2, pen); + csch_alien_mkline(&rctx->alien, *dst, -4, +2, -4, 0, pen); + csch_alien_mkline(&rctx->alien, *dst, -4, 0, -6, 0, pen); + return 7+ox; + + case 13: /* schmitt */ + { + int sgn = textrot ? -1 : +1; /* don't y-mirror this one on text rotation */ + allocdst(); + csch_alien_mkline(&rctx->alien, *dst, 1, +3*sgn, -1, +2.1*sgn, pen); + csch_alien_mkline(&rctx->alien, *dst, -1, +2.1*sgn, -1, -1.5*sgn, pen); + csch_alien_mkline(&rctx->alien, *dst, -1, -1.5*sgn, -8, -3*sgn, pen); + csch_alien_mkline(&rctx->alien, *dst, -8, -3*sgn, -6, -2.1*sgn, pen); + csch_alien_mkline(&rctx->alien, *dst, -6, -2.1*sgn, -6, +1.5*sgn, pen); + csch_alien_mkline(&rctx->alien, *dst, -6, +1.5*sgn, 1, +3*sgn, pen); + } + return 9+ox; + + case 22: /* open collector + pullup */ + allocdst(); + diamond(0, 1, 1); + return 5+ox; + + case 23: /* open emitter */ + allocdst(); + diamond(1, 0, 0); + return 5+ox; + + case 24: /* open emitter + pullup */ + allocdst(); + diamond(1, 1, 0); + return 5+ox; + + case 30: /* shift left */ + allocdst(); + csch_alien_mkline(&rctx->alien, *dst, 0, 0, -2.5, +1.5, pen); + csch_alien_mkline(&rctx->alien, *dst, 0, 0, -2.5, -1.5, pen); + csch_alien_mkline(&rctx->alien, *dst, -2.5, +1.5, -2.5, -1.5, pen); + csch_alien_mkline(&rctx->alien, *dst, -2.5, 0, -4.5, 0, pen); + return 5+ox; + + case 32: /* open output */ + allocdst(); + diamond(0, 0, 0); + return 5+ox; + + + default: + error(rec, ("io_altium: unknown pin inner edge type: %ld\n", inr)); + } + + return ox; +} + +static void *altium_prealloc_pin(io_altium_rctx_t *rctx, altium_record_t *rec) +{ + csch_cgrp_t *parent = NULL, *pin, *igfx = NULL; + csch_source_arg_t *src; + altium_field_t *field; + altium_record_t *prec; + const char *designator = NULL, *name = NULL, *opartid = NULL, *opartdsp = NULL; + double x = 0, y = 0, xf = 0, yf = 0, len = -1, lenf = 0, startx, starty, endx, endy, nameshx; + long pidx = -1, cong = -1, oute = 0, outr = 0, ine = 0, inr = 0, ele = 0; + long r = 3, fonth = 3000; + int textrot, textydir; + + for(field = gdl_first(&rec->fields); field != NULL; field = gdl_next(&rec->fields, field)) { + switch(field->type) { + case altium_kw_field_ownerindex: pidx = conv_long_field(field); break; + case altium_kw_field_ownerpartid: opartid = field->val.str; break; + case altium_kw_field_ownerpartdisplaymode: opartdsp = field->val.str; break; + case altium_kw_field_name: name = field->val.str; break; + case altium_kw_field_designator: designator = field->val.str; break; + case altium_kw_field_location_x: x = conv_long_field(field); break; + case altium_kw_field_location_y: y = conv_long_field(field); break; + case altium_kw_field_location_x_frac: xf = conv_long_field(field); break; + case altium_kw_field_location_y_frac: yf = conv_long_field(field); break; + case altium_kw_field_pinlength: len = conv_long_field(field); break; + case altium_kw_field_pinlength_frac: lenf = conv_long_field(field); break; + case altium_kw_field_pinconglomerate: cong = conv_long_field(field); break; + case altium_kw_field_symbol_outer: outr = conv_long_field(field); break; + case altium_kw_field_symbol_outeredge: oute = conv_long_field(field); break; + case altium_kw_field_symbol_inner: inr = conv_long_field(field); break; + case altium_kw_field_symbol_inneredge: ine = conv_long_field(field); break; + case altium_kw_field_electrical: ele = conv_long_field(field); break; + default: break; + } + } + + if (len < 0) { + error(rec, ("altium_prealloc_pin(): length\n")); + return NULL; + } + + x += (double)xf / FRAC_DIV; + y += (double)yf / FRAC_DIV; + len += (double)lenf / FRAC_DIV; + + if (cong < 0) { + error(rec, ("altium_prealloc_pin(): missing pinconglomerate\n")); + return NULL; + } + + if (pidx >= 0) { + prec = htip_get(&rctx->id2rec, pidx); + if (prec != NULL) + parent = prec->user_data; + } + + if (parent == NULL) { + error(rec, ("altium_prealloc_pin(): missing or invalid ownerindex\n")); + return NULL; + } + + if (alti_slot_skip(parent, opartid, opartdsp)) + return NOGRP; + + /* orientation */ + switch(cong & 0x03) { + case 0: + case 1: textrot = 0; textydir = -1; break; + case 2: + case 3: textrot = 1; textydir = +1; break; + } + + /* room for the decoration */ + startx = x; + starty = y; + switch(oute) { + case 1: /* negation circle */ + startx += 2*r; + break; + case 4: /* low input? */ + case 17: /* low output? */ + break; + } + + endx = x+len; + endy = y; + + src = csch_attrib_src_c(rctx->fn, rec->idx+1, 0, NULL); + pin = (csch_cgrp_t *)csch_alien_mkpin_line(&rctx->alien, src, parent, startx, starty, endx, endy); + + nameshx = alti_pin_gfx_inside(rctx, rec, pin, &igfx, inr, ine, textrot); + + TODO("set attributes for the DRC, once we have a DRC"); + /* decoration on the outside */ + switch(oute) { + case 1: /* negation circle */ + csch_alien_mkarc(&rctx->alien, (csch_cgrp_t *)pin, x+r, y, r, 0, 360, "term-decor"); + break; + case 4: /* active low input */ + csch_alien_mkline(&rctx->alien, (csch_cgrp_t *)pin, startx, starty, startx+5, starty-1.5, "term-decor"); + csch_alien_mkline(&rctx->alien, (csch_cgrp_t *)pin, startx+5, starty-1.5, startx+5, starty, "term-decor"); + break; + case 17: /* active low output */ + csch_alien_mkline(&rctx->alien, (csch_cgrp_t *)pin, startx+5, starty, startx, starty-1.5, "term-decor"); + csch_alien_mkline(&rctx->alien, (csch_cgrp_t *)pin, startx, starty-1.5, startx, starty, "term-decor"); + break; + } + + switch(ele) { + case 4: /* normal */ break; + case 0: /* input */ outr = 2; break; + case 2: /* output */ outr = 33; break; + } + + switch(outr) { + case 2: /* arrow in */ + csch_alien_mkline(&rctx->alien, (csch_cgrp_t *)pin, startx, starty, startx+5, starty-1.5, "term-decor"); + csch_alien_mkline(&rctx->alien, (csch_cgrp_t *)pin, startx, starty, startx+5, starty+1.5, "term-decor"); + csch_alien_mkline(&rctx->alien, (csch_cgrp_t *)pin, startx+5, starty-1.5, startx+5, starty+1.5, "term-decor"); + break; + + case 5: /* analog */ + csch_alien_mkarc(&rctx->alien, (csch_cgrp_t *)pin, startx+2, starty-1.7, 1.5, 0, -180, "term-decor"); + break; + + case 6: /* not logic */ + csch_alien_mkline(&rctx->alien, (csch_cgrp_t *)pin, startx+5, starty+2, startx+1, starty-2, "term-decor"); + csch_alien_mkline(&rctx->alien, (csch_cgrp_t *)pin, startx+5, starty-2, startx+1, starty+2, "term-decor"); + break; + + case 33: /* arrow out */ + csch_alien_mkline(&rctx->alien, (csch_cgrp_t *)pin, startx+5, starty, startx, starty-1.5, "term-decor"); + csch_alien_mkline(&rctx->alien, (csch_cgrp_t *)pin, startx+5, starty, startx, starty+1.5, "term-decor"); + csch_alien_mkline(&rctx->alien, (csch_cgrp_t *)pin, startx, starty-1.5, startx, starty+1.5, "term-decor"); + break; + + case 34: /* arrow in-out */ + /* in */ + csch_alien_mkline(&rctx->alien, (csch_cgrp_t *)pin, startx, starty, startx+4, starty-1.5, "term-decor"); + csch_alien_mkline(&rctx->alien, (csch_cgrp_t *)pin, startx, starty, startx+4, starty+1.5, "term-decor"); + csch_alien_mkline(&rctx->alien, (csch_cgrp_t *)pin, startx+4, starty-1.5, startx+4, starty+1.5, "term-decor"); + + /* out */ + csch_alien_mkline(&rctx->alien, (csch_cgrp_t *)pin, startx+10, starty, startx+6, starty-1.5, "term-decor"); + csch_alien_mkline(&rctx->alien, (csch_cgrp_t *)pin, startx+10, starty, startx+6, starty+1.5, "term-decor"); + csch_alien_mkline(&rctx->alien, (csch_cgrp_t *)pin, startx+6, starty-1.5, startx+6, starty+1.5, "term-decor"); + break; + } + + if (igfx != NULL) { + /* place inner graphics in front of name text; y is aligned with the pin line's */ + igfx->x = csch_alien_coord_x(&rctx->alien, x - 2); + igfx->y = csch_alien_coord_y(&rctx->alien, y); + if (textrot) + igfx->miry = 1; + } + + /* labels and attributes */ + if (name != NULL) { + src = csch_attrib_src_c(rctx->fn, rec->idx+1, 0, NULL); + csch_attrib_set(&pin->attr, CSCH_ATP_USER_DEFAULT, "name", name, src, NULL); + + if (cong & 0x08) { /* show pin name */ + csch_text_t *text = (csch_text_t *)csch_alien_mktext(&rctx->alien, pin, x - 7 - nameshx, y + fonth/rctx->alien.coord_factor/2 * textydir, "sym-decor"); + text->text = rnd_strdup("%../A.name%"); + text->dyntext = 1; + if (textrot) + text->spec_rot = 180; + else + text->spec_mirx = 1; + } + } + + if (designator != NULL) { + src = csch_attrib_src_c(rctx->fn, rec->idx+1, 0, NULL); + csch_attrib_set(&pin->attr, CSCH_ATP_USER_DEFAULT, "pinnum", designator, src, NULL); + + if (cong & 0x10) { /* show pin number (designator) */ + csch_text_t *text = (csch_text_t *)csch_alien_mktext(&rctx->alien, pin, (startx+endx)/2, (starty+endy)/2, "term-primary"); + text->text = rnd_strdup("%../a.display/name%"); + text->dyntext = 1; + if (textrot) { + text->spec_rot = 180; + text->spec_mirx = 1; + } + } + } + + csch_rotate90(parent->hdr.sheet, &pin->hdr, csch_alien_coord_x(&rctx->alien, x), csch_alien_coord_y(&rctx->alien, y), cong & 0x03, 0); + + return pin; +} + +static int altium_map_indices(io_altium_rctx_t *rctx) +{ + altium_record_t *rec; + + for(rec = gdl_first(&rctx->tree.rec[altium_kw_record_1]); rec != NULL; rec = gdl_next(&rctx->tree.rec[altium_kw_record_1], rec)) { + rec->user_data = altium_prealloc_sym(rctx, rec); + htip_set(&rctx->id2rec, rec->idx, rec); + } + + for(rec = gdl_first(&rctx->tree.rec[altium_kw_record_2]); rec != NULL; rec = gdl_next(&rctx->tree.rec[altium_kw_record_2], rec)) { + rec->user_data = altium_prealloc_pin(rctx, rec); + htip_set(&rctx->id2rec, rec->idx, rec); + } + + return 0; +} + +static void rctx_init(io_altium_rctx_t *rctx, csch_sheet_t *dst) +{ + rctx->alien.sheet = dst; + rctx->alien.fmt_prefix = "io_altium"; + rctx->alien.coord_factor = io_altium_conf.plugins.io_altium.coord_mult; + rctx->alien.flip_y = 0; + + htip_init(&rctx->id2rec, longhash, longkeyeq); +} + +static void rctx_uninit(io_altium_rctx_t *rctx) +{ + htip_uninit(&rctx->id2rec); +} + +int altium_parse_sheet(io_altium_rctx_t *rctx, csch_sheet_t *dst) +{ + altium_record_t *rec; + altium_field_t *field; + int res = 0; + + + /* process the header */ + rec = gdl_first(&rctx->tree.rec[altium_kw_record_header]); + if (rec == NULL) { + error(rec, ("altium_parse_sheet(): missing HEADER record\n")); + return -1; + } + field = gdl_first(&rec->fields); + if (field == NULL) { + error(rec, ("altium_parse_sheet(): broken HEADER record\n")); + return -1; + } + + for(field = gdl_first(&rec->fields); field != NULL; field = gdl_next(&rec->fields, field)) { + if (field->type == altium_kw_field_header) { + TODO("save this as a sheet attrib"); + rnd_trace("altium header: '%s'\n", field->val); + } + } + + rctx_init(rctx, dst); + csch_alien_sheet_setup(&rctx->alien, 1); + + res |= altium_map_indices(rctx); + res |= altium_parse_signs(rctx); + res |= altium_parse_sheet_conf(rctx); + res |= altium_parse_arcs(rctx); + res |= altium_parse_beziers(rctx); + res |= altium_parse_polys(rctx); + res |= altium_parse_rects(rctx); + res |= altium_parse_lines(rctx); + res |= altium_parse_net_labels(rctx); /* must be after altium_parse_lines() */ + res |= altium_parse_rails_ncs(rctx); + res |= altium_parse_ports(rctx); + res |= altium_parse_notes(rctx); + res |= altium_parse_attribs(rctx); + res |= altium_parse_junctions(rctx); + + if (res == 0) { + csch_cgrp_render_all(dst, &dst->direct); + res = csch_alien_postproc_sheet(&rctx->alien); + + csch_cgrp_update(dst, &dst->direct, 1); + csch_alien_update_conns(&rctx->alien); + + if (io_altium_conf.plugins.io_altium.rename_redundant_pins) + csch_alien_postproc_rename_redundant_terms(&rctx->alien); + + if (io_altium_conf.plugins.io_altium.emulate_text_ang_180) + csch_alien_postproc_text_autorot(&rctx->alien, &dst->direct, 1, 1); + + if ((res == 0) && io_altium_conf.plugins.io_altium.auto_normalize) + csch_alien_postproc_normalize(&rctx->alien); + } + + rctx_uninit(rctx); + + return res; +} Index: tags/1.0.5/src/plugins/io_altium/schdoc.h =================================================================== --- tags/1.0.5/src/plugins/io_altium/schdoc.h (nonexistent) +++ tags/1.0.5/src/plugins/io_altium/schdoc.h (revision 10414) @@ -0,0 +1,2 @@ +int altium_parse_sheet(io_altium_rctx_t *rctx, csch_sheet_t *dst); + Index: tags/1.0.5/src/plugins/io_geda/Makefile =================================================================== --- tags/1.0.5/src/plugins/io_geda/Makefile (nonexistent) +++ tags/1.0.5/src/plugins/io_geda/Makefile (revision 10414) @@ -0,0 +1,2 @@ +all: + cd ../../sch-rnd && make mod_io_geda Index: tags/1.0.5/src/plugins/io_geda/Plug.tmpasm =================================================================== --- tags/1.0.5/src/plugins/io_geda/Plug.tmpasm (nonexistent) +++ tags/1.0.5/src/plugins/io_geda/Plug.tmpasm (revision 10414) @@ -0,0 +1,16 @@ +put /local/rnd/mod {io_geda} +put /local/rnd/mod/OBJS [@ + $(PLUGDIR)/io_geda/io_geda.o + $(PLUGDIR)/io_geda/read.o +@] + +put /local/rnd/mod/CONFFILE {io_geda.conf} +put /local/rnd/mod/CONF {$(PLUGDIR)/io_geda/io_geda_conf.h} +put /local/rnd/mod/CONFVAR {io_geda_conf_internal} + + +switch /local/module/io_geda/controls + case {buildin} include /local/csch/tmpasm/buildin; end; + case {plugin} include /local/csch/tmpasm/plugin; end; + case {disable} include /local/csch/tmpasm/disable; end; +end Index: tags/1.0.5/src/plugins/io_geda/io_geda.c =================================================================== --- tags/1.0.5/src/plugins/io_geda/io_geda.c (nonexistent) +++ tags/1.0.5/src/plugins/io_geda/io_geda.c (revision 10414) @@ -0,0 +1,85 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - gEDA format support + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + + +#include +#include +#include +#include +#include +#include +#include "read.h" + +#include "io_geda_conf.h" +#include "conf_internal.c" + +conf_io_geda_t io_geda_conf; + +static csch_plug_io_t geda; +static char geda_cookie[] = "io_geda"; + +static int io_geda_load_prio(const char *fn, const char *fmt, csch_plug_io_type_t type) +{ + if (fmt != NULL) { + if (!strstr(fmt, "geda") && !strstr(fmt, "gEDA") && !strstr(fmt, "sch")) + return 0; + } + if (type == CSCH_IOTYP_SHEET) + return 90; + return 0; +} + +int pplg_check_ver_io_geda(int ver_needed) { return 0; } + +void pplg_uninit_io_geda(void) +{ + csch_plug_io_unregister(&geda); + rnd_conf_plug_unreg("plugins/io_geda/", io_geda_conf_internal, geda_cookie); +} + +int pplg_init_io_geda(void) +{ + RND_API_CHK_VER; + + geda.name = "gEDA schematics sheet v2 or symbol v1"; + geda.load_prio = io_geda_load_prio; + geda.load_sheet = io_geda_load_sheet; + geda.load_grp = io_geda_load_grp; + geda.test_parse = io_geda_test_parse; + + geda.ext_save_sheet = "sch"; + geda.ext_save_grp = "sym"; + csch_plug_io_register(&geda); + + + rnd_conf_plug_reg(io_geda_conf, io_geda_conf_internal, geda_cookie); +#define conf_reg(field,isarray,type_name,cpath,cname,desc,flags) \ + rnd_conf_reg_field(io_geda_conf, field,isarray,type_name,cpath,cname,desc,flags); +#include "io_geda_conf_fields.h" + + return 0; +} + Index: tags/1.0.5/src/plugins/io_geda/io_geda.conf =================================================================== --- tags/1.0.5/src/plugins/io_geda/io_geda.conf (nonexistent) +++ tags/1.0.5/src/plugins/io_geda/io_geda.conf (revision 10414) @@ -0,0 +1,26 @@ +li:pcb-rnd-conf-v1 { + ha:overwrite { + ha:plugins { + ha:io_geda { + coord_mult = 20 + auto_normalize = 1 + li:library_search_paths { + /usr/share/gEDA/sym + /usr/local/share/gEDA/sym + /usr/share/lepton-eda/sym + /usr/local/share/lepton-eda/sym + } + emulate_text_ang_180 = 1 + li:postproc_sheet_load { + {(@.a.refdes != "")}; {propset(@, rename/a/refdes, name)} + {(@.type == TEXT) && (@.text == "%../A.refdes%")}; {propset(@, p/text/text, "%../A.name%")} + {(@.a.role == "terminal") }; {propset(@, rename/a/pinnumber, name)} + {(@.type == TEXT) && (@.text == "%../A.pinnumber%")}; {propset(@, p/text/text, "%../a.display/name%")} + {(@.a.netname != "")}; {propset(@, rename/a/netname, name)} + {(@.type == TEXT) && (@.text == "%../A.netname%")}; {propset(@, p/text/text, "%../A.name%")} + {(@.type == TEXT) && (@.text == "netname=%../A.netname%")}; {propset(@, p/text/text, "netname=%../A.name%")} + } + } + } + } +} Index: tags/1.0.5/src/plugins/io_geda/io_geda.pup =================================================================== --- tags/1.0.5/src/plugins/io_geda/io_geda.pup (nonexistent) +++ tags/1.0.5/src/plugins/io_geda/io_geda.pup (revision 10414) @@ -0,0 +1,10 @@ +$class io +$short gEDA schematics and symbols +$long Load schematics and symbols from gEDA format. +$state works +$fmt-feature-r geda cschem schematics (v2) +$fmt-feature-r geda cschem symbol (v1) +$package io-alien +dep lib_alien +default buildin +autoload 1 Index: tags/1.0.5/src/plugins/io_geda/io_geda_conf.h =================================================================== --- tags/1.0.5/src/plugins/io_geda/io_geda_conf.h (nonexistent) +++ tags/1.0.5/src/plugins/io_geda/io_geda_conf.h (revision 10414) @@ -0,0 +1,20 @@ +#ifndef SCH_RND_IO_GEDA_CONF_H +#define SCH_RND_IO_GEDA_CONF_H + +#include + +typedef struct { + const struct { + const struct { + RND_CFT_REAL coord_mult; /* all gEDA coordinates are multiplied by this value to get sch-rnd coords */ + RND_CFT_LIST library_search_paths; /* ordered list of paths that are each recursively searched for gEDA sym files */ + RND_CFT_BOOLEAN emulate_text_ang_180; /* gschem displays text objects with angle==180 with an extra 180 degree rotation; it's a display hack sch-rnd doesn't have; when this emulation is enabled, the loader adds a +180 degree rotation in such text (changing data!) to match the behavior */ + RND_CFT_BOOLEAN auto_normalize; /* move all objects so that starting coords are near 0;0, without the high, usually 40000 offset of gschem */ + RND_CFT_LIST postproc_sheet_load; /* pattern;action pairs for object transformations after a succesful load; mostly used for attribute editing */ + } io_geda; + } plugins; +} conf_io_geda_t; + +extern conf_io_geda_t io_geda_conf; + +#endif Index: tags/1.0.5/src/plugins/io_geda/read.c =================================================================== --- tags/1.0.5/src/plugins/io_geda/read.c (nonexistent) +++ tags/1.0.5/src/plugins/io_geda/read.c (revision 10414) @@ -0,0 +1,1305 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - gEDA file format support + * Copyright (C) 2022, 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022, Entrust in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "io_geda_conf.h" +extern conf_io_geda_t io_geda_conf; + +#include "read.h" + +/*#define dbg_printf printf*/ + +#ifndef dbg_printf +#define dbg_printf nope_printf +static int nope_printf(const char *fmt, ...) { return 0; } +#endif + +#define error(ctx, args) \ + do { \ + if (!ctx->silent) { \ + rnd_message(RND_MSG_ERROR, "gEDA parse error at %s:%ld:\n", ctx->fn, ctx->lineno); \ + rnd_msg_error args; \ + } \ + } while(0) + +typedef struct read_ctx_s { + FILE *f; + const char *fn; + long ver; /* file version */ + long lineno; + int level; + + csch_sheet_t *sheet; + csch_project_t *proj; + csch_chdr_t *last; /* last object succesfully loaded; required for attaching attributes */ + + csch_cgrp_t *last_comp; /* last component read, useful for a [] */ + char *last_comp_name; /* matters in case of non-embedded component - we need to load from disk by name after the {} block when we figured there was no [] block */ + int last_comp_rot; + unsigned last_comp_mir:1; + unsigned last_comp_embedded:1; + + unsigned silent:1; + unsigned no_ext_sym:1; /* do not attempt to load external symbols from the geda lib */ + unsigned buffer_dirty:1; /* set if the scratch buffer got used */ + + unsigned sym_hash_inited:1; + htsp_t sym_hash; + + csch_alien_read_ctx_t alien; +} read_ctx_t; + +typedef struct { + char *name; + char *path; + csch_cgrp_t *grp; /* NULL if not yet loaded */ +} disk_sym_t; + +static int read_ver(read_ctx_t *ctx) +{ + int cmd; + long prog_ver; + + cmd = fgetc(ctx->f); + if (cmd != 'v') { + error(ctx, ("Expected 'v' in first line\n")); + return -1; + } + + if (fscanf(ctx->f, "%ld %ld\n", &prog_ver, &ctx->ver) != 2) { + error(ctx, ("Expected two integers in 'v' version line\n")); + return -1; + } + + ctx->lineno++; + return 0; +} + +static char *read_str(read_ctx_t *ctx) +{ + gds_t tmp = {0}; + + gds_append(&tmp, '\0'); + tmp.used = 0; + + for(;;) { + int c = fgetc(ctx->f); + + if ((c == '\n') || (c == EOF)) { + ctx->lineno++; + return tmp.array; + } + + gds_append(&tmp, c); + } +} + +static char *read_data_dot(read_ctx_t *ctx) +{ + gds_t tmp = {0}; + int last_nl = 0; + + for(;;) { + int c = fgetc(ctx->f); + + if (c == EOF) { + error(ctx, ("Premature end of file: expected embedded data terminator dot line\n")); + return NULL; + } + + if ((c == '.') && last_nl) + return tmp.array; + + if (c == '\n') { + ctx->lineno++; + last_nl = 1; + } + else + last_nl = 0; + + gds_append(&tmp, c); + } +} + +#define IPENMAX 20 +static const char *pen_name_sheet[IPENMAX+1] = { + "sheet-decor", /* 0 BACKGROUND_COLOR */ + "term-primary", /* 1 PIN_COLOR */ + "term-secondary", /* 2 NET_ENDPOINT_COLOR */ + "sheet-decor", /* 3 GRAPHIC_COLOR */ + "wire", /* 4 NET_COLOR */ + "sheet-decor", /* 5 ATTRIBUTE_COLOR */ + "sheet-decor", /* 6 LOGIC_BUBBLE_COLOR */ + "sheet-decor", /* 7 DOTS_GRID_COLOR */ + "sheet-decor", /* 8 DETACHED_ATTRIBUTE_COLOR */ + "sheet-decor", /* 9 TEXT_COLOR */ + "bus", /* 10 BUS_COLOR */ + "sheet-decor", /* 11 SELECT_COLOR */ + "sheet-decor", /* 12 BOUNDINGBOX_COLOR */ + "sheet-decor", /* 13 ZOOM_BOX_COLOR */ + "sheet-decor", /* 14 STROKE_COLOR */ + "sheet-decor", /* 15 LOCK_COLOR */ + "sheet-decor", /* 16 OUTPUT_BACKGROUND_COLOR */ + "sheet-decor", /* 17 FREESTYLE1_COLOR */ + "sheet-decor", /* 18 FREESTYLE2_COLOR */ + "sheet-decor", /* 19 FREESTYLE3_COLOR */ + "sheet-decor" /* 20 FREESTYLE4_COLOR */ +}; + +static const char *pen_name_term[IPENMAX+1] = { + "sheet-decor", /* 0 BACKGROUND_COLOR */ + "term-primary", /* 1 PIN_COLOR */ + "term-secondary", /* 2 NET_ENDPOINT_COLOR */ + "term-decor", /* 3 GRAPHIC_COLOR */ + "wire", /* 4 NET_COLOR */ + "term-decor", /* 5 ATTRIBUTE_COLOR */ + "term-decor", /* 6 LOGIC_BUBBLE_COLOR */ + "term-decor", /* 7 DOTS_GRID_COLOR */ + "term-decor", /* 8 DETACHED_ATTRIBUTE_COLOR */ + "term-decor", /* 9 TEXT_COLOR */ + "bus", /* 10 BUS_COLOR */ + "term-decor", /* 11 SELECT_COLOR */ + "term-decor", /* 12 BOUNDINGBOX_COLOR */ + "term-decor", /* 13 ZOOM_BOX_COLOR */ + "term-decor", /* 14 STROKE_COLOR */ + "sheet-decor", /* 15 LOCK_COLOR */ + "term-decor", /* 16 OUTPUT_BACKGROUND_COLOR */ + "term-decor", /* 17 FREESTYLE1_COLOR */ + "term-decor", /* 18 FREESTYLE2_COLOR */ + "term-decor", /* 19 FREESTYLE3_COLOR */ + "term-decor" /* 20 FREESTYLE4_COLOR */ +}; + +static const char *pen_name_sym[IPENMAX+1] = { + "sheet-decor", /* 0 BACKGROUND_COLOR */ + "term-primary", /* 1 PIN_COLOR */ + "term-secondary", /* 2 NET_ENDPOINT_COLOR */ + "sym-decor", /* 3 GRAPHIC_COLOR */ + "wire", /* 4 NET_COLOR */ + "sym-decor", /* 5 ATTRIBUTE_COLOR */ + "sym-decor", /* 6 LOGIC_BUBBLE_COLOR */ + "sym-decor", /* 7 DOTS_GRID_COLOR */ + "sym-decor", /* 8 DETACHED_ATTRIBUTE_COLOR */ + "sym-decor", /* 9 TEXT_COLOR */ + "bus", /* 10 BUS_COLOR */ + "sym-decor", /* 11 SELECT_COLOR */ + "sym-decor", /* 12 BOUNDINGBOX_COLOR */ + "sym-decor", /* 13 ZOOM_BOX_COLOR */ + "sym-decor", /* 14 STROKE_COLOR */ + "sheet-decor", /* 15 LOCK_COLOR */ + "sym-decor", /* 16 OUTPUT_BACKGROUND_COLOR */ + "sym-decor", /* 17 FREESTYLE1_COLOR */ + "sym-decor", /* 18 FREESTYLE2_COLOR */ + "sym-decor", /* 19 FREESTYLE3_COLOR */ + "sym-decor" /* 20 FREESTYLE4_COLOR */ +}; + +static const char *pen_name_wire[IPENMAX+1] = { + "sheet-decor", /* 0 BACKGROUND_COLOR */ + "term-primary", /* 1 PIN_COLOR */ + "term-secondary", /* 2 NET_ENDPOINT_COLOR */ + "sym-decor", /* 3 GRAPHIC_COLOR */ + "wire", /* 4 NET_COLOR */ + "wire", /* 5 ATTRIBUTE_COLOR */ + "sym-decor", /* 6 LOGIC_BUBBLE_COLOR */ + "sym-decor", /* 7 DOTS_GRID_COLOR */ + "sym-decor", /* 8 DETACHED_ATTRIBUTE_COLOR */ + "sym-decor", /* 9 TEXT_COLOR */ + "bus", /* 10 BUS_COLOR */ + "sym-decor", /* 11 SELECT_COLOR */ + "sym-decor", /* 12 BOUNDINGBOX_COLOR */ + "sym-decor", /* 13 ZOOM_BOX_COLOR */ + "sym-decor", /* 14 STROKE_COLOR */ + "sheet-decor", /* 15 LOCK_COLOR */ + "sym-decor", /* 16 OUTPUT_BACKGROUND_COLOR */ + "sym-decor", /* 17 FREESTYLE1_COLOR */ + "sym-decor", /* 18 FREESTYLE2_COLOR */ + "sym-decor", /* 19 FREESTYLE3_COLOR */ + "sym-decor" /* 20 FREESTYLE4_COLOR */ +}; + +const char *read_alloc_pen_by_color(read_ctx_t *ctx, csch_cgrp_t *parent, int color) +{ + const char **p; + + if (parent->role == CSCH_ROLE_SYMBOL) + p = pen_name_sym; + else if (parent->role == CSCH_ROLE_TERMINAL) + p = pen_name_term; + else if (parent->role == CSCH_ROLE_WIRE_NET) + p = pen_name_wire; + else + p = pen_name_sheet; + + if ((color >= 0) && (color <= IPENMAX)) + return p[color]; + + return "sheet-decor"; +} + +const char *read_alloc_pen(read_ctx_t *ctx, csch_cgrp_t *parent, int color, long width, int capstyle, int dashstyle, long dashlength, long dashspace) +{ + TODO("do not ignore dash and width"); + return read_alloc_pen_by_color(ctx, parent, color); +} + +const char *read_alloc_pen_text(read_ctx_t *ctx, csch_cgrp_t *parent, int color, long size) +{ + TODO("do not ignore size"); + return read_alloc_pen_by_color(ctx, parent, color); +} + +static int read_nl(read_ctx_t *ctx) +{ + for(;;) { + int c = fgetc(ctx->f); + + if (c == '\n') { + ctx->lineno++; + return 0; + } + + if (!isspace(c)) { + error(ctx, ("Expected character '%c' near the end of the line\n", c)); + return -1; + } + } +} + +#define READ_NL(ctx) if (read_nl(ctx) != 0) return -1; + +static csch_source_arg_t *geda_src(read_ctx_t *ctx) +{ + return csch_attrib_src_c(ctx->fn, ctx->lineno, 0, NULL); +} + +/* Create a text object and create attribue as needed. read_line returns an + allocated string that will be free()'d here. Returns 0 on success. */ +static int place_text(read_ctx_t *ctx, csch_cgrp_t *parent, long x, long y, long nlines, const char *penname, int vis, int nvis, int rot, int align, int is_attr, int create_attr, char *(*read_line)(void *uctx), void *uctx) +{ + long n; + + TODO("this splits up multiline text into separate lines; in gEDA coords"); +#define DEF_TERM_GRID 200.0 + y += (nlines-1) * DEF_TERM_GRID; + + dbg_printf("%s at %ld %ld on level %d\n", (is_attr ? "attr" : "text"), x, y, ctx->level); + for(n = 0; n < nlines; n++) { + csch_text_t *text = NULL; + char *sep, *s = read_line(uctx); + int do_attr = 0; + + dbg_printf(" '%s'\n", s); + + sep = strchr(s, '='); + if (!is_attr && (n == 0) && (sep != NULL)) { + dbg_printf(" implicit attr\n"); + do_attr = 1; + } + else if (is_attr) + do_attr = 1; + + + if (do_attr && (parent != NULL)) { + *sep = '\0'; + sep++; + if (create_attr) + csch_cobj_attrib_set(ctx->sheet, parent, CSCH_ATP_USER_DEFAULT, s, sep, geda_src(ctx)); + if (vis) { + text = (csch_text_t *)csch_alien_mktext(&ctx->alien, parent, x, y, penname); + y -= DEF_TERM_GRID; + switch(nvis) { + case 0: + text->text = rnd_strdup_printf("%s=%%../A.%s%%", s, s); + text->dyntext = 1; + text->hdr.floater = 1; + break; + case 1: + text->text = rnd_strdup_printf("%%../A.%s%%", s); + text->dyntext = 1; + text->hdr.floater = 1; + break; + case 2: + text->text = s; + s = NULL; + break; + default: + text->text = rnd_strdup(""); + } + } + } + else { + text = (csch_text_t *)csch_alien_mktext(&ctx->alien, parent, x, y, penname); + y -= DEF_TERM_GRID; + + text->text = s; + s = NULL; + } + if (text != NULL) { + text->spec_rot = rot; + } + free(s); + + if (text != NULL) { + /* halign */ + switch(align) { + case 0: case 1: case 2: /* left */ + break; + case 3: case 4: case 5: /* center */ + TODO("Center\n"); + break; + case 6: case 7: case 8: /* right */ + text->spec_mirx = 1; + break; + } + + /* valign */ + switch(align) { + case 2: case 5: case 8: /* top */ + text->spec_miry = 1; + break; + case 1: case 4: case 7: /* center */ + text->spec1.y -= 1500; + TODO("Center\n"); + break; + case 0: case 3: case 6: /* bottom */ + break; + } + } + } + + + + return 0; +} + +/*** read objects ***/ + +static int read_text(read_ctx_t *ctx, csch_cgrp_t *parent, int is_attr) +{ + long x, y, nlines; + int color, size, vis, nvis, rot, align; + const char *penname; + + if (fscanf(ctx->f, "%ld %ld %d %d %d %d %d %d %ld", &x, &y, &color, &size, &vis, &nvis, &rot, &align, &nlines) != 9) { + error(ctx, ("invalid integer fields in 'T'\n")); + return -1; + } + READ_NL(ctx); + + penname = read_alloc_pen_text(ctx, parent, color, size); + + return place_text(ctx, parent, x, y, nlines, penname, vis, nvis, rot, align, is_attr, 1, (char *(*)(void *))read_str, ctx); +} + +static int read_line(read_ctx_t *ctx, csch_cgrp_t *parent) +{ + long x1, y1, x2, y2, width, dashlength, dashspace; + int color, capstyle, dashstyle; + const char *penname; + + if (fscanf(ctx->f, "%ld %ld %ld %ld %d %ld %d %d %ld %ld", &x1, &y1, &x2, &y2, &color, &width, &capstyle, &dashstyle, &dashlength, &dashspace) != 10) { + error(ctx, ("invalid integer fields in 'L'\n")); + return -1; + } + dbg_printf("line at %ld;%ld %ld;%ld\n", x1, y1, x2, y2); + penname = read_alloc_pen(ctx, parent, color, width, capstyle, dashstyle, dashlength, dashspace); + ctx->last = csch_alien_mkline(&ctx->alien, parent, x1, y1, x2, y2, penname); + READ_NL(ctx); + return 0; +} + +static int read_arc(read_ctx_t *ctx, csch_cgrp_t *parent) +{ + long cx, cy, r, width, dashlength, dashspace; + int sa, da, color, capstyle, dashstyle; + const char *penname; + + if (fscanf(ctx->f, "%ld %ld %ld %d %d %d %ld %d %d %ld %ld", &cx, &cy, &r, &sa, &da, &color, &width, &capstyle, &dashstyle, &dashlength, &dashspace) != 11) { + error(ctx, ("invalid integer fields in 'A'\n")); + return -1; + } + dbg_printf("arc at %ld;%ld r=%ld angles: %d %d\n", cx, cy, r, sa, da); + READ_NL(ctx); + + penname = read_alloc_pen(ctx, parent, color, width, capstyle, dashstyle, dashlength, dashspace); + ctx->last = csch_alien_mkarc(&ctx->alien, parent, cx, cy, r, sa, da, penname); + + return 0; +} + +static int read_circle(read_ctx_t *ctx, csch_cgrp_t *parent) +{ + long cx, cy, r, p1, p2, fillwidth, width, dashlength, dashspace; + int color, capstyle, dashstyle; + int filltype, a1, a2; + const char *penname; + + if (fscanf(ctx->f, "%ld %ld %ld %d %ld %d %d %ld %ld %d %ld %d %ld %d %ld", + &cx, &cy, &r, + &color, &width, &capstyle, &dashstyle, &dashlength, &dashspace, + &filltype, &fillwidth, &a1, &p1, &a2, &p2) != 15) { + error(ctx, ("invalid integer fields in 'A'\n")); + return -1; + } + dbg_printf("circle at %ld;%ld r=%ld\n", cx, cy, r); + READ_NL(ctx); + + penname = read_alloc_pen(ctx, parent, color, width, capstyle, dashstyle, dashlength, dashspace); + ctx->last = csch_alien_mkarc(&ctx->alien, parent, cx, cy, r, 0, 360, penname); + + return 0; +} + +static int read_pin(read_ctx_t *ctx, csch_cgrp_t *parent) +{ + long x1, y1, x2, y2; + int color, pintype, whichend; + csch_source_arg_t *src; + + if (fscanf(ctx->f, "%ld %ld %ld %ld %d %d %d", &x1, &y1, &x2, &y2, &color, &pintype, &whichend) != 7) { + error(ctx, ("invalid integer fields in 'P'\n")); + return -1; + } + dbg_printf("pin: %ld %ld to %ld %ld\n", x1, y1, x2, y2); + READ_NL(ctx); + + TODO("if whichend is 0, swap coords?"); + + src = csch_attrib_src_c(ctx->fn, ctx->lineno, 0, NULL); + ctx->last = csch_alien_mkpin_line(&ctx->alien, src, parent, x1, y1, x2, y2); + + return 0; +} + +static int read_picture(read_ctx_t *ctx, csch_cgrp_t *parent) +{ + long x, y, w, h; + int rot, mir, emb; + char *fn; + + if (fscanf(ctx->f, "%ld %ld %ld %ld %d %d %d", &x, &y, &w, &h, &rot, &mir, &emb) != 7) { + error(ctx, ("invalid integer fields in 'G'\n")); + return -1; + } + READ_NL(ctx); + + fn = read_str(ctx); + if (fn == NULL) + return -1; + + if (emb) { + char *data = read_data_dot(ctx); + if (data == NULL) + return -1; + free(data); + READ_NL(ctx); + } + + dbg_printf("picture at %ld %ld (%s)\n", x, y, fn); + TODO("create bitmap"); + + free(fn); + return 0; +} + +static int read_box(read_ctx_t *ctx, csch_cgrp_t *parent) +{ + long x, y, w, h, width, dashlength, dashspace, fillwidth, p1, p2; + int color, capstyle, dashstyle, filltype, a1, a2; + const char *penname; + + if (fscanf(ctx->f, "%ld %ld %ld %ld %d %ld %d %d %ld %ld %d %ld %d %ld %d %ld", + &x, &y, &w, &h, &color, &width, &capstyle, &dashstyle, &dashlength, + &dashspace, &filltype, &fillwidth, &a1, &p1, &a2, &p2) != 16) { + error(ctx, ("invalid integer fields in 'B'\n")); + return -1; + } + dbg_printf("box at %ld %ld, size %ld %ld\n", x, y, w, h); + + penname = read_alloc_pen(ctx, parent, color, width, capstyle, dashstyle, dashlength, dashspace); + csch_alien_mkrect(&ctx->alien, parent, x, y, x+w, y+h, penname, (filltype > 0) ? penname : 0); + READ_NL(ctx); + return 0; +} + +static int read_net(read_ctx_t *ctx, csch_cgrp_t *parent) +{ + long x1, y1, x2, y2; + int color; + + if (fscanf(ctx->f, "%ld %ld %ld %ld %d", &x1, &y1, &x2, &y2, &color) != 5) { + error(ctx, ("invalid integer fields in 'N'\n")); + return -1; + } + READ_NL(ctx); + dbg_printf("net at %ld;%ld %ld;%ld\n", x1, y1, x2, y2); + ctx->last = csch_alien_mknet(&ctx->alien, parent, x1, y1, x2, y2); + return 0; +} + +static int read_bus(read_ctx_t *ctx, csch_cgrp_t *parent) +{ + long x1, y1, x2, y2; + int color, ripdir; + + if (fscanf(ctx->f, "%ld %ld %ld %ld %d %d", &x1, &y1, &x2, &y2, &color, &ripdir) != 6) { + error(ctx, ("invalid integer fields in 'U'\n")); + return -1; + } + dbg_printf("bus at %ld;%ld %ld;%ld\n", x1, y1, x2, y2); + TODO("create bus, watch for rippers? or rather keep buses as purely graphical"); + READ_NL(ctx); + return 0; +} + +static int read_path_xy(read_ctx_t *ctx, long *x, long *y) +{ + int c; + if (fscanf(ctx->f, "%ld", x) != 1) + return -1; + c = fgetc(ctx->f); + if ((c != ',') && (!isspace(c))) + return -1; + if (fscanf(ctx->f, "%ld", y) != 1) + return -1; + return 0; +} + +#define READ_PATH_END \ +do { \ + for(;;) { \ + int c = fgetc(ctx->f); \ + if (c == '\n') { \ + ctx->lineno++; \ + stay = 0; \ + break; \ + } \ + if (!isspace(c)) { \ + ungetc(c, ctx->f); \ + break; \ + } \ + } \ +} while(0) + +static int read_path(read_ctx_t *ctx, csch_cgrp_t *parent) +{ + long p1, p2, fillwidth, numlines, n; + int color, width, capstyle, dashstyle, dashlength, dashspace; + int filltype, a1, a2; + csch_chdr_t *poly; + const char *penname = NULL; + + if (fscanf(ctx->f, "%d %d %d %d %d %d %d %ld %d %ld %d %ld %ld", + &color, &width, &capstyle, &dashstyle, &dashlength, &dashspace, + &filltype, &fillwidth, &a1, &p1, &a2, &p2, &numlines) != 13) { + error(ctx, ("invalid integer fields in 'A'\n")); + return -1; + } + READ_NL(ctx); + dbg_printf("path of %ld:\n", numlines); + + if (numlines > 0) { + penname = read_alloc_pen(ctx, parent, color, width, capstyle, dashstyle, dashlength, dashspace); + poly = csch_alien_mkpoly(&ctx->alien, parent, penname, (filltype > 0) ? penname : NULL); + ctx->last = poly; + } + + for(n = 0; n < numlines; n++) { + long sx, sy, cx, cy, x, y, x1, y1, x2, y2; + int cmd, stay; + + cmd = fgetc(ctx->f); + switch(cmd) { + case 'M': + for(stay = 1; stay;) { + if (read_path_xy(ctx, &cx, &cy) != 0) { + error(ctx, ("invalid x y coordinate for path M\n")); + return -1; + } + sx = cx; + sy = cy; + dbg_printf(" move to %ld %ld\n", sx, sy); + READ_PATH_END; + } + break; + case 'L': + for(stay = 1; stay;) { + if (read_path_xy(ctx, &x, &y) != 0) { + error(ctx, ("invalid x y coordinate for path L\n")); + return -1; + } + dbg_printf(" line to %ld %ld (from %ld %ld)\n", x, y, cx, cy); + csch_alien_append_poly_line(&ctx->alien, poly, cx, cy, x, y); + cx = x; + cy = y; + READ_PATH_END; + } + break; + case 'C': + for(stay = 1; stay;) { + if (read_path_xy(ctx, &x1, &y1) != 0) { + error(ctx, ("invalid x1 y1 coordinate for path C\n")); + return -1; + } + if (read_path_xy(ctx, &x2, &y2) != 0) { + error(ctx, ("invalid x2 y2 coordinate for path C\n")); + return -1; + } + if (read_path_xy(ctx, &x, &y) != 0) { + error(ctx, ("invalid x y coordinate for path C\n")); + return -1; + } + dbg_printf(" Curve to %ld %ld %ld %ld %ld %ld (from %ld %ld)\n", x1, y1, x2, y2, x, y, cx, cy); + csch_alien_append_poly_bezier(&ctx->alien, poly, cx, cy, x1, y1, x2, y2, x, y); + cx = x; + cy = y; + READ_PATH_END; + } + break; + case 'Z': + case 'z': + dbg_printf(" Line to %ld %ld (from %ld %ld)\n", sx, sy, cx, cy); + csch_alien_append_poly_line(&ctx->alien, poly, cx, cy, sx, sy); + READ_NL(ctx); + break; + } + } + + return 0; +} + +static void map_sym(read_ctx_t *ctx, char *name, gds_t *path) +{ + disk_sym_t *sym = malloc(sizeof(disk_sym_t)); + + sym->name = name; + sym->path = rnd_strdup(path->array); + sym->grp = NULL; + htsp_set(&ctx->sym_hash, sym->name, sym); +/* rnd_trace(" geda symbol: '%s' '%s'\n", name, path->array);*/ +} + +static void map_dir_(read_ctx_t *ctx, gds_t *path) +{ + struct dirent *de; + DIR *dir; + int saved_used = path->used, restore; + + dir = rnd_opendir(&ctx->sheet->hidlib, path->array); + if (dir == NULL) + return; + + gds_append(path, RND_DIR_SEPARATOR_C); + restore = path->used; + while((de = rnd_readdir(dir)) != NULL) { + struct stat st; + + if (de->d_name[0] == '.') + continue; + + path->used = restore; + gds_append_str(path, de->d_name); + + if (stat(path->array, &st) != 0) + continue; + + if (!S_ISDIR(st.st_mode)) { + char *name, *ext; + + ext = strrchr(de->d_name, '.'); + if ((ext == NULL) || (rnd_strcasecmp(ext+1, "sym") != 0)) + continue; + + name = rnd_strdup(de->d_name); + if (htsp_has(&ctx->sym_hash, name)) { + free(name); + continue; + } + + map_sym(ctx, name, path); + } + else + map_dir_(ctx, path); + } + rnd_closedir(dir); + + path->used = saved_used; +} + +static void map_dir(read_ctx_t *ctx, const char *cfgdir, const char *cwd, gds_t *tmp) +{ + tmp->used = 0; + if (!rnd_is_path_abs(cfgdir)) { + gds_append_str(tmp, cwd); + gds_append(tmp, RND_DIR_SEPARATOR_C); + } + gds_append_str(tmp, cfgdir); + map_dir_(ctx, tmp); +} + +static void init_sym_hash(read_ctx_t *ctx) +{ + gds_t tmp = {0}; + char *cwd, *sep; + rnd_conf_listitem_t *ci; + + if (ctx->sym_hash_inited) + return; + + cwd = rnd_strdup(ctx->fn); + + TODO("make an rnd_dirname(): on windows this is / or \\"); + sep = strrchr(cwd, RND_DIR_SEPARATOR_C); + if (sep != NULL) + *sep = '\0'; + + htsp_init(&ctx->sym_hash, strhash, strkeyeq); + + for(ci = rnd_conflist_first((rnd_conflist_t *)&io_geda_conf.plugins.io_geda.library_search_paths); ci != NULL; ci = rnd_conflist_next(ci)) { + char *path = rnd_build_fn(&ctx->sheet->hidlib, ci->val.string[0]); + /*rnd_trace("io_geda: path resovle '%s' -> '%s'\n", ci->val.string[0], path);*/ + map_dir(ctx, path, cwd, &tmp); + free(path); + } + + free(cwd); + gds_uninit(&tmp); + ctx->sym_hash_inited = 1; +} + +static void uninit_sym_hash(read_ctx_t *ctx) +{ + if (!ctx->sym_hash_inited) + return; + + genht_uninit_deep(htsp, &ctx->sym_hash, { + disk_sym_t *ds = htent->value; + free(ds->name); + free(ds->path); + if (ds->grp != NULL) + csch_cgrp_free(ds->grp); + free(ds); + }); +} + +/* Remove one text object from sym that references the same attribute that can + be extracted from the dyntext template string orig */ +static void remove_orig_attr_by_text(read_ctx_t *ctx, csch_cgrp_t *sym, const char *orig) +{ + char *template, *sep; + htip_entry_t *e; + + sep = strchr(orig, '%'); + if (sep == NULL) + return; + + template = rnd_strdup(sep); + sep = strchr(template+1, '%'); + if (sep != NULL) + sep[1] = '\0'; + + for(e = htip_first(&sym->id2obj); e != NULL; e = htip_next(&sym->id2obj, e)) { + csch_text_t *t = e->value; + + if (t->hdr.type != CSCH_CTYPE_TEXT) continue; + if (strstr(t->text, template) != NULL) { + csch_cnc_remove(ctx->sheet, &t->hdr); + break; /* expect only one - each attribute created only once */ + } + } + + free(template); +} + +static csch_cgrp_t *load_sym(rnd_design_t *hidlib, const char *fn, csch_sheet_t *sheet); + +/* Move over all attributes and properites from src sym to dst sym and remove + src sym */ +static void last_comp_move_fields(read_ctx_t *ctx, csch_cgrp_t *dst, csch_cgrp_t *src) +{ + double x, y; + + dst->hdr.lock = src->hdr.lock; + + x = (double)src->x * ctx->alien.coord_factor; + y = (double)src->y * ctx->alien.coord_factor; + + dst->spec_rot = ctx->last_comp_rot; + dst->mirx = ctx->last_comp_mir; + dst->x = rnd_round(x); + dst->y = rnd_round(y); + + /* move over all attributes: any src attrib fully rewrites dst attrib */ + { + htsp_entry_t *e; + for(e = htsp_first(&src->attr); e != NULL; e = htsp_next(&src->attr, e)) { + csch_source_arg_t *src; + csch_attrib_t *a = e->value; + + src = csch_attrib_src_c(ctx->fn, ctx->lineno, 0, NULL); + csch_attrib_set(&dst->attr, CSCH_ATP_USER_DEFAULT-1, a->key, a->val, src, NULL); + } + } + + /* copy over all text objects, replace existing attribute text where needed */ + { + htip_entry_t *e; + for(e = htip_first(&src->id2obj); e != NULL; e = htip_next(&src->id2obj, e)) { + csch_text_t *t = e->value, *newt; + + if (t->hdr.type != CSCH_CTYPE_TEXT) continue; + + remove_orig_attr_by_text(ctx, dst, t->text); + + newt = csch_text_dup(ctx->sheet, dst, t, 0, 0); + newt->spec1.x -= dst->x; + newt->spec1.y -= dst->y; + csch_text_update(ctx->sheet, newt, 1); + } + } + + csch_cnc_remove(ctx->sheet, &src->hdr); +} + +static void flush_last_comp(read_ctx_t *ctx) +{ + if (!ctx->no_ext_sym && (ctx->last_comp != NULL) && !ctx->last_comp_embedded && (ctx->last_comp_name != NULL)) { + disk_sym_t *ds; + + init_sym_hash(ctx); + ds = htsp_get(&ctx->sym_hash, ctx->last_comp_name); + if (ds != NULL) { + + if (ds->grp == NULL) { + ds->grp = load_sym(&ctx->sheet->hidlib, ds->path, sch_rnd_buffer[SCH_RND_BUFFER_SCRATCH]); + ctx->buffer_dirty = 1; + } + + if (ds->grp != NULL) { + csch_cgrp_t *newo = (csch_cgrp_t *)csch_cobj_dup(ctx->sheet, &ctx->sheet->direct, &ds->grp->hdr, 0, 0); + rnd_coord_t ox, oy; + + last_comp_move_fields(ctx, newo, ctx->last_comp); + +/* This breaks. We shouldn't ever use the bbox, but symbol's 0;0 */ + ox = ds->grp->hdr.bbox.x1 * 0; + oy = ds->grp->hdr.bbox.y1; + if ((ox != 0) || (oy != 0)) { + if (newo->spec_rot != 0) { + double rad = -newo->spec_rot / RND_RAD_TO_DEG; + rnd_rotate(&ox, &oy, 0, 0, cos(rad), sin(rad)); + } + if (newo->mirx) + ox = -ox; + newo->x -= ox; + newo->y -= oy; + } + + } + else + error(ctx, ("Failed to load library symbol called '%s'\n", ctx->last_comp_name)); + } + else + error(ctx, ("Can't find library symbol called '%s'\n", ctx->last_comp_name)); + + } + + free(ctx->last_comp_name); + ctx->last_comp_name = NULL; + ctx->last_comp = NULL; + ctx->last_comp_embedded = 0; +} + +static int read_comp(read_ctx_t *ctx, csch_cgrp_t *parent) +{ + csch_source_arg_t *src; + long x, y; + int selectable, angle, mirror; + char *name; + + if (fscanf(ctx->f, "%ld %ld %d %d %d ", &x, &y, &selectable, &angle, &mirror) != 5) { + error(ctx, ("invalid integer fields in 'C'\n")); + return -1; + } + + name = read_str(ctx); + if (name == NULL) { + error(ctx, ("missing name in 'C'\n")); + return -1; + } + + flush_last_comp(ctx); + ctx->last_comp = csch_cgrp_alloc(ctx->sheet, parent, csch_oid_new(ctx->sheet, parent)); + src = csch_attrib_src_c(ctx->fn, ctx->lineno, 0, NULL); + csch_cobj_attrib_set(ctx->sheet, ctx->last_comp, CSCH_ATP_HARDWIRED, "role", "symbol", src); + ctx->last_comp->x = x; + ctx->last_comp->y = y; + ctx->last_comp->hdr.lock = !selectable; + ctx->last_comp_name = rnd_strdup(name); + ctx->last_comp_rot = angle; + ctx->last_comp_mir = mirror; + ctx->last = &ctx->last_comp->hdr; + + dbg_printf("Comp at %ld %ld: '%s'\n", x, y, name); + return 0; +} + +static int read_attr(read_ctx_t *ctx) +{ + csch_cgrp_t *parent; + + READ_NL(ctx); /* of the opening line */ + + if (ctx->last != NULL) + parent = csch_alien_attr_grp(&ctx->alien, &ctx->last); + else + parent = &ctx->sheet->direct; + + for(;;) { + int ws, cmd; + + cmd = fgetc(ctx->f); + if (cmd == '}') { + /* if last object already had attributes in a {} block, any new + attribute defined on the same level is really attribute of the parent + group of the last object; until a new object is created */ + if (ctx->last != NULL) + ctx->last = &ctx->last->parent->hdr; + break; + } + if (cmd != 'T') { + error(ctx, ("Invalid '%c' line in attribute list, only 'T' is supported\n", cmd)); + return -1; + } + + ws = fgetc(ctx->f); + if (!isspace(ws)) { + error(ctx, ("Expected whitespace after command char\n")); + return -1; + } + + if (read_text(ctx, parent, 1) != 0) + return -1; + } + + READ_NL(ctx); /* of the closing line */ + return 0; +} + +static int read_any(read_ctx_t *ctx, csch_cgrp_t *parent, int in_emcomp); + +static int read_emcomp(read_ctx_t *ctx, csch_cgrp_t *parent) +{ + csch_cgrp_t *grp = ctx->last_comp; + + if (grp == NULL) { + error(ctx, ("Unexpected '[': not in a component\n")); + return -1; + } + + if (ctx->last_comp_embedded) { + error(ctx, ("Unexpected '[': multiple blocks in the same component\n")); + return -1; + } + + READ_NL(ctx); /* of the opening line */ + + ctx->last_comp_embedded = 1; + grp->x = grp->y = 0; + + for(;;) { + int cmd; + + cmd = fgetc(ctx->f); + if (cmd == ']') + break; + + ungetc(cmd, ctx->f); + if (read_any(ctx, grp, 1) != 0) { + error(ctx, ("Error in emebdded component data\n")); + return -1; + } + } + + READ_NL(ctx); /* of the closing line */ + flush_last_comp(ctx); + return 0; +} + +static int read_any(read_ctx_t *ctx, csch_cgrp_t *parent, int in_emcomp) +{ + int cmd, ws, res; + + ctx->level++; + + cmd = fgetc(ctx->f); + switch(cmd) { /* No argument commands (so that the whitespace is not read */ + case EOF: res = 1; goto done; /* empty line, typically at the end */ + case '\0': goto done; /* empty line, typically at the end */ + case '{': res = read_attr(ctx); goto done; + case '[': res = read_emcomp(ctx, parent); goto done; + } + + ws = fgetc(ctx->f); + if (!isspace(ws)) { + error(ctx, ("Expected whitespace after command char\n")); + return -1; + } + + switch(cmd) { + case 'C': res = read_comp(ctx, parent); break; + case 'T': res = read_text(ctx, parent, 0); break; + case 'L': res = read_line(ctx, parent); break; + case 'A': res = read_arc(ctx, parent); break; + case 'V': res = read_circle(ctx, parent); break; + case 'P': res = read_pin(ctx, parent); break; + case 'G': res = read_picture(ctx, parent); break; + case 'B': res = read_box(ctx, parent); break; + case 'N': res = read_net(ctx, parent); break; + case 'U': res = read_bus(ctx, parent); break; + case 'H': res = read_path(ctx, parent); break; + /* No support for 'F', that's used only in special font files */ + default: + error(ctx, ("Unknown command char: '%c'\n", cmd)); + return -1; + } + + done:; + ctx->level--; + return res; +} + +#include "read_postproc.c" + +/*** file level parsing and entry points ***/ + +static void alien_setup(read_ctx_t *ctx) +{ + ctx->alien.sheet = ctx->sheet; + ctx->alien.coord_factor = io_geda_conf.plugins.io_geda.coord_mult; + ctx->alien.fmt_prefix = "io_geda"; +} + +static int io_geda_postproc(read_ctx_t *ctx) +{ + if (io_geda_conf.plugins.io_geda.emulate_text_ang_180) { + csch_cgrp_update(ctx->sheet, &ctx->sheet->direct, 1); + csch_alien_postproc_text_autorot(&ctx->alien, &ctx->sheet->direct, 1, 0); + } + postproc_symbols(ctx); + return csch_alien_postproc_sheet(&ctx->alien); +} + +int io_geda_load_sheet(FILE *f, const char *fn, const char *fmt, csch_sheet_t *dst) +{ + int res = -1; + read_ctx_t ctx = {0}; + + ctx.f = f; + ctx.fn = fn; + ctx.sheet = dst; + ctx.lineno = 1; + + if (read_ver(&ctx) != 0) + return -1; + + if (ctx.ver != 2) { + error((&ctx), ("wrong version of gEDA schematics: only file version 2 is supported, yours is %d\n", ctx.ver)); + return -1; + } + + alien_setup(&ctx); + csch_alien_sheet_setup(&ctx.alien, 1); + + for(;;) { + int r = read_any(&ctx, &ctx.sheet->direct, 0); + + if (r < 0) /* error */ + return r; + + if (r == 1) { /* reached eof without error */ + res = 0; + break; + } + } + + flush_last_comp(&ctx); + + if (ctx.buffer_dirty) + sch_rnd_buffer_clear(sch_rnd_buffer[SCH_RND_BUFFER_SCRATCH]); + + if (res == 0) + res = io_geda_postproc(&ctx); + + if ((res == 0) && io_geda_conf.plugins.io_geda.auto_normalize) + csch_alien_postproc_normalize(&ctx.alien); + + uninit_sym_hash(&ctx); + + return res; +} + +static csch_cgrp_t *load_sym_(read_ctx_t *ctx) +{ + csch_source_arg_t *src; + csch_cgrp_t *resgrp = NULL; + int rv = 0; + + if (read_ver(ctx) != 0) + return NULL; + + if ((ctx->ver != 1) && (ctx->ver != 2)) { + error(ctx, ("wrong version of gEDA symbol: only file version 1 and 2 are supported, yours is %d\n", ctx->ver)); + return NULL; + } + + resgrp = csch_cgrp_alloc(ctx->sheet, &ctx->sheet->direct, csch_oid_new(ctx->sheet, &ctx->sheet->direct)); + src = csch_attrib_src_c(ctx->fn, ctx->lineno, 0, NULL); + csch_cobj_attrib_set(ctx->sheet, resgrp, CSCH_ATP_HARDWIRED, "role", "symbol", src); + + /* read the file */ + for(;;) { + int cmd; + + cmd = fgetc(ctx->f); + if (cmd == EOF) + break; + ungetc(cmd, ctx->f); + if (read_any(ctx, resgrp, 1) != 0) { + error(ctx, ("Error in gEDA symbol data\n")); + rv = -1; + break; + } + } + + if (rv == 0) { + csch_cgrp_update(ctx->sheet, resgrp, 1); + csch_sheet_bbox_update(ctx->sheet); + } + else { + csch_cgrp_free(resgrp); + resgrp = NULL; + } + + return resgrp; +} + +/* Load symbol from fn into sheet and return the group; sheet is typically a buffer */ +static csch_cgrp_t *load_sym(rnd_design_t *hidlib, const char *fn, csch_sheet_t *sheet) +{ + read_ctx_t ctx = {0}; + csch_cgrp_t *res; + + ctx.f = rnd_fopen(hidlib, fn, "r"); + if (ctx.f == NULL) { + rnd_message(RND_MSG_ERROR, "Failed to open symbol file %s for read\n", fn); + return NULL; + } + + ctx.fn = fn; + ctx.sheet = sheet; + ctx.lineno = 1; + + alien_setup(&ctx); + + res = load_sym_(&ctx); + + if (res == 0) + io_geda_postproc(&ctx); + + fclose(ctx.f); + + return res; +} + + +csch_cgrp_t *io_geda_load_grp(FILE *f, const char *fn, const char *fmt, csch_sheet_t *sheet) +{ + read_ctx_t ctx = {0}; + + if (htip_get(&sheet->direct.id2obj, 1) != NULL) { + rnd_message(RND_MSG_ERROR, "Error loading '%s': there's already a group1 in destination sheet\n", fn); + return NULL; + } + + ctx.f = f; + ctx.fn = fn; + ctx.sheet = sheet; + ctx.lineno = 1; + + alien_setup(&ctx); + + return load_sym_(&ctx); +} + +int io_geda_test_parse(FILE *f, const char *fn, const char *fmt, csch_plug_io_type_t type) +{ + read_ctx_t ctx = {0}; + + ctx.f = f; + ctx.fn = fn; + ctx.silent = 1; + ctx.no_ext_sym = 1; + + if (read_ver(&ctx) != 0) + return -1; + + return 0; +} + Index: tags/1.0.5/src/plugins/io_geda/read.h =================================================================== --- tags/1.0.5/src/plugins/io_geda/read.h (nonexistent) +++ tags/1.0.5/src/plugins/io_geda/read.h (revision 10414) @@ -0,0 +1,7 @@ +#include +int io_geda_load_sheet(FILE *f, const char *fn, const char *fmt, csch_sheet_t *dst); +csch_cgrp_t *io_geda_load_grp(FILE *f, const char *fn, const char *fmt, csch_sheet_t *sheet); +int io_geda_test_parse(FILE *f, const char *fn, const char *fmt, csch_plug_io_type_t type); + + + Index: tags/1.0.5/src/plugins/io_geda/read_postproc.c =================================================================== --- tags/1.0.5/src/plugins/io_geda/read_postproc.c (nonexistent) +++ tags/1.0.5/src/plugins/io_geda/read_postproc.c (revision 10414) @@ -0,0 +1,111 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - gEDA file format support + * Copyright (C) 2022, 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022, Entrust in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/*** post processing - fixups after load; #included from read.c ***/ + +/* convert geda net= attribute to sch-rnd connect= attribute on a symbol; + geda net attrib is net=netname:pinnumber */ +static void postproc_sym_net(read_ctx_t *ctx, csch_cgrp_t *sym, gds_t *tmp) +{ + const char *refdes, *neta; + htip_entry_t *e; + char *sep, *net_pinname; + + neta = csch_attrib_get_str(&sym->attr, "net"); + if (neta == NULL) + return; + + refdes = csch_attrib_get_str(&sym->attr, "refdes"); + if (refdes == NULL) refdes = ""; + + /* figure net_pinname */ + sep = strchr(neta, ':'); + if (sep == NULL) { + rnd_message(RND_MSG_ERROR, "Invalid net attrib '%s' on sym '%s' (missing colon)\n", neta, refdes); + return; + } + net_pinname = sep+1; + +/* rnd_trace("neta='%s'\n", neta);*/ + + for(e = htip_first(&sym->id2obj); e != NULL; e = htip_next(&sym->id2obj, e)) { + csch_cgrp_t *t = e->value; + const char *pinnum; + + if (!csch_obj_is_grp(&t->hdr) || (t->role != CSCH_ROLE_TERMINAL)) + continue; + + pinnum = csch_attrib_get_str(&t->attr, "pinnumber"); + +/* rnd_trace(" term pin: '%s' target '%s'\n", pinnum, net_pinname);*/ + if ((pinnum != NULL) && (net_pinname != NULL) && (strcmp(pinnum, net_pinname) == 0)) { + csch_source_arg_t *src; + + tmp->used = 0; + gds_append_str(tmp, pinnum); + gds_append(tmp, ':'); + gds_append_len(tmp, neta, sep-neta); + + src = csch_attrib_src_c(ctx->fn, 0, 0, NULL); + csch_attrib_append(&sym->attr, CSCH_ATP_USER_DEFAULT, "connect", tmp->array, src); + +/* rnd_trace(" found! append '%s'\n", tmp->array, res); */ + } + } + + +} + +/* On each symbol (runs before configured/flexible/user postproc): + - recalc conns so terminal-terminal connections are established + - convert geda net= attribute to sch-rnd connect= attribute +*/ +static void postproc_symbols(read_ctx_t *ctx) +{ + htip_entry_t *e; + vtp0_t syms = {0}; + gds_t tmp = {0}; + long n; + + /* first collect all syms; can't do the actual job here becuase it may modify + the hash */ + for(e = htip_first(&ctx->sheet->direct.id2obj); e != NULL; e = htip_next(&ctx->sheet->direct.id2obj, e)) { + csch_chdr_t *o = e->value; + if (csch_obj_is_grp(o) && (((csch_cgrp_t *)o)->role == CSCH_ROLE_SYMBOL)) + vtp0_append(&syms, o); + } + + /* recalc conns on all collected symbols */ + for(n = 0; n < syms.used; n++) { + postproc_sym_net(ctx, syms.array[n], &tmp); + csch_conn_auto_recalc(ctx->sheet, syms.array[n]); + } + + vtp0_uninit(&syms); + gds_uninit(&tmp); +} Index: tags/1.0.5/src/plugins/io_lihata/Makefile =================================================================== --- tags/1.0.5/src/plugins/io_lihata/Makefile (nonexistent) +++ tags/1.0.5/src/plugins/io_lihata/Makefile (revision 10414) @@ -0,0 +1,2 @@ +all: + cd ../../sch-rnd && make mod_io_lihata Index: tags/1.0.5/src/plugins/io_lihata/Plug.tmpasm =================================================================== --- tags/1.0.5/src/plugins/io_lihata/Plug.tmpasm (nonexistent) +++ tags/1.0.5/src/plugins/io_lihata/Plug.tmpasm (revision 10414) @@ -0,0 +1,12 @@ +put /local/rnd/mod {io_lihata} +put /local/rnd/mod/OBJS [@ + $(PLUGDIR)/io_lihata/io_lihata.o + $(PLUGDIR)/io_lihata/read.o + $(PLUGDIR)/io_lihata/write.o +@] + +switch /local/module/io_lihata/controls + case {buildin} include /local/csch/tmpasm/buildin; end; + case {plugin} include /local/csch/tmpasm/plugin; end; + case {disable} include /local/csch/tmpasm/disable; end; +end Index: tags/1.0.5/src/plugins/io_lihata/io_lihata.c =================================================================== --- tags/1.0.5/src/plugins/io_lihata/io_lihata.c (nonexistent) +++ tags/1.0.5/src/plugins/io_lihata/io_lihata.c (revision 10414) @@ -0,0 +1,98 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - lihata format support + * Copyright (C) 2018,2020 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + + +#include +#include +#include +#include +#include +#include "read.h" +#include "write.h" + +static csch_plug_io_t lhtv1; + +static int io_lihata_load_prio(const char *fn, const char *fmt, csch_plug_io_type_t type) +{ + if (fmt != NULL) { + if (!strstr(fmt, "lihata") && !strstr(fmt, "lht")) + return 0; + } + if (type == CSCH_IOTYP_SHEET) + return 100; + if (type == CSCH_IOTYP_BUFFER) + return 100; + if (type == CSCH_IOTYP_PROJECT) + return 100; + return 0; +} + +static int io_lihata_save_prio(const char *fn, const char *fmt, csch_plug_io_type_t type) +{ + if (fmt != NULL) { + if (!strstr(fmt, "lihata") && !strstr(fmt, "lht")) + return 0; + } + if (type == CSCH_IOTYP_SHEET) + return 100; + if (type == CSCH_IOTYP_BUFFER) + return 100; + if (type == CSCH_IOTYP_PROJECT) + return 100; + return 0; +} + + +int pplg_check_ver_io_lihata(int ver_needed) { return 0; } + +void pplg_uninit_io_lihata(void) +{ + csch_plug_io_unregister(&lhtv1); +} + +int pplg_init_io_lihata(void) +{ + RND_API_CHK_VER; + + lhtv1.name = "lihata schematics sheet v1"; + lhtv1.load_prio = io_lihata_load_prio; + lhtv1.save_prio = io_lihata_save_prio; + lhtv1.load_sheet = io_lihata_load_sheet; + lhtv1.load_buffer = io_lihata_load_buffer; + lhtv1.load_project = io_lihata_load_project; + lhtv1.load_grp = io_lihata_load_grp; + lhtv1.save_sheet = io_lihata_save_sheet; + lhtv1.save_buffer = io_lihata_save_buffer; + lhtv1.save_grp = io_lihata_save_grp; + lhtv1.test_parse = io_lihata_test_parse; + + lhtv1.ext_save_sheet = "rs"; + lhtv1.ext_save_buffer = "lht"; + lhtv1.ext_save_grp = "ry"; + csch_plug_io_register(&lhtv1); + return 0; +} + Index: tags/1.0.5/src/plugins/io_lihata/io_lihata.pup =================================================================== --- tags/1.0.5/src/plugins/io_lihata/io_lihata.pup (nonexistent) +++ tags/1.0.5/src/plugins/io_lihata/io_lihata.pup (revision 10414) @@ -0,0 +1,12 @@ +$class io +$short lihata schematics and symbols +$long Load and save the schematics and symbols in the native lihata format. +$state works +$fmt-native yes +$fmt-feature-r lihata cschem schematics (any version) +$fmt-feature-w lihata cschem schematics (any version) +$fmt-feature-r lihata cschem symbol (any version) +$fmt-feature-w lihata cschem symbol (any version) +$package (core) +default buildin +autoload 1 Index: tags/1.0.5/src/plugins/io_lihata/read.c =================================================================== --- tags/1.0.5/src/plugins/io_lihata/read.c (nonexistent) +++ tags/1.0.5/src/plugins/io_lihata/read.c (revision 10414) @@ -0,0 +1,1317 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - lihata format support + * Copyright (C) 2018,2022 Tibor 'Igor2' Palinkas + * (test parse code imported from pcb-rnd by the same author) + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "read.h" + + + +#define error(node, args) \ + do { \ + rnd_message(RND_MSG_ERROR, "Lihata parse error at %s:%d.%d:\n", node->file_name, node->line, node->col); \ + rnd_msg_error args; \ + } while(0) + +typedef struct read_ctx_s { + lht_doc_t *doc; + const char *fn; + int ver; /* file version */ + csch_sheet_t *sheet; + csch_project_t *proj; + rnd_conf_role_t cfg_dest; +} read_ctx_t; + +/*** low level field parsing ***/ + +/* wrapper around lht_dom_hash_get() that throws an error on missing node */ +static lht_node_t *hash_must_get(lht_node_t *parent, const char *name) +{ + lht_node_t *res = lht_dom_hash_get(parent, name); + if (res == NULL) + error(parent, ("Missing lihata subtree: %s\n", name)); + return res; +} + +static void attr_error(void *ectx, lht_node_t *n, const char *msg) +{ +/* read_ctx_t *ctx = ectx;*/ + error(n, ("%s\n", msg)); +} + +static int parse_attribs(read_ctx_t *ctx, csch_chdr_t *dsth, csch_attribs_t *dsta, lht_node_t *subtree) +{ + if (subtree == NULL) + return 0; + return csch_lht_parse_attribs_(ctx->sheet, dsth, dsta, subtree, attr_error, ctx); +} + +/* Convert an oid from string, making sure there's no duplicate */ +static csch_oid_t load_oid(read_ctx_t *ctx, csch_cgrp_t *parent, lht_node_t *nd, const char *oids) +{ + csch_oid_t oid; + char *end; + + oid = strtol(oids, &end, 10); + if (*end != '\0') { + error(nd, ("invalid ID appendix (not an integer: %s)\n", oids)); + return 0; + } + + if (htip_get(&parent->id2obj, oid) != NULL) { + error(nd, ("duplicate oid %lu\n", oid)); + return 0; + } + + if (parent->hdr.type == CSCH_CTYPE_GRP) { + if (oid >= parent->data.grp.next_id) + parent->data.grp.next_id = oid+1; + } + + return oid; +} + +/* Make sure node name matches the expected name and node type matches + the expected type. On match, parse or invent the oid and return it. On + error return 0. */ +csch_oid_t check_type_oid_(read_ctx_t *ctx, csch_cgrp_t *grp, lht_node_t *nd, const char *name, int namelen, lht_node_type_t type) +{ + const char *oids; + + if (nd->type != type) { + error(nd, ("%s must be a hash\n", name)); + return 0; + } + if (strncmp(nd->name, name, namelen) != 0) { + error(nd, ("expected node %s, got %s\n", name, nd->name)); + return 0; + } + + oids = nd->name + namelen; +TODO("delayed ID allocation!"); + if (*oids == '\0') { + return -1; +/* return ctx->sheet->next_id++;*/ + } + if (*oids != '.') { + error(nd, ("invalid ID appendix or wrong node name (expected %s. got %s)\n", name, nd->name)); + return 0; + } + + return load_oid(ctx, grp, nd, oids+1); +} + +/* shorthand with compile-time string length */ +#define check_type_oid(ctx, grp, nd, name, type) \ + check_type_oid_(ctx, grp, nd, #name, strlen(#name), type) + +TODO("revise whether this is needed at all") +#if 0 +/* Parse an object 'name.oid' or 'name' (automatic ID allocation) */ +csch_oid_t get_name_oid(read_ctx_t *ctx, lht_node_t *nd, char *name, int namelen) +{ + int len; + const char *sep = strchr(nd->name, '.'); + csch_oid_t oid; + + if (sep != NULL) { + len = sep - nd->name; + oid = load_oid(ctx, nd, sep+1); + if (oid == 0) + return 0; + } + else { + len = strlen(name)+1; +TODO("delayed ID allocation!"); + oid = ctx->sheet->next_id++; + } + + if (len >= namelen-1) { + error(nd, ("invalid object name '%s': too long\n", nd->name)); + return 0; + } + + memcpy(name, nd->name, len); + name[len] = '\0'; + return oid; +} +#endif + +typedef struct dispatch_s { + const char *prefix; + int (*handler)(read_ctx_t *ctx, csch_cgrp_t *parent, lht_node_t *nd, csch_oid_t oid); +} dispatch_t; + +static int dispatch_node(read_ctx_t *ctx, csch_cgrp_t *parent, lht_node_t *nd, const dispatch_t *tbl) +{ + char *sep = strchr(nd->name, '.'); + int len; + const dispatch_t *t; + csch_oid_t oid = 0; + + if (sep != NULL) { + len = sep - nd->name; + if (strncmp(nd->name, "pen.", 4) != 0) { + oid = load_oid(ctx, parent, nd, sep+1); + if (oid == 0) + return -1; + } + } + else + len = strlen(nd->name); + + for(t = tbl; t->prefix != NULL; t++) + if (strncmp(nd->name, t->prefix, len) == 0) + return t->handler(ctx, parent, nd, oid); + + error(nd, ("invalid object name '%s': unknown under node %s\n", nd->name, nd->parent->name)); + return -1; +} + +static int dispatch_subtree(read_ctx_t *ctx, csch_cgrp_t *parent, lht_node_t *parent_tree, lht_node_t *subtree, const dispatch_t *tbl, int allow_empty) +{ + lht_node_t *n; + lht_dom_iterator_t it; + + if (subtree == NULL) { + if (allow_empty) + return 0; + error(parent_tree, ("the subtree of '%s' shall not be empty\n", parent_tree->name)); + return -1; + } + + for(n = lht_dom_first(&it, subtree); n != NULL; n = lht_dom_next(&it)) + if (dispatch_node(ctx, parent, n, tbl)) + return -1; + + return 0; +} + +static int parse_coord_(read_ctx_t *ctx, csch_coord_t *dst, const lht_node_t *src, int silent) +{ + char *end; + long l; + + if (src == NULL) { + if (silent) + return -1; + *dst = 0; + return 0; + } + + if (src->type != LHT_TEXT) { + if (!silent) + error(src, ("coordinate value must be text\n")); + return -1; + } + l = strtol(src->data.text.value, &end, 10); + if (*end != '\0') { + if (!silent) + error(src, ("coordinate value: invalid integer '%s'\n", src->data.text.value)); + return -1; + } + *dst = l; + return 0; +} + +static int parse_coord(read_ctx_t *ctx, csch_coord_t *dst, const lht_node_t *src) +{ + return parse_coord_(ctx, dst, src, 0); +} + +static int parse_coord_maybe(read_ctx_t *ctx, csch_coord_t *dst, const lht_node_t *src) +{ + if (src == NULL) + return 0; + return parse_coord_(ctx, dst, src, 0); +} + +static int parse_angle(read_ctx_t *ctx, g2d_angle_t *dst, const lht_node_t *src) +{ + char *end; + double d; + + if (src == NULL) { + *dst = 0; + return 0; + } + + if (src->type != LHT_TEXT) { + error(src, ("angle value must be text\n")); + return -1; + } + d = strtod(src->data.text.value, &end); + if (*end != '\0') { + error(src, ("angle value: invalid decimal '%s'\n", src->data.text.value)); + return -1; + } + *dst = d; + return 0; +} + +static int parse_dash(read_ctx_t *ctx, unsigned short *dst, const lht_node_t *src) +{ + char *s, *end; + long l; + + if (src == NULL) { + *dst = 0; + return 0; + } + + if (src->type != LHT_TEXT) { + error(src, ("dash value must be text\n")); + return -1; + } + s = src->data.text.value; + if ((s[0] == '0') && (s[1] == 'x')) s += 2; + l = strtol(s, &end, 16); + if (*end != '\0') { + error(src, ("dash value: invalid hex numeric '%s'\n", src->data.text.value)); + return -1; + } + + if ((l < 0) || (l > 0xFFFF)) { + error(src, ("dash value: out of range: '%s' (must be between 0 and 0xFFFF)\n", src->data.text.value)); + return -1; + } + + *dst = l; + return 0; +} + +static int parse_oid(read_ctx_t *ctx, csch_oid_t *dst, const lht_node_t *src, int silent) +{ + char *end; + long l; + + if (src == NULL) { + if (!silent) + error(src, ("missing oid\n")); + return -1; + } + + if (src->type != LHT_TEXT) { + if (!silent) + error(src, ("oid value must be text\n")); + return -1; + } + l = strtol(src->data.text.value, &end, 10); + if (*end != '\0') { + if (!silent) + error(src, ("oid value: invalid integer '%s'\n", src->data.text.value)); + return -1; + } + if (l < 0) { + if (!silent) + error(src, ("oid value: must be positive: '%s'\n", src->data.text.value)); + return -1; + } + *dst = l; + return 0; +} + +static int parse_oidpath(read_ctx_t *ctx, char **dst, const lht_node_t *src) +{ + if ((src == NULL) || (src->type != LHT_TEXT)) + return -1; + *dst = rnd_strdup(src->data.text.value); + return 0; +} + +static int parse_double(read_ctx_t *ctx, double *dst, const lht_node_t *src) +{ + char *end; + double d; + + if (src == NULL) { + *dst = 0; + return 0; + } + + if (src->type != LHT_TEXT) { + error(src, ("oid value must be text\n")); + return -1; + } + d = strtod(src->data.text.value, &end); + if (*end != '\0') { + error(src, ("oid value: invalid integer '%s'\n", src->data.text.value)); + return -1; + } + *dst = d; + return 0; +} + +static int parse_double_maybe(read_ctx_t *ctx, double *dst, const lht_node_t *src) +{ + if (src == NULL) return 0; + return parse_double(ctx, dst, src); +} + + +static int parse_halign(read_ctx_t *ctx, csch_halign_t *dst, const lht_node_t *src) +{ + if (src == NULL) { + *dst = CSCH_HALIGN_START; + return 0; + } + if (src->type != LHT_TEXT) { + error(src, ("halign value must be text\n")); + return -1; + } + + *dst = csch_str2halign(src->data.text.value); + if (*dst == CSCH_HALIGN_invalid) { + error(src, ("halign value is unkown/invalid: %s\n", src->data.text.value)); + return -1; + } + return 0; +} + +static int parse_bool(read_ctx_t *ctx, int *dst, const lht_node_t *src, const lht_node_t *parent, int defval) +{ + if (src == NULL) { + if (defval < 0) { + error(parent, ("missing mandatory bool field\n")); + return defval; + } + *dst = defval; + return 0; + } + if (src->type != LHT_TEXT) { + error(src, ("bool value must be text\n")); + return -1; + } + + *dst = rnd_istrue(src->data.text.value); + return 0; +} + +static int parse_uuid(read_ctx_t *ctx, minuid_bin_t dst, const lht_node_t *src) +{ + static minuid_bin_t uuid0 = {0}; + + if (src == NULL) { + minuid_cpy(dst, uuid0); + return 0; + } + + if (src->type != LHT_TEXT) { + error(src, ("uuid must be text\n")); + return -1; + } + + if (strlen(src->data.text.value) != (MINUID_TXT_LEN-1)) { + error(src, ("invalid uuid format; wrong length\n")); + return -1; + } + + if (minuid_str2bin(dst, src->data.text.value) != 0) { + error(src, ("invalid uuid format; parse error\n")); + return -1; + } + + return 0; +} + +/*** atomic object parsing ***/ + +static int parse_color(read_ctx_t *ctx, rnd_color_t *dst, const lht_node_t *src) +{ + char *end; + unsigned long l; + + if (src->type != LHT_TEXT) { + error(src, ("color value must be text\n")); + return -1; + } + if (*src->data.text.value != '#') { + error(src, ("color value must start with '#' (wrong value: '%s')\n", src->data.text.value)); + return -1; + } + if (strlen(src->data.text.value+1) < 6) { + error(src, ("color value: invalid integer length '%s' - must be 24 bit hexadecimap\n", src->data.text.value+1)); + return -1; + } + l = strtol(src->data.text.value+1, &end, 16); + if ((*end != '\0') && (!isspace(*end))) { + error(src, ("color value: invalid integer '%s' - must be 24 bit hexadecimap\n", src->data.text.value+1)); + return -1; + } + if ((l < 0) || (l > 0xffffff)) { + error(src, ("color value: invalid integer '%s' - out of bounds\n", src->data.text.value+1)); + return -1; + } + l = l << 8; + return rnd_color_load_packed(dst, l); +} + +static int parse_pen_shape(read_ctx_t *ctx, csch_pen_shape_t *dst, const lht_node_t *src) +{ + const char *val; + if (src->type != LHT_TEXT) { + error(src, ("pen shape value must be text\n")); + return -1; + } + val = src->data.text.value; + if ((strncmp(val, "circle", 6) == 0) || (strncmp(val, "round", 5) == 0)) { + *dst = CSCH_PSHP_ROUND; + return 0; + } + if (strncmp(val, "square", 6) == 0) { + *dst = CSCH_PSHP_SQUARE; + return 0; + } + return -1; +} + +static int parse_common_properties(read_ctx_t *ctx, csch_chdr_t *obj, lht_node_t *subtree) +{ + int tmp; + + if (parse_bool(ctx, &tmp, lht_dom_hash_get(subtree, "lock"), subtree, 0) != 0) + return -1; + obj->lock = tmp; + + if (parse_bool(ctx, &tmp, lht_dom_hash_get(subtree, "floater"), subtree, 0) != 0) + return -1; + obj->floater = tmp; + + return 0; +} + +static int parse_pen(read_ctx_t *ctx, csch_cgrp_t *parent, lht_node_t *subtree, csch_oid_t oid) +{ + csch_cpen_t *pen; + const char *name = NULL; + lht_node_t *n; + + if (subtree == NULL) + return 0; + + name = subtree->name + 4; + + pen = csch_pen_alloc(ctx->sheet, parent, name); + if (pen == NULL) { + error(subtree, ("failed to allocate pen\n")); + return -1; + } + + if (parse_common_properties(ctx, &pen->hdr, subtree) != 0) + return -1; + if (parse_coord(ctx, &pen->size, lht_dom_hash_get(subtree, "size")) != 0) + return -1; + if (parse_color(ctx, &pen->color, lht_dom_hash_get(subtree, "color")) != 0) + return -1; + if (parse_pen_shape(ctx, &pen->shape, lht_dom_hash_get(subtree, "shape")) != 0) + return -1; + if (parse_attribs(ctx, &pen->hdr, NULL, lht_dom_hash_get(subtree, "attrib")) != 0) + return -1; + + if (parse_dash(ctx, &pen->dash, lht_dom_hash_get(subtree, "dash")) != 0) + return -1; + if (parse_coord(ctx, &pen->dash_period, lht_dom_hash_get(subtree, "dash_period")) != 0) + return -1; + + if (parse_coord(ctx, &pen->font_height, lht_dom_hash_get(subtree, "font_height")) != 0) + return -1; + + n = lht_dom_hash_get(subtree, "font_family"); + if (n != NULL) { + if (n->type != LHT_TEXT) { + error(n, ("font_family is not a text node\n")); + return -1; + } + pen->font_family = rnd_strdup(n->data.text.value); + } + + n = lht_dom_hash_get(subtree, "font_style"); + if (n != NULL) { + if (n->type != LHT_TEXT) { + error(n, ("font_style is not a text node\n")); + return -1; + } + pen->font_style = rnd_strdup(n->data.text.value); + } + + if (parse_coord(ctx, &pen->font_height, lht_dom_hash_get(subtree, "font_height")) != 0) + return -1; + + return 0; +} + +static int parse_pen_ref_(read_ctx_t *ctx, csch_chdr_t *obj, lht_node_t *subtree, int silent, int is_stroke) +{ + const lht_node_t *pn = lht_dom_hash_get(subtree, (is_stroke ? "stroke" : "fill")); + if (pn == NULL) { + if (!silent) + error(subtree, ("missing pen\n")); + return -1; + } + if (is_stroke) + obj->stroke_name = csch_comm_str(ctx->sheet, pn->data.text.value, 1); + else + obj->fill_name = csch_comm_str(ctx->sheet, pn->data.text.value, 1); + return 0; +} + +static int parse_stroke(read_ctx_t *ctx, csch_chdr_t *obj, lht_node_t *subtree, int silent) +{ + return parse_pen_ref_(ctx, obj, subtree, silent, 1); +} + +static int parse_fill(read_ctx_t *ctx, csch_chdr_t *obj, lht_node_t *subtree, int silent) +{ + return parse_pen_ref_(ctx, obj, subtree, silent, 0); +} + +static int parse_line_fields(read_ctx_t *ctx, csch_line_t *line, lht_node_t *subtree) +{ + if (parse_common_properties(ctx, &line->hdr, subtree) != 0) + return -1; + if (parse_coord(ctx, &line->spec.p1.x, lht_dom_hash_get(subtree, "x1")) != 0) + return -1; + if (parse_coord(ctx, &line->spec.p1.y, lht_dom_hash_get(subtree, "y1")) != 0) + return -1; + if (parse_coord(ctx, &line->spec.p2.x, lht_dom_hash_get(subtree, "x2")) != 0) + return -1; + if (parse_coord(ctx, &line->spec.p2.y, lht_dom_hash_get(subtree, "y2")) != 0) + return -1; + return 0; +} + +static int parse_line(read_ctx_t *ctx, csch_cgrp_t *parent, lht_node_t *subtree, csch_oid_t oid) +{ + csch_line_t *line; + + if (subtree == NULL) + return 0; + + if (subtree->type != LHT_HASH) { + error(subtree, ("line must be a hash\n")); + return -1; + } + + line = csch_line_alloc(ctx->sheet, parent, oid); + + if (parse_line_fields(ctx, line, subtree) != 0) + return -1; + + return parse_stroke(ctx, &line->hdr, subtree, 0); +} + +static int parse_arc_fields(read_ctx_t *ctx, csch_arc_t *arc, lht_node_t *subtree) +{ + int has_x, has_y; + + if (parse_common_properties(ctx, &arc->hdr, subtree) != 0) + return -1; + if (parse_coord(ctx, &arc->spec.c.x, lht_dom_hash_get(subtree, "cx")) != 0) + return -1; + if (parse_coord(ctx, &arc->spec.c.y, lht_dom_hash_get(subtree, "cy")) != 0) + return -1; + if (parse_coord(ctx, &arc->spec.r, lht_dom_hash_get(subtree, "r")) != 0) + return -1; + if (parse_angle(ctx, &arc->spec.start, lht_dom_hash_get(subtree, "sang")) != 0) + return -1; + if (parse_angle(ctx, &arc->spec.delta, lht_dom_hash_get(subtree, "dang")) != 0) + return -1; + + arc->spec.start /= RND_RAD_TO_DEG; + arc->spec.delta /= RND_RAD_TO_DEG; + + /* optional endpoint fields */ + has_x = (parse_coord_(ctx, &arc->spec_sx, lht_dom_hash_get(subtree, "sx"), 1) == 0); + has_y = (parse_coord_(ctx, &arc->spec_sy, lht_dom_hash_get(subtree, "sy"), 1) == 0); + arc->svalid = has_x && has_y; + + has_x = (parse_coord_(ctx, &arc->spec_ex, lht_dom_hash_get(subtree, "ex"), 1) == 0); + has_y = (parse_coord_(ctx, &arc->spec_ey, lht_dom_hash_get(subtree, "ey"), 1) == 0); + arc->evalid = has_x && has_y; + + return 0; +} + +static int parse_arc(read_ctx_t *ctx, csch_cgrp_t *parent, lht_node_t *subtree, csch_oid_t oid) +{ + csch_arc_t *arc; + + if (subtree == NULL) + return 0; + + if (subtree->type != LHT_HASH) { + error(subtree, ("arc must be a hash\n")); + return -1; + } + + arc = csch_arc_alloc(ctx->sheet, parent, oid); + + if (parse_arc_fields(ctx, arc, subtree) != 0) + return -1; + + return parse_stroke(ctx, &arc->hdr, subtree, 0); +} + + +static int parse_poly(read_ctx_t *ctx, csch_cgrp_t *parent, lht_node_t *subtree, csch_oid_t oid) +{ + csch_cpoly_t *poly; + lht_node_t *outline, *o; + + if (subtree == NULL) + return 0; + + if (subtree->type != LHT_HASH) { + error(subtree, ("polygon must be a hash\n")); + return -1; + } + outline = lht_dom_hash_get(subtree, "outline"); + if (outline == NULL) { + error(outline, ("polygon outline does not exist\n")); + return -1; + } + if (outline->type != LHT_LIST) { + error(outline, ("polygon outline must be a list\n")); + return -1; + } + + poly = csch_cpoly_alloc(ctx->sheet, parent, oid); + + for(o = outline->data.list.first; o != NULL; o = o->next) { + if (o->type != LHT_HASH) { + error(o, ("polygon outline list must contain hash items\n")); + return -1; + } + + if (strncmp(o->name, "line", 4) == 0) { + csch_coutline_t *dst = csch_vtcoutline_alloc_append(&poly->outline, 1); + dst->hdr = poly->hdr; + dst->hdr.type = CSCH_CTYPE_LINE; + if (parse_line_fields(ctx, &dst->line, o) != 0) + return -1; + } + else if (strncmp(o->name, "arc", 3) == 0) { + csch_coutline_t *dst = csch_vtcoutline_alloc_append(&poly->outline, 1); + dst->hdr = poly->hdr; + dst->hdr.type = CSCH_CTYPE_ARC; + if (parse_arc_fields(ctx, &dst->arc, o) != 0) + return -1; + } + else { + error(o, ("polygon outline: invalid/unsupported object type\n")); + return -1; + } + } + + /* common has to be after the outline loop so that outline objects don't + inherit common properties of the parent poly */ + if (parse_common_properties(ctx, &poly->hdr, subtree) != 0) + return -1; + + if (parse_fill(ctx, &poly->hdr, subtree, 1) == 0) + poly->has_fill = 1; + + if (parse_stroke(ctx, &poly->hdr, subtree, 1) == 0) + poly->has_stroke = 1; + + if (!poly->has_stroke && !poly->has_fill) + error(subtree, ("invisible polygon: no stroke, no fill; this is probably an error in your data\n")); + + return 0; +} + +static int parse_text(read_ctx_t *ctx, csch_cgrp_t *parent, lht_node_t *subtree, csch_oid_t oid) +{ + csch_text_t *text; + lht_node_t *ntext, *nx2, *ny2; + int itmp; + + if (subtree == NULL) + return 0; + + if (subtree->type != LHT_HASH) { + error(subtree, ("text must be a hash\n")); + return -1; + } + + ntext = lht_dom_hash_get(subtree, "text"); + if (ntext == NULL) { + error(subtree, ("text.text is missing\n")); + return -1; + } + if (ntext->type != LHT_TEXT) { + error(ntext, ("text.text is not a text node\n")); + return -1; + } + + text = csch_text_alloc(ctx->sheet, parent, oid); + + if (parse_common_properties(ctx, &text->hdr, subtree) != 0) + return -1; + if (parse_coord(ctx, &text->spec1.x, lht_dom_hash_get(subtree, "x1")) != 0) + return -1; + if (parse_coord(ctx, &text->spec1.y, lht_dom_hash_get(subtree, "y1")) != 0) + return -1; + + nx2 = lht_dom_hash_get(subtree, "x2"); + ny2 = lht_dom_hash_get(subtree, "y2"); + if ((nx2 != NULL) && (ny2 != NULL)) { + if (parse_coord(ctx, &text->spec2.x, nx2) != 0) + return -1; + if (parse_coord(ctx, &text->spec2.y, ny2) != 0) + return -1; + text->has_bbox = 1; + } + else + text->has_bbox = 0; + + + + if (parse_angle(ctx, &text->spec_rot, lht_dom_hash_get(subtree, "rot")) != 0) + return -1; + + if (parse_bool(ctx, &itmp, lht_dom_hash_get(subtree, "mirx"), subtree, 0) != 0) + return -1; + text->spec_mirx = itmp; + if (parse_bool(ctx, &itmp, lht_dom_hash_get(subtree, "miry"), subtree, 0) != 0) + return -1; + text->spec_miry = itmp; + + if (parse_halign(ctx, &text->halign, lht_dom_hash_get(subtree, "halign")) != 0) { + error(subtree, ("wrong halign in text object\n")); + return -1; + } + + text->text = rnd_strdup(ntext->data.text.value); + + if (parse_bool(ctx, &itmp, lht_dom_hash_get(subtree, "dyntext"), subtree, 0) != 0) + return -1; + text->dyntext = itmp; + + + return parse_stroke(ctx, &text->hdr, subtree, 0); +} + +static int parse_connection(read_ctx_t *ctx, csch_cgrp_t *parent, lht_node_t *subtree, csch_oid_t oid) +{ + csch_conn_t *conn; + lht_node_t *n, *nconn; + + if (subtree == NULL) + return 0; + + if (subtree->type != LHT_HASH) { + error(subtree, ("connection must be a hash\n")); + return -1; + } + + nconn = lht_dom_hash_get(subtree, "conn"); + if (nconn == NULL) { + error(subtree, ("connection without conn list\n")); + return -1; + } + + conn = csch_conn_alloc(ctx->sheet, parent, oid); + + for(n = nconn->data.list.first; n != NULL; n = n->next) { + csch_oidpath_t *oidp = csch_vtoidpath_alloc_append(&conn->conn_path, 1); + if (csch_oidpath_parse(oidp, n->data.text.value) != 0) { + error(subtree, ("invalid oid path in conn\n")); + return -1; + } + } + + return 0; +} + +/*** composite object parsing: groups, object lists */ + +static int parse_group(read_ctx_t *ctx, csch_cgrp_t *parent, lht_node_t *subtree, csch_oid_t oid); +static int parse_group_ref(read_ctx_t *ctx, csch_cgrp_t *parent, lht_node_t *subtree, csch_oid_t oid); + +static const dispatch_t objs_tbl[] = { + {"group", parse_group}, + {"group_ref", parse_group_ref}, + {"line", parse_line}, + {"text", parse_text}, + {"arc", parse_arc}, + {"polygon", parse_poly}, + {"pen", parse_pen}, + {"connection",parse_connection}, + {NULL, NULL} +}; + +static int parse_group_(read_ctx_t *ctx, csch_cgrp_t *grp, lht_node_t *subtree) +{ + int res, itmp; + lht_node_t *nd; + + if (subtree == NULL) + return -1; + + if (parse_uuid(ctx, &grp->uuid, lht_dom_hash_get(subtree, "uuid")) != 0) + return -1; + if (grp->hdr.type == CSCH_CTYPE_GRP) { + if (parse_uuid(ctx, &grp->data.grp.src_uuid, lht_dom_hash_get(subtree, "src_uuid")) != 0) + return -1; + } + + if (parse_attribs(ctx, &grp->hdr, NULL, lht_dom_hash_get(subtree, "attrib")) != 0) + return -1; + if (parse_common_properties(ctx, &grp->hdr, subtree) != 0) + return -1; + + nd = lht_dom_hash_get(subtree, "loclib_name"); + if (nd != NULL) { + if (nd->type != LHT_TEXT) { + error(nd, ("loclib_name needs to be a text node\n")); + return -1; + } + grp->loclib_name = rnd_strdup(nd->data.text.value); + } + + if (parse_coord(ctx, &grp->x, lht_dom_hash_get(subtree, "x")) != 0) + return -1; + if (parse_coord(ctx, &grp->y, lht_dom_hash_get(subtree, "y")) != 0) + return -1; + if (parse_double(ctx, &grp->spec_rot, lht_dom_hash_get(subtree, "rot")) != 0) + return -1; + + if (parse_bool(ctx, &itmp, lht_dom_hash_get(subtree, "mirx"), subtree, 0) != 0) + return -1; + grp->mirx = itmp; + + if (parse_bool(ctx, &itmp, lht_dom_hash_get(subtree, "miry"), subtree, 0) != 0) + return -1; + grp->miry = itmp; + + csch_cgrp_xform_update(ctx->sheet, grp); /* set up the matrix for object transformations */ + csch_cgrp_role_update(ctx->sheet, grp); /* set up display layer before parsing children (they will depend on this) */ + + res = dispatch_subtree(ctx, grp, subtree, lht_dom_hash_get(subtree, "objects"), objs_tbl, 0); + + csch_cgrp_bbox_update(ctx->sheet, grp); + + return res; +} + +static int parse_group(read_ctx_t *ctx, csch_cgrp_t *parent, lht_node_t *subtree, csch_oid_t oid) +{ + csch_cgrp_t *grp = csch_cgrp_alloc(ctx->sheet, parent, oid); + if (grp == NULL) { + error(subtree, ("failed to allocate group\n")); + return -1; + } + return parse_group_(ctx, grp, subtree); +} + +static int parse_root_group(read_ctx_t *ctx, csch_cgrp_t *grp, lht_node_t *subtree, csch_oid_t oid) +{ + if ((grp != &ctx->sheet->direct) && (grp != &ctx->sheet->indirect)) + csch_cgrp_init(ctx->sheet, grp, NULL, oid); + return parse_group_(ctx, grp, subtree); +} + +static int parse_child_xform_entry(read_ctx_t *ctx, csch_cgrp_t *grp, lht_node_t *subtree, csch_child_xform_t *cx) +{ + int mirx = 0, miry = 0, remv = 0; + + if (subtree->type != LHT_HASH) { + error(subtree, ("group ref child_xform list entries need to be hashes\n")); + return -1; + } + + if (csch_oidpath_parse_relative(&cx->path, subtree->name) != 0) { + error(subtree, ("group ref child_xform: syntax error in path\n")); + rnd_trace("name=%s\n", subtree->name); + return -1; + } + + if (parse_coord_maybe(ctx, &cx->movex, lht_dom_hash_get(subtree, "movex")) != 0) return -1; + if (parse_coord_maybe(ctx, &cx->movey, lht_dom_hash_get(subtree, "movey")) != 0) return -1; + if (parse_double_maybe(ctx, &cx->rot, lht_dom_hash_get(subtree, "rot")) != 0) return -1; + if (parse_bool(ctx, &mirx, lht_dom_hash_get(subtree, "mirx"), subtree, 0) != 0) return -1; + if (parse_bool(ctx, &miry, lht_dom_hash_get(subtree, "miry"), subtree, 0) != 0) return -1; + if (parse_bool(ctx, &remv, lht_dom_hash_get(subtree, "remove"), subtree, 0) != 0) return -1; + + cx->mirx = mirx; + cx->miry = miry; + cx->remove = remv; + + return 0; +} + +static int parse_child_xform(read_ctx_t *ctx, csch_cgrp_t *grpref, lht_node_t *subtree) +{ + lht_node_t *n; + + if (subtree == NULL) + return 0; /* optional */ + + if (subtree->type != LHT_LIST) { + error(subtree, ("group ref child_xform needs to be a list\n")); + return -1; + } + + for(n = subtree->data.list.first; n != NULL; n = n->next) { + csch_child_xform_t *cx = calloc(sizeof(csch_child_xform_t), 1); + vtp0_append(&grpref->data.ref.child_xform, cx); + if (parse_child_xform_entry(ctx, grpref, n, cx) != 0) + return -1; + } + return 0; +} + +static int parse_group_ref(read_ctx_t *ctx, csch_cgrp_t *parent, lht_node_t *subtree, csch_oid_t oid) +{ + csch_cgrp_t *grp = csch_cgrp_ref_alloc(ctx->sheet, parent, oid); + + if (grp == NULL) { + error(subtree, ("failed to allocate group ref\n")); + return -1; + } + + if (parse_attribs(ctx, &grp->hdr, NULL, lht_dom_hash_get(subtree, "attrib")) != 0) + return -1; + if (parse_common_properties(ctx, &grp->hdr, subtree) != 0) + return -1; + + if (parse_coord(ctx, &grp->x, lht_dom_hash_get(subtree, "x")) != 0) + return -1; + if (parse_coord(ctx, &grp->y, lht_dom_hash_get(subtree, "y")) != 0) + return -1; + if (parse_double(ctx, &grp->spec_rot, lht_dom_hash_get(subtree, "rot")) != 0) + return -1; + if (parse_oidpath(ctx, &grp->data.ref.ref_str, lht_dom_hash_get(subtree, "ref")) != 0) + return -1; + if (parse_child_xform(ctx, grp, lht_dom_hash_get(subtree, "child_xform")) != 0) + return -1; + + return 0; +} + +static int parse_conf(read_ctx_t *ctx, lht_node_t *sub) +{ + if ((sub == NULL) || (ctx->cfg_dest == RND_CFR_invalid)) + return 0; + if (rnd_conf_insert_tree_as(ctx->cfg_dest, sub) != 0) { + rnd_message(RND_MSG_ERROR, "Failed to insert the config subtree '%s' found in %s\n", sub->name, ctx->sheet->hidlib.fullpath); + return -1; + } + else + rnd_conf_update(NULL, -1); + return 0; +} + +static int parse_sheet(read_ctx_t *ctx, lht_node_t *subtree, int load_conf) +{ + if ((ctx->ver < 1) || (ctx->ver > 1)) { + error(subtree, ("Unknown sheet version (too old or too new)\n")); + return -1; + } + + if (parse_root_group(ctx, &ctx->sheet->indirect, hash_must_get(subtree, "obj_indirect.1"), 1) != 0) + return -1; + if (parse_root_group(ctx, &ctx->sheet->direct, hash_must_get(subtree, "obj_direct.2"), 2) != 0) + return -1; + if (load_conf && (parse_conf(ctx, lht_dom_hash_get(subtree, "sch-rnd-conf-v1")) != 0)) + return -1; + return 0; +} + +/* Copy only standard, symbol-related pen names from the default sheet */ +static int sym_as_sheet_chk_copy_pen(void *udata, csch_sheet_t *dst, csch_cpen_t *p) +{ +/* read_ctx_t *ctx = udata;*/ + if (strncmp(p->name.str, "busterm-", 8) == 0) return 1; + if (strncmp(p->name.str, "term-", 5) == 0) return 1; + if (strncmp(p->name.str, "sym-", 4) == 0) return 1; + return 0; +} + +static int parse_sym_as_sheet(read_ctx_t *ctx, lht_node_t *root_hash, int load_conf) +{ + int res; + lht_node_t *grp1; + + /* ctx->sheet->indirect and ctx->sheet->direct are initialized and empty */ + rnd_trace("SYM LOAD\n"); + + grp1 = lht_dom_hash_get(root_hash, "group.1"); + if (grp1 == NULL) { + rnd_message(RND_MSG_ERROR, "Symbol-as-sheet load: group.1 doesn't exist\n"); + return -1; + } + if (grp1->type != LHT_HASH) { + rnd_message(RND_MSG_ERROR, "Symbol-as-sheet load: group.1 is not a hash\n"); + return -1; + } + + + + res = parse_group_(ctx, &ctx->sheet->direct, grp1); + if (res == 0) { + ctx->sheet->is_symbol = 1; + sch_rnd_sheet_setup(ctx->sheet, SCH_RND_SSC_PENS | SCH_RND_SSC_PEN_MARK_DEFAULT, sym_as_sheet_chk_copy_pen, ctx); + } + + return res; +} + +/*** file level parsing and entry points ***/ + +static int io_lihata_load_sheet_or_buff_or_sym(FILE *f, const char *fn, const char *fmt, csch_sheet_t *dst, const char *root_prefix, int root_prefix_len, int load_conf, int allow_sym) +{ + int res = -1; + char *errmsg = NULL; + read_ctx_t ctx; + + ctx.fn = fn; + ctx.sheet = dst; + ctx.doc = lht_dom_load(fn, &errmsg); + if (ctx.doc == NULL) { + rnd_message(RND_MSG_ERROR, "Error loading '%s':\n%s\n", fn, errmsg); + free(errmsg); + return -1; + } + + TODO("This should be coming from an arg for loading file into buffer: , rnd_conf_role_t settings_dest"); + ctx.cfg_dest = RND_CFR_DESIGN; + + if ((ctx.doc->root->type == LHT_HASH) && (strncmp(ctx.doc->root->name, root_prefix, root_prefix_len) == 0)) { + char *end; + ctx.ver = strtol(ctx.doc->root->name + root_prefix_len, &end, 10); + if (*end != '\0') + error(ctx.doc->root, ("invalid sheet version (not an integer)\n")); + else { + res = parse_sheet(&ctx, ctx.doc->root, load_conf); + if (res == 0) + csch_sheet_bbox_update(dst); + } + } + else if (allow_sym && (ctx.doc->root->type == LHT_HASH) && (strncmp(ctx.doc->root->name, "cschem-group-v", 14) == 0)) { + /* special case: load sym as sheet for direct editing */ + res = parse_sym_as_sheet(&ctx, ctx.doc->root, load_conf); + if (res == 0) + csch_sheet_bbox_update(dst); + } + else { + rnd_message(RND_MSG_ERROR, "Error loading '%s': not a %s\n", fn, root_prefix); + res = -1; + } + + lht_dom_uninit(ctx.doc); + free(errmsg); + return res; +} + +int io_lihata_load_sheet(FILE *f, const char *fn, const char *fmt, csch_sheet_t *dst) +{ + return io_lihata_load_sheet_or_buff_or_sym(f, fn, fmt, dst, "cschem-sheet-v", 14, 1, 1); +} + +int io_lihata_load_buffer(FILE *f, const char *fn, const char *fmt, csch_sheet_t *dst) +{ + return io_lihata_load_sheet_or_buff_or_sym(f, fn, fmt, dst, "cschem-buffer-v", 15, 0, 0); +} + +int io_lihata_load_project(FILE *f, const char *fn, const char *fmt, csch_project_t *dst, int with_sheets) +{ + int res = -1; + char *errmsg = NULL; + read_ctx_t ctx; + + ctx.fn = fn; + ctx.proj = dst; + ctx.doc = lht_dom_load(fn, &errmsg); + if (ctx.doc == NULL) { + rnd_message(RND_MSG_ERROR, "Error loading '%s':\n%s\n", fn, errmsg); + free(errmsg); + return -1; + } + + if ((ctx.doc->root->type == LHT_HASH) && (strncmp(ctx.doc->root->name, "coraleda-project-v", 18) == 0)) { + char *end; + ctx.ver = strtol(ctx.doc->root->name+18, &end, 10); + if (*end == '\0') { + free(dst->hdr.loadname); + dst->hdr.loadname = rnd_strdup(fn); + csch_proj_update_filename(dst); + dst->hdr.root = ctx.doc; + ctx.doc = NULL; + res = 0; + } + else + error(ctx.doc->root, ("invalid project version (not an integer)\n")); + } + else { + rnd_message(RND_MSG_ERROR, "Error loading '%s': not a project\n", fn); + res = -1; + } + + if (ctx.doc != NULL) + lht_dom_uninit(ctx.doc); + free(errmsg); + return res; +} + +csch_cgrp_t *io_lihata_load_grp(FILE *f, const char *fn, const char *fmt, csch_sheet_t *sheet) +{ + csch_cgrp_t *resgrp = NULL; + char *errmsg = NULL; + read_ctx_t ctx; + + ctx.fn = fn; + ctx.sheet = sheet; + ctx.doc = lht_dom_load(fn, &errmsg); + if (ctx.doc == NULL) { + rnd_message(RND_MSG_ERROR, "Error loading '%s':\n%s\n", fn, errmsg); + free(errmsg); + return NULL; + } + + TODO("code dup with sheet load"); + + if ((ctx.doc->root != NULL) && (ctx.doc->root->type == LHT_HASH) && (strncmp(ctx.doc->root->name, "cschem-group-v", 14) == 0)) { + char *end; + ctx.ver = strtol(ctx.doc->root->name+14, &end, 10); + if (*end != '\0') + error(ctx.doc->root, ("invalid sheet version (not an integer)\n")); + else { + lht_node_t *nd = lht_dom_hash_get(ctx.doc->root, "group.1"); + + if (nd != NULL) { + if (htip_get(&sheet->direct.id2obj, 1) == NULL) { + int rv = parse_group(&ctx, &sheet->direct, nd, 1); + if (rv == 0) { + resgrp = htip_get(&sheet->direct.id2obj, 1); + csch_cgrp_update(sheet, resgrp, 1); + csch_sheet_bbox_update(sheet); + if (sheet->direct.data.grp.next_id < 2) + sheet->direct.data.grp.next_id = 2; + } + } + else + rnd_message(RND_MSG_ERROR, "Error loading '%s': there's already a group1 in destination sheet\n", fn); + } + } + } + else + rnd_message(RND_MSG_ERROR, "Error loading '%s': not a group\n", fn); + + lht_dom_uninit(ctx.doc); + free(errmsg); + return resgrp; +} + +typedef struct { + csch_plug_io_type_t expect, have; + enum { + TPS_UNDECIDED, + TPS_GOOD, + TPS_BAD + } state; +} test_parse_t; + +/* expect root to be a ha:pcb-rnd-board-v* */ +void test_parse_ev(lht_parse_t *ctx, lht_event_t ev, lht_node_type_t nt, const char *name, const char *value) +{ + test_parse_t *tp = ctx->user_data; + if (ev == LHT_OPEN) { + if ((nt == LHT_HASH) && (strncmp(name, "cschem-sheet-v", 14) == 0)) + tp->have = CSCH_IOTYP_SHEET; + else if ((nt == LHT_HASH) && (strncmp(name, "cschem-buffer-v", 15) == 0)) + tp->have = CSCH_IOTYP_BUFFER; + else if ((nt == LHT_HASH) && (strncmp(name, "cschem-group-v", 14) == 0)) + tp->have = CSCH_IOTYP_GROUP; + else if ((nt == LHT_HASH) && (strncmp(name, "coraleda-project-v", 18) == 0)) + tp->have = CSCH_IOTYP_PROJECT; + else + tp->have = 0; + + if ((tp->have == CSCH_IOTYP_GROUP) && (tp->expect == CSCH_IOTYP_SHEET)) + tp->state = TPS_GOOD; /* special case: loading a symbol group as a sheet for direct editing */ + else + tp->state = (tp->have & tp->expect) ? TPS_GOOD : TPS_BAD; + } +} + + +/* run an event parser for the first 32k of the file; accept the file if it + has a valid looking root; refuse if: + - no root in the first 32k (or till eof) + - not a valid lihata doc (parser error) + - lihata, but the wrong root +*/ +int io_lihata_test_parse(FILE *f, const char *fn, const char *fmt, csch_plug_io_type_t type) +{ + lht_parse_t ctx; + int count; + test_parse_t tp; + + tp.expect = type; + tp.state = TPS_UNDECIDED; + + lht_parser_init(&ctx); + ctx.event = test_parse_ev; + ctx.user_data = &tp; + + for(count = 0; count < 32768; count++) { + int c = fgetc(f); + if (lht_parser_char(&ctx, c) != LHTE_SUCCESS) { + /* parse error or end */ + tp.state = TPS_BAD; + break; + } + if (tp.state != TPS_UNDECIDED) + break; + } + lht_parser_uninit(&ctx); + return (tp.state == TPS_GOOD) ? 0 : -1; +} Index: tags/1.0.5/src/plugins/io_lihata/read.h =================================================================== --- tags/1.0.5/src/plugins/io_lihata/read.h (nonexistent) +++ tags/1.0.5/src/plugins/io_lihata/read.h (revision 10414) @@ -0,0 +1,37 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - lihata format support + * Copyright (C) 2018,2022 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + + +#include +#include +#include + +int io_lihata_load_sheet(FILE *f, const char *fn, const char *fmt, csch_sheet_t *dst); +int io_lihata_load_buffer(FILE *f, const char *fn, const char *fmt, csch_sheet_t *dst); +int io_lihata_load_project(FILE *f, const char *fn, const char *fmt, csch_project_t *dst, int with_sheets); +csch_cgrp_t *io_lihata_load_grp(FILE *f, const char *fn, const char *fmt, csch_sheet_t *sheet); +int io_lihata_test_parse(FILE *f, const char *fn, const char *fmt, csch_plug_io_type_t type); + Index: tags/1.0.5/src/plugins/io_lihata/write.c =================================================================== --- tags/1.0.5/src/plugins/io_lihata/write.c (nonexistent) +++ tags/1.0.5/src/plugins/io_lihata/write.c (revision 10414) @@ -0,0 +1,639 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - lihata format support + * Copyright (C) 2020,2022,2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "write.h" + +typedef struct { + FILE *f; + const csch_sheet_t *sheet; +} write_ctx_t; + +static char *ind_gen(char *dst, int max, int lev) +{ + if (lev > max) lev = max; + memset(dst, '\t', lev); + dst[lev] = '\0'; + return dst; +} + +#define IND(indlev) \ + char ind_[128], *ind = ind_gen(ind_, sizeof(ind_)-1, indlev); + +static int lht_save_group(write_ctx_t *ctx, int indlev, const csch_cgrp_t *grp, const char *name, long oid, int inhibit_uuid); + + +static int attr_cmp(const void *v1, const void *v2) +{ + csch_attrib_t * const *a1 = v1, * const *a2 = v2; + return strcmp((*a1)->key, (*a2)->key); +} + +static void lht_print_str(FILE *f, const char *s) +{ + if (s == NULL) { + fprintf(f, "{}"); + return; + } + if (!lht_need_brace(LHT_TEXT, s, 0)) { + fprintf(f, "%s", s); + return; + } + fputc('{', f); + for(; *s != '\0'; s++) { + if ((*s == '\\') || (*s == '}')) + fputc('\\', f); + fputc(*s, f); + } + fputc('}', f); +} + +static int lht_save_attribs(write_ctx_t *ctx, int indlev, char *parind, const htsp_t *att) +{ + htsp_entry_t *e; + vtp0_t ord; + long n; + + memset(&ord, 0, sizeof(ord)); + + for(e = htsp_first(att); e != NULL; e = htsp_next(att, e)) + vtp0_append(&ord, e->value); + if (ord.used > 0) { + qsort(ord.array, ord.used, sizeof(void *), attr_cmp); + fprintf(ctx->f, "%s ha:attrib {\n", parind); + for(n = 0; n < ord.used; n++) { + const csch_attrib_t *a = ord.array[n]; + if (a->val != NULL) { + if (a->prio != CSCH_ATP_USER_DEFAULT) { + fprintf(ctx->f, "%s ha:%s = { value=", parind, a->key); + lht_print_str(ctx->f, a->val); + fprintf(ctx->f, "; prio=%d; }\n", a->prio); + } + else { + fprintf(ctx->f, "%s ", parind); + lht_print_str(ctx->f, a->key); + fprintf(ctx->f, "="); + lht_print_str(ctx->f, a->val); + fprintf(ctx->f, "\n"); + } + } + else { + long n; + + if (a->prio != CSCH_ATP_USER_DEFAULT) + fprintf(ctx->f, "%s ha:%s = { li:value = {\n", parind, a->key); + else + fprintf(ctx->f, "%s li:%s {\n", parind, a->key); + + for(n = 0; n < a->arr.used; n++) { + fprintf(ctx->f, "%s ", parind); + lht_print_str(ctx->f, a->arr.array[n]); + fprintf(ctx->f, "\n"); + } + if (a->prio != CSCH_ATP_USER_DEFAULT) { + fprintf(ctx->f, "%s }\n", parind); + fprintf(ctx->f, "%s prio=%d; }\n", parind, a->prio); + } + else + fprintf(ctx->f, "%s }\n", parind); + } + } + fprintf(ctx->f, "%s }\n", parind); + } + vtp0_uninit(&ord); + return 0; +} + +/* Returns if anything has been written */ +static int lht_print_common_properties(write_ctx_t *ctx, const csch_chdr_t *obj, const char *ind, const char *ind2) +{ + int res = 0; + + if (ind == NULL) ind = " "; + if (ind2 == NULL) ind2 = ""; + + if (obj->lock) { + fprintf(ctx->f, "%s%slock=1;", ind, ind2); + ind = " "; + ind2 = ""; + res = 1; + } + if (obj->floater) { + fprintf(ctx->f, "%s%sfloater=1;", ind, ind2); + ind = " "; + ind2 = ""; + res = 1; + } + + return res; +} + +static int lht_print_line_(write_ctx_t *ctx, const csch_line_t *line, int in_poly) +{ + fprintf(ctx->f, " x1=%ld; y1=%ld; x2=%ld; y2=%ld;", + line->spec.p1.x, line->spec.p1.y, + line->spec.p2.x, line->spec.p2.y); + + if (!in_poly) { + fprintf(ctx->f, " stroke=%s;", line->hdr.stroke_name.str); + lht_print_common_properties(ctx, &line->hdr, NULL, NULL); + } + + fprintf(ctx->f, " }\n"); + return 0; +} + +static int lht_print_line(write_ctx_t *ctx, int indlev, char *parind, const csch_line_t *line) +{ + return lht_print_line_(ctx, line, 0); +} + + +static int lht_print_arc_(write_ctx_t *ctx, const csch_arc_t *arc, int in_poly) +{ + fprintf(ctx->f, " cx=%ld; cy=%ld; r=%ld; sang=%f; dang=%f;", + arc->spec.c.x, arc->spec.c.y, arc->spec.r, + arc->spec.start * RND_RAD_TO_DEG, arc->spec.delta * RND_RAD_TO_DEG); + + if (arc->svalid) + fprintf(ctx->f, " sx=%ld; sy=%ld;", arc->spec_sx, arc->spec_sy); + if (arc->evalid) + fprintf(ctx->f, " ex=%ld; ey=%ld;", arc->spec_ex, arc->spec_ey); + + if (!in_poly) { + fprintf(ctx->f, " stroke=%s;", arc->hdr.stroke_name.str); + lht_print_common_properties(ctx, &arc->hdr, NULL, NULL); + } + + fprintf(ctx->f, " }\n"); + return 0; +} + +static int lht_print_arc(write_ctx_t *ctx, int indlev, char *parind, const csch_arc_t *arc) +{ + return lht_print_arc_(ctx, arc, 0); +} + +static int lht_print_cpoly(write_ctx_t *ctx, int indlev, char *parind, const csch_cpoly_t *poly) +{ + long n; + csch_coutline_t *o; + + /* write outline list */ + fprintf(ctx->f, "\n%s li:outline {\n", parind); + for(n = 0, o = poly->outline.array; n < poly->outline.used; n++, o++) { + switch(o->hdr.type) { + case CSCH_CTYPE_LINE: + fprintf(ctx->f, "%s ha:line {", parind); + lht_print_line_(ctx, &o->line, 1); + break; + case CSCH_CTYPE_ARC: + fprintf(ctx->f, "%s ha:arc {", parind); + lht_print_arc_(ctx, &o->arc, 1); break; + break; + default: + rnd_message(RND_MSG_ERROR, "Invalid object in polygon outline\n"); + break; + } + } + fprintf(ctx->f, "%s }\n", parind); + + /* write pens */ + if (poly->has_stroke) + fprintf(ctx->f, "%s stroke=%s;\n", parind, poly->hdr.stroke_name.str); + if (poly->has_fill) + fprintf(ctx->f, "%s fill=%s;\n", parind, poly->hdr.fill_name.str); + + if (lht_print_common_properties(ctx, &poly->hdr, parind, "\t\t")) + fprintf(ctx->f, "\n"); + + fprintf(ctx->f, "%s }\n", parind); + return 0; +} + +static int lht_print_cbitmap(write_ctx_t *ctx, int indlev, char *parind, const csch_cbitmap_t *bitmap) +{ + return -1; +} + +static int lht_print_conn(write_ctx_t *ctx, int indlev, char *parind, const csch_conn_t *conn) +{ + long n; + + fprintf(ctx->f, "\n%s li:conn {\n", parind); + if (conn->conn.used != 0) { + for(n = 0; n < conn->conn.used; n++) { + char *path = csch_chdr_to_oidpath_str(conn->conn.array[n]); + fprintf(ctx->f, "%s %s\n", parind, path); + free(path); + } + } + else { + for(n = 0; n < conn->conn_path.used; n++) { + char *path = csch_oidpath_to_str(&conn->conn_path.array[n]); + fprintf(ctx->f, "%s %s\n", parind, path); + free(path); + } + } + fprintf(ctx->f, "%s }\n", parind); + fprintf(ctx->f, "%s }\n", parind); + return 0; +} + +static int lht_print_text(write_ctx_t *ctx, int indlev, char *parind, const csch_text_t *text) +{ + fprintf(ctx->f, " x1=%ld; y1=%ld;", text->spec1.x, text->spec1.y); + + if (text->has_bbox) + fprintf(ctx->f, " x2=%ld; y2=%ld;", text->spec2.x, text->spec2.y); + + if (text->spec_rot != 0) + fprintf(ctx->f, " rot=%f;", text->spec_rot); + if (text->spec_mirx != 0) + fprintf(ctx->f, " mirx=1;"); + if (text->spec_miry != 0) + fprintf(ctx->f, " miry=1;"); + + if (text->halign != CSCH_HALIGN_START) + fprintf(ctx->f, " halign=%s;", csch_halign2str(text->halign)); + + fprintf(ctx->f, " dyntext=%d; stroke=%s;", + text->dyntext, text->hdr.stroke_name.str); + + fprintf(ctx->f, " text="); + lht_print_str(ctx->f, text->text); + fprintf(ctx->f, ";"); + + + lht_print_common_properties(ctx, &text->hdr, NULL, NULL); + + fprintf(ctx->f, " }\n"); + return 0; +} + +static int lht_print_cgrp(write_ctx_t *ctx, int indlev, char *parind, const csch_cgrp_t *grp) +{ + return lht_save_group(ctx, indlev, grp, "group", grp->hdr.oid, 0); +} + +static int lht_print_cgrp_ref(write_ctx_t *ctx, int indlev, char *parind, const csch_cgrp_t *grp) +{ + return lht_save_group(ctx, indlev, grp, "group_ref", grp->hdr.oid, 0); +} + +static int lht_print_pen(write_ctx_t *ctx, int indlev, char *parind, const csch_cpen_t *pen) +{ + char clr[8]; + + /* truncate alpha */ + strncpy(clr, pen->color.str, 7); + clr[7] = '\0'; + fprintf(ctx->f, " shape=%s; size=%ld; color=%s; font_height=%ld;", + csch_pen_shape_name(pen->shape), pen->size, clr, pen->font_height); + + if (pen->dash != 0) + fprintf(ctx->f, " dash=%04x; dash_period=%ld;", pen->dash, pen->dash_period); + + if (pen->font_family != NULL) { + fprintf(ctx->f, " font_family="); + lht_print_str(ctx->f, pen->font_family); + fprintf(ctx->f, ";"); + } + + if (pen->font_style != NULL) { + fprintf(ctx->f, " font_style="); + lht_print_str(ctx->f, pen->font_style); + fprintf(ctx->f, ";"); + } + + lht_print_common_properties(ctx, &pen->hdr, NULL, NULL); + + fprintf(ctx->f, " }\n"); + + return 0; +} + + + +static int lht_print_obj(write_ctx_t *ctx, int indlev, char *parind, const csch_chdr_t *obj) +{ + int r = -1, want_hdr = (obj->type != CSCH_CTYPE_GRP) && (obj->type != CSCH_CTYPE_GRP_REF); + + /* pen is special case: instead of oid, its name is the ID */ + if (obj->type == CSCH_CTYPE_PEN) { +TODO("may need to quote ID") + csch_cpen_t *pen = (csch_cpen_t *)obj; + fprintf(ctx->f, "%s ha:pen.%s {", parind, pen->name.str); + r = lht_print_pen(ctx, indlev+1, parind, pen); + return r; + } + + if (want_hdr) + fprintf(ctx->f, "%s ha:%s.%d {", parind, csch_ctype_name(obj->type), obj->oid); + switch(obj->type) { + case CSCH_CTYPE_max: + case CSCH_CTYPE_invalid: r = -1; break; + case CSCH_CTYPE_LINE: r = lht_print_line(ctx, indlev+1, parind, (const csch_line_t *)obj); break; + case CSCH_CTYPE_ARC: r = lht_print_arc(ctx, indlev+1, parind, (const csch_arc_t *)obj); break; + case CSCH_CTYPE_POLY: r = lht_print_cpoly(ctx, indlev+1, parind, (const csch_cpoly_t *)obj); break; + case CSCH_CTYPE_TEXT: r = lht_print_text(ctx, indlev+1, parind, (const csch_text_t *)obj); break; + case CSCH_CTYPE_BITMAP: r = lht_print_cbitmap(ctx, indlev+1, parind, (const csch_cbitmap_t *)obj); break; + case CSCH_CTYPE_CONN: r = lht_print_conn(ctx, indlev+1, parind, (const csch_conn_t *)obj); break; + case CSCH_CTYPE_GRP: r = lht_print_cgrp(ctx, indlev, parind, (const csch_cgrp_t *)obj); break; + case CSCH_CTYPE_GRP_REF: r = lht_print_cgrp_ref(ctx, indlev, parind, (const csch_cgrp_t *)obj); break; + case CSCH_CTYPE_PEN: break; /* can't get here: already handled above */ + } + return r; +} + +static int ord_cmp(const void *v1, const void *v2) +{ + csch_chdr_t * const *o1 = v1, * const *o2 = v2; + if (((*o1)->oid < 0) && ((*o2)->oid < 0)) { + /* special case: order negative numbers the other way, that's how + save-load-save round trips won't invert their order because of + new negative IDs are assigned decreasing order */ + if ((*o1)->oid >= (*o2)->oid) + return -1; + return +1; + } + if ((*o1)->oid >= (*o2)->oid) + return +1; + return -1; +} + +static void ord_objs(write_ctx_t *ctx, const htip_t *id2obj, vtp0_t *ord) +{ + htip_entry_t *e; + ord->used = 0; + for(e = htip_first(id2obj); e != NULL; e = htip_next(id2obj, e)) + vtp0_append(ord, e->value); + qsort(ord->array, ord->used, sizeof(void *), ord_cmp); +} + +int lht_save_grp_ref_child_xforms(write_ctx_t *ctx, const char *ind, const csch_cgrp_t *grp) +{ + long n, i; + fprintf(ctx->f, "%s\tli:child_xform {\n", ind); + for(n = 0; n < grp->data.ref.child_xform.used; n++) { + csch_child_xform_t *cx = grp->data.ref.child_xform.array[n]; + if ((cx == NULL) || cx->cache || cx->removed || csch_grp_ref_child_xform_is_empty(cx)) continue; + /* print path */ + fprintf(ctx->f, "%s\t\t{ha:", ind); + for(i = 0; i < cx->path.vt.used; i++) { + if (i > 0) fprintf(ctx->f, "/"); + fprintf(ctx->f, "%d", cx->path.vt.array[i]); + } + fprintf(ctx->f, "} {"); + + if (cx->movex != 0) fprintf(ctx->f, " movex=%ld;", cx->movex); + if (cx->movey != 0) fprintf(ctx->f, " movey=%ld;", cx->movey); + if (cx->rot != 0) rnd_fprintf(ctx->f, " rot=%.04f;", cx->rot); + if (cx->mirx != 0) fprintf(ctx->f, " mirx=1;"); + if (cx->miry != 0) fprintf(ctx->f, " miry=1;"); + if (cx->remove != 0) fprintf(ctx->f, " remove=1;"); + + fprintf(ctx->f, " }\n"); + + } + fprintf(ctx->f, "%s\t}\n", ind); + return 0; +} + +int lht_save_grp_objects(write_ctx_t *ctx, int indlev, const csch_cgrp_t *grp, vtp0_t *ord) +{ + long n; + IND(indlev); + + ord_objs(ctx, &grp->id2obj, ord); + fprintf(ctx->f, "%sli:objects {\n", ind); + for(n = 0; n < ord->used; n++) { + csch_chdr_t *obj = ord->array[n]; + + if (obj->type == CSCH_CTYPE_PEN) { + csch_cpen_t *pen = (csch_cpen_t *)obj; + if (pen->copied_from_default) + continue; /* happens when saving sheet-as-symbol - skip saving unchanged pens inherited from the default sheet */ + } + if (lht_print_obj(ctx, indlev+1, ind, obj) != 0) + return -1; + } + fprintf(ctx->f, "%s}\n", ind); + return 0; +} + +static int lht_save_group(write_ctx_t *ctx, int indlev, const csch_cgrp_t *grp, const char *name, long oid, int inhibit_uuid) +{ + static minuid_bin_t uuid0 = {0}; + minuid_str_t utmp; + int r = 0; + int optind = 0; + vtp0_t ord = {0}; + IND(indlev); + +#define OPTIND \ + if (optind == 0) { \ + fprintf(ctx->f, "%s ", ind); \ + optind = 1; \ + } \ + else \ + fprintf(ctx->f, " "); + + /* print placement */ + fprintf(ctx->f, "%sha:%s.%ld {\n", ind, name, oid); + if (!inhibit_uuid && (minuid_cmp(grp->uuid, uuid0) != 0)) { + OPTIND; + minuid_bin2str(utmp, grp->uuid); + fprintf(ctx->f, "uuid="); + lht_print_str(ctx->f, utmp); + fprintf(ctx->f, ";"); + } + if ((grp->hdr.type == CSCH_CTYPE_GRP) && (minuid_cmp(grp->data.grp.src_uuid, uuid0) != 0)) { + OPTIND; + minuid_bin2str(utmp, grp->data.grp.src_uuid); + fprintf(ctx->f, "src_uuid="); + lht_print_str(ctx->f, utmp); + fprintf(ctx->f, ";"); + } + if (grp->loclib_name != NULL) { + OPTIND; + fprintf(ctx->f, "loclib_name="); + lht_print_str(ctx->f, grp->loclib_name); + fprintf(ctx->f, ";"); + } + + if (optind != 0) { + fprintf(ctx->f, "\n"); + optind = 0; + } + + + if ((grp->x != 0) || (grp->y != 0)) { + OPTIND; + fprintf(ctx->f, "x=%ld; y=%ld;", grp->x, grp->y); + } + + if (grp->spec_rot != 0) { + OPTIND; + fprintf(ctx->f, "rot=%f;", grp->spec_rot); + } + if (grp->mirx) { + OPTIND; + fprintf(ctx->f, "mirx=1;"); + } + if (grp->miry) { + OPTIND; + fprintf(ctx->f, "miry=1;"); + } + if (optind != 0) + fprintf(ctx->f, "\n"); + + /* print ref */ + if (grp->hdr.type == CSCH_CTYPE_GRP_REF) { + char *path, *fp = NULL; + if (grp->data.ref.ref_str == NULL) + fp = path = csch_chdr_to_oidpath_str(&grp->data.ref.grp->hdr); + else + path = grp->data.ref.ref_str; + fprintf(ctx->f, "%s ref=%s\n", ind, path); + free(fp); + if (lht_save_grp_ref_child_xforms(ctx, ind, grp) != 0) + return -1; + } + + /* print objects */ + if (grp->hdr.type != CSCH_CTYPE_GRP_REF) + r |= lht_save_grp_objects(ctx, indlev+1, grp, &ord); + r |= lht_save_attribs(ctx, indlev+1, ind, &grp->attr); + + if (lht_print_common_properties(ctx, &grp->hdr, ind, NULL)) + fprintf(ctx->f, "\n"); + + fprintf(ctx->f, "%s}\n", ind); + vtp0_uninit(&ord); + return r; +} + +static int lht_save_conf(write_ctx_t *ctx) +{ + lht_err_t r; + const char **s, *del_paths[] = { "editor/mode", NULL }; + lht_node_t *n, *tmp, *root = rnd_conf_lht_get_first(RND_CFR_DESIGN, 0); + + if (root == NULL) + return 0; + + tmp = lht_dom_duptree(root->parent); + + for(n = tmp->data.list.first; n != NULL; n = n->next) { + for(s = del_paths; *s != NULL; s++) { + lht_node_t *sub = lht_tree_path_(n->doc, n, *s, 0, 0, NULL); + if (sub != NULL) { + lht_tree_del(sub); + } + } + } + + assert(tmp->type == LHT_LIST); + assert(strncmp(tmp->name, "sch-rnd-conf-v", 14) == 0); + + r = lht_dom_export(tmp, ctx->f, " "); + + lht_tree_del(tmp); + + return r; +} + +static int io_lihata_save_sheet_or_buff(const char *fn, const char *fmt, const csch_sheet_t *dst, const char *root_prefix, int with_conf) +{ + int r = 0; + write_ctx_t ctx; + + ctx.sheet = dst; + ctx.f = rnd_fopen((rnd_design_t *)&dst->hidlib, fn, "w"); + if (ctx.f == NULL) + return -1; + + fprintf(ctx.f, "ha:%s1 {\n", root_prefix); + r |= lht_save_group(&ctx, 1, &ctx.sheet->indirect, "obj_indirect", 1, 0); + r |= lht_save_group(&ctx, 1, &ctx.sheet->direct, "obj_direct", 2, 0); + if (with_conf) + r |= lht_save_conf(&ctx); + fprintf(ctx.f, "}\n"); + + fclose(ctx.f); + return r; +} + +int io_lihata_save_sheet(const char *fn, const char *fmt, const csch_sheet_t *dst) +{ + return io_lihata_save_sheet_or_buff(fn, fmt, dst, "cschem-sheet-v", 1); +} + +int io_lihata_save_buffer(const char *fn, const char *fmt, const csch_sheet_t *dst) +{ + return io_lihata_save_sheet_or_buff(fn, fmt, dst, "cschem-buffer-v", 0); +} + + +int io_lihata_save_grp(const char *fn, const char *fmt, const csch_cgrp_t *src, int inhibit_uuid) +{ + int r = 0; + write_ctx_t ctx; + + ctx.sheet = src->hdr.sheet; + ctx.f = rnd_fopen((rnd_design_t *)&ctx.sheet->hidlib, fn, "w"); + if (ctx.f == NULL) + return -1; + + fprintf(ctx.f, "ha:cschem-group-v1 {\n"); + r |= lht_save_group(&ctx, 1, src, "group", 1, inhibit_uuid); + fprintf(ctx.f, "}\n"); + + fclose(ctx.f); + return r; +} + Index: tags/1.0.5/src/plugins/io_lihata/write.h =================================================================== --- tags/1.0.5/src/plugins/io_lihata/write.h (nonexistent) +++ tags/1.0.5/src/plugins/io_lihata/write.h (revision 10414) @@ -0,0 +1,33 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - lihata file format support + * Copyright (C) 2020 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + + +#include + +int io_lihata_save_sheet(const char *fn, const char *fmt, const csch_sheet_t *dst); +int io_lihata_save_buffer(const char *fn, const char *fmt, const csch_sheet_t *dst); +int io_lihata_save_grp(const char *fn, const char *fmt, const csch_cgrp_t *src, int inhibit_uuid); + Index: tags/1.0.5/src/plugins/io_ngrp_fawk/Makefile =================================================================== --- tags/1.0.5/src/plugins/io_ngrp_fawk/Makefile (nonexistent) +++ tags/1.0.5/src/plugins/io_ngrp_fawk/Makefile (revision 10414) @@ -0,0 +1,2 @@ +all: + cd ../../sch-rnd && make mod_io_ngrp_fawk Index: tags/1.0.5/src/plugins/io_ngrp_fawk/Plug.tmpasm =================================================================== --- tags/1.0.5/src/plugins/io_ngrp_fawk/Plug.tmpasm (nonexistent) +++ tags/1.0.5/src/plugins/io_ngrp_fawk/Plug.tmpasm (revision 10414) @@ -0,0 +1,11 @@ +put /local/rnd/mod {io_ngrp_fawk} +put /local/rnd/mod/OBJS [@ + $(PLUGDIR)/io_ngrp_fawk/io_ngrp_fawk.o + $(PLUGDIR)/io_ngrp_fawk/read.o +@] + +switch /local/module/io_ngrp_fawk/controls + case {buildin} include /local/csch/tmpasm/buildin; end; + case {plugin} include /local/csch/tmpasm/plugin; end; + case {disable} include /local/csch/tmpasm/disable; end; +end Index: tags/1.0.5/src/plugins/io_ngrp_fawk/io_ngrp_fawk.c =================================================================== --- tags/1.0.5/src/plugins/io_ngrp_fawk/io_ngrp_fawk.c (nonexistent) +++ tags/1.0.5/src/plugins/io_ngrp_fawk/io_ngrp_fawk.c (revision 10414) @@ -0,0 +1,92 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - fawk non-graphical sheet support + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + + +#include +#include +#include +#include +#include +#include +#include "read.h" + +static csch_plug_io_t fawkv1; + +static int io_ngrp_fawk_load_prio(const char *fn, const char *fmt, csch_plug_io_type_t type) +{ + if (fmt != NULL) { + if (!strstr(fmt, "fawk")) + return 0; + } + if (type == CSCH_IOTYP_SHEET) + return 100; + return 0; +} + +static int io_ngrp_fawk_save_prio(const char *fn, const char *fmt, csch_plug_io_type_t type) +{ + if (fmt != NULL) { + if (!strstr(fmt, "fawk")) + return 0; + } + if (type == CSCH_IOTYP_SHEET) + return 100; + return 0; +} + + +int pplg_check_ver_io_ngrp_fawk(int ver_needed) { return 0; } + +void pplg_uninit_io_ngrp_fawk(void) +{ + csch_non_graphical_impl_pre_unload(&io_ngrp_fawk_impl); + csch_plug_io_unregister(&fawkv1); + fgw_eng_unreg(fgw_ngrp_fawk_eng.name); + pup_uninit(&io_ngrp_fawk_pup); +} + +int pplg_init_io_ngrp_fawk(void) +{ + RND_API_CHK_VER; + + fawkv1.name = "fawk non-graphical schematic sheet"; + fawkv1.load_prio = io_ngrp_fawk_load_prio; + fawkv1.save_prio = io_ngrp_fawk_save_prio; + fawkv1.load_sheet = io_ngrp_fawk_load_sheet; + fawkv1.test_parse = io_ngrp_fawk_test_parse; + + fawkv1.ext_save_sheet = "fawk"; + csch_plug_io_register(&fawkv1); + + pup_init(&io_ngrp_fawk_pup); + fgw_eng_reg(&fgw_ngrp_fawk_eng); + + + return 0; +} + Index: tags/1.0.5/src/plugins/io_ngrp_fawk/io_ngrp_fawk.pup =================================================================== --- tags/1.0.5/src/plugins/io_ngrp_fawk/io_ngrp_fawk.pup (nonexistent) +++ tags/1.0.5/src/plugins/io_ngrp_fawk/io_ngrp_fawk.pup (revision 10414) @@ -0,0 +1,11 @@ +$class io +$short fawk non-graphical sheets +$long non-graphical schematic sheets in form of fawk scripts. +$state works +$fmt-native yes +$fmt-feature-r cschem non-graphical schematic sheets in fawk format +$package (core) +default buildin +dep lib_ngrp +dep script +autoload 1 Index: tags/1.0.5/src/plugins/io_ngrp_fawk/read.c =================================================================== --- tags/1.0.5/src/plugins/io_ngrp_fawk/read.c (nonexistent) +++ tags/1.0.5/src/plugins/io_ngrp_fawk/read.c (revision 10414) @@ -0,0 +1,295 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - fawk non-graphical sheet support + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/* High level fawk parser and glue to core and comp.c */ + +#include +#include + +#include +#include +#include + +#include +#include + +#include + +#include "read.h" + +pup_context_t io_ngrp_fawk_pup; + + +typedef struct ngrp_fawk_s { + sch_ngrp_t ngrp; /* must be the first field */ + fgw_ctx_t fgw; + fgw_obj_t *obj; + pup_plugin_t *pup; +} ngrp_fawk_t; + +static void io_ngrp_fawk_free(csch_sheet_t *sheet) +{ + ngrp_fawk_t *ctx = sheet->non_graphical_data; + + if (ctx->obj != NULL) + fgw_obj_unreg(&ctx->fgw, ctx->obj); +#ifdef RND_HAVE_SYS_FUNGW + if (ctx->pup != NULL) + pup_unload(&io_ngrp_fawk_pup, ctx->pup, NULL); +#endif + fgw_uninit(&ctx->fgw); + + + sch_ngrp_free(&ctx->ngrp); /* also frees ctx */ +} + +static int io_ngrp_fawk_load_file(csch_sheet_t *sheet, const char *fn) +{ + ngrp_fawk_t *ctx = sheet->non_graphical_data; + return sch_ngrp_load_file(sheet, &ctx->ngrp, fn); +} + +static char *io_ngrp_fawk_draw_getline(csch_sheet_t *sheet, long *cnt, void **cookie) +{ + ngrp_fawk_t *ctx = sheet->non_graphical_data; + return sch_ngrp_draw_getline(&ctx->ngrp, cnt, cookie); +} + +static int io_ngrp_fawk_compile_sheet(csch_abstract_t *dst, int viewid, csch_hier_path_t *hpath, const csch_sheet_t *src) +{ + ngrp_fawk_t *ctx = src->non_graphical_data; + return sch_ngrp_compile_sheet(dst, viewid, hpath, src, &ctx->ngrp); +} + +static void io_ngrp_fawk_async_error(fgw_obj_t *obj, const char *msg) +{ + rnd_message(RND_MSG_ERROR, "%s", msg); +} + +#define CONV_ISTR_(arg) \ +do { \ + if (arg->type == FGW_DOUBLE) { \ + if (arg->val.nat_double == floor(arg->val.nat_double)) \ + FGW_ARG_CONV(arg, FGW_LONG); \ + } \ + else if (arg->type == FGW_FLOAT) { \ + if (arg->val.nat_float == floor(arg->val.nat_float)) \ + FGW_ARG_CONV(arg, FGW_LONG); \ + } \ + FGW_ARG_CONV(arg, FGW_STR); \ +} while(0) + +#define CONV_ISTR(arg) CONV_ISTR_((arg)) + +static fgw_error_t ngrp_fawk_acomp_attr(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + FGW_DECL_CTX; + ngrp_fawk_t *nctx = (ngrp_fawk_t *)argv[0].val.argv0.user_call_ctx; + sch_ngrp_obj_t *comp; + int n; + + CONV_ISTR(&argv[1]); + + comp = sch_ngrp_add_obj(&nctx->ngrp.comps, argv[1].val.str, 0); + for(n = 2; n+1 < argc; n += 2) { + CONV_ISTR(&argv[n]); + CONV_ISTR(&argv[n+1]); + sch_ngrp_add_attr(&comp->attr_head, argv[n].val.str, argv[n+1].val.str, -1, 0); + } + + return 0; +} + +static fgw_error_t ngrp_fawk_anet_attr(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + FGW_DECL_CTX; + ngrp_fawk_t *nctx = (ngrp_fawk_t *)argv[0].val.argv0.user_call_ctx; + sch_ngrp_obj_t *net; + int n; + + CONV_ISTR(&argv[1]); + + net = sch_ngrp_add_obj(&nctx->ngrp.nets, argv[1].val.str, 0); + for(n = 2; n+1 < argc; n += 2) { + CONV_ISTR(&argv[n]); + CONV_ISTR(&argv[n+1]); + sch_ngrp_add_attr(&net->attr_head, argv[n].val.str, argv[n+1].val.str, -1, 0); + } + + return 0; +} + +static fgw_error_t ngrp_fawk_aconn(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + FGW_DECL_CTX; + ngrp_fawk_t *nctx = (ngrp_fawk_t *)argv[0].val.argv0.user_call_ctx; + int n; + + CONV_ISTR(&argv[1]); + + sch_ngrp_add_obj(&nctx->ngrp.nets, argv[1].val.str, 0); + for(n = 2; n+1 < argc; n += 2) { + CONV_ISTR(&argv[n]); + CONV_ISTR(&argv[n+1]); + sch_ngrp_add_conn(&nctx->ngrp.conns, argv[1].val.str, argv[n].val.str, argv[n+1].val.str, 0); + } + + return 0; +} + +static int on_load(fgw_obj_t *obj, const char *filename, const char *opts) +{ + fgw_func_reg(obj, "acomp_attr", ngrp_fawk_acomp_attr); + fgw_func_reg(obj, "anet_attr", ngrp_fawk_anet_attr); + fgw_func_reg(obj, "aconn", ngrp_fawk_aconn); + return 0; +} + +static fgw_error_t c_call_script(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + fgw_error_t rv; + fgw_func_t *fnc = argv[0].val.func; + rv = fnc->func(res, argc, argv); + fgw_argv_free(fnc->obj->parent, argc, argv); + return rv; +} + +const fgw_eng_t fgw_ngrp_fawk_eng = { + "io_ngrp_fawk", + c_call_script, + NULL, + on_load +}; + + +int io_ngrp_fawk_parse(ngrp_fawk_t *ctx, const char *fn) +{ + csch_sheet_t *sheet = ctx->ngrp.sheet; + + rnd_trace("FAWK: parse fawk non-graphical sheet?\n"); + + fgw_init(&ctx->fgw, "sch-rnd non-graphical sheet: fawk"); + + ctx->fgw.async_error = io_ngrp_fawk_async_error; + +#ifdef RND_HAVE_SYS_FUNGW + { /* need to load the fawk engine */ + static const char *pupname = "fungw_fawk"; + const char *paths[2]; + int st; + + paths[0] = FGW_CFG_PUPDIR; + paths[1] = NULL; + ctx->pup = pup_load(&io_ngrp_fawk_pup, paths, pupname, 0, &st); + + if (ctx->pup == NULL) { + rnd_message(RND_MSG_ERROR, "non-graphical fawk sheet: can not load script engine %s\n", pupname); + io_ngrp_fawk_free(sheet); + return -1; + } + } +#endif + + fgw_obj_new(&ctx->fgw, "env", "io_ngrp_fawk", NULL, NULL); + + ctx->obj = fgw_obj_new2(&ctx->fgw, "script", "fawk", fn, NULL, ctx); + if (ctx->obj == NULL) { + rnd_message(RND_MSG_ERROR, "Failed to parse/execute script from file %s\n", fn); + io_ngrp_fawk_free(sheet); + return -1; + } + + + rnd_trace("FAWK: parsed fawk non-graphical sheet\n"); + + return 0; +} + + +csch_non_graphical_impl_t io_ngrp_fawk_impl; + +int io_ngrp_fawk_load_sheet(FILE *f, const char *fn, const char *fmt, csch_sheet_t *dst) +{ + ngrp_fawk_t *ctx = calloc(sizeof(ngrp_fawk_t), 1); + + if (ctx == NULL) + return -1; + + ctx->ngrp.sheet = dst; + dst->non_graphical = 1; + dst->non_graphical_data = ctx; + dst->non_graphical_impl = &io_ngrp_fawk_impl; + + io_ngrp_fawk_impl.compile_sheet = io_ngrp_fawk_compile_sheet; + io_ngrp_fawk_impl.free_sheet = io_ngrp_fawk_free; + io_ngrp_fawk_impl.draw_getline = io_ngrp_fawk_draw_getline; + + if (io_ngrp_fawk_load_file(dst, fn) != 0) { + rnd_message(RND_MSG_ERROR, "Failed to load content of file '%s'\n", fn); + goto error; + } + + return io_ngrp_fawk_parse(ctx, fn); + + error:; + io_ngrp_fawk_free(dst); + return -1; +} + +int io_ngrp_fawk_test_parse(FILE *f, const char *fn, const char *fmt, csch_plug_io_type_t type) +{ + char line[256], *s; + fgets(line, sizeof(line), f); + + if ((line[0] != '#') || (line[1] != '#')) + return -1; + + for(s = line+2; isspace(*s); s++) ; + + if (strncmp(s, "cschem", 6) != 0) + return -1; + + for(s += 6; isspace(*s); s++) ; + + if (strncmp(s, "fawk", 4) != 0) + return -1; + + for(s += 4; isspace(*s); s++) ; + + if (strncmp(s, "sheet", 5) != 0) + return -1; + + s += 5; + + if ((*s == '\0') || isspace(*s)) + return 0; + + return -1; +} + + Index: tags/1.0.5/src/plugins/io_ngrp_fawk/read.h =================================================================== --- tags/1.0.5/src/plugins/io_ngrp_fawk/read.h (nonexistent) +++ tags/1.0.5/src/plugins/io_ngrp_fawk/read.h (revision 10414) @@ -0,0 +1,14 @@ +/* High level fawk parser and glue to core and comp.c */ + +#include +#include +#include + +extern pup_context_t io_ngrp_fawk_pup; + + +int io_ngrp_fawk_load_sheet(FILE *f, const char *fn, const char *fmt, csch_sheet_t *dst); +int io_ngrp_fawk_test_parse(FILE *f, const char *fn, const char *fmt, csch_plug_io_type_t type); + +extern csch_non_graphical_impl_t io_ngrp_fawk_impl; +extern const fgw_eng_t fgw_ngrp_fawk_eng; Index: tags/1.0.5/src/plugins/io_ngrp_tedax/Makefile =================================================================== --- tags/1.0.5/src/plugins/io_ngrp_tedax/Makefile (nonexistent) +++ tags/1.0.5/src/plugins/io_ngrp_tedax/Makefile (revision 10414) @@ -0,0 +1,2 @@ +all: + cd ../../sch-rnd && make mod_io_ngrp_tedax Index: tags/1.0.5/src/plugins/io_ngrp_tedax/Plug.tmpasm =================================================================== --- tags/1.0.5/src/plugins/io_ngrp_tedax/Plug.tmpasm (nonexistent) +++ tags/1.0.5/src/plugins/io_ngrp_tedax/Plug.tmpasm (revision 10414) @@ -0,0 +1,11 @@ +put /local/rnd/mod {io_ngrp_tedax} +put /local/rnd/mod/OBJS [@ + $(PLUGDIR)/io_ngrp_tedax/io_ngrp_tedax.o + $(PLUGDIR)/io_ngrp_tedax/read.o +@] + +switch /local/module/io_ngrp_tedax/controls + case {buildin} include /local/csch/tmpasm/buildin; end; + case {plugin} include /local/csch/tmpasm/plugin; end; + case {disable} include /local/csch/tmpasm/disable; end; +end Index: tags/1.0.5/src/plugins/io_ngrp_tedax/io_ngrp_tedax.c =================================================================== --- tags/1.0.5/src/plugins/io_ngrp_tedax/io_ngrp_tedax.c (nonexistent) +++ tags/1.0.5/src/plugins/io_ngrp_tedax/io_ngrp_tedax.c (revision 10414) @@ -0,0 +1,85 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - tEDAx non-graphical sheet support + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + + +#include +#include +#include +#include +#include +#include +#include "read.h" + +static csch_plug_io_t tdxv1; + +static int io_ngrp_tedax_load_prio(const char *fn, const char *fmt, csch_plug_io_type_t type) +{ + if (fmt != NULL) { + if (!strstr(fmt, "tedax") && !strstr(fmt, "tEDAx") && !strstr(fmt, "tdx")) + return 0; + } + if (type == CSCH_IOTYP_SHEET) + return 100; + return 0; +} + +static int io_ngrp_tedax_save_prio(const char *fn, const char *fmt, csch_plug_io_type_t type) +{ + if (fmt != NULL) { + if (!strstr(fmt, "tedax") && !strstr(fmt, "tEDAx") && !strstr(fmt, "tdx")) + return 0; + } + if (type == CSCH_IOTYP_SHEET) + return 100; + return 0; +} + + +int pplg_check_ver_io_ngrp_tedax(int ver_needed) { return 0; } + +void pplg_uninit_io_ngrp_tedax(void) +{ + csch_non_graphical_impl_pre_unload(&io_ngrp_tedax_impl); + csch_plug_io_unregister(&tdxv1); +} + +int pplg_init_io_ngrp_tedax(void) +{ + RND_API_CHK_VER; + + tdxv1.name = "tEDAx non-graphical schematic sheet v1"; + tdxv1.load_prio = io_ngrp_tedax_load_prio; + tdxv1.save_prio = io_ngrp_tedax_save_prio; + tdxv1.load_sheet = io_ngrp_tedax_load_sheet; + tdxv1.test_parse = io_ngrp_tedax_test_parse; + + tdxv1.ext_save_sheet = "tdx"; + csch_plug_io_register(&tdxv1); + return 0; +} + Index: tags/1.0.5/src/plugins/io_ngrp_tedax/io_ngrp_tedax.pup =================================================================== --- tags/1.0.5/src/plugins/io_ngrp_tedax/io_ngrp_tedax.pup (nonexistent) +++ tags/1.0.5/src/plugins/io_ngrp_tedax/io_ngrp_tedax.pup (revision 10414) @@ -0,0 +1,11 @@ +$class io +$short tEDAx non-graphical sheets +$long Load non-graphical schematic sheets in tEDAx format. +$state works +$fmt-native yes +$fmt-feature-r cschem non-graphical schematic sheets in tEDAx format +$package (core) +dep lib_ngrp +dep lib_tedax +default buildin +autoload 1 Index: tags/1.0.5/src/plugins/io_ngrp_tedax/read.c =================================================================== --- tags/1.0.5/src/plugins/io_ngrp_tedax/read.c (nonexistent) +++ tags/1.0.5/src/plugins/io_ngrp_tedax/read.c (revision 10414) @@ -0,0 +1,335 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - tEDAx non-graphical sheet support + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/* High level tEDAx parser and glue to core and comp.c */ + +#include +#include + +#include + +#include +#include +#include + +#include +#include + +#include "read.h" + +static void ngrp_tedax_free(csch_sheet_t *sheet) +{ + sch_ngrp_free(sheet->non_graphical_data); +} + +static int ngrp_tedax_load_file(csch_sheet_t *sheet, const char *fn) +{ + return sch_ngrp_load_file(sheet, sheet->non_graphical_data, fn); +} + +static char *ngrp_tedax_draw_getline(csch_sheet_t *sheet, long *cnt, void **cookie) +{ + return sch_ngrp_draw_getline(sheet->non_graphical_data, cnt, cookie); +} + +static int ngrp_tedax_compile_sheet(csch_abstract_t *dst, int viewid, csch_hier_path_t *hpath, const csch_sheet_t *src) +{ + return sch_ngrp_compile_sheet(dst, viewid, hpath, src, src->non_graphical_data); +} + +static int io_ngrp_tedax_parse_acompact_attrs(sch_ngrp_t *ctx, sch_ngrp_comp_t *dst, int argc, char *argv[], long lineno) +{ + int n; + for(n = 0; n < argc; n++) { + char *key = argv[n], *val; + val = strchr(key, '='); + if (val != NULL) { + *val = '\0'; + val++; + } + else + val = ""; + sch_ngrp_add_attr(&dst->attr_head, key, val, -1, lineno); + } + return 0; +} + +/* Parse a line of an acompact block */ +static int io_ngrp_tedax_parse_acompact(csch_sheet_t *sheet, int argc, char *argv[], long lineno) +{ + sch_ngrp_t *ctx = sheet->non_graphical_data; + + if (strcmp(argv[0], "comp") == 0) { + sch_ngrp_obj_t *c = sch_ngrp_add_obj(&ctx->comps, argv[1], lineno); + return io_ngrp_tedax_parse_acompact_attrs(ctx, c, argc-2, argv+2, lineno); + } + + if (strcmp(argv[0], "net") == 0) { + sch_ngrp_obj_t *n = sch_ngrp_add_obj(&ctx->nets, argv[1], lineno); + return io_ngrp_tedax_parse_acompact_attrs(ctx, n, argc-2, argv+2, lineno); + } + + else if (strcmp(argv[0], "conn") == 0) { + const char *netname = argv[1]; + int n; + for(n = 2; n < argc; n++) { + char *comp= argv[n], *port; + port = strchr(comp, '='); + if (port == NULL) { + rnd_message(RND_MSG_ERROR, "tEDAx syntax error in '%s':%ld: invalid acompact conn '%s': missing port name\n", sheet->hidlib.fullpath, lineno, argv[n]); + return -1; + } + *port = '\0'; + port++; + sch_ngrp_add_conn(&ctx->conns, netname, comp, port, lineno); + } + return 0; + } + + rnd_message(RND_MSG_ERROR, "tEDAx syntax error in '%s':%ld: invalid acompact instruction %s\n", sheet->hidlib.fullpath, lineno, argv[0]); + return -1; +} + +static int parse_long_attr(sch_ngrp_obj_t *parent, int argc, char *argv[], const char *rest, int rest_len, long lineno) +{ + sch_ngrp_add_attr(&parent->attr_head, argv[0], rest, rest_len, lineno); + return 0; +} + +/* Parse a line of an acomp block */ +static int io_ngrp_tedax_parse_acomp(csch_sheet_t *sheet, sch_ngrp_comp_t *parent, int argc, char *argv[], long lineno, const char *rest, int rest_len) +{ + sch_ngrp_t *ctx = sheet->non_graphical_data; + + if ((argv[0][0] == '-') && (argv[0][1] == '\0')) { + if (argc != 3) { + rnd_message(RND_MSG_ERROR, "tEDAx syntax error in '%s':%ld: invalid acompact conn '%s': need 3 fields for an acomp connection\n", sheet->hidlib.fullpath, lineno); + return -1; + } + sch_ngrp_add_conn(&ctx->conns, argv[2], parent->name, argv[1], lineno); + return 0; + } + + if (argc < 2) { + rnd_message(RND_MSG_ERROR, "tEDAx syntax error in '%s':%ld: invalid acompact conn '%s': need 2+ fields for attributes\n", sheet->hidlib.fullpath, lineno); + return -1; + } + + return parse_long_attr(parent, argc, argv, rest, rest_len, lineno); +} + +/* Parse a line of an anet block */ +static int io_ngrp_tedax_parse_anet(csch_sheet_t *sheet, sch_ngrp_net_t *parent, int argc, char *argv[], long lineno, const char *rest, int rest_len) +{ + sch_ngrp_t *ctx = sheet->non_graphical_data; + + if ((argv[0][0] == '-') && (argv[0][1] == '\0')) { + if (argc != 3) { + rnd_message(RND_MSG_ERROR, "tEDAx syntax error in '%s':%ld: invalid acompact conn '%s': need 3 fields for an anet connection\n", sheet->hidlib.fullpath, lineno); + return -1; + } + sch_ngrp_add_conn(&ctx->conns, parent->name, argv[1], argv[2], lineno); + return 0; + } + + if (argc < 2) { + rnd_message(RND_MSG_ERROR, "tEDAx syntax error in '%s':%ld: invalid acompact conn '%s': need 2+ fields for attributes\n", sheet->hidlib.fullpath, lineno); + return -1; + } + + return parse_long_attr(parent, argc, argv, rest, rest_len, lineno); +} + +int io_ngrp_tedax_parse(csch_sheet_t *sheet) +{ + sch_ngrp_t *ctx = sheet->non_graphical_data; + char *argv[128], buf[515], **s, *orig; + int gothdr = 0; + long lineno; + enum { NONE, ACOMPACT, ACOMP, ANET } blocktype = NONE; + sch_ngrp_obj_t *parent; + + sch_ngrp_clean_cache(ctx); + + orig = ctx->text.array; + for(s = &orig, lineno = 1; **s != '\0'; lineno++) { + const char *rest; /* rest of the arguments after argv[0] */ + int argc, rest_offs, rest_len; + + rest = *s; + argc = tedax_getline_mem(s, buf, sizeof(buf), argv, sizeof(argv)/sizeof(argv[0])); + if (argc < 0) { + rnd_message(RND_MSG_ERROR, "tEDAx syntax error in '%s':%ld\n", sheet->hidlib.fullpath, lineno); + return -1; + } + + if (argc > 1) { + rest_offs = argv[1] - buf; + rest += rest_offs; + rest_len = *s - rest; + if (rest[rest_len-1] == '\n') + rest_len--; + } + else { + rest_offs = -1; + rest_len = 0; + rest = NULL; + } + + + if (argv[0] == NULL) + continue; /* skip empty lines */ + + if (strcmp(argv[0], "tEDAx") == 0) { + if (gothdr) { + rnd_message(RND_MSG_ERROR, "tEDAx syntax error in '%s':%ld: multiple tEDAx headers\n", sheet->hidlib.fullpath, lineno); + return -1; + } + gothdr = 1; + } + else if (strcmp(argv[0], "begin") == 0) { + if (!gothdr) { + rnd_message(RND_MSG_ERROR, "tEDAx syntax error in '%s':%ld: 'begin' before tEDAx header\n", sheet->hidlib.fullpath, lineno); + return -1; + } + if (blocktype != NONE) { + rnd_message(RND_MSG_ERROR, "tEDAx syntax error in '%s':%ld: nested blocks\n", sheet->hidlib.fullpath, lineno); + return -1; + } + if (strcmp(argv[1], "cschem_acompact") == 0) { + blocktype = ACOMPACT; + } + else if (strcmp(argv[1], "cschem_acomp") == 0) { + blocktype = ACOMP; + parent = sch_ngrp_add_obj(&ctx->comps, argv[2], lineno); + } + else if (strcmp(argv[1], "cschem_anet") == 0) { + blocktype = ANET; + parent = sch_ngrp_add_obj(&ctx->nets, argv[2], lineno); + } + else { + rnd_message(RND_MSG_ERROR, "tEDAx syntax error in '%s':%ld: unknown block type %s\n", sheet->hidlib.fullpath, lineno, argv[1]); + return -1; + } + } + else if (strcmp(argv[0], "end") == 0) { + if (blocktype == NONE) { + rnd_message(RND_MSG_ERROR, "tEDAx syntax error in '%s':%ld: END with no block open\n", sheet->hidlib.fullpath, lineno); + return -1; + } + blocktype = NONE; + parent = NULL; + } + else { + int res; + + switch(blocktype) { + case ACOMPACT: res = io_ngrp_tedax_parse_acompact(sheet, argc, argv, lineno); break; + case ACOMP: res = io_ngrp_tedax_parse_acomp(sheet, parent, argc, argv, lineno, rest, rest_len); break; + case ANET: res = io_ngrp_tedax_parse_anet(sheet, parent, argc, argv, lineno, rest, rest_len); break; + default: + rnd_message(RND_MSG_ERROR, "tEDAx syntax error in '%s':%ld: instruction outside of blocks\n", sheet->hidlib.fullpath, lineno); + return -1; + } + if (res != 0) + return -1; + } + } + + return 0; +} + + +csch_non_graphical_impl_t io_ngrp_tedax_impl; + +int io_ngrp_tedax_load_sheet(FILE *f, const char *fn, const char *fmt, csch_sheet_t *dst) +{ + sch_ngrp_t *ctx = calloc(sizeof(sch_ngrp_t), 1); + + if (ctx == NULL) + return -1; + + ctx->sheet = dst; + dst->non_graphical = 1; + dst->non_graphical_data = ctx; + dst->non_graphical_impl = &io_ngrp_tedax_impl; + + io_ngrp_tedax_impl.compile_sheet = ngrp_tedax_compile_sheet; + io_ngrp_tedax_impl.free_sheet = ngrp_tedax_free; + io_ngrp_tedax_impl.draw_getline = ngrp_tedax_draw_getline; + + if (ngrp_tedax_load_file(dst, fn) != 0) { + rnd_message(RND_MSG_ERROR, "Failed to load content of file '%s'\n", fn); + goto error; + } + + io_ngrp_tedax_parse(dst); + + return 0; + + error:; + ngrp_tedax_free(dst); + return -1; +} + +int io_ngrp_tedax_test_parse(FILE *f, const char *fn, const char *fmt, csch_plug_io_type_t type) +{ + char line[515], *s; + int n, fmthdr = 0; + + for(n = 0; n < 2048; n++) { + s = fgets(line, sizeof(line), f); + if (s == NULL) + return -1; + while(isspace(*s)) s++; + if (*s == '#') + continue; + if (strncmp(s, "tEDAx", 5) == 0) { + s += 5; + while(isspace(*s)) s++; + if ((s[0] == 'v') && (s[1] == '1')) + fmthdr = 1; + } + + if (!fmthdr && (n > 32)) + return -1; /* expect file header in the first few lines */ + + if (fmthdr && (strncmp(s, "begin", 5) == 0)) { + /* if we got the file header, look for a known block */ + s += 5; + while(isspace(*s)) s++; + if (strncmp(s, "cschem_acompact", 15) == 0) return 0; + if (strncmp(s, "cschem_acomp", 12) == 0) return 0; + if (strncmp(s, "cschem_anet", 11) == 0) return 0; + } + } + + return -1; +} + + Index: tags/1.0.5/src/plugins/io_ngrp_tedax/read.h =================================================================== --- tags/1.0.5/src/plugins/io_ngrp_tedax/read.h (nonexistent) +++ tags/1.0.5/src/plugins/io_ngrp_tedax/read.h (revision 10414) @@ -0,0 +1,8 @@ +/* High level tEDAx parser and glue to core and comp.c */ + +#include + +int io_ngrp_tedax_load_sheet(FILE *f, const char *fn, const char *fmt, csch_sheet_t *dst); +int io_ngrp_tedax_test_parse(FILE *f, const char *fn, const char *fmt, csch_plug_io_type_t type); + +extern csch_non_graphical_impl_t io_ngrp_tedax_impl; Index: tags/1.0.5/src/plugins/io_orcad/Makefile =================================================================== --- tags/1.0.5/src/plugins/io_orcad/Makefile (nonexistent) +++ tags/1.0.5/src/plugins/io_orcad/Makefile (revision 10414) @@ -0,0 +1,2 @@ +all: + cd ../../sch-rnd && make mod_io_orcad Index: tags/1.0.5/src/plugins/io_orcad/Plug.tmpasm =================================================================== --- tags/1.0.5/src/plugins/io_orcad/Plug.tmpasm (nonexistent) +++ tags/1.0.5/src/plugins/io_orcad/Plug.tmpasm (revision 10414) @@ -0,0 +1,24 @@ +put /local/rnd/mod {io_orcad} +put /local/rnd/mod/OBJS [@ + $(PLUGDIR)/io_orcad/io_orcad.o + $(PLUGDIR)/io_orcad/read.o + $(PLUGDIR)/io_orcad/read_cache.o + $(PLUGDIR)/io_orcad/read_common.o + $(PLUGDIR)/io_orcad/read_prim.o + $(PLUGDIR)/io_orcad/read_page.o + $(PLUGDIR)/io_orcad/read_prim.o + $(PLUGDIR)/io_orcad/read_fio.o + $(PLUGDIR)/io_orcad/read_dump.o + $(PLUGDIR)/io_orcad/read_free.o + $(PLUGDIR)/io_orcad/read_library.o +@] + +put /local/rnd/mod/CONFFILE {io_orcad.conf} +put /local/rnd/mod/CONF {$(PLUGDIR)/io_orcad/io_orcad_conf.h} +put /local/rnd/mod/CONFVAR {io_orcad_conf_internal} + +switch /local/module/io_orcad/controls + case {buildin} include /local/csch/tmpasm/buildin; end; + case {plugin} include /local/csch/tmpasm/plugin; end; + case {disable} include /local/csch/tmpasm/disable; end; +end Index: tags/1.0.5/src/plugins/io_orcad/io_orcad.c =================================================================== --- tags/1.0.5/src/plugins/io_orcad/io_orcad.c (nonexistent) +++ tags/1.0.5/src/plugins/io_orcad/io_orcad.c (revision 10414) @@ -0,0 +1,85 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - OrCAD format support + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust Fund in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + + +#include +#include +#include +#include +#include +#include "read.h" + +#include "io_orcad_conf.h" +#include "conf_internal.c" + +conf_io_orcad_t io_orcad_conf; +static char orcad_cookie[] = "io_orcad"; + +static csch_plug_io_t orcad; + +static int io_orcad_common_load_prio(const char *fn, const char *fmt, csch_plug_io_type_t type) +{ + if (fmt != NULL) { + if (!strstr(fmt, "orcad") && !strstr(fmt, "dsn")) + return 0; + } + if (type == CSCH_IOTYP_SHEET) + return 90; + return 0; +} + +int pplg_check_ver_io_orcad(int ver_needed) { return 0; } + +void pplg_uninit_io_orcad(void) +{ + csch_plug_io_unregister(&orcad); + rnd_conf_plug_unreg("plugins/io_orcad/", io_orcad_conf_internal, orcad_cookie); +} + +int pplg_init_io_orcad(void) +{ + RND_API_CHK_VER; + + orcad.name = "orcad schematics sheets from dsn (cdf)"; + orcad.load_prio = io_orcad_common_load_prio; + orcad.test_parse_bundled = io_orcad_test_parse_bundled; + orcad.load_sheet_bundled = io_orcad_load_sheet_bundled; + orcad.end_bundled = io_orcad_end_bundled; + + + orcad.ext_save_sheet = "dsn"; + csch_plug_io_register(&orcad); + + rnd_conf_plug_reg(io_orcad_conf, io_orcad_conf_internal, orcad_cookie); +#define conf_reg(field,isarray,type_name,cpath,cname,desc,flags) \ + rnd_conf_reg_field(io_orcad_conf, field,isarray,type_name,cpath,cname,desc,flags); +#include "io_orcad_conf_fields.h" + + return 0; +} + Index: tags/1.0.5/src/plugins/io_orcad/io_orcad.conf =================================================================== --- tags/1.0.5/src/plugins/io_orcad/io_orcad.conf (nonexistent) +++ tags/1.0.5/src/plugins/io_orcad/io_orcad.conf (revision 10414) @@ -0,0 +1,16 @@ +li:pcb-rnd-conf-v1 { + ha:overwrite { + ha:plugins { + ha:io_orcad { + coord_mult = 400 + auto_normalize = 1 + emulate_text_ang_180 = 1 + li:postproc_sheet_load { + } + ha:debug { + trace_test_parse = 0 + } + } + } + } +} Index: tags/1.0.5/src/plugins/io_orcad/io_orcad.pup =================================================================== --- tags/1.0.5/src/plugins/io_orcad/io_orcad.pup (nonexistent) +++ tags/1.0.5/src/plugins/io_orcad/io_orcad.pup (revision 10414) @@ -0,0 +1,10 @@ +$class io +$short OrCAD schematics +$long Load schematics from OrCad dsn +$state works +$fmt-feature-r orcad schematics +$package io-alien +dep lib_alien +dep lib_ucdf +default buildin +autoload 1 Index: tags/1.0.5/src/plugins/io_orcad/io_orcad_conf.h =================================================================== --- tags/1.0.5/src/plugins/io_orcad/io_orcad_conf.h (nonexistent) +++ tags/1.0.5/src/plugins/io_orcad/io_orcad_conf.h (revision 10414) @@ -0,0 +1,22 @@ +#ifndef SCH_RND_IO_ORCAD_CONF_H +#define SCH_RND_IO_ORCAD_CONF_H + +#include + +typedef struct { + const struct { + const struct { + RND_CFT_REAL coord_mult; /* all orcad coordinates are multiplied by this value to get sch-rnd coords */ + RND_CFT_BOOLEAN emulate_text_ang_180; /* TODO: ? orcad displays text objects with angle==180 with an extra 180 degree rotation; it's a display hack sch-rnd doesn't have; when this emulation is enabled, the loader adds a +180 degree rotation in such text (changing data!) to match the behavior */ + RND_CFT_BOOLEAN auto_normalize; /* move all objects so that starting coords are near 0;0 */ + RND_CFT_LIST postproc_sheet_load; /* pattern;action pairs for object transformations after a succesful load; mostly used for attribute editing */ + const struct { + RND_CFT_BOOLEAN trace_test_parse; + } debug; + } io_orcad; + } plugins; +} conf_io_orcad_t; + +extern conf_io_orcad_t io_orcad_conf; + +#endif Index: tags/1.0.5/src/plugins/io_orcad/read.c =================================================================== --- tags/1.0.5/src/plugins/io_orcad/read.c (nonexistent) +++ tags/1.0.5/src/plugins/io_orcad/read.c (revision 10414) @@ -0,0 +1,1480 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - OrCAD file format support + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust Fund in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "read.h" +#include "read_parse.h" +#include "read_fio.h" +#include "io_orcad_conf.h" + +/* optional trace */ +#if 1 +# include +# define tprintf printf +#else + static int tprintf(const char *fmt, ...) { return 0; } +#endif + +#define TEXT_HEIGHT 3000 +#define TEXT_HEIGHT_ORCAD (TEXT_HEIGHT / rctx->alien.coord_factor) + +typedef struct cache_sym_s { + const char *name; /* points into ->root; also key for the hash */ + orcad_xcachesymvariant_node_t *root; + orcad_symbolpinmapping_node_t *pinmap; + csch_cgrp_t *grp; + long width, height; /* actual bbox of the sym, based on info from the file (in alien size) */ + unsigned simple:1; /* see explanation at cache_sym_how_t */ + unsigned slotted:1; /* has the portmap attribute (converted from pinmap) */ + unsigned linked:1; /* used in cross-linking (propagation) during load*/ +} cache_sym_t; + +/*** generic utility ***/ + +/* Convert net_id to wirenet group; if net_id doesn't exist in curent page: + return NULL (alloc==0) or allocate a new wirenet */ +static csch_cgrp_t *orcad_wirenet_lookup(io_orcad_rctx_t *rctx, long net_id, int alloc) +{ + csch_cgrp_t *wn = htip_get(&rctx->wirenets, net_id); + + if (wn == NULL) { + csch_source_arg_t *src; + csch_sheet_t *sheet = rctx->alien.sheet; + + if (!alloc) + return NULL; + + + wn = csch_cgrp_alloc(sheet, &sheet->direct, csch_oid_new(sheet, &sheet->direct)); + src = csch_attrib_src_c(rctx->fn, 0, 0, NULL); + csch_cobj_attrib_set(sheet, wn, CSCH_ATP_HARDWIRED, "role", "wire-net", src); + htip_set(&rctx->wirenets, net_id, wn); + } + + return wn; +} + +/* Set wn's name attribute; if already set, remember new names as alternative + names */ +static void orcad_cgrp_set_name(csch_cgrp_t *dst, const char *name, const char *src_fn, long src_lineno) +{ + csch_source_arg_t *src; + + src = csch_attrib_src_c(src_fn, src_lineno, 0, NULL); + + if (csch_attrib_get_str(&dst->attr, "name") == NULL) + csch_attrib_set(&dst->attr, CSCH_ATP_USER_DEFAULT, "name", name, src, NULL); + else + csch_attrib_append(&dst->attr, CSCH_ATP_USER_DEFAULT, "alt_names", name, src); +} + +/* Change drawing area extents to width/height (origin is always at 0;0) */ +static void orcad_sheet_set_extents(io_orcad_rctx_t *rctx, long width, long height, rnd_bool grid_ref, long src_lineno, int is_metric) +{ + csch_sheet_t *sheet = rctx->alien.sheet; + + if (is_metric) { + width = width/254; + height = height/254; + } + else { + width = width/10; + height = height/10; + } + + if (grid_ref) { + width -= 20; + height -= 20; + } + +#if 0 + csch_source_arg_t *src; + char tmp[128]; + + /* alternative to drawing the box; this one wouldn't claim 0;0 tho */ + sprintf(tmp, "%ld", csch_alien_coord_x(&rctx->alien, height)); + src = csch_attrib_src_c(rctx->fn, src_lineno, 0, NULL); + csch_attrib_set(&sheet->direct.attr, CSCH_ATP_USER_DEFAULT, "drawing_min_height", tmp, src, NULL); + + sprintf(tmp, "%ld", csch_alien_coord_x(&rctx->alien, width)); + src = csch_attrib_src_c(rctx->fn, src_lineno, 0, NULL); + csch_attrib_set(&sheet->direct.attr, CSCH_ATP_USER_DEFAULT, "drawing_min_width", tmp, src, NULL); +#endif + + rctx->alien.oy = height; + + csch_alien_mkline(&rctx->alien, &sheet->direct, 0, 0, width, 0, "sheet-decor"); + csch_alien_mkline(&rctx->alien, &sheet->direct, 0, 0, 0, height, "sheet-decor"); + csch_alien_mkline(&rctx->alien, &sheet->direct, width, height, width, 0, "sheet-decor"); + csch_alien_mkline(&rctx->alien, &sheet->direct, width, height, 0, height, "sheet-decor"); +} + +/* textstr needs to be strdup()'d by the caller */ +static csch_text_t *place_text(io_orcad_rctx_t *rctx, csch_cgrp_t *dst, double x, double y, const char *stroke, char *txtstr) +{ + csch_text_t *t; + + t = (csch_text_t *)csch_alien_mktext(&rctx->alien, dst, x, y, stroke); + if (t == NULL) + return NULL; + + t->text = txtstr; + t->spec_miry = 1; + return t; +} + +static csch_text_t *add_attr_with_text(io_orcad_rctx_t *rctx, csch_cgrp_t *dst, double x, double y, const char *stroke, const char *key, const char *val, int vis_key, int vis_val, int capital, long src_lineno) +{ + csch_source_arg_t *src; + csch_text_t *t; + + src = csch_attrib_src_c(rctx->fn, src_lineno, 0, NULL); + csch_cobj_attrib_set(rctx->alien.sheet, dst, CSCH_ATP_USER_DEFAULT, key, val, src); + + if (vis_key || vis_val) { + char *templ; + const char *capa = capital ? "A" : "a"; + double save; + + if (vis_key && vis_val) templ = rnd_concat(key, " = %../", capa, ".", key, "%", NULL); + if (vis_key && !vis_val) templ = rnd_strdup(key); + if (!vis_key && vis_val) templ = rnd_concat("%../", capa, ".", key, "%", NULL); + + /* do not mirror using sheet height whenplacing in a sub-group */ + if (dst != &rctx->alien.sheet->direct) { + save = rctx->alien.oy; + rctx->alien.oy = 0; + } + + t = place_text(rctx, dst, x, y, stroke, templ); + if (vis_val) + t->dyntext = 1; + + /* restore mirroring */ + if (dst != &rctx->alien.sheet->direct) + rctx->alien.oy = save; + } + + return t; +} + + +/*** sym cache and primitives ***/ +static csch_chdr_t *render_primitive_in(io_orcad_rctx_t *rctx, csch_cgrp_t *dst, orcad_prim_t *prim, const char *stroke, const char *fill) +{ + switch(prim->type) { + case ORCAD_PRIMITIVE_RECT: + { + orcad_rect_prim_t *rect = (orcad_rect_prim_t *)prim; + return csch_alien_mkrect(&rctx->alien, dst, rect->x1, rect->y1, rect->x2, rect->y2, stroke, rect->have_fill_style ? fill : NULL); + } + + case ORCAD_PRIMITIVE_LINE: + { + orcad_line_prim_t *line = (orcad_line_prim_t *)prim; + return csch_alien_mkline(&rctx->alien, dst, line->x1, line->y1, line->x2, line->y2, stroke); + } + + case ORCAD_PRIMITIVE_ARC: + { + orcad_arc_prim_t *arc = (orcad_arc_prim_t *)prim; /* the bbox stored in arc is really the bbox of the whole circle */ + double cx = (double)(arc->x1 + arc->x2) / 2.0, cy = (double)(arc->y1 + arc->y2) / 2.0; + double rx = (double)(arc->x2 - arc->x1) / 2.0, ry = (double)(arc->y2 - arc->y1) / 2.0; + double rd = fabs(rx - ry); + double sa, ea, da; + + sa = atan2(cy - arc->start_y, arc->start_x - cx); + ea = atan2(cy - arc->end_y, arc->end_x - cx); + + /* normalize angles and calculate delta */ + if (sa < 0) sa += 2*G2D_PI; + if (ea < 0) ea += 2*G2D_PI; + da = ea - sa; + if (da < 0) da += 2*G2D_PI; + + if (rd < 0.1) + return csch_alien_mkarc(&rctx->alien, dst, cx, cy, (rx+ry)/2.0, sa * RND_RAD_TO_DEG, da * RND_RAD_TO_DEG, stroke); + else + return csch_alien_mkearc(&rctx->alien, dst, cx, cy, rx, ry, sa, -da, stroke, NULL); + + TODO("low prio: Elliptical arc endpoints are off"); + } + + case ORCAD_PRIMITIVE_ELLIPSE: + { + orcad_ellipse_prim_t *e = (orcad_ellipse_prim_t *)prim; + return csch_alien_mkearc(&rctx->alien, dst, (e->x1+e->x2)/2, (e->y1+e->y2)/2, (e->x2-e->x1)/2, (e->y2-e->y1)/2, 0, 2*G2D_PI, stroke, NULL); + } + break; + + case ORCAD_PRIMITIVE_POLYGON: + { + orcad_polygon_prim_t *poly = (orcad_polygon_prim_t *)prim; + long n; + csch_chdr_t *p = csch_alien_mkpoly(&rctx->alien, dst, stroke, poly->have_fill_style ? fill : NULL); + for(n = 0; n < poly->num_points-1; n++) + csch_alien_append_poly_line(&rctx->alien, p, poly->points[n].x, poly->points[n].y, poly->points[n+1].x, poly->points[n+1].y); + n = poly->num_points-1; + csch_alien_append_poly_line(&rctx->alien, p, poly->points[n].x, poly->points[n].y, poly->points[0].x, poly->points[0].y); + + return p; + } + + case ORCAD_PRIMITIVE_POLYLINE: + { + orcad_polyline_prim_t *poly = (orcad_polyline_prim_t *)prim; + long n; + csch_chdr_t *p = csch_alien_mkpoly(&rctx->alien, dst, stroke, NULL); + /* start loop from 1, index backwards */ + for(n = 1; n < poly->num_points; n++) + csch_alien_append_poly_line(&rctx->alien, p, poly->points[n-1].x, poly->points[n-1].y, poly->points[n].x, poly->points[n].y); + + return p; + } + + case ORCAD_PRIMITIVE_TEXT: + { + orcad_text_prim_t *text = (orcad_text_prim_t *)prim; + csch_text_t *t = place_text(rctx, dst, text->x, text->y, stroke, rnd_strdup(text->text)); + return &t->hdr; + } + break; + + case ORCAD_PRIMITIVE_BEZIER: + { + csch_sheet_t *sheet = rctx->alien.sheet; + orcad_bezier_prim_t *bezier = (orcad_bezier_prim_t *)prim; + csch_cgrp_t *grp; + long n; + + grp = csch_cgrp_alloc(sheet, dst, csch_oid_new(sheet, &sheet->direct)); + for(n = 0; n < bezier->num_segments; n++) { + orcad_bsegment_t *bs = &bezier->segments[n]; + csch_alien_mkbezier(&rctx->alien, grp, + bs->p1.x, bs->p1.y, bs->p2.x, bs->p2.y, bs->p3.x, bs->p3.y, bs->p4.x, bs->p4.y, + stroke); + } + + return &grp->hdr; + } + break; + + default: + rnd_message(RND_MSG_ERROR, "orcad: unknown primitive 0x%x\n", (unsigned int)prim->type); + break; + } + + return NULL; +} + +static void render_symbolpin_in(io_orcad_rctx_t *rctx, csch_cgrp_t *dst, orcad_symbolpin_node_t *nd, int vis_disp_name, int vis_name, int rot_name) +{ + csch_cgrp_t *pin; + csch_source_arg_t *src; + int shape_gr = nd->pin_shape & 0x0e; + enum { + PT_INPUT = 0, + PT_BIDIR = 1, + PT_OUTPUT = 2, + PT_OPEN_COLLECTOR = 3, + PT_PASSIVE = 4, /* default */ + PT_TRISTATE = 5, + PT_OPEN_EMITTER = 6, + PT_POWER = 7 + } ptype = nd->port_type; + static const char *ptype_names[] = { "input", "bidir", "output", "oc", NULL, NULL, "oe", "power", NULL }; /* coraleda crl002 dir names */ + int dot_r = 3, dx, dy, nx, ny, invis = 0; + long start_x = nd->start_x, start_y = nd->start_y; + + if (nd->pin_shape & 128) { + /* invisible pin - not creating it would make gnd and vcc fail */ + invis = 1; + start_x = nd->hotpt_x; + start_y = nd->hotpt_y; + } + + /* calculate directional vector assuming 90 degree rotations only */ + dx = start_x - nd->hotpt_x; + dy = start_y - nd->hotpt_y; + if (dx > 0) dx = +1; + else if (dx < 0) dx = -1; + if (dy > 0) dy = +1; + else if (dy < 0) dy = -1; + + /* normal vector */ + nx = dy; + ny = -dx; + + if (shape_gr & 0x04) { + /* dot outside: make the pin shorter */ + start_x -= dx * dot_r * 2; + start_y -= dy * dot_r * 2; + } + if (ptype == PT_INPUT) { + /* input arrow outside: make the pin shorter */ + start_x -= dx * dot_r; + start_y -= dy * dot_r; + } + + src = csch_attrib_src_c(rctx->fn, nd->node.offs, 0, NULL); + pin = (csch_cgrp_t *)csch_alien_mkpin_line(&rctx->alien, src, dst, nd->hotpt_x, nd->hotpt_y, start_x, start_y); + src = csch_attrib_src_c(rctx->fn, nd->node.offs, 0, NULL); + csch_cobj_attrib_set(rctx->alien.sheet, pin, CSCH_ATP_HARDWIRED, "name", nd->pin_name, src); + + /* add extra graphics */ + if (shape_gr & 0x04) { + /* dot (circle outside) */ + csch_alien_mkarc(&rctx->alien, pin, + nd->start_x - dx * dot_r, nd->start_y - dy * dot_r, + dot_r, 0, 360, "sym-decor"); + } + if (shape_gr & 0x02) { + /* clock (triangle inside) */ + csch_alien_mkline(&rctx->alien, pin, + nd->start_x + nx * dot_r, nd->start_y + ny * dot_r, + nd->start_x + dx * dot_r, nd->start_y + dy * dot_r, + "sym-decor"); + + csch_alien_mkline(&rctx->alien, pin, + nd->start_x - nx * dot_r, nd->start_y - ny * dot_r, + nd->start_x + dx * dot_r, nd->start_y + dy * dot_r, + "sym-decor"); + } + + if (ptype == PT_INPUT) { + /* clock (triangle inside) */ + csch_alien_mkline(&rctx->alien, pin, + nd->start_x, nd->start_y, + nd->start_x - dx * dot_r + nx * dot_r, nd->start_y - dy * dot_r + ny * dot_r, + "sym-decor"); + csch_alien_mkline(&rctx->alien, pin, + nd->start_x, nd->start_y, + nd->start_x - dx * dot_r - nx * dot_r, nd->start_y - dy * dot_r - ny * dot_r, + "sym-decor"); + csch_alien_mkline(&rctx->alien, pin, + nd->start_x - dx * dot_r - nx * dot_r, nd->start_y - dy * dot_r - ny * dot_r, + nd->start_x - dx * dot_r + nx * dot_r, nd->start_y - dy * dot_r + ny * dot_r, + "sym-decor"); + } + + if ((ptype >= 0) && (ptype < sizeof(ptype_names) / sizeof(ptype_names[0])) && (ptype_names[ptype] != NULL)) { + src = csch_attrib_src_c(rctx->fn, nd->node.offs, 0, NULL); + csch_cobj_attrib_set(rctx->alien.sheet, pin, CSCH_ATP_HARDWIRED, "dir", ptype_names[ptype], src); + } + + /* place pin name */ + if (!invis) { + csch_text_t *t; + double text_ang; + + if ((dx == 0) && (dy == +1)) { + /* north */ + nx = -nx; + ny = -ny; + } + else if (dx < 0) { + /* east */ + nx = -nx; + ny = -ny; + } + + /* tune text rotation and placement depending on rot_name */ + if (rot_name) { + if (dy == 0) { + text_ang = 0; + nx = 0; + } + else + text_ang = 90; + } + else + text_ang = 0; + + /* display/name is always printed next to the pin's end */ + if (vis_disp_name) { + t = (csch_text_t *)csch_alien_mktext(&rctx->alien, pin, nd->start_x - dx * dot_r * 2, nd->start_y - dy * dot_r * 2, "sym-decor"); + if (t != NULL) { + t->text = rnd_strdup("%../a.display/name%"); + t->dyntext = 1; + t->spec_rot = text_ang; + if (dx < 0) + t->spec_mirx = 1; + } + } + + /* this is the pin's original name inside the box */ + if (vis_name) { + t = (csch_text_t *)csch_alien_mktext(&rctx->alien, pin, nd->start_x + dx * dot_r * 2 - nx * TEXT_HEIGHT_ORCAD/2, nd->start_y + dy * dot_r * 2 - ny * TEXT_HEIGHT_ORCAD/2, "sym-decor"); + if (t != NULL) { + t->text = rnd_strdup("%../A.name%"); + t->dyntext = 1; + t->spec_rot = text_ang; + if (dx < 0) + t->spec_mirx = 1; + } + } + } +} + +static int sym_create_pinmap_in_cache(io_orcad_rctx_t *rctx, cache_sym_t *cs) +{ + gds_t tmp = {0}; + int m, p; + orcad_symbolgraphic_node_t *root = (orcad_symbolgraphic_node_t *)cs->root->obj; + + if ((cs->pinmap == NULL) || (cs->grp == NULL)) + return 0; + + for(m = 0; m < cs->pinmap->num_pinidxmappings; m++) { + orcad_pinidxmapping_node_t *map = cs->pinmap->pinidxmappings[m]; +/* rnd_trace(" unit_ref=%s\n", map->unit_ref);*/ + for(p = 0; (p < map->num_pins) && (p < root->num_symbolpins); p++) { + csch_source_arg_t *src; + orcad_pin_t *map_pin = map->pins[p]; + orcad_symbolpin_node_t *sym_pin = root->symbolpins[p]; + + if (map_pin == NULL) continue; + + tmp.used = 0; + gds_append_str(&tmp, map->unit_ref); + gds_append(&tmp, '/'); + gds_append_str(&tmp, sym_pin->pin_name); + gds_append_str(&tmp, "->pcb/pinnum="); + gds_append_str(&tmp, map_pin->pin_name); + +/* rnd_trace(" [%d] map=%s sym=%s: '%s'\n", p, map_pin->pin_name, sym_pin->pin_name, tmp.array);*/ + + src = csch_attrib_src_c(rctx->fn, map->node.offs, 0, NULL); + csch_attrib_append(&cs->grp->attr, CSCH_ATP_USER_DEFAULT, "portmap", tmp.array, src); + cs->slotted = 1; + } + } + + gds_uninit(&tmp); + return 0; +} + +/* Look up name for a slot index (->pim_idx in the partinst node). Returns NULL on + error. */ +static const char *cs_slot_name(io_orcad_rctx_t *rctx, cache_sym_t *cs, int slot_idx) +{ + orcad_pinidxmapping_node_t *map; + + if ((slot_idx < 0) || (cs->pinmap == NULL) || (slot_idx >= cs->pinmap->num_pinidxmappings)) + return NULL; + + map = cs->pinmap->pinidxmappings[slot_idx]; + if (map == NULL) + return NULL; + + return map->unit_ref; +} + +/* Create cs->grp building all the objects from the tree */ +static int render_sym_in_cache(io_orcad_rctx_t *rctx, cache_sym_t *cs) +{ + csch_sheet_t *sheet = rctx->alien.sheet; + csch_source_arg_t *src; + + cs->grp = csch_cgrp_alloc(sheet, &sheet->indirect, csch_oid_new(sheet, &sheet->indirect)); + src = csch_attrib_src_c("orcad sym cache", cs->root->node.offs, 0, NULL); + csch_cobj_attrib_set(sheet, cs->grp, CSCH_ATP_HARDWIRED, "role", "symbol", src); + + switch(cs->root->obj->type) { + case ORCAD_TYPE_GLOBALSYMBOL: + case ORCAD_TYPE_PORTSYMBOL: + case ORCAD_TYPE_OFFPAGECONNSYMBOL: + /* note: these 3 nodes share the same structure */ + { + double oy_save; + unsigned int n; + orcad_globalsymbol_node_t *root = (orcad_globalsymbol_node_t *)cs->root->obj; + + oy_save = rctx->alien.oy; + rctx->alien.oy = 0; + + for(n = 0; n < root->num_primitives; n++) + render_primitive_in(rctx, cs->grp, root->primitives[n], "sym-decor", "sym-decor-fill"); + for(n = 0; n < root->num_symbolpins; n++) + render_symbolpin_in(rctx, cs->grp, root->symbolpins[n], 0, 0, 0); + + cs->width = root->symbox_x; + cs->height = root->symbox_y; + + rctx->alien.oy = oy_save; + } + return 0; + case ORCAD_TYPE_SYMBOLGRAPHIC: + { + double oy_save; + unsigned int n; + orcad_symbolgraphic_node_t *root = (orcad_symbolgraphic_node_t *)cs->root->obj; + + oy_save = rctx->alien.oy; + rctx->alien.oy = 0; + + for(n = 0; n < root->num_primitives; n++) + render_primitive_in(rctx, cs->grp, root->primitives[n], "sym-decor", "sym-decor-fill"); + for(n = 0; n < root->num_symbolpins; n++) + render_symbolpin_in(rctx, cs->grp, root->symbolpins[n], root->pin_numbers_visible, root->pin_names_visible, root->pin_names_rotate); + + /* Note: floaters (displayprops) are created only at placment */ + + cs->width = root->symbox_x; + cs->height = root->symbox_y; + + rctx->alien.oy = oy_save; + } + return sym_create_pinmap_in_cache(rctx, cs); + default: + rnd_message(RND_MSG_ERROR, "orcad cache symbol render: invalid obj type 0x%x\n", cs->root->obj->type); + return -1; + } + + + return -1; +} + +/* Place a symbol from the cahce onto the sheet; render symbol in cache if + needed. Returns the symbol group just placed (or NULL on error) */ +static csch_cgrp_t *place_sym_from_cache(io_orcad_rctx_t *rctx, cache_sym_t *cs, long x_in, long y_in, int rot_in, int in_mirror, int slot_idx, int lineno) +{ + csch_sheet_t *sheet = rctx->alien.sheet; + csch_cgrp_t *placed; + + if (cs->grp == NULL) + render_sym_in_cache(rctx, cs); + + if (cs->grp == NULL) + return NULL; + + + placed = csch_cgrp_dup(sheet, &sheet->direct, cs->grp, 0); + + /* initial placement wherever, rotate, mirror */ + placed->x = placed->y = 0; + placed->spec_rot = rot_in * 90; + placed->mirx = in_mirror; + + csch_cgrp_update(rctx->alien.sheet, placed, 1); + + /* shift coords so that ("bbox without pins") top-left is at 0;0, this + compensation depends on rotation and mirror */ + switch (rot_in) { + case 0: + if (in_mirror) + placed->x += csch_alien_coord(&rctx->alien, cs->width); + break; + + case 1: + if (in_mirror) + placed->spec_rot += 180; + else + placed->y -= csch_alien_coord(&rctx->alien, cs->width); + break; + + case 2: + if (!in_mirror) + placed->x += csch_alien_coord(&rctx->alien, cs->width); + placed->y -= csch_alien_coord(&rctx->alien, cs->height); + break; + + case 3: + placed->x += csch_alien_coord(&rctx->alien, cs->height); + if (in_mirror) { + placed->spec_rot -= 180; + placed->y -= csch_alien_coord(&rctx->alien, cs->width); + } + break; + } + + /* apply requested placement move, effectively grabbing the top-left corner */ + placed->x += csch_alien_coord_x(&rctx->alien, x_in); + placed->y += csch_alien_coord_y(&rctx->alien, y_in); + + /* set slot if symbol is slotted */ + if ((slot_idx >= 0) && cs->slotted) { + const char *slot_name = cs_slot_name(rctx, cs, slot_idx); + if (slot_name != NULL) { + csch_source_arg_t *src = csch_attrib_src_c(rctx->fn, lineno, 0, NULL); + csch_attrib_set(&placed->attr, CSCH_ATP_USER_DEFAULT, "-slot", slot_name, src, NULL); + } + else + rnd_message(RND_MSG_ERROR, "io_orcad: failed to find slot name for pim_idx=%d - please report this bug\n", slot_idx); + } + + return placed; +} + +static const char *lookup_displayprop_name(io_orcad_rctx_t *rctx, unsigned long name_idx) +{ + if ((rctx->library_root == NULL) || (name_idx >= rctx->library_root->num_names)) + return NULL; + + return rctx->library_root->names[name_idx]; +} + +/* Linear search for name_idx in the ->name_idx fields of nm[] */ +static orcad_namemapping_t *lookup_name_mapping(io_orcad_rctx_t *rctx, unsigned int nms_len, orcad_namemapping_t *nms, unsigned long name_idx) +{ + unsigned long n; + for(n = 0; n < nms_len; n++) + if (nms[n].name_idx == name_idx) + return &nms[n]; + return NULL; +} + +typedef struct { + const char *name; + const char *value; +} floater_map_hardwired_t; + +static void place_floaters_from_displayprops(io_orcad_rctx_t *rctx, csch_cgrp_t *dst, unsigned int num_dp, orcad_symboldisplayprop_node_t **dp, unsigned int nm1_len, orcad_namemapping_t *nm1, unsigned int nm2_len, orcad_namemapping_t *nm2, floater_map_hardwired_t *hw, int floaters, const char *stroke_pri, const char *stroke_sec, long src_lineno) +{ + unsigned int n; + const char *stroke = stroke_sec; + csch_text_t *txt; + enum { + FMT_VAL_ONLY = 1, + FMT_BOTH = 2, + FMT_NAME_ONLY = 3, + FMT_BOTH_IF_NONEMPTY = 4 + } fmt; + + rnd_trace("place_floaters_from_displayprops():\n"); + for(n = 0; n < num_dp; n++) { + orcad_symboldisplayprop_node_t *p = dp[n]; + orcad_namemapping_t *m = NULL; + const char *key = NULL, *val = NULL; + int capital = 0; + + fmt = p->format; + + /* find the name mapping in the two alternaive maps provided by the + caller. Normally nm1 is partinst's mapping (placement), nm2 is the + symbolgraphics's mapping (from the Cache lib) */ + if (nm1 != NULL) + m = lookup_name_mapping(rctx, nm1_len, nm1, p->name_idx); + if ((m == NULL) && (nm2 != NULL)) + m = lookup_name_mapping(rctx, nm2_len, nm2, p->name_idx); + + /* Fallback mechanism of mapping was not found in either: use name_idx + as a direct string index for lookup_displayprop_name(); + except these values are cached in read_library() */ + if (m == NULL) { + if (p->name_idx == rctx->hwpropnames.part_ref) { + key = "name"; + val = hw->name; + stroke = stroke_pri; + } + else if (p->name_idx == rctx->hwpropnames.name) { + key = "name"; + val = hw->name; + stroke = stroke_pri; + } + else if (p->name_idx == rctx->hwpropnames.value) { + key = "value"; + val = hw->value; + } + } + +#if 0 + /* trace prints for floater placement */ + rnd_trace(" [%d] at %d %d format %d idx %d %p\n", n, p->x, p->y, fmt, p->name_idx, m); + if (key != NULL) { + rnd_trace(" '%s' = '%s'\n", key, val); + } + else if (m != NULL) { + rnd_trace(" %ld:'%s' = %ld:'%s'\n", + (long)m->name_idx, lookup_displayprop_name(rctx, m->name_idx), + (long)m->value_idx, lookup_displayprop_name(rctx, m->value_idx)); + } +#endif + + /* if key and val are not hardwired and we had a matching map entry, look + them string values up */ + if ((key == NULL) && (m != NULL)) { + key = lookup_displayprop_name(rctx, m->name_idx); + val = lookup_displayprop_name(rctx, m->value_idx); + } + + if (key != NULL) { + int vis_key, vis_val; + + switch(fmt) { + case FMT_VAL_ONLY: + vis_key = 0; + vis_val = 1; + break; + case FMT_NAME_ONLY: + vis_key = 1; + vis_val = 0; + break; + case FMT_BOTH_IF_NONEMPTY: + if ((val == NULL) || (*val == '\0')) { + vis_key = 0; + vis_val = 0; + break; + } + /* else: fall thru */ + case FMT_BOTH: + vis_key = 1; + vis_val = 1; + break; + } + rnd_trace(" [%d] at %d %d sym: %d %d\n", n, p->x, p->y, dst->x, dst->y); + txt = add_attr_with_text(rctx, dst, p->x, p->y, stroke, key, val, vis_key, vis_val, capital, src_lineno); + if (floaters) + txt->hdr.floater = 1; + } + } +} + +/* Read displayprops from the library symbol (cs) to place floaters: partinst variant */ +static void place_sym_floaters_pi(io_orcad_rctx_t *rctx, cache_sym_t *cs, csch_cgrp_t *sym, orcad_partinst_node_t *partinst) +{ + orcad_symbolgraphic_node_t *sg = (orcad_symbolgraphic_node_t *)cs->root->obj; + floater_map_hardwired_t hw = {0}; + + if (partinst == NULL) + return; + + hw.name = partinst->refdes; + hw.value = lookup_displayprop_name(rctx, partinst->value_idx); + +/* don't do this: it seems partinst has these copied: + if (sg != NULL) + place_floaters_from_displayprops(rctx, sym, sg->num_displayprops, sg->displayprops); +*/ + place_floaters_from_displayprops(rctx, sym, partinst->num_displayprops, partinst->displayprops, partinst->node.num_namemappings, partinst->node.namemappings, sg->node.num_namemappings, sg->node.namemappings, &hw, 1, "sym-primary", "sym-secondary", partinst->node.offs); +} + +/* Read displayprops from the library symbol (cs) to place floaters: global symbol variant */ +static void place_sym_floaters_gs(io_orcad_rctx_t *rctx, cache_sym_t *cs, csch_cgrp_t *sym, orcad_graphicinst_node_t *gr) +{ + orcad_symbolgraphic_node_t *sg = (orcad_symbolgraphic_node_t *)cs->root->obj; + floater_map_hardwired_t hw = {0}; + + hw.name = lookup_displayprop_name(rctx, gr->graphic.instname_idx); + +/* don't do this: it seems partinst has these copied: + if (sg != NULL) + place_floaters_from_displayprops(rctx, sym, sg->num_displayprops, sg->displayprops, NULL, NULL, sg->num_namemappings, sg->namemappings, &hw, 1, "sym-primary", "sym-secondary", 0); +*/ + if (gr != NULL) + place_floaters_from_displayprops(rctx, sym, gr->graphic.num_displayprops, gr->graphic.displayprops, gr->node.num_namemappings, gr->node.namemappings, sg->node.num_namemappings, sg->node.namemappings, &hw, 0, "sym-primary", "sym-secondary", 0); +} + +/**** high level (tree walk) ****/ + +typedef enum { + CHCSYM_SIMPLE, /* simple "graphic" symbols: holds symbol graphics; vcc and gnd are like this, and are directly referenced */ + CHCSYM_PROPS, /* complex symbols, properties: reference back to one or more symple symbols */ + CHCSYM_MAPS /* complex symbols, pin mapping: matches the name of a CHCSYM_PROPS */ +} cache_sym_how_t; + +/* Do not parse the whole symbol yet, just remember its tree node and name; + parse and create the group later, on-demand */ +static int read_cache_sym_dir(io_orcad_rctx_t *ctx, orcad_xsymbolgroup_node_t *sgrp, cache_sym_how_t how) +{ + long n; + + for(n = 0; n < sgrp->num_symbols; n++) { + cache_sym_t *cs, *cs2; + orcad_xcachesymbol_node_t *snd = sgrp->symbols[n]; + + if (snd->num_variants == 0) /* nothing stored */ + continue; + + /* look up or create cs */ + cs = htsp_get(&ctx->syms, snd->symname); + switch(how) { + case CHCSYM_SIMPLE: + case CHCSYM_PROPS: + if (cs != NULL) { /* these are unique */ + rnd_message(RND_MSG_ERROR, "orcad: multiple occurances of cache symbol '%s'\n", snd->symname); + continue; + } + cs = calloc(sizeof(cache_sym_t), 1); + cs->name = snd->symname; + TODO("low prio: how to decide which variant to use? (using the first one for now)"); + htsp_insert(&ctx->syms, (char *)cs->name, cs); + break; + case CHCSYM_MAPS: + if (cs == NULL) { /* created at CHCSYM_PROPS */ + rnd_message(RND_MSG_ERROR, "orcad: cache symbol '%s' does not exist for pin mapping\n", snd->symname); + continue; + } + if (cs->simple) { /* if created at CHCSYM_SIMPLE, we can't pinmap it */ + rnd_message(RND_MSG_ERROR, "orcad: cache symbol '%s' is a simple graphic symbol, can't be pinmapped\n", snd->symname); + continue; + } + break; + } + + /* fill in extra fields */ + switch(how) { + case CHCSYM_SIMPLE: + cs->root = snd->variants[0]; + cs->simple = 1; + break; + case CHCSYM_PROPS: + { + orcad_properties_node_t *pn = (orcad_properties_node_t *)snd->variants[0]->obj; + + if (pn->node.type != ORCAD_TYPE_PROPERTIES) { + rnd_message(RND_MSG_ERROR, "orcad: prop type complex cache symbol '%s' doesn't have properties\n", snd->symname); + break; + } + if (pn->num_partnames < 1) { + rnd_message(RND_MSG_ERROR, "orcad: prop type complex cache symbol '%s' doesn't have part names\n", snd->symname); + break; + } + + /* link cs to an existing symbol */ + TODO("low prio: this assumes there's only one part - find an example (heterogenous slotting doesn't trigger) - for(p = 0; p < pn->num_partnames; p++)"); + cs2 = htsp_get(&ctx->syms, pn->partnames[0]); + if (cs2 == NULL) { + rnd_message(RND_MSG_ERROR, "orcad: prop type complex cache symbol '%s' references non-existing graphics '%s'\n", snd->symname, pn->partnames[0]); + break; + } + if (!cs2->simple) + rnd_message(RND_MSG_ERROR, "orcad: prop type complex cache symbol '%s' references another complex symbol '%s'\n", snd->symname, pn->partnames[0]); + cs->root = cs2->root; + } + break; + case CHCSYM_MAPS: + cs->pinmap = (orcad_symbolpinmapping_node_t *)snd->variants[0]->obj; + break; + } + } + + return 0; +} + +/* propagate pinmaps among linked objects: if multiple cs's are using the + same root, they should also share pinmap (can't be done in + read_cache_sym_dir() because props have to be read before pinmaps) */ +static void cache_link_propagate(io_orcad_rctx_t *ctx) +{ + htsp_entry_t *e, *f; + for(e = htsp_first(&ctx->syms); e != NULL; e = htsp_next(&ctx->syms, e)) { + cache_sym_t *cs = e->value; + if (cs->linked) + continue; + cs->linked = 1; + if (cs->pinmap == NULL) + continue; + + for(f = htsp_first(&ctx->syms); f != NULL; f = htsp_next(&ctx->syms, f)) { + cache_sym_t *cs2 = f->value; + if ((cs2->root == cs->root) && (cs2->pinmap == NULL)) { + cs2->pinmap = cs->pinmap; + cs2->linked = 1; + } + } + } +} + +static int read_cache_sym_dirs(io_orcad_rctx_t *ctx) +{ + int res; + + res = read_cache_sym_dir(ctx, ctx->cache_root->titleblocks, CHCSYM_SIMPLE); + res |= read_cache_sym_dir(ctx, ctx->cache_root->symbolgraphics, CHCSYM_SIMPLE); + res |= read_cache_sym_dir(ctx, ctx->cache_root->symbolproperties, CHCSYM_PROPS); + res |= read_cache_sym_dir(ctx, ctx->cache_root->symbolpinmappings, CHCSYM_MAPS); + + cache_link_propagate(ctx); + + return res; +} + +static int read_library(io_orcad_rctx_t *rctx) +{ + long n; + + rctx->hwpropnames.part_ref = -1; + rctx->hwpropnames.value = -1; + rctx->hwpropnames.name = -1; + + for(n = 0; n < rctx->library_root->num_names; n++) { + const char *s = rctx->library_root->names[n]; + if (strcmp(s, "Part Reference") == 0) rctx->hwpropnames.part_ref = n; + if (strcmp(s, "Value") == 0) rctx->hwpropnames.value = n; + if (strcmp(s, "Name") == 0) rctx->hwpropnames.name = n; + } + + return 0; +} + + +static int read_wire(io_orcad_rctx_t *rctx, orcad_wire_node_t *nd) +{ + csch_cgrp_t *wn = orcad_wirenet_lookup(rctx, nd->net_id, 1); + csch_alien_mkline(&rctx->alien, wn, nd->start_x, nd->start_y, nd->end_x, nd->end_y, "wire"); + return 0; +} + +static int read_xnetalias(io_orcad_rctx_t *rctx, orcad_xnetalias_node_t *nd) +{ + csch_cgrp_t *wn = orcad_wirenet_lookup(rctx, nd->net_id, 0); + + if (wn == NULL) { /* happens on wireless nets, anon-rail symbols's terminal touching a rail symbol's terminal */ + csch_cgrp_t *term = htip_get(&rctx->pinconns, nd->net_id); + if (term != NULL) { + csch_sheet_t *sheet = rctx->alien.sheet; + csch_source_arg_t *src = csch_attrib_src_c(rctx->fn, nd->node.offs, 0, NULL); + csch_line_t *line; + csch_coord_t x, y; + + wn = csch_cgrp_alloc(sheet, &sheet->direct, csch_oid_new(sheet, &sheet->direct)); + csch_cobj_attrib_set(sheet, wn, CSCH_ATP_HARDWIRED, "role", "wire-net", src); + + line = csch_line_alloc(sheet, wn, csch_oid_new(sheet, wn)); + + x = (term->hdr.bbox.x1 + term->hdr.bbox.x2)/2; + y = (term->hdr.bbox.y1 + term->hdr.bbox.y2)/2; + line->spec.p1.x = x - 1000; + line->spec.p1.y = y - 1000; + line->spec.p2.x = x + 1000; + line->spec.p2.y = y + 1000; + line->hdr.stroke_name = csch_comm_str(sheet, "wire", 1); + } + else { + rnd_message(RND_MSG_ERROR, "Failed to find net_id %d - connection not made to %s\n", nd->net_id, nd->alias); + return 0; + } + } + orcad_cgrp_set_name(wn, nd->alias, rctx->fn, nd->node.offs); + return 0; +} + +/* Global/Port/Offpageconn graphic symbol */ +static int read_gpo_graphic(io_orcad_rctx_t *rctx, orcad_graphicinst_node_t *gr, long offs) +{ + cache_sym_t *cs; + csch_cgrp_t *sym; + + if (gr == NULL) { + rnd_message(RND_MSG_ERROR, "orcad: missing graphic in page global/port/offpageconn (symbol placement)\n"); + return -1; + } + + cs = htsp_get(&rctx->syms, gr->graphic.name); + if (cs == NULL) { + rnd_message(RND_MSG_ERROR, "orcad: page global/port/offpageconn (symbol placement) references non-existing cache symbol: '%s'\n", gr->graphic.name); + return -1; + } + + sym = place_sym_from_cache(rctx, cs, gr->graphic.x, gr->graphic.y, gr->graphic.rotation, gr->graphic.mirrored, -1, offs); + place_sym_floaters_gs(rctx, cs, sym, gr); + + return 0; +} + +static int read_global(io_orcad_rctx_t *rctx, orcad_global_node_t *nd) +{ + return read_gpo_graphic(rctx, (orcad_graphicinst_node_t *)nd, nd->node.offs); +} + +static int read_port(io_orcad_rctx_t *rctx, orcad_port_node_t *nd) +{ + return read_gpo_graphic(rctx, (orcad_graphicinst_node_t *)nd, nd->node.offs); +} + +static int read_offpageconn(io_orcad_rctx_t *rctx, orcad_offpageconn_node_t *nd) +{ + return read_gpo_graphic(rctx, (orcad_graphicinst_node_t *)nd, nd->node.offs); +} + +/* Remember pinconns so xnetalias can be applied later */ +static int partinst_load_pinconns(io_orcad_rctx_t *rctx, orcad_partinst_node_t *nd, csch_cgrp_t *sym) +{ + int n; + + for(n = 0; n < nd->num_pinconnections; n++) { + orcad_pinconnection_node_t *pnc = nd->pinconnections[n]; + htip_entry_t *e, *e2; + csch_coord_t x, y; + + rnd_trace("PINCONN: idx=%d %d;%d net_id = %d\n", pnc->idx, pnc->x, pnc->y, (int)pnc->net_id); + + if (pnc->net_id == 0) + continue; + + x = csch_alien_coord_x(&rctx->alien, pnc->x); + y = csch_alien_coord_y(&rctx->alien, pnc->y); +/* rnd_trace(" search at %d;%d\n", x, y);*/ + + for(e = htip_first(&sym->id2obj); e != NULL; e = htip_next(&sym->id2obj, e)) { + csch_cgrp_t *grp = e->value; + if (csch_obj_is_grp(&grp->hdr) && (grp->role == CSCH_ROLE_TERMINAL)) { + for(e2 = htip_first(&grp->id2obj); e2 != NULL; e2 = htip_next(&grp->id2obj, e2)) { + csch_line_t *lin = e2->value; + if (lin->hdr.type == CSCH_CTYPE_LINE) { + if (((lin->inst.c.p1.x == x) && (lin->inst.c.p1.y == y)) || ((lin->inst.c.p2.x == x) && (lin->inst.c.p2.y == y))) { + rnd_trace("term line %d -> %p!\n", pnc->net_id, grp); + htip_set(&rctx->pinconns, pnc->net_id, grp); + } + } + } + } + } + } + + return 0; +} + +static int read_partinst(io_orcad_rctx_t *rctx, orcad_partinst_node_t *nd) +{ + cache_sym_t *cs; + csch_cgrp_t *sym; + + cs = htsp_get(&rctx->syms, nd->name); + if (cs == NULL) { + rnd_message(RND_MSG_ERROR, "orcad: page partinst (symbol placement) references non-existing cache symbol: '%s'\n", nd->name); + return -1; + } + + sym = place_sym_from_cache(rctx, cs, nd->x, nd->y, nd->rotation, nd->mirrored, nd->pim_idx, nd->node.offs); + if (sym != NULL) { + csch_source_arg_t *src; + orcad_cgrp_set_name(sym, nd->refdes, rctx->fn, nd->node.offs); + + /* overwrite symtypename: the cache version contains the long one from + the simple symbol while partinst is using the complex symbol */ + src = csch_attrib_src_c(rctx->fn, nd->node.offs, 0, NULL); + csch_attrib_set(&sym->attr, CSCH_ATP_USER_DEFAULT, "symtypename", nd->symname, src, NULL); + + place_sym_floaters_pi(rctx, cs, sym, nd); + } + + csch_cgrp_update(rctx->alien.sheet, sym, 1); /* get terminal line coords calculated for pinconn lookup */ + return partinst_load_pinconns(rctx, nd, sym); +} + +static int draw_graphic_in(io_orcad_rctx_t *rctx, csch_cgrp_t *parent, orcad_graphic_inline_t *gr, const char *stroke, const char *fill) +{ + if (gr->obj->num_primitives == 1) { + /* special case: single object, just place it on the sheet; translate + are embedded in the primitive, ignore gr->x, gr->y, but rotation matters. */ + csch_chdr_t *obj = render_primitive_in(rctx, parent, gr->obj->primitives[0], stroke, fill); + if (gr->rotation != 0) { + csch_text_t *txt = (csch_text_t *)obj; + txt->spec_miry = 0; + if (gr->rotation == 2) + txt->spec_mirx = 1; + if (gr->rotation == 1) + txt->spec_mirx = txt->spec_miry = 1; + csch_rotate90(rctx->alien.sheet, obj, txt->spec1.x, txt->spec1.y, gr->rotation, 0); + } + } + else { + /* create a custom user group */ + TODO("low prio: implement me when an example comes up"); + abort(); + } + return 0; +} + +static int read_graphicinst(io_orcad_rctx_t *rctx, orcad_graphicinst_node_t *nd) +{ + draw_graphic_in(rctx, &rctx->alien.sheet->direct, &nd->graphic, "sheet-decor", "sheet-decor-fill"); + return 0; +} + + +/* Read global page properties (not drawing objects) */ +static int read_page_props(io_orcad_rctx_t *rctx) +{ + orcad_page_node_t *pg = rctx->page_root; + rnd_bool grid_ref = pg->settings.gridref_displayed || pg->settings.gridref_printed; + + orcad_sheet_set_extents(rctx, pg->settings.width, pg->settings.height, grid_ref, pg->node.offs, pg->settings.is_metric); + + return 0; +} + +/* Read drawing objects */ +static int read_page_objs(io_orcad_rctx_t *rctx) +{ + orcad_page_node_t *pg = rctx->page_root; + long n; + int res = 0; + + for(n = 0; n < pg->num_wires; n++) + res |= read_wire(rctx, pg->wires[n]); + + + for(n = 0; n < pg->num_globals; n++) + res |= read_global(rctx, pg->globals[n]); + + for(n = 0; n < pg->num_ports; n++) + res |= read_port(rctx, pg->ports[n]); + + for(n = 0; n < pg->num_offpageconns; n++) + res |= read_offpageconn(rctx, pg->offpageconns[n]); + + for(n = 0; n < pg->num_partinsts; n++) + res |= read_partinst(rctx, pg->partinsts[n]); + + for(n = 0; n < pg->num_graphicinsts; n++) + res |= read_graphicinst(rctx, pg->graphicinsts[n]); + + for(n = 0; n < pg->num_netaliases; n++) /* must be after parts because it depends on terminals */ + res |= read_xnetalias(rctx, pg->netaliases[n]); + + return res; +} + + +/**** binary ****/ + +ucdf_direntry_t *cdf_path(ucdf_ctx_t *ucdf, const char **path, ucdf_direntry_t *from) +{ + ucdf_direntry_t *de = from; + + if (path[0] == NULL) + return de; + + if (de == NULL) + de = ucdf->root->children; + else + de = de->children; + + for(; de != NULL; de = de->next) + if (strcmp(de->name, path[0]) == 0) + return cdf_path(ucdf, path+1, de); + + return NULL; +} + +void *io_orcad_test_parse_bundled(FILE *f, const char *fn, const char *fmt, csch_plug_io_type_t type) +{ + io_orcad_rctx_t *ctx = calloc(sizeof(io_orcad_rctx_t), 1); + const char *path[] = { "Views", NULL }; + const char *path2[] = { "Pages", NULL }; + ucdf_direntry_t *de; + + if (ucdf_open(&ctx->ucdf, fn) != 0) { + if (io_orcad_conf.plugins.io_orcad.debug.trace_test_parse) + rnd_message(RND_MSG_ERROR, "io_orcad test_parse: failed to open cdf\n"); + free(ctx); + return NULL; + } + + de = cdf_path(&ctx->ucdf, path, NULL); + if (de == NULL) { + if (io_orcad_conf.plugins.io_orcad.debug.trace_test_parse) + rnd_message(RND_MSG_ERROR, "io_orcad test_parse: failed to find Views/ in cdf\n"); + free(ctx); + return NULL; + } + + if (de->children == NULL) { + if (io_orcad_conf.plugins.io_orcad.debug.trace_test_parse) + rnd_message(RND_MSG_ERROR, "io_orcad test_parse: failed to find sheets in Views/\n"); + free(ctx); + return NULL; + } + + de = cdf_path(&ctx->ucdf, path2, de->children); + if (de->children == NULL) { + if (io_orcad_conf.plugins.io_orcad.debug.trace_test_parse) + rnd_message(RND_MSG_ERROR, "io_orcad test_parse: failed to find sheets in Views/*/Pages/\n"); + free(ctx); + return NULL; + } + + ctx->next_page = de->children; + + ctx->alien.fmt_prefix = "io_orcad"; + ctx->alien.flip_y = 1; + ctx->fn = fn; + + return ctx; +} + + +int io_orcad_load_cache(io_orcad_rctx_t *ctx) +{ + orcad_node_t *nd; + ucdf_direntry_t *de; + const char *path[] = { "Cache", NULL }; + int res = -1; + + rnd_message(RND_MSG_INFO, "io_orcad: reading cache...\n"); + + htsp_init(&ctx->syms, strhash, strkeyeq); + ctx->cache_loaded = 1; + + + de = cdf_path(&ctx->ucdf, path, NULL); + if (de == NULL) + return 0; + + if (ucdf_fopen(&ctx->ucdf, &ctx->fp, de) != 0) + return -1; + + ctx->has_fp = 1; + + TODO("low prio: workaround for missing short seek"); + ctx->cheat_buf = malloc(de->size); + ucdf_fread(&ctx->fp, ctx->cheat_buf, de->size); + ctx->cheat_offs = 0; + ctx->cheat_len = de->size; + + nd = orcad_read_cache(ctx); + if (nd == NULL) { + rnd_message(RND_MSG_ERROR, "io_orcad: failed to read (symbol) cache\n"); + goto err1; + } + + if (nd->type != ORCAD_TYPE_X_CACHE) { + rnd_message(RND_MSG_ERROR, "io_orcad: (symbol) cache root type mismatch: expected %d got %d\n", ORCAD_TYPE_X_CACHE, nd->type); + goto err1; + } + + ctx->cache_root = (orcad_xcache_node_t *)nd; + + res = read_cache_sym_dirs(ctx); + + err1:; + ctx->has_fp = 0; + free(ctx->cheat_buf); + + return res; +} + +int io_orcad_free_cache(io_orcad_rctx_t *ctx) +{ + htsp_entry_t *e; + + assert(ctx->cache_loaded); + + for(e = htsp_first(&ctx->syms); e != NULL; e = htsp_next(&ctx->syms, e)) { + cache_sym_t *cs = e->value; + if (cs->grp != NULL) + csch_cgrp_free(cs->grp); + /* do not free cs->name or e->key: they are pointing to a field in ctx->cache_root */ + free(cs); + } + + htsp_uninit(&ctx->syms); + ctx->cache_loaded = 0; + + if (ctx->cache_root != NULL) + orcad_free((orcad_node_t *)ctx->cache_root); + ctx->cache_root = NULL; + + return 0; +} + +int io_orcad_load_library(io_orcad_rctx_t *ctx) +{ + orcad_node_t *nd; + ucdf_direntry_t *de; + const char *path[] = { "Library", NULL }; + int res = -1; + + rnd_message(RND_MSG_INFO, "io_orcad: reading library...\n"); + + ctx->library_loaded = 1; + de = cdf_path(&ctx->ucdf, path, NULL); + if (de == NULL) + return 0; + + if (ucdf_fopen(&ctx->ucdf, &ctx->fp, de) != 0) + return -1; + + ctx->has_fp = 1; + + TODO("low prio: workaround for missing short seek"); + ctx->cheat_buf = malloc(de->size); + ucdf_fread(&ctx->fp, ctx->cheat_buf, de->size); + ctx->cheat_offs = 0; + ctx->cheat_len = de->size; + + nd = orcad_read_library(ctx); + if (nd == NULL) { + rnd_message(RND_MSG_ERROR, "io_orcad: failed to read strings (Library)\n"); + goto err1; + } + + if (nd->type != ORCAD_TYPE_X_LIBRARY) { + rnd_message(RND_MSG_ERROR, "io_orcad: strings (Library) root type mismatch: expected %d got %d\n", ORCAD_TYPE_X_LIBRARY, nd->type); + goto err1; + } + + ctx->library_root = (orcad_xlibrary_node_t *)nd; + + res = read_library(ctx); + + err1:; + ctx->has_fp = 0; + free(ctx->cheat_buf); + + return res; +} + +int io_orcad_free_library(io_orcad_rctx_t *ctx) +{ + if (ctx->library_root != NULL) + orcad_free((orcad_node_t *)ctx->library_root); + ctx->library_root = NULL; + + return 0; +} + +static int io_orcad_load_page(io_orcad_rctx_t *ctx, ucdf_direntry_t *de) +{ + int res = -1; + orcad_node_t *nd; + + TODO("low prio: workaround for missing short seek"); + ctx->cheat_buf = malloc(de->size); + ucdf_fread(&ctx->fp, ctx->cheat_buf, de->size); + ctx->cheat_offs = 0; + ctx->cheat_len = de->size; + + + nd = orcad_read(ctx); + if (nd == NULL) { + rnd_message(RND_MSG_ERROR, "io_orcad: failed to read page\n"); + goto err1; + } + + if (nd->type != ORCAD_TYPE_PAGE) { + rnd_message(RND_MSG_ERROR, "io_orcad: page root type mismatch: expected %d got %d\n", ORCAD_TYPE_PAGE, nd->type); + goto err1; + } + + ctx->page_root = (orcad_page_node_t *)nd; + + res = read_page_props(ctx) | read_page_objs(ctx); + + /* postprocess sheet */ + csch_cgrp_update(ctx->alien.sheet, &ctx->alien.sheet->direct, 1); + csch_alien_postproc_sheet(&ctx->alien); + csch_alien_update_conns(&ctx->alien); + + /* free temps */ + htip_uninit(&ctx->wirenets); + htip_uninit(&ctx->pinconns); + if (ctx->page_root != NULL) + orcad_free((orcad_node_t *)ctx->page_root); + ctx->page_root = NULL; + err1:; + free(ctx->cheat_buf); + + return res; +} + + + +int io_orcad_load_sheet_bundled(void *cookie, FILE *f, const char *fn, csch_sheet_t *dst) +{ + io_orcad_rctx_t *ctx = cookie; + ucdf_direntry_t *de = ctx->next_page; + const char *pagename; + int res; + + pagename = ctx->next_page->name; + + if (ctx->has_fp) + ctx->has_fp = 0; + + if (!ctx->cache_loaded) + io_orcad_load_cache(ctx); + + if (!ctx->library_loaded) + io_orcad_load_library(ctx); + + rnd_message(RND_MSG_INFO, "io_orcad: reading page %s...\n", pagename); + + ctx->alien.sheet = dst; + ctx->alien.sheet->hidlib.loadname = rnd_strdup(pagename); + + ctx->alien.coord_factor = io_orcad_conf.plugins.io_orcad.coord_mult; + htip_init(&ctx->wirenets, longhash, longkeyeq); + htip_init(&ctx->pinconns, longhash, longkeyeq); + csch_alien_sheet_setup(&ctx->alien, 1); + + if (ucdf_fopen(&ctx->ucdf, &ctx->fp, ctx->next_page) != 0) + return -1; + + ctx->has_fp = 1; + + res = io_orcad_load_page(ctx, de); + + +/* ctx->alien.sheet->hidlib.fullpath = rnd_strdup_printf("%s_%ld.rs", fn, ++ctx->sheetno); + ctx->alien.sheet = NULL;*/ + + if (res == 0) { + ctx->next_page = ctx->next_page->next; + if (ctx->next_page == NULL) { + io_orcad_free_cache(ctx); + return 1; /* no more pages */ + } + return 0; /* proceed to read next page */ + } + + io_orcad_free_cache(ctx); + io_orcad_free_library(ctx); + return -1; /* error */ +} + +void io_orcad_end_bundled(void *cookie, const char *fn) +{ + io_orcad_rctx_t *ctx = cookie; + + if (ctx->has_fp) + ctx->has_fp = 0; + + ucdf_close(&ctx->ucdf); + free(ctx); +} Index: tags/1.0.5/src/plugins/io_orcad/read.h =================================================================== --- tags/1.0.5/src/plugins/io_orcad/read.h (nonexistent) +++ tags/1.0.5/src/plugins/io_orcad/read.h (revision 10414) @@ -0,0 +1,5 @@ +#include + +void *io_orcad_test_parse_bundled(FILE *f, const char *fn, const char *fmt, csch_plug_io_type_t type); +int io_orcad_load_sheet_bundled(void *cookie, FILE *f, const char *fn, csch_sheet_t *dst); +void io_orcad_end_bundled(void *cookie, const char *fn); Index: tags/1.0.5/src/plugins/io_orcad/read_cache.c =================================================================== --- tags/1.0.5/src/plugins/io_orcad/read_cache.c (nonexistent) +++ tags/1.0.5/src/plugins/io_orcad/read_cache.c (revision 10414) @@ -0,0 +1,653 @@ +#ifdef ORCAD_TESTER +# include "tester/read_fio.h" +#else +# include "read_fio.h" +#endif +#include "read_common.h" +#include +#include +#include +#include + +static long orcad_read_symbolpin(io_orcad_rctx_t* const rctx, long offs, + struct orcad_node* const parent, struct orcad_node** const out_node) +{ + orcad_create_node(struct orcad_symbolpin_node, ORCAD_TYPE_SYMBOLPIN); + + if(0>(offs=orcad_read_string2(rctx, offs, &node->pin_name))) + { + fprintf(stderr, "Error: Could not read pin name\n"); + return -1; + } + + read_i32(start_x); + read_i32(start_y); + read_i32(hotpt_x); + read_i32(hotpt_y); + read_u16(pin_shape); + read_u16(unknown_0); + read_u32(port_type); + read_u16(unknown_1); + read_u16(unknown_2); + + read_node_array(displayprop, orcad_read_symboldisplayprop); + + return offs; +} + +static long orcad_read_pinidxmapping(io_orcad_rctx_t* const rctx, long offs, + struct orcad_node* const parent, struct orcad_node** const out_node) +{ + orcad_uint16_t i; + + orcad_create_node(struct orcad_pinidxmapping_node, + ORCAD_TYPE_PINIDXMAPPING); + + if(0>(offs=orcad_read_string2(rctx, offs, &node->unit_ref))) + { + fprintf(stderr, "Error: Could not read unit_ref\n"); + return -1; + } + + if(0>(offs=orcad_read_string2(rctx, offs, &node->symname))) + { + fprintf(stderr, "Error: Could not read symname\n"); + return -1; + } + + read_u16(num_pins); + + if(NULL==(node->pins=(struct orcad_pin**)calloc( + node->num_pins, sizeof(struct orcad_pin*)))) + { + fprintf(stderr, "Error: Could not allocate memory for pins\n"); + return -1; + } + + for(i=0;inum_pins;++i) + { + orcad_uint16_t len; + + if(0>(offs=orcad_read_field_u16(rctx, offs, &len))) + { + fprintf(stderr, "Error: Could not read pin string length\n"); + return -1; + } + + if(0xFFFF!=len) + { + orcad_uint8_t pincfg; + + struct orcad_pin* const pin = (struct orcad_pin*)calloc(1, + sizeof(struct orcad_pin)); + + if(NULL==pin) + { + fprintf(stderr, "Error: Could not allocate pin\n"); + return -1; + } + + node->pins[i] = pin; + + if(0>(offs=orcad_read_string(rctx, offs, &pin->pin_name, len))) + { + fprintf(stderr, "Error: Could not read pin name\n"); + return -1; + } + + if(1!=fio_fread(rctx, (char*)&pincfg, 1)) + { + fprintf(stderr, "Error: Could not read pincfg\n"); + return -1; + } + + ++offs; + + if(0x80 & pincfg) + { + pin->pin_ignore = 1; + pincfg ^= 0x80; + } + + if(0x7f!=pincfg) + { + pin->pin_group = pincfg; + } + else + { + /* pin is in an empty group */ + pin->pin_group = -1; + } + } + } + + return offs; +} + +struct orcad_symbol_common_node__int +{ + struct orcad_node node; + struct orcad_symbol_common sym_common; +}; + +static long orcad_read_symbol_common(io_orcad_rctx_t* const rctx, long offs, + struct orcad_symbol_common_node__int* const node) +{ + if(0>(offs=orcad_read_string2(rctx, offs, &node->sym_common.name))) + { + fprintf(stderr, "Error: Could not read sym name\n"); + return -1; + } + + if(0>(offs=orcad_read_string2(rctx, offs, &node->sym_common.source))) + { + fprintf(stderr, "Error: Could not read sym source\n"); + return -1; + } + + return offs; +} + +static long orcad_read_titleblocksymbol(io_orcad_rctx_t* const rctx, long offs, + struct orcad_node* const parent, struct orcad_node** const out_node) +{ + orcad_uint16_t i; + + orcad_create_node(struct orcad_titleblocksymbol_node, + ORCAD_TYPE_TITLEBLOCKSYMBOL); + + if(0>(offs=orcad_read_symbol_common(rctx, offs, + (struct orcad_symbol_common_node__int*)&node->node))) + { + fprintf(stderr, "Error: Could not read symbol common\n"); + return -1; + } + + read_u16(unknown_0); + read_u16(unknown_1); + + read_u16(num_primitives); + + if(NULL==(node->primitives=(struct orcad_prim**)calloc( + node->num_primitives, sizeof(struct orcad_prim*)))) + { + fprintf(stderr, "Error: Could not allocate memory for primitives\n"); + return -1; + } + + for(i=0;inum_primitives;++i) + { + if(0>(offs=orcad_read_primitive(rctx, offs, &node->primitives[i]))) + { + orcad_error_backtrace__(&node->node, "read primitives"); + return -1; + } + } + + if(0>(offs=orcad_skip_field_32(rctx, offs, 0x00000000))) + { + fprintf(stderr, "Error: Could not skip zero field\n"); + return -1; + } + + read_u16(unknown_2); + read_u16(unknown_3); + + /* symbolpins in a title block? I'm confused */ + read_node_array(symbolpin, orcad_read_symbolpin); + read_node_array(displayprop, orcad_read_symboldisplayprop); + + return offs; +} + +static long orcad_read_symbolgraphic(io_orcad_rctx_t* const rctx, long offs, + struct orcad_node* const parent, struct orcad_node** const out_node) +{ + orcad_uint16_t i; + + orcad_create_node(struct orcad_symbolgraphic_node, + ORCAD_TYPE_SYMBOLGRAPHIC); + + if(0>(offs=orcad_read_symbol_common(rctx, offs, + (struct orcad_symbol_common_node__int*)&node->node))) + { + fprintf(stderr, "Error: Could not read symbol common\n"); + return -1; + } + + read_u16(unknown_0); + read_u16(unknown_1); + + read_u16(num_primitives); + + if(NULL==(node->primitives=(struct orcad_prim**)calloc( + node->num_primitives, sizeof(struct orcad_prim*)))) + { + fprintf(stderr, "Error: Could not allocate memory for primitives\n"); + return -1; + } + + for(i=0;inum_primitives;++i) + { + if(0>(offs=orcad_read_primitive(rctx, offs, &node->primitives[i]))) + { + orcad_error_backtrace__(&node->node, "read primitives"); + return -1; + } + } + + if(0>(offs=orcad_skip_field_32(rctx, offs, 0x00000000))) + { + fprintf(stderr, "Error: Could not skip zero field\n"); + return -1; + } + + read_u16(symbox_x); + read_u16(symbox_y); + + read_node_array(symbolpin, orcad_read_symbolpin); + TODO( + "NOTE: symbolpins can have symboldisplayprops as well, when the user " + "moved the Name or Number in the symbol editor (by default both " + "pin name and pin number positions are implied). If Name (or Number) " + "is moved, then symboldisplayprops are genereted both into " + "symbolgraphic->symbolpin and partinst->pinconnection with a magic " + "name_idx. These names will be evaluated to \"Name\" or \"Number\" " + "depending on the thing was moved. If a symboldisplayprop is found " + "and this magic number/string is matched, the implied coordinates " + "must be overridden by the coordinates and rotation in " + "symboldisplayprop." + ); + + read_node_array(displayprop, orcad_read_symboldisplayprop); + + if(0>(offs=orcad_read_string2(rctx, offs, &node->unk_str0))) + { + fprintf(stderr, "Error: Could not read unk_str0\n"); + return -1; + } + + if(0>(offs=orcad_read_string2(rctx, offs, &node->unk_str1))) + { + fprintf(stderr, "Error: Could not read unk_str1\n"); + return -1; + } + + if(0>(offs=orcad_read_string2(rctx, offs, &node->sym_prefix))) + { + fprintf(stderr, "Error: Could not read sym_prefix\n"); + return -1; + } + + if(0>(offs=orcad_read_string2(rctx, offs, &node->unk_str2))) + { + fprintf(stderr, "Error: Could not read unk_str2\n"); + return -1; + } + + read_u16(flags); + node->pin_names_visible = !!(0x1 & node->flags); + node->pin_names_rotate = !!(0x2 & node->flags); + node->pin_numbers_visible = !(0x4 & node->flags); + + return offs; +} + +static long orcad_read_properties(io_orcad_rctx_t* const rctx, long offs, + struct orcad_node* const parent, struct orcad_node** const out_node) +{ + orcad_uint16_t i; + + orcad_create_node(struct orcad_properties_node, ORCAD_TYPE_PROPERTIES); + + if(0>(offs=orcad_read_symbol_common(rctx, offs, + (struct orcad_symbol_common_node__int*)&node->node))) + { + fprintf(stderr, "Error: Could not read symbol common\n"); + return -1; + } + + read_u16(num_partnames); + + if(NULL==(node->partnames= + (char**)calloc(node->num_partnames, sizeof(char*)))) + { + node->num_partnames = 0; + fprintf(stderr, "Error: Could not allocate memory for partnames\n"); + return -1; + } + + for(i=0;inum_partnames;++i) + { + if(0>(offs=orcad_read_string2(rctx, offs, &node->partnames[i]))) + { + fprintf(stderr, "Error: Could not read partnames[%u]\n", + (unsigned int)i); + return -1; + } + } + + return offs; +} + +static long orcad_read_symbolpinmapping(io_orcad_rctx_t* const rctx, long offs, + struct orcad_node* const parent, struct orcad_node** const out_node) +{ + orcad_create_node(struct orcad_symbolpinmapping_node, + ORCAD_TYPE_SYMBOLPINMAPPING); + + if(0>(offs=orcad_read_symbol_common(rctx, offs, + (struct orcad_symbol_common_node__int*)&node->node))) + { + fprintf(stderr, "Error: Could not read symbol common\n"); + return -1; + } + + if(0>(offs=orcad_read_string2(rctx, offs, &node->sym_prefix))) + { + fprintf(stderr, "Error: Could not read sym_prefix\n"); + return -1; + } + + if(0>(offs=orcad_read_string2(rctx, offs, &node->unk_str0))) + { + fprintf(stderr, "Error: Could not read unk_str0\n"); + return -1; + } + + if(0>(offs=orcad_read_string2(rctx, offs, &node->unk_str1))) + { + fprintf(stderr, "Error: Could not read unk_str1\n"); + return -1; + } + + read_node_array(pinidxmapping, orcad_read_pinidxmapping); + + return offs; +} + +static long orcad_read__symbol(io_orcad_rctx_t* const rctx, long offs, + struct orcad_node* const parent, struct orcad_node** const out_node, + const enum orcad_type type) +{ + orcad_uint16_t i; + + orcad_create_node(struct orcad_globalsymbol_node, type); + + if(0>(offs=orcad_read_symbol_common(rctx, offs, + (struct orcad_symbol_common_node__int*)&node->node))) + { + fprintf(stderr, "Error: Could not read symbol common\n"); + return -1; + } + + read_u16(unknown_0); + read_u16(unknown_1); + + read_u16(num_primitives); + + if(NULL==(node->primitives=(struct orcad_prim**)calloc( + node->num_primitives, sizeof(struct orcad_prim*)))) + { + fprintf(stderr, "Error: Could not allocate memory for primitives\n"); + return -1; + } + + for(i=0;inum_primitives;++i) + { + if(0>(offs=orcad_read_primitive(rctx, offs, &node->primitives[i]))) + { + orcad_error_backtrace__(&node->node, "read primitives"); + return -1; + } + } + + if(0>(offs=orcad_skip_field_32(rctx, offs, 0x00000000))) + { + fprintf(stderr, "Error: Could not skip zero field\n"); + return -1; + } + + read_u16(symbox_x); + read_u16(symbox_y); + + read_node_array(symbolpin, orcad_read_symbolpin); + + read_node_array(displayprop, orcad_read_symboldisplayprop); + + return offs; +} + +static long orcad_read_ercsymbol(io_orcad_rctx_t* const rctx, long offs, + struct orcad_node* const parent, struct orcad_node** const out_node) +{ + orcad_uint16_t i; + + orcad_create_node(struct orcad_ercsymbol_node, + ORCAD_TYPE_ERCSYMBOL); + + if(0>(offs=orcad_read_symbol_common(rctx, offs, + (struct orcad_symbol_common_node__int*)&node->node))) + { + fprintf(stderr, "Error: Could not read symbol common\n"); + return -1; + } + + read_u16(unknown_0); + read_u16(unknown_1); + + read_u16(num_primitives); + + if(NULL==(node->primitives=(struct orcad_prim**)calloc( + node->num_primitives, sizeof(struct orcad_prim*)))) + { + fprintf(stderr, "Error: Could not allocate memory for primitives\n"); + return -1; + } + + for(i=0;inum_primitives;++i) + { + if(0>(offs=orcad_read_primitive(rctx, offs, &node->primitives[i]))) + { + orcad_error_backtrace__(&node->node, "read primitives"); + return -1; + } + } + + read_i16(x1); + read_i16(y1); + read_i16(x2); + read_i16(y2); + read_i16(x); + read_i16(y); + + return offs; +} + +static long orcad_read_xcachesymvariant(io_orcad_rctx_t* const rctx, long offs, + struct orcad_node* const parent, struct orcad_node** const out_node) +{ + orcad_create_xnode(struct orcad_xcachesymvariant_node, + ORCAD_TYPE_X_CACHESYMVARIANT); + + if(0>(offs=orcad_read_string2(rctx, offs, &node->lib_path))) + { + fprintf(stderr, "Error: Could not read lib_path\n"); + return -1; + } + + read_u32(ctime); + read_u32(mtime); + read_u8(type); + + if(0>(offs=orcad_skip_field_8(rctx, offs, 0x00))) + { + fprintf(stderr, "Error: Failed to skip\n"); + return -1; + } + + switch((enum orcad_type)node->type) + { + case ORCAD_TYPE_TITLEBLOCKSYMBOL: + offs = orcad_read_titleblocksymbol(rctx, offs, &node->node, &node->obj); + break; + + case ORCAD_TYPE_SYMBOLGRAPHIC: + offs = orcad_read_symbolgraphic(rctx, offs, &node->node, &node->obj); + break; + + case ORCAD_TYPE_PROPERTIES: + offs = orcad_read_properties(rctx, offs, &node->node, &node->obj); + break; + + case ORCAD_TYPE_SYMBOLPINMAPPING: + offs = orcad_read_symbolpinmapping(rctx, offs, &node->node, &node->obj); + break; + + case ORCAD_TYPE_GLOBALSYMBOL: + case ORCAD_TYPE_OFFPAGECONNSYMBOL: + case ORCAD_TYPE_PORTSYMBOL: + offs = orcad_read__symbol(rctx, offs, &node->node, &node->obj, + (enum orcad_type)node->type); + break; + + case ORCAD_TYPE_ERCSYMBOL: + offs = orcad_read_ercsymbol(rctx, offs, &node->node, &node->obj); + break; + + default: + fprintf(stderr, + "Error: xcachesymvariant: Unhandled type in cache: 0x%x (%s) @ offs 0x%lx\n", + (unsigned int)node->type, orcad_type2str(node->type), offs); + orcad_error_backtrace__(&node->node, NULL); + return -1; + } + + if(NULL!=node->obj) + { + const long end = node->obj->offs + node->obj->size; + + if(end!=offs) + { + fprintf(stderr, "Error: xcachesymvariant: Structure overread or " + "unparsed segments of '%s' remained! start=0x%lx, offs=0x%lx, " + "end=0x%lx\n", orcad_type2str(node->type), node->node.offs, + offs, end); + return -1; + } + } + + return offs; +} + +static long orcad_read_xcachesymbol(io_orcad_rctx_t* const rctx, long offs, + struct orcad_node* const parent, struct orcad_node** const out_node) +{ + orcad_create_xnode(struct orcad_xcachesymbol_node, + ORCAD_TYPE_X_CACHESYMBOL); + + if(0>(offs=orcad_read_string2(rctx, offs, &node->symname))) + { + fprintf(stderr, "Error: Could not read symname\n"); + return -1; + } + + read_node_array(variant, orcad_read_xcachesymvariant); + + return offs; +} + +static long orcad_read_xsymbolgroup(io_orcad_rctx_t* const rctx, long offs, + struct orcad_node* const parent, struct orcad_node** const out_node) +{ + orcad_create_xnode(struct orcad_xsymbolgroup_node, + ORCAD_TYPE_X_SYMBOLGROUP); + + read_node_array(symbol, orcad_read_xcachesymbol); + + return offs; +} + +static long orcad_read_cache__(struct io_orcad_rctx_s* const rctx, long offs, + struct orcad_node** const out_node) +{ + struct orcad_node* const parent = NULL; + + orcad_create_xnode(struct orcad_xcache_node, ORCAD_TYPE_X_CACHE); + + if(0>(offs=orcad_skip_field_16(rctx, offs, 0x0000))) + { + fprintf(stderr, "Error: First 16-bit field is not 0x0000!\n"); + return -1; + } + + /* titleblocks */ + if(0>(offs=orcad_read_xsymbolgroup(rctx, offs, &node->node, + (struct orcad_node**)&node->titleblocks))) + { + fprintf(stderr, "Error: Could not read titleblocks xsymbolgroup\n"); + return -1; + } + + /* symbolgraphics */ + if(0>(offs=orcad_read_xsymbolgroup(rctx, offs, &node->node, + (struct orcad_node**)&node->symbolgraphics))) + { + fprintf(stderr, "Error: Could not read symbolgraphics xsymbolgroup\n"); + return -1; + } + + /* symbolproperties */ + if(0>(offs=orcad_read_xsymbolgroup(rctx, offs, &node->node, + (struct orcad_node**)&node->symbolproperties))) + { + fprintf(stderr, "Error: Could not read symbolproperties xsymbolgroup\n"); + return -1; + } + + /* symbolpinmappings */ + if(0>(offs=orcad_read_xsymbolgroup(rctx, offs, &node->node, + (struct orcad_node**)&node->symbolpinmappings))) + { + fprintf(stderr, "Error: Could not read symbolpinmappings xsymbolgroup\n"); + return -1; + } + + return offs; +} + +struct orcad_node* orcad_read_cache(struct io_orcad_rctx_s* const rctx) +{ + struct orcad_node* res = NULL; + + long offs = orcad_read_cache__(rctx, 0, &res); + + if(0>offs) + { + if(NULL!=res) + { + orcad_free(res); + } + + return NULL; + } + + { + char c; + + if(0 +#include +#include +#include + +static const unsigned char orcad_magic[] = { 0xFF, 0xE4, 0x5C, 0x39 }; + +long orcad_read_header(io_orcad_rctx_t* const rctx, long offs, + struct orcad_header* const hdr) +{ + if(0>(offs=orcad_read_field_u8(rctx, offs, &hdr->type))) + { + fprintf(stderr, "Error: Could not read header type @ 0x%lx\n", + offs); + return -1; + } + + if(0>(offs=orcad_read_field_u32(rctx, offs, &hdr->size))) + { + fprintf(stderr, "Error: Could not read header size field\n"); + return -1; + } + + if(0>(offs=orcad_read_field_u32(rctx, offs, &hdr->unknown))) + { + fprintf(stderr, "Error: Could not read header's unknown field\n"); + return -1; + } + + return offs; +} + +/* find the magic number and validate additional data (size of the last */ +/* header is stored in the 'size' field of predecessor header) */ +/* | TYPE[1] ... MAGIC[4] SOME_LENGTH[4] ... | */ +/* <--------------- hdr_size ----------------> */ +static int orcad_check_last_header(io_orcad_rctx_t* const rctx, long offs, + const orcad_uint32_t hdr_size, struct orcad_namemapping_info* const nmi) +{ + char magic_data[sizeof(orcad_magic)]; + orcad_uint32_t some_len; + + /* expected header end */ + const long end = offs + hdr_size; + + /* the last valid position of the magic number (keep in mind, we always */ + /* have a 4-byte size field *after* the magic number) */ + const long last = offs + hdr_size - sizeof(orcad_magic) - 1; + + const long extra_start = offs + 1; + + /* skip type (1 byte) and a 16-bit number, which is always there */ + /* (2 bytes), but its purpose is not known */ + offs += 3; + + /* fetch initial buffer (read 1 byte less then needed, see loop below) */ + + if(0!=fio_fseek(rctx, offs)) + { + fprintf(stderr, "Error: Seek to magic (offs 0x%lx) failed\n", offs); + return -1; + } + + if((sizeof(orcad_magic)-1)!=fio_fread(rctx, magic_data+1, + sizeof(orcad_magic)-1)) + { + return -1; + } + + offs += sizeof(orcad_magic)-1; + + while(offs<=last) + { + if(0!=fio_fseek(rctx, offs)) + { + fprintf(stderr, "Error: Seek to magic (offs 0x%lx) failed\n", + offs); + return -1; + } + + /* shift buffer */ + memmove(magic_data, magic_data+1, sizeof(orcad_magic)-1); + + /* read missing byte */ + if(1!=fio_fread(rctx, &magic_data[sizeof(orcad_magic)-1], 1)) + { + return -1; + } + + ++offs; + + if(0==memcmp(magic_data, orcad_magic, sizeof(orcad_magic))) + { + if(0!=fio_fseek(rctx, offs)) + { + fprintf(stderr, "Error: Seek to magic length info " + "(offs 0x%lx) failed\n", offs); + return -1; + } + + if(0<=orcad_read_field_u32(rctx, offs, &some_len) && + end==(offs+4+some_len)) + { + nmi->offs = extra_start; + nmi->size = (offs - sizeof(orcad_magic)) - extra_start; + return 1; + } + } + } + + return 0; +} + +/* Parse header or headers. Returns file offset after the header(s), and */ +/* returns the type and the remaining length in 'out_hdr'. */ +long orcad_parse_header(io_orcad_rctx_t* const rctx, long offs, + struct orcad_header* const out_hdr, + struct orcad_namemapping_info* const nmi) +{ + struct orcad_header hdr; + int extra_headers; + long save_offs1; /* save offset after primary header */ + long save_offsN; /* save offset after the N-th header */ + int res; + + memset(nmi, 0, sizeof(*nmi)); + + if(0>(offs=orcad_read_header(rctx, offs, out_hdr))) + { + fprintf(stderr, "Error: Could not read object primary header\n"); + return -1; + } + + /* [pos]: after the primary header */ + + save_offs1 = offs; + + if(sizeof(hdr.type)!=fio_fread(rctx, (char*)&hdr.type, sizeof(hdr.type))) + { + /* probably a huge problem (way too early EOF), but delegate the */ + /* problem to the caller */ + if(0!=fio_fseek(rctx, save_offs1)) + { + fprintf(stderr, "Error: Seek to payload (offs %ld) failed\n", + save_offs1); + return -1; + } + + return save_offs1; + } + + if(hdr.type!=out_hdr->type) + { + /* we have only the primary header */ + goto primary_header_only; + } + + save_offsN = save_offs1; + + for(extra_headers=5;0(offs=orcad_read_header(rctx, offs, &hdr))) + { + fprintf(stderr, "Error: Could not read N-th header\n"); + return -1; + } + + /* [pos]: after the N-th header */ + /* check type; is there a next header? */ + + save_offsN = offs; + + if(sizeof(hdr.type)!=fio_fread(rctx, (char*)&hdr.type, + sizeof(hdr.type)) || hdr.type!=out_hdr->type) + { + goto primary_header_only; + } + + if(0>(res=orcad_check_last_header(rctx, offs, hdr.size, nmi))) + { + return -1; + } + + if(res) + { + offs += hdr.size; + + if(0!=fio_fseek(rctx, offs)) + { + fprintf(stderr, "Error: Seek to payload (offs %ld) failed\n", + offs); + return -1; + } + + out_hdr->size -= (offs - save_offs1); + + return offs; + } + } + +primary_header_only: + if(0!=fio_fseek(rctx, save_offs1)) + { + fprintf(stderr, "Error: Seek after primary header (offs %ld) failed\n", + save_offs1); + return -1; + } + + return save_offs1; +} + +long orcad_peek_field_u8(io_orcad_rctx_t* const rctx, long offs, + orcad_uint8_t* const out) +{ + unsigned char raw[1]; + + if(sizeof(raw)!=fio_fread(rctx, (char*)&raw[0], sizeof(raw))) + { + fprintf(stderr, "Error: Could not peek 8-bit field\n"); + return -1; + } + + *out = raw[0]; + + if(0!=fio_fseek(rctx, offs)) + { + fprintf(stderr, "Error: Could not seek back to 0x%lx in peek\n", offs); + return -1; + } + + return offs; +} + +long orcad_read_field_u8(io_orcad_rctx_t* const rctx, long offs, + orcad_uint8_t* const out) +{ + unsigned char raw[1]; + + if(sizeof(raw)!=fio_fread(rctx, (char*)&raw[0], sizeof(raw))) + { + fprintf(stderr, "Error: Could not read 8-bit field\n"); + return -1; + } + + *out = raw[0]; + offs += sizeof(raw); + + return offs; +} + +long orcad_read_field_u16(io_orcad_rctx_t* const rctx, long offs, + orcad_uint16_t* const out) +{ + unsigned char raw[2]; + + if(sizeof(raw)!=fio_fread(rctx, (char*)&raw[0], sizeof(raw))) + { + fprintf(stderr, "Error: Could not read 16-bit field\n"); + return -1; + } + + offs += sizeof(raw); + *out = ((orcad_uint16_t)raw[0]) | (((orcad_uint16_t)raw[1]) << 8); + + return offs; +} + +long orcad_read_field_i16(io_orcad_rctx_t* const rctx, long offs, + orcad_int16_t* const out) +{ + orcad_int16_t stmp; + orcad_uint16_t tmp; + + if(0>(offs=orcad_read_field_u16(rctx, offs, &tmp))) + { + return -1; + } + + stmp = 0; + + if(0x8000 & tmp) + { + stmp = ~stmp; + + /* shift left by 8 bits twice, to elude warning */ + stmp <<= 8; + } + + *out = (stmp << 8) | tmp; + + return offs; +} + +long orcad_read_field_u32(io_orcad_rctx_t* const rctx, long offs, + orcad_uint32_t* const out) +{ + unsigned char raw[4]; + + if(sizeof(raw)!=fio_fread(rctx, (char*)&raw[0], sizeof(raw))) + { + fprintf(stderr, "Error: Could not read 32-bit field\n"); + return -1; + } + + offs += sizeof(raw); + *out = ((orcad_uint32_t)raw[0]) | (((orcad_uint32_t)raw[1]) << 8) | + (((orcad_uint32_t)raw[2]) << 16) | (((orcad_uint32_t)raw[3]) << 24); + + return offs; +} + +long orcad_read_field_i32(io_orcad_rctx_t* const rctx, long offs, + orcad_int32_t* const out) +{ + orcad_int32_t stmp; + orcad_uint32_t tmp; + + if(0>(offs=orcad_read_field_u32(rctx, offs, &tmp))) + { + return -1; + } + + stmp = 0; + + if(0x80000000 & tmp) + { + stmp = ~stmp; + + /* shift left by 16 bits twice, to elude warning */ + stmp <<= 16; + } + + *out = (stmp << 16) | tmp; + + return offs; +} + +long orcad_skip_field_8(io_orcad_rctx_t* const rctx, long offs, + const orcad_uint8_t expected) +{ + orcad_uint8_t tmp; + + if(0>(offs=orcad_read_field_u8(rctx, offs, &tmp))) + { + return -1; + } + + if(expected!=tmp) + { + fprintf(stderr, "Error: Could not skip 8-bit field at 0x%lx: " + "expected 0x%x, but got 0x%x!\n", (offs-sizeof(tmp)), + (unsigned int)expected, (unsigned int)tmp); + return -1; + } + + return offs; +} + +long orcad_skip_field_16(io_orcad_rctx_t* const rctx, long offs, + const orcad_uint16_t expected) +{ + orcad_uint16_t tmp; + + if(0>(offs=orcad_read_field_u16(rctx, offs, &tmp))) + { + return -1; + } + + if(expected!=tmp) + { + fprintf(stderr, "Error: Could not skip 16-bit field at 0x%lx: " + "expected 0x%x, but got 0x%x!\n", (offs-sizeof(tmp)), + (unsigned int)expected, (unsigned int)tmp); + return -1; + } + + return offs; +} + +long orcad_skip_field_32(io_orcad_rctx_t* const rctx, long offs, + const orcad_uint32_t expected) +{ + orcad_uint32_t tmp; + + if(0>(offs=orcad_read_field_u32(rctx, offs, &tmp))) + { + return -1; + } + + if(expected!=tmp) + { + fprintf(stderr, "Error: Could not skip 32-bit field at 0x%lx: " + "expected 0x%lx, but got 0x%lx!\n", (offs-sizeof(tmp)), + (unsigned long)expected, (unsigned long)tmp); + return -1; + } + + return offs; +} + +long orcad_read_string(io_orcad_rctx_t* const rctx, long offs, char** buf, + orcad_uint16_t len) +{ + char* const str = (char*)malloc(len+1); + + *buf = str; + + if(NULL==str) + { + fprintf(stderr, "Error: Could not allocate string\n"); + return -1; + } + + if((len+1)!=fio_fread(rctx, str, len+1)) + { + fprintf(stderr, "Error: Unexpected EOF while reading string\n"); + return -1; + } + + if(0!=str[len]) + { + fprintf(stderr, "Error: String is not zero-terminated\n"); + return -1; + } + + return offs + len+1; +} + +/* read zero-terminated string which is prefixed with a 16-bit length field */ +long orcad_read_string2(io_orcad_rctx_t* const rctx, long offs, char** buf) +{ + orcad_uint16_t len; + + if(0>(offs=orcad_read_field_u16(rctx, offs, &len))) + { + fprintf(stderr, "Error: Could not read string length field\n"); + return -1; + } + + return orcad_read_string(rctx, offs, buf, len); +} + +long orcad_skip_magic(io_orcad_rctx_t* const rctx, long offs) +{ + char data[sizeof(orcad_magic)+4]; + char* ptr; + + if(sizeof(data)!=fio_fread(rctx, data, sizeof(data))) + { + fprintf(stderr, "Error: Could not read magic data to skip\n"); + return -1; + } + + if(0!=memcmp(data, orcad_magic, sizeof(orcad_magic))) + { + if(0!=fio_fseek(rctx, offs)) + { + fprintf(stderr, "Error: Could not seek back to 0x%lx\n", offs); + return -1; + } + + return offs; + } + + ptr = data + sizeof(orcad_magic); + + if(0!=ptr[0] || 0!=ptr[1] || 0!=ptr[2] || 0!=ptr[3]) + { + fprintf(stderr, "Error: Word after magic is not zero\n"); + return -1; + } + + return offs + sizeof(data); +} + +int orcad_is_end_or_magic(io_orcad_rctx_t* const rctx, long offs, long end) +{ + char data[sizeof(orcad_magic)]; + size_t n; + + if(offs==end) + { + return 1; + } + + n = fio_fread(rctx, data, sizeof(data)); + fio_fseek(rctx, offs); + + return sizeof(data)==n && + 0==memcmp(data, orcad_magic, sizeof(orcad_magic)); +} + +const char* orcad_type2str(const enum orcad_type type) +{ + switch(type) + { + case ORCAD_TYPE_INLINEPAGEOBJECT: return "InlinePageObject"; + case ORCAD_TYPE_PROPERTIES: return "Properties"; + case ORCAD_TYPE_PAGE: return "Page"; + case ORCAD_TYPE_PARTINST: return "PartInst"; + case ORCAD_TYPE_PINCONNECTION: return "PinConnection"; + case ORCAD_TYPE_WIRE: return "Wire"; + case ORCAD_TYPE_PORT: return "Port"; + case ORCAD_TYPE_SYMBOLGRAPHIC: return "SymbolGraphic"; + case ORCAD_TYPE_SYMBOLPIN: return "SymbolPin"; + case ORCAD_TYPE_SYMBOLPINMAPPING: return "SymbolPinMapping"; + case ORCAD_TYPE_PINIDXMAPPING: return "PinIdxMapping"; + case ORCAD_TYPE_GLOBALSYMBOL: return "GlobalSymbol"; + case ORCAD_TYPE_PORTSYMBOL: return "PortSymbol"; + case ORCAD_TYPE_OFFPAGECONNSYMBOL: return "OffPageConnSymbol"; + case ORCAD_TYPE_GLOBAL: return "Global"; + case ORCAD_TYPE_OFFPAGECONN: return "OffPageConn"; + case ORCAD_TYPE_SYMBOLDISPLAYPROP: return "SymbolDisplayProp"; + case ORCAD_TYPE_NETPROP: return "NetProp"; + case ORCAD_TYPE_GRAPHICBOXINST: return "GraphicBoxInst"; + case ORCAD_TYPE_GRAPHICLINEINST: return "GraphicLineInst"; + case ORCAD_TYPE_GRAPHICARCINST: return "GraphicArcInst"; + case ORCAD_TYPE_GRAPHICELLIPSEINST: return "GraphicEllipseInst"; + case ORCAD_TYPE_GRAPHICPOLYGONINST: return "GraphicPolygonInst"; + case ORCAD_TYPE_GRAPHICTEXTINST: return "GraphicTextInst"; + case ORCAD_TYPE_TITLEBLOCKSYMBOL: return "TitleBlockSymbol"; + case ORCAD_TYPE_TITLEBLOCK: return "TitleBlock"; + case ORCAD_TYPE_ERCSYMBOL: return "ERCSymbol"; + case ORCAD_TYPE_BOOKMARKSYMBOL: return "BookMarkSymbol"; + case ORCAD_TYPE_ERCSYMBOLINST: return "ERCSymbolInst"; + case ORCAD_TYPE_BOOKMARKSYMBOLINST: return "BookMarkSymbolInst"; + case ORCAD_TYPE_GRAPHICBEZIERINST: return "GraphicBezierInst"; + case ORCAD_TYPE_X_NETALIAS: return "X-NetAlias"; + case ORCAD_TYPE_X_CACHE: return "X-Cache"; + case ORCAD_TYPE_X_SYMBOLGROUP: return "X-SymbolGroup"; + case ORCAD_TYPE_X_CACHESYMBOL: return "X-CacheSymbol"; + case ORCAD_TYPE_X_CACHESYMVARIANT: return "X-CacheSymVariant"; + case ORCAD_TYPE_X_LIBRARY: return "X-Library"; + + default: break; + } + + return "?"; +} + +struct orcad_node* orcad_create_node__(io_orcad_rctx_t* const rctx, + long* const p_offs, const size_t struct_size, const enum orcad_type type, + struct orcad_node* const parent) +{ + struct orcad_header hdr; + struct orcad_namemapping_info nmi; + + if(0>((*p_offs)=orcad_parse_header(rctx, *p_offs, &hdr, &nmi))) + { + fprintf(stderr, "Error: Could not read header of %s\n", + orcad_type2str(type)); + return NULL; + } + + return orcad_create_node_from__(rctx, *p_offs, struct_size, type, &hdr, + parent, &nmi); +} + +static int read_namemappings(io_orcad_rctx_t* const rctx, + const long orig_offs, struct orcad_node* const node) +{ + long offs = node->nmi.offs; + + orcad_uint16_t i; + orcad_uint16_t num; + struct orcad_namemapping* map; + + if(2>=node->nmi.size || 0==node->nmi.offs) + { + /* do nothing, just return */ + return 0; + } + + if(0!=fio_fseek(rctx, node->nmi.offs)) + { + fprintf(stderr, "Error: Could not seek to namemappings (0x%lx)\n", + node->nmi.offs); + return -1; + } + + vread_u16(num); + + if(NULL==(map=node->namemappings=(struct orcad_namemapping*)calloc(num, + sizeof(struct orcad_namemapping)))) + { + fprintf(stderr, "Error: Could not allocate memory for namemappings\n"); + return -1; + } + + for(i=0;inum_namemappings = num; + + /* seek back where we were */ + + if(0!=fio_fseek(rctx, orig_offs)) + { + fprintf(stderr, "Error: Could not seek to original offset (0x%lx)\n", + orig_offs); + return -1; + } + + return 0; +} + +struct orcad_node* orcad_create_node_from__(io_orcad_rctx_t* const rctx, + const long offs, const size_t struct_size, const enum orcad_type type, + const struct orcad_header* const p_hdr, struct orcad_node* const parent, + struct orcad_namemapping_info* const nmi) +{ + struct orcad_node* node; + + if(type!=p_hdr->type) + { + fprintf(stderr, + "Error: Object at 0x%lx expected to be 0x%x, but got 0x%x\n", + offs, (unsigned int)type, (unsigned int)p_hdr->type); + return NULL; + } + + if(NULL==(node=calloc(1, struct_size))) + { + fprintf(stderr, "Error: Could not allocate node memory for %s\n", + orcad_type2str(type)); + return NULL; + } + + node->type = type; + node->offs = offs; + node->size = p_hdr->size; + node->parent = parent; + + memcpy(&node->nmi, nmi, sizeof(*nmi)); + + if(0!=read_namemappings(rctx, offs, node)) + { + free(node); + return NULL; + } + + return node; +} + +void orcad_error_backtrace__(struct orcad_node* node, const char* const msg) +{ + if(NULL!=msg) + { + fprintf(stderr, "Error: Could not %s\n", msg); + } + + fprintf(stderr, "Backtrace:\n"); + + while(NULL!=node) + { + fprintf(stderr, " %s @0x%lx\n", orcad_type2str(node->type), + node->offs); + node = node->parent; + } +} + +long orcad_read_nodes__(io_orcad_rctx_t* const rctx, long offs, + struct orcad_node* const parent, struct orcad_node*** const p_array, + size_t count, long (*const read_object)(io_orcad_rctx_t* const rctx, + long offs, struct orcad_node* const parent, + struct orcad_node** const out_node)) +{ + struct orcad_node** array = + (struct orcad_node**)calloc(count, sizeof(struct orcad_node*)); + + if(NULL==array) + { + return -1; + } + + *p_array = array; + + while(0<(count--)) + { + if(0>(offs=read_object(rctx, offs, parent, array))) + { + return -1; + } + + ++array; + } + + return offs; +} + +long orcad_skip_objects(io_orcad_rctx_t* const rctx, long offs, int count) +{ + while(0<(count--)) + { + if(0>(offs=orcad_skip_object(rctx, offs))) + { + return -1; + } + } + + return offs; +} + +long orcad_skip_object(io_orcad_rctx_t* const rctx, long offs) +{ + /* first header contains the length we need */ + + struct orcad_header hdr; + + if(0>(offs=orcad_read_header(rctx, offs, &hdr))) + { + fprintf(stderr, "Error: Could not read object header\n"); + return -1; + } + + offs += hdr.size; + + if(0!=fio_fseek(rctx, offs)) + { + fprintf(stderr, "Error: Seek after object (offs %ld) failed\n", + offs); + return -1; + } + + return offs; +} + +long orcad_read_inlinepageobject(io_orcad_rctx_t* const rctx, long offs, + struct orcad_node* const parent, struct orcad_node** const out_node) +{ + long end; + orcad_uint16_t i; + + orcad_create_node(struct orcad_inlinepageobject_node, + ORCAD_TYPE_INLINEPAGEOBJECT); + + end = offs + node->node.size; + + if(0>(offs=orcad_read_string2(rctx, offs, &node->name))) + { + fprintf(stderr, "Error: Could not read name\n"); + return -1; + } + + if(0>(offs=orcad_read_string2(rctx, offs, &node->unk_str))) + { + fprintf(stderr, "Error: Could not read name\n"); + return -1; + } + + read_u32(color); + read_u16(num_primitives); + + if(NULL==(node->primitives=(struct orcad_prim**)calloc( + node->num_primitives, sizeof(struct orcad_prim*)))) + { + fprintf(stderr, "Error: Could not allocate memory for primitives\n"); + return -1; + } + + /* NOTE: there are some additional bytes here and there, which are not */ + /* included in the size fields, so it could be misunderstood! */ + + for(i=0;inum_primitives;++i) + { + if(0>(offs=orcad_read_primitive(rctx, offs, &node->primitives[i]))) + { + orcad_error_backtrace__(&node->node, "read primitives"); + return -1; + } + } + + if(0!=fio_fseek(rctx, end)) + { + fprintf(stderr, "Error: Seek after inline_object (offs %ld) failed\n", + end); + return -1; + } + + return end; +} + +long orcad_read_symboldisplayprop(io_orcad_rctx_t* const rctx, long offs, + struct orcad_node* const parent, struct orcad_node** const out_node) +{ + orcad_create_node(struct orcad_symboldisplayprop_node, + ORCAD_TYPE_SYMBOLDISPLAYPROP); + + read_u32(name_idx); + read_i16(x); + read_i16(y); + read_u16(font_id); + + node->rotation = node->font_id >> 14; + node->font_id &= 0x3ffff; + + read_u8(color); + read_u8(unknown_0); + read_u8(format); + read_u8(unknown_2); + + return offs; +} + +long orcad_read_pagesettings(io_orcad_rctx_t* const rctx, long offs, + struct orcad_pagesettings* const settings) +{ + vread_u32(settings->ctime); + vread_u32(settings->mtime); + vread_u32(settings->unknown_0); + vread_u32(settings->unknown_1); + vread_u32(settings->unknown_2); + vread_u32(settings->unknown_3); + vread_u32(settings->width); + vread_u32(settings->height); + vread_u32(settings->pin_to_pin); + vread_u16(settings->unknown_4); + vread_u16(settings->horiz_count); + vread_u16(settings->vert_count); + vread_u16(settings->unknown_5); + vread_u32(settings->horiz_width); + vread_u32(settings->vert_width); + vread_u32(settings->unknown_6); + vread_u32(settings->unknown_7); + vread_u32(settings->unknown_8); + vread_u32(settings->unknown_9); + vread_u32(settings->unknown_10); + vread_u32(settings->unknown_11); + vread_u32(settings->unknown_12); + vread_u32(settings->unknown_13); + vread_u32(settings->unknown_14); + vread_u32(settings->unknown_15); + vread_u32(settings->unknown_16); + vread_u32(settings->unknown_17); + vread_u32(settings->horiz_char); + vread_u32(settings->unknown_18); + vread_u32(settings->horiz_ascending); + vread_u32(settings->vert_char); + vread_u32(settings->unknown_19); + vread_u32(settings->vert_ascending); + vread_u32(settings->is_metric); + vread_u32(settings->border_displayed); + vread_u32(settings->border_printed); + vread_u32(settings->gridref_displayed); + vread_u32(settings->gridref_printed); + vread_u32(settings->titleblock_displayed); + vread_u32(settings->titleblock_printed); + vread_u32(settings->ansi_grid_refs); + + return offs; +} Property changes on: tags/1.0.5/src/plugins/io_orcad/read_common.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Index: tags/1.0.5/src/plugins/io_orcad/read_common.h =================================================================== --- tags/1.0.5/src/plugins/io_orcad/read_common.h (nonexistent) +++ tags/1.0.5/src/plugins/io_orcad/read_common.h (revision 10414) @@ -0,0 +1,219 @@ +#include "read_parse.h" + +struct orcad_header +{ + orcad_uint8_t type; + orcad_uint32_t size; + orcad_uint32_t unknown; +}; + +long orcad_read_header(io_orcad_rctx_t* const rctx, long offs, + struct orcad_header* const hdr); + +/* Parse header or headers. Returns file offset after the header(s), and */ +/* returns the type and the remaining length in 'out_hdr'. */ +long orcad_parse_header(io_orcad_rctx_t* const rctx, long offs, + struct orcad_header* const out_hdr, + struct orcad_namemapping_info* const nmi); + +long orcad_peek_field_u8(io_orcad_rctx_t* const rctx, long offs, + orcad_uint8_t* const out); + +long orcad_read_field_u8(io_orcad_rctx_t* const rctx, long offs, + orcad_uint8_t* const out); + +long orcad_read_field_i16(io_orcad_rctx_t* const rctx, long offs, + orcad_int16_t* const out); +long orcad_read_field_u16(io_orcad_rctx_t* const rctx, long offs, + orcad_uint16_t* const out); + +long orcad_read_field_i32(io_orcad_rctx_t* const rctx, long offs, + orcad_int32_t* const out); +long orcad_read_field_u32(io_orcad_rctx_t* const rctx, long offs, + orcad_uint32_t* const out); + +long orcad_skip_field_8(io_orcad_rctx_t* const rctx, long offs, + const orcad_uint8_t expected); + +long orcad_skip_field_16(io_orcad_rctx_t* const rctx, long offs, + const orcad_uint16_t expected); + +long orcad_skip_field_32(io_orcad_rctx_t* const rctx, long offs, + const orcad_uint32_t expected); + +/* read zero-terminated string with the specified length */ +long orcad_read_string(io_orcad_rctx_t* const rctx, long offs, char** buf, + orcad_uint16_t len); + +/* read zero-terminated string which is prefixed with a 16-bit length field */ +long orcad_read_string2(io_orcad_rctx_t* const rctx, long offs, char** buf); + +const char* orcad_type2str(const enum orcad_type type); + +struct orcad_node* orcad_create_node__(io_orcad_rctx_t* const rctx, + long* const p_offs, const size_t struct_size, const enum orcad_type type, + struct orcad_node* const parent); + +struct orcad_node* orcad_create_node_from__(io_orcad_rctx_t* const rctx, + const long offs, const size_t struct_size, const enum orcad_type type, + const struct orcad_header* const p_hdr, struct orcad_node* const parent, + struct orcad_namemapping_info* const nmi); + +void orcad_error_backtrace__(struct orcad_node* node, const char* const msg); + +#define orcad_create_node(_type_name_, _type_) \ + _type_name_* const node = (_type_name_*)orcad_create_node__( \ + rctx, &offs, sizeof(_type_name_), _type_, parent); \ + if(NULL==node) \ + { \ + return -1; \ + } \ + else \ + { \ + *out_node = &node->node; \ + } + +#define orcad_create_node_from(_type_name_, _type_, _hdr_, _nmi_) \ + _type_name_* const node = (_type_name_*)orcad_create_node_from__( \ + rctx, offs, sizeof(_type_name_), _type_, _hdr_, parent, _nmi_); \ + if(NULL==node) \ + { \ + return -1; \ + } \ + else \ + { \ + *out_node = &node->node; \ + } + +#define orcad_create_xnode(_typename_, _type_) \ + _typename_* const node = (_typename_*)calloc(1, sizeof(_typename_)); \ + \ + if(NULL==node) \ + { \ + fprintf(stderr, "Error: Could not allocate memory for %s\n", \ + orcad_type2str(_type_)); \ + return -1; \ + } \ + \ + do \ + { \ + node->node.type = (_type_); \ + node->node.offs = offs; \ + node->node.size = 0; /* dunno, fill later? */ \ + node->node.parent = parent; \ + \ + *out_node = &node->node; \ + } \ + while(0) + +#define read_u8(field) \ + if(0>(offs=orcad_read_field_u8(rctx, offs, &node->field))) \ + { \ + orcad_error_backtrace__(&node->node, "read '" #field "'"); \ + return -1; \ + } + +#define read_i16(field) \ + if(0>(offs=orcad_read_field_i16(rctx, offs, &node->field))) \ + { \ + orcad_error_backtrace__(&node->node, "read '" #field "'"); \ + return -1; \ + } + +#define read_u16(field) \ + if(0>(offs=orcad_read_field_u16(rctx, offs, &node->field))) \ + { \ + orcad_error_backtrace__(&node->node, "read '" #field "'"); \ + return -1; \ + } + +#define read_i32(field) \ + if(0>(offs=orcad_read_field_i32(rctx, offs, &node->field))) \ + { \ + orcad_error_backtrace__(&node->node, "read '" #field "'"); \ + return -1; \ + } + +#define read_u32(field) \ + if(0>(offs=orcad_read_field_u32(rctx, offs, &node->field))) \ + { \ + orcad_error_backtrace__(&node->node, "read '" #field "'"); \ + return -1; \ + } + +#define vread_u8(var) \ + if(0>(offs=orcad_read_field_u8(rctx, offs, &(var)))) \ + { \ + fprintf(stderr, "Error: Could not read '%s'\n", #var); \ + return -1; \ + } + +#define vread_i16(var) \ + if(0>(offs=orcad_read_field_i16(rctx, offs, &(var)))) \ + { \ + fprintf(stderr, "Error: Could not read '%s'\n", #var); \ + return -1; \ + } + +#define vread_u16(var) \ + if(0>(offs=orcad_read_field_u16(rctx, offs, &(var)))) \ + { \ + fprintf(stderr, "Error: Could not read '%s'\n", #var); \ + return -1; \ + } + +#define vread_i32(var) \ + if(0>(offs=orcad_read_field_i32(rctx, offs, &(var)))) \ + { \ + fprintf(stderr, "Error: Could not read '%s'\n", #var); \ + return -1; \ + } + +#define vread_u32(var) \ + if(0>(offs=orcad_read_field_u32(rctx, offs, &(var)))) \ + { \ + fprintf(stderr, "Error: Could not read '%s'\n", #var); \ + return -1; \ + } + +long orcad_read_nodes__(io_orcad_rctx_t* const rctx, long offs, + struct orcad_node* const parent, struct orcad_node*** const p_array, + size_t count, long (*const read_object)(io_orcad_rctx_t* const rctx, + long offs, struct orcad_node* const parent, + struct orcad_node** const out_node)); + +#define read_node_array(child_name, child_read_func) \ + do \ + { \ + read_u16(num_ ## child_name ## s); \ + \ + if(0>(offs=orcad_read_nodes__(rctx, offs, &node->node, \ + (struct orcad_node***)&node->child_name ## s, \ + node->num_ ## child_name ## s, child_read_func))) \ + { \ + orcad_error_backtrace__(&node->node, "read '" #child_name "s'"); \ + return -1; \ + } \ + } \ + while(0) + +long orcad_skip_object(io_orcad_rctx_t* const rctx, long offs); +long orcad_skip_objects(io_orcad_rctx_t* const rctx, long offs, int count); + +long orcad_read_primitive(io_orcad_rctx_t* const rctx, long offs, + struct orcad_prim** const out_prim); +void orcad_free_primitive(struct orcad_prim* const prim); + +long orcad_read_inlinepageobject(io_orcad_rctx_t* const rctx, long offs, + struct orcad_node* const parent, struct orcad_node** const out_node); +long orcad_read_symboldisplayprop(io_orcad_rctx_t* const rctx, long offs, + struct orcad_node* const parent, struct orcad_node** const out_node); + +long orcad_read_pagesettings(io_orcad_rctx_t* const rctx, long offs, + struct orcad_pagesettings* const settings); + +long orcad_skip_magic(io_orcad_rctx_t* const rctx, long offs); + +/* tests whether we reached the expected end; or we are at the magic number */ +/* (file position should be at 'offs', and it will be restored) */ +int orcad_is_end_or_magic(io_orcad_rctx_t* const rctx, long offs, long end); Property changes on: tags/1.0.5/src/plugins/io_orcad/read_common.h ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Index: tags/1.0.5/src/plugins/io_orcad/read_dump.c =================================================================== --- tags/1.0.5/src/plugins/io_orcad/read_dump.c (nonexistent) +++ tags/1.0.5/src/plugins/io_orcad/read_dump.c (revision 10414) @@ -0,0 +1,1296 @@ +#ifdef ORCAD_TESTER +# include "tester/read_fio.h" +#else +# include "read_fio.h" +#endif + +#include "read_common.h" +#include +#include +#include +#include + +static void indent_impl(FILE* const out, int indent) +{ + while(0<(indent--)) + { + fputs(" ", out); + } +} + +#define indent_printf \ + indent_impl(stdout, indent), printf + +#define indent_u(field) \ + indent_printf("%s: %lu\n", #field, (unsigned long)node->field) + +#define indent_i(field) \ + indent_printf("%s: %li\n", #field, (long)node->field) + +#define indent_x(field) \ + indent_printf("%s: 0x%lx\n", #field, (unsigned long)node->field) + +#define indent_s(field) \ + indent_printf("%s: \"%s\"\n", #field, node->field) + +#define dump_node_array(tag) \ + do \ + { \ + indent_u(num_##tag##s); \ + orcad_dump_node_array((struct orcad_node**)node->tag##s, \ + node->num_##tag##s, indent); \ + } \ + while(0) + +static void orcad_dump_node(struct orcad_node* const node, int indent); +static void orcad_dump_prim(struct orcad_prim* const prim, int indent); + +static void orcad_dump_node_array(struct orcad_node** array, size_t count, + int indent) +{ + while(0<(count--)) + { + orcad_dump_node(*array++, indent); + } +} + +static void orcad_dump_node_common(struct orcad_node* const node, int indent) +{ + orcad_uint16_t i; + + indent_printf("num_namemappings: %u\n", + (unsigned int)node->num_namemappings); + + for(i=0;inum_namemappings;++i) + { + indent_printf("namemappings[%u]: %u -> %u\n", (unsigned int)i, + (unsigned int)node->namemappings[i].name_idx, + (unsigned int)node->namemappings[i].value_idx); + } +} + +static void orcad_dump_text_prim(struct orcad_text_prim* const node, + int indent) +{ + indent_printf("begin text\n"); + ++indent; + + indent_i(x); + indent_i(y); + indent_i(x1); + indent_i(y1); + indent_i(x2); + indent_i(y2); + indent_u(font_id); + indent_u(unknown_0); + indent_s(text); + + --indent; + indent_printf("end text\n"); +} + +static void orcad_dump_line_prim(struct orcad_line_prim* const node, + int indent) +{ + indent_printf("begin line\n"); + ++indent; + + indent_i(x1); + indent_i(y1); + indent_i(x2); + indent_i(y2); + + if(node->have_line_style) + { + indent_u(line_style); + indent_u(line_width); + } + + --indent; + indent_printf("end line\n"); +} + +static void orcad_dump_rect_prim(struct orcad_rect_prim* const node, + int indent) +{ + indent_printf("begin rect\n"); + ++indent; + + indent_i(x1); + indent_i(y1); + indent_i(x2); + indent_i(y2); + + if(node->have_line_style) + { + indent_u(line_style); + indent_u(line_width); + } + + if(node->have_fill_style) + { + indent_u(fill_style); + indent_u(hatch_style); + } + + --indent; + indent_printf("end rect\n"); +} + +static void orcad_dump_ellipse_prim(struct orcad_ellipse_prim* const node, + int indent) +{ + indent_printf("begin ellipse\n"); + ++indent; + + indent_i(x1); + indent_i(y1); + indent_i(x2); + indent_i(y2); + + if(node->have_line_style) + { + indent_u(line_style); + indent_u(line_width); + } + + if(node->have_fill_style) + { + indent_u(fill_style); + indent_u(hatch_style); + } + + --indent; + indent_printf("end ellipse\n"); +} + +static void orcad_dump_arc_prim(struct orcad_arc_prim* const node, int indent) +{ + indent_printf("begin arc\n"); + ++indent; + + indent_i(x1); + indent_i(y1); + indent_i(x2); + indent_i(y2); + indent_i(start_x); + indent_i(start_y); + indent_i(end_x); + indent_i(end_y); + + if(node->have_line_style) + { + indent_u(line_style); + indent_u(line_width); + } + + --indent; + indent_printf("end arc\n"); +} + +static void orcad_dump_polygon_prim(struct orcad_polygon_prim* const node, + int indent) +{ + orcad_uint32_t i; + + indent_printf("begin polygon\n"); + ++indent; + + if(node->have_line_style) + { + indent_u(line_style); + indent_u(line_width); + } + + if(node->have_fill_style) + { + indent_u(fill_style); + indent_u(hatch_style); + } + + indent_u(num_points); + + for(i=0;inum_points;++i) + { + indent_printf("point[%lu]: {%li, %li}\n", (unsigned long)i, + (long)node->points[i].x, + (long)node->points[i].y); + } + + --indent; + indent_printf("end polygon\n"); +} + +static void orcad_dump_polyline_prim(struct orcad_polyline_prim* const node, + int indent) +{ + orcad_uint32_t i; + + indent_printf("begin polyline\n"); + ++indent; + + if(node->have_line_style) + { + indent_u(line_style); + indent_u(line_width); + } + + indent_u(num_points); + + for(i=0;inum_points;++i) + { + indent_printf("point[%lu]: {%li, %li}\n", (unsigned long)i, + (long)node->points[i].x, + (long)node->points[i].y); + } + + --indent; + indent_printf("end polyline\n"); +} + +static void orcad_dump_bezier_prim(struct orcad_bezier_prim* const node, + int indent) +{ + orcad_uint32_t i; + + indent_printf("begin bezier\n"); + ++indent; + + if(node->have_line_style) + { + indent_u(line_style); + indent_u(line_width); + } + + indent_u(num_segments); + + for(i=0;inum_segments;++i) + { + struct orcad_bsegment* const seg = &node->segments[i]; + + indent_printf( + "segment[%lu]: {%li, %li}, {%li, %li}, {%li, %li}, {%li, %li}\n", + (unsigned long)i, + (long)seg->p1.x, (long)seg->p1.y, + (long)seg->p2.x, (long)seg->p2.y, + (long)seg->p3.x, (long)seg->p3.y, + (long)seg->p4.x, (long)seg->p4.y); + } + + --indent; + indent_printf("end bezier\n"); +} + +static void orcad_dump_symbolvector_prim( + struct orcad_symbolvector_prim* const node, int indent) +{ + orcad_uint32_t i; + + indent_printf("begin symbolvector\n"); + ++indent; + + indent_i(x); + indent_i(y); + + indent_u(num_primitives); + + for(i=0;inum_primitives;++i) + { + orcad_dump_prim(node->primitives[i], indent); + } + + indent_s(name); + + --indent; + indent_printf("end symbolvector\n"); +} + +static void orcad_dump_prim(struct orcad_prim* const prim, int indent) +{ + switch(prim->type) + { + case ORCAD_PRIMITIVE_RECT: + orcad_dump_rect_prim((struct orcad_rect_prim*)prim, indent); + break; + + case ORCAD_PRIMITIVE_LINE: + orcad_dump_line_prim((struct orcad_line_prim*)prim, indent); + break; + + case ORCAD_PRIMITIVE_ARC: + orcad_dump_arc_prim((struct orcad_arc_prim*)prim, indent); + break; + + case ORCAD_PRIMITIVE_ELLIPSE: + orcad_dump_ellipse_prim((struct orcad_ellipse_prim*)prim, indent); + break; + + case ORCAD_PRIMITIVE_POLYGON: + orcad_dump_polygon_prim((struct orcad_polygon_prim*)prim, indent); + break; + + case ORCAD_PRIMITIVE_POLYLINE: + orcad_dump_polyline_prim((struct orcad_polyline_prim*)prim, indent); + break; + + case ORCAD_PRIMITIVE_TEXT: + orcad_dump_text_prim((struct orcad_text_prim*)prim, indent); + break; + + case ORCAD_PRIMITIVE_BEZIER: + orcad_dump_bezier_prim((struct orcad_bezier_prim*)prim, indent); + break; + + case ORCAD_PRIMITIVE_SYMBOLVECTOR: + orcad_dump_symbolvector_prim((struct orcad_symbolvector_prim*)prim, + indent); + break; + + default: + fprintf(stderr, "Error: Primitive 0x%x is not handled!\n", + (unsigned int)prim->type); + break; + } +} + +static void orcad_dump_xnetalias(struct orcad_xnetalias_node* const node, + int indent) +{ + indent_printf("begin x-netalias\n"); + ++indent; + + indent_s(alias); + indent_u(net_id); + + --indent; + indent_printf("end x-netalias\n"); +} + +static void orcad_dump_netprop(struct orcad_netprop_node* const node, + int indent) +{ + indent_printf("begin netprop\n"); + ++indent; + + indent_u(net_id); + indent_x(unknown[0]); + indent_x(unknown[1]); + indent_x(unknown[2]); + indent_x(unknown[3]); + indent_x(unknown[4]); + indent_x(unknown[5]); + indent_x(unknown[6]); + indent_u(color); + indent_u(line_width); + indent_u(line_style); + + orcad_dump_node_common(&node->node, indent); + + --indent; + indent_printf("end netprop\n"); +} + +static void orcad_dump_busprop(struct orcad_busprop_node* const node, + int indent) +{ + orcad_uint16_t i; + + indent_printf("begin busprop\n"); + ++indent; + + indent_u(net_id); + indent_x(unknown[0]); + indent_x(unknown[1]); + indent_x(unknown[2]); + indent_x(unknown[3]); + indent_x(unknown[4]); + indent_x(unknown[5]); + indent_x(unknown[6]); + indent_u(color); + indent_u(line_width); + indent_u(line_style); + indent_u(num_busnetids); + + for(i=0;inum_busnetids;++i) + { + indent_printf("busnetids[%i]: %lu\n", (unsigned int)i, + (unsigned long)node->busnetids[i]); + } + + orcad_dump_node_common(&node->node, indent); + + --indent; + indent_printf("end busprop\n"); +} + +static void orcad_dump_wire(struct orcad_wire_node* const node, int indent) +{ + indent_printf("begin wire\n"); + ++indent; + + indent_u(wire_id); + indent_u(net_id); + indent_u(color); + indent_u(start_x); + indent_u(start_y); + indent_u(end_x); + indent_u(end_y); + indent_x(unknown_0); + + indent_u(num_alias); + + dump_node_array(displayprop); + + indent_u(line_width); + indent_u(line_style); + + orcad_dump_node_common(&node->node, indent); + + --indent; + indent_printf("end wire\n"); +} + +static void orcad_dump_pinconnection( + struct orcad_pinconnection_node* const node, int indent) +{ + indent_printf("begin pinconnection\n"); + ++indent; + + indent_i(nc); + indent_i(idx); + indent_u(x); + indent_u(y); + indent_i(wire_id); + indent_u(net_id); + + dump_node_array(displayprop); + + orcad_dump_node_common(&node->node, indent); + + --indent; + indent_printf("end pinconnection\n"); +} + +static void orcad_dump_symbolpin(struct orcad_symbolpin_node* const node, + int indent) +{ + indent_printf("begin symbolpin\n"); + ++indent; + + indent_s(pin_name); + indent_i(start_x); + indent_i(start_y); + indent_i(hotpt_x); + indent_i(hotpt_y); + indent_u(pin_shape); + indent_x(unknown_0); + indent_u(port_type); + indent_x(unknown_1); + indent_x(unknown_2); + + dump_node_array(displayprop); + + orcad_dump_node_common(&node->node, indent); + + --indent; + indent_printf("end symbolpin\n"); +} + +static void orcad_dump_pinidxmapping( + struct orcad_pinidxmapping_node* const node, int indent) +{ + orcad_uint16_t i; + + indent_printf("begin pinidxmapping\n"); + ++indent; + + indent_s(unit_ref); + indent_s(symname); + indent_u(num_pins); + + for(i=0;inum_pins;++i) + { + struct orcad_pin* const pin = node->pins[i]; + + indent_printf("begin pin[%i]\n", i); + ++indent; + + if(NULL==pin) + { + indent_printf("empty/missing\n"); + } + else + { + indent_printf("pin_name: \"%s\"\n", pin->pin_name); + indent_printf("pin_ignore: %u\n", (unsigned int)pin->pin_ignore); + + if(0<=pin->pin_group) + { + indent_printf("pin_group: %u\n", (unsigned int)pin->pin_group); + } + else + { + indent_printf("pin_group: empty\n"); + } + } + + --indent; + indent_printf("end pin[%i]\n", i); + } + + orcad_dump_node_common(&node->node, indent); + + --indent; + indent_printf("end pinidxmapping\n"); +} + +static void orcad_dump_pagesettings__( + const struct orcad_pagesettings* const settings, int indent) +{ + time_t tim; + + indent_printf("begin pagesettings\n"); + ++indent; + + tim = settings->ctime; + indent_printf("ctime: %s", ctime(&tim)); + + tim = settings->mtime; + indent_printf("mtime: %s", ctime(&tim)); + + indent_printf("unknown_0: 0x%x\n", (unsigned int)settings->unknown_0); + indent_printf("unknown_1: 0x%x\n", (unsigned int)settings->unknown_1); + indent_printf("unknown_2: 0x%x\n", (unsigned int)settings->unknown_2); + indent_printf("unknown_3: 0x%x\n", (unsigned int)settings->unknown_3); + indent_printf("width: %lu\n", (unsigned long)settings->width); + indent_printf("height: %lu\n", (unsigned long)settings->height); + indent_printf("pin_to_pin: %u\n", (unsigned int)settings->pin_to_pin); + indent_printf("unknown_4: 0x%x\n", (unsigned int)settings->unknown_4); + indent_printf("horiz_count: %u\n", (unsigned int)settings->horiz_count); + indent_printf("vert_count: %u\n", (unsigned int)settings->vert_count); + indent_printf("unknown_5: 0x%x\n", (unsigned int)settings->unknown_5); + indent_printf("horiz_width: %u\n", (unsigned int)settings->horiz_width); + indent_printf("vert_width: %u\n", (unsigned int)settings->vert_width); + indent_printf("unknown_6: 0x%x\n", (unsigned int)settings->unknown_6); + indent_printf("unknown_7: 0x%x\n", (unsigned int)settings->unknown_7); + indent_printf("unknown_8: 0x%x\n", (unsigned int)settings->unknown_8); + indent_printf("unknown_9: 0x%x\n", (unsigned int)settings->unknown_9); + indent_printf("unknown_10: 0x%x\n", (unsigned int)settings->unknown_10); + indent_printf("unknown_11: 0x%x\n", (unsigned int)settings->unknown_11); + indent_printf("unknown_12: 0x%x\n", (unsigned int)settings->unknown_12); + indent_printf("unknown_13: 0x%x\n", (unsigned int)settings->unknown_13); + indent_printf("unknown_14: 0x%x\n", (unsigned int)settings->unknown_14); + indent_printf("unknown_15: 0x%x\n", (unsigned int)settings->unknown_15); + indent_printf("unknown_16: 0x%x\n", (unsigned int)settings->unknown_16); + indent_printf("unknown_17: 0x%x\n", (unsigned int)settings->unknown_17); + indent_printf("horiz_char: %u\n", (unsigned int)settings->horiz_char); + indent_printf("unknown_18: 0x%x\n", (unsigned int)settings->unknown_18); + indent_printf("horiz_ascending: %u\n", (unsigned int)settings->horiz_ascending); + indent_printf("vert_char: %u\n", (unsigned int)settings->vert_char); + indent_printf("unknown_19: 0x%x\n", (unsigned int)settings->unknown_19); + indent_printf("vert_ascending: %u\n", (unsigned int)settings->vert_ascending); + indent_printf("is_metric: %u\n", (unsigned int)settings->is_metric); + indent_printf("border_displayed: %u\n", (unsigned int)settings->border_displayed); + indent_printf("border_printed: %u\n", (unsigned int)settings->border_printed); + indent_printf("gridref_displayed: %u\n", (unsigned int)settings->gridref_displayed); + indent_printf("gridref_printed: %u\n", (unsigned int)settings->gridref_printed); + indent_printf("titleblock_displayed: %u\n", (unsigned int)settings->titleblock_displayed); + indent_printf("titleblock_printed: %u\n", (unsigned int)settings->titleblock_printed); + indent_printf("ansi_grid_refs: %u\n", (unsigned int)settings->ansi_grid_refs); + + --indent; + indent_printf("end pagesettings\n"); +} + +static void orcad_dump_page(struct orcad_page_node* const node, int indent) +{ + indent_printf("begin page\n"); + ++indent; + + indent_s(page_name); + indent_s(page_size); + + orcad_dump_pagesettings__(&node->settings, indent); + + indent_u(num_titleblocks); + dump_node_array(netprop); + dump_node_array(busprop); + + indent_u(num_netaliases); + orcad_dump_node_array((struct orcad_node**)node->netaliases, + node->num_netaliases, indent); + + dump_node_array(wire); + dump_node_array(partinst); + dump_node_array(port); + dump_node_array(global); + dump_node_array(offpageconn); + indent_u(num_ercsymbolinsts); + indent_u(num_busentries); + dump_node_array(graphicinst); + indent_u(num_unk10); + indent_u(num_unk11); + + orcad_dump_node_common(&node->node, indent); + + --indent; + indent_printf("end page\n"); +} + +static void orcad_dump__graphic_inline( + struct orcad_graphic_inline* const node, int indent) +{ + indent_printf("begin graphic\n"); + ++indent; + + indent_u(instname_idx); + indent_u(libpath_idx); + indent_s(name); + indent_u(db_id); + indent_i(x); + indent_i(y); + indent_i(x1); + indent_i(y1); + indent_i(x2); + indent_i(y2); + indent_u(color); + indent_u(rotation); + indent_u(mirrored); + indent_x(unknown_2); + indent_x(unknown_3); + + dump_node_array(displayprop); + + indent_printf("type: %s\n", orcad_type2str(node->type)); + + if(NULL!=node->obj) + { + orcad_dump_node((struct orcad_node*)node->obj, indent); + } + + --indent; + indent_printf("end graphic\n"); +} + +static void orcad_dump_global(struct orcad_global_node* const node, int indent) +{ + indent_printf("begin global\n"); + ++indent; + + orcad_dump__graphic_inline(&node->graphic, indent); + + indent_u(wire_id); + indent_x(unknown_0); + + orcad_dump_node_common(&node->node, indent); + + --indent; + indent_printf("end global\n"); +} + +static void orcad_dump_offpageconn(struct orcad_offpageconn_node* const node, + int indent) +{ + indent_printf("begin offpageconn\n"); + ++indent; + + orcad_dump__graphic_inline(&node->graphic, indent); + + indent_u(wire_id); + indent_x(unknown_0); + + orcad_dump_node_common(&node->node, indent); + + --indent; + indent_printf("end offpageconn\n"); +} + +static void orcad_dump_port(struct orcad_port_node* const node, int indent) +{ + indent_printf("begin port\n"); + ++indent; + + orcad_dump__graphic_inline(&node->graphic, indent); + + indent_u(wire_id); + indent_x(unknown_0); + indent_x(unknown_1); + + orcad_dump_node_common(&node->node, indent); + + --indent; + indent_printf("end port\n"); +} + +static void orcad_dump_partinst(struct orcad_partinst_node* const node, + int indent) +{ + indent_printf("begin partinst\n"); + ++indent; + + indent_u(instname_idx); + indent_u(libpath_idx); + indent_s(name); + indent_u(db_id); + indent_i(x1); + indent_i(y1); + indent_i(x2); + indent_i(y2); + indent_i(x); + indent_i(y); + indent_u(color); + indent_u(rotation); + indent_u(mirrored); + indent_x(unknown_4); + + dump_node_array(displayprop); + + indent_x(unknown_5); + indent_s(refdes); + indent_u(value_idx); + indent_x(unknown_7); + indent_x(unknown_8); + indent_x(flags); + indent_u(primitive); + indent_u(power_pins_visible); + dump_node_array(pinconnection); + indent_s(symname); + indent_u(pim_idx); + + orcad_dump_node_common(&node->node, indent); + + --indent; + indent_printf("end partinst\n"); +} + +static void orcad_dump_graphicinst(struct orcad_graphicinst_node* const node, + int indent) +{ + indent_printf("begin graphicinst\n"); + ++indent; + + orcad_dump__graphic_inline(&node->graphic, indent); + + --indent; + indent_printf("end graphicinst\n"); +} + +static void orcad_dump_inlinepageobject( + struct orcad_inlinepageobject_node* const node, int indent) +{ + orcad_uint16_t i; + + indent_printf("begin inlinepageobject\n"); + ++indent; + + indent_s(name); + indent_s(unk_str); + indent_u(color); + indent_u(num_primitives); + + for(i=0;inum_primitives;++i) + { + orcad_dump_prim(node->primitives[i], indent); + } + + orcad_dump_node_common(&node->node, indent); + + --indent; + indent_printf("end inlinepageobject\n"); +} + +static void orcad_dump_symbol_common( + const struct orcad_symbol_common* const common, int indent) +{ + indent_printf("name: \"%s\"\n", common->name); + indent_printf("source: \"%s\"\n", common->source); +} + +static void orcad_dump_titleblocksymbol( + struct orcad_titleblocksymbol_node* const node, int indent) +{ + orcad_uint16_t i; + + indent_printf("begin titleblocksymbol\n"); + ++indent; + + orcad_dump_symbol_common(&node->sym_common, indent); + + indent_x(unknown_0); + indent_x(unknown_1); + + indent_u(num_primitives); + + for(i=0;inum_primitives;++i) + { + orcad_dump_prim(node->primitives[i], indent); + } + + indent_x(unknown_2); + indent_x(unknown_3); + + dump_node_array(symbolpin); + dump_node_array(displayprop); + + orcad_dump_node_common(&node->node, indent); + + --indent; + indent_printf("end titleblocksymbol\n"); +} + +static void orcad_dump_symbolgraphic( + struct orcad_symbolgraphic_node* const node, int indent) +{ + orcad_uint16_t i; + + indent_printf("begin symbolgraphic\n"); + ++indent; + + orcad_dump_symbol_common(&node->sym_common, indent); + + indent_x(unknown_0); + indent_x(unknown_1); + + indent_u(num_primitives); + + for(i=0;inum_primitives;++i) + { + orcad_dump_prim(node->primitives[i], indent); + } + + indent_u(symbox_x); + indent_u(symbox_y); + dump_node_array(symbolpin); + dump_node_array(displayprop); + indent_s(unk_str0); + indent_s(unk_str1); + indent_s(sym_prefix); + indent_s(unk_str2); + indent_x(flags); + indent_u(pin_names_visible); + indent_u(pin_names_rotate); + indent_u(pin_numbers_visible); + + orcad_dump_node_common(&node->node, indent); + + --indent; + indent_printf("end symbolgraphic\n"); +} + +static void orcad_dump_properties( + struct orcad_properties_node* const node, int indent) +{ + orcad_uint16_t i; + + indent_printf("begin properties\n"); + ++indent; + + orcad_dump_symbol_common(&node->sym_common, indent); + + indent_u(num_partnames); + + for(i=0;inum_partnames;++i) + { + indent_printf("partnames[%u]: \"%s\"\n", (unsigned int)i, + node->partnames[i]); + } + + orcad_dump_node_common(&node->node, indent); + + --indent; + indent_printf("end properties\n"); +} + +static void orcad_dump_symbolpinmapping( + struct orcad_symbolpinmapping_node* const node, int indent) +{ + indent_printf("begin symbolpinmapping\n"); + ++indent; + + orcad_dump_symbol_common(&node->sym_common, indent); + + indent_s(sym_prefix); + indent_s(unk_str0); + indent_s(unk_str1); + dump_node_array(pinidxmapping); + + orcad_dump_node_common(&node->node, indent); + + --indent; + indent_printf("end symbolpinmapping\n"); +} + +static void orcad_dump__symbol(struct orcad_globalsymbol_node* const node, + int indent, const char* const name) +{ + orcad_uint16_t i; + + indent_printf("begin %s\n", name); + ++indent; + + orcad_dump_symbol_common(&node->sym_common, indent); + + indent_x(unknown_0); + indent_x(unknown_1); + + indent_u(num_primitives); + + for(i=0;inum_primitives;++i) + { + orcad_dump_prim(node->primitives[i], indent); + } + + indent_u(symbox_x); + indent_u(symbox_y); + dump_node_array(symbolpin); + dump_node_array(displayprop); + + orcad_dump_node_common(&node->node, indent); + + --indent; + indent_printf("end %s\n", name); +} + +static void orcad_dump_ercsymbol(struct orcad_ercsymbol_node* const node, + int indent) +{ + orcad_uint16_t i; + + indent_printf("begin ercsymbol\n"); + ++indent; + + orcad_dump_symbol_common(&node->sym_common, indent); + + indent_x(unknown_0); + indent_x(unknown_1); + + indent_u(num_primitives); + + for(i=0;inum_primitives;++i) + { + orcad_dump_prim(node->primitives[i], indent); + } + + indent_i(x1); + indent_i(y1); + indent_i(x2); + indent_i(y2); + indent_i(x); + indent_i(y); + + orcad_dump_node_common(&node->node, indent); + + --indent; + indent_printf("end ercsymbol\n"); +} + +static void orcad_dump_symboldisplayprop( + struct orcad_symboldisplayprop_node* const node, int indent) +{ + indent_printf("begin symboldisplayprop\n"); + ++indent; + + indent_u(name_idx); + indent_i(x); + indent_i(y); + indent_u(font_id); + indent_u(rotation); + indent_u(color); + indent_x(unknown_0); + indent_u(format); + indent_x(unknown_2); + + --indent; + indent_printf("end symboldisplayprop\n"); +} + +static void orcad_dump_xcache(struct orcad_xcache_node* const node, int indent) +{ + indent_printf("begin x-cache\n"); + ++indent; + + orcad_dump_node((struct orcad_node*)node->titleblocks, indent); + orcad_dump_node((struct orcad_node*)node->symbolgraphics, indent); + orcad_dump_node((struct orcad_node*)node->symbolproperties, indent); + orcad_dump_node((struct orcad_node*)node->symbolpinmappings, indent); + + --indent; + indent_printf("end x-cache\n"); +} + +static void orcad_dump_xsymbolgroup( + struct orcad_xsymbolgroup_node* const node, int indent) +{ + indent_printf("begin x-symbolgroup\n"); + ++indent; + + dump_node_array(symbol); + + --indent; + indent_printf("end x-symbolgroup\n"); +} + +static void orcad_dump_xcachesymbol( + struct orcad_xcachesymbol_node* const node, int indent) +{ + indent_printf("begin x-cachesymbol\n"); + ++indent; + + indent_s(symname); + dump_node_array(variant); + + --indent; + indent_printf("end x-cachesymbol\n"); +} + +static void orcad_dump_xcachesymvariant( + struct orcad_xcachesymvariant_node* const node, int indent) +{ + time_t tim; + + indent_printf("begin x-cachesymvariant\n"); + ++indent; + + indent_s(lib_path); + + tim = node->ctime; + indent_printf("ctime: %s", ctime(&tim)); + + tim = node->mtime; + indent_printf("mtime: %s", ctime(&tim)); + + indent_printf("type: %s\n", orcad_type2str(node->type)); + + if(NULL!=node->obj) + { + orcad_dump_node(node->obj, indent); + } + + --indent; + indent_printf("end x-cachesymvariant\n"); +} + +static void orcad_dump_xlibrary(struct orcad_xlibrary_node* const node, + int indent) +{ + time_t tim; + orcad_uint32_t i; + + indent_printf("begin x-library\n"); + ++indent; + + indent_s(introduction); + indent_u(ver_major); + indent_u(ver_minor); + + tim = node->ctime; + indent_printf("ctime: %s", ctime(&tim)); + + tim = node->mtime; + indent_printf("mtime: %s", ctime(&tim)); + + indent_u(num_fonts); + /* do we need to display these fonts? */ + + indent_u(num_unks); + + for(i=0;inum_unks;++i) + { + indent_printf("unks[%u]: %u\n", (unsigned int)i, + (unsigned int)node->unks[i]); + } + + indent_x(unknown_0); + indent_x(unknown_1); + + for(i=0;i<(sizeof(node->partfields)/sizeof(node->partfields[0]));++i) + { + indent_printf("partfields[%lu]: \"%s\"\n", (unsigned long)i, + node->partfields[i]); + } + + orcad_dump_pagesettings__(&node->settings, indent); + + indent_u(num_names); + + if(NULL!=node->names) + { + for(i=0;inum_names;++i) + { + indent_printf("names[%lu]: \"%s\"\n", (unsigned long)i, + node->names[i]); + } + } + + indent_u(num_aliases); + + if(NULL!=node->aliases) + { + for(i=0;inum_aliases;++i) + { + indent_printf("begin aliases[%lu]\n", (unsigned long)i); + ++indent; + indent_printf("alias: \"%s\"\n", node->aliases[i].alias); + indent_printf("package: \"%s\"\n", node->aliases[i].package); + --indent; + indent_printf("end aliases[%u]\n", (unsigned int)i); + } + } + + indent_x(unknown_2); + indent_x(unknown_3); + + indent_printf("sch_name: \"%s\"\n", node->sch_name); + + --indent; + indent_printf("end x-library\n"); +} + +static void orcad_dump_node(struct orcad_node* const node, int indent) +{ + switch(node->type) + { + case ORCAD_TYPE_INLINEPAGEOBJECT: + orcad_dump_inlinepageobject((struct orcad_inlinepageobject_node*)node, + indent); + break; + + case ORCAD_TYPE_PROPERTIES: + orcad_dump_properties((struct orcad_properties_node*)node, indent); + break; + + case ORCAD_TYPE_PAGE: + orcad_dump_page((struct orcad_page_node*)node, indent); + break; + + case ORCAD_TYPE_PARTINST: + orcad_dump_partinst((struct orcad_partinst_node*)node, indent); + break; + + case ORCAD_TYPE_PINCONNECTION: + orcad_dump_pinconnection((struct orcad_pinconnection_node*)node, + indent); + break; + + case ORCAD_TYPE_WIRE: + orcad_dump_wire((struct orcad_wire_node*)node, indent); + break; + + case ORCAD_TYPE_PORT: + orcad_dump_port((struct orcad_port_node*)node, indent); + break; + + case ORCAD_TYPE_SYMBOLGRAPHIC: + orcad_dump_symbolgraphic((struct orcad_symbolgraphic_node*)node, + indent); + break; + + case ORCAD_TYPE_SYMBOLPIN: + orcad_dump_symbolpin((struct orcad_symbolpin_node*)node, indent); + break; + + case ORCAD_TYPE_SYMBOLPINMAPPING: + orcad_dump_symbolpinmapping((struct orcad_symbolpinmapping_node*)node, + indent); + break; + + case ORCAD_TYPE_PINIDXMAPPING: + orcad_dump_pinidxmapping((struct orcad_pinidxmapping_node*)node, + indent); + break; + + case ORCAD_TYPE_GLOBALSYMBOL: + orcad_dump__symbol((struct orcad_globalsymbol_node*)node, indent, + "globalsymbol"); + break; + + case ORCAD_TYPE_PORTSYMBOL: + orcad_dump__symbol((struct orcad_globalsymbol_node*)node, indent, + "portsymbol"); + break; + + case ORCAD_TYPE_OFFPAGECONNSYMBOL: + orcad_dump__symbol((struct orcad_globalsymbol_node*)node, indent, + "offpageconnsymbol"); + break; + + case ORCAD_TYPE_GLOBAL: + orcad_dump_global((struct orcad_global_node*)node, indent); + break; + + case ORCAD_TYPE_OFFPAGECONN: + orcad_dump_offpageconn((struct orcad_offpageconn_node*)node, indent); + break; + + case ORCAD_TYPE_SYMBOLDISPLAYPROP: + orcad_dump_symboldisplayprop( + (struct orcad_symboldisplayprop_node*)node, indent); + break; + + case ORCAD_TYPE_NETPROP: + orcad_dump_netprop((struct orcad_netprop_node*)node, indent); + break; + + case ORCAD_TYPE_BUSPROP: + orcad_dump_busprop((struct orcad_busprop_node*)node, indent); + break; + + case ORCAD_TYPE_GRAPHICBOXINST: + case ORCAD_TYPE_GRAPHICLINEINST: + case ORCAD_TYPE_GRAPHICARCINST: + case ORCAD_TYPE_GRAPHICELLIPSEINST: + case ORCAD_TYPE_GRAPHICPOLYGONINST: + case ORCAD_TYPE_GRAPHICTEXTINST: + case ORCAD_TYPE_GRAPHICBEZIERINST: + orcad_dump_graphicinst((struct orcad_graphicinst_node*)node, indent); + break; + + case ORCAD_TYPE_TITLEBLOCKSYMBOL: + orcad_dump_titleblocksymbol((struct orcad_titleblocksymbol_node*)node, + indent); + break; + + /* + case ORCAD_TYPE_TITLEBLOCK: + */ + + case ORCAD_TYPE_ERCSYMBOL: + orcad_dump_ercsymbol((struct orcad_ercsymbol_node*)node, indent); + break; + + case ORCAD_TYPE_X_NETALIAS: + orcad_dump_xnetalias((struct orcad_xnetalias_node*)node, indent); + break; + + case ORCAD_TYPE_X_CACHE: + orcad_dump_xcache((struct orcad_xcache_node*)node, indent); + break; + + case ORCAD_TYPE_X_SYMBOLGROUP: + orcad_dump_xsymbolgroup((struct orcad_xsymbolgroup_node*)node, indent); + break; + + case ORCAD_TYPE_X_CACHESYMBOL: + orcad_dump_xcachesymbol((struct orcad_xcachesymbol_node*)node, indent); + break; + + case ORCAD_TYPE_X_CACHESYMVARIANT: + orcad_dump_xcachesymvariant((struct orcad_xcachesymvariant_node*)node, + indent); + break; + + case ORCAD_TYPE_X_LIBRARY: + orcad_dump_xlibrary((struct orcad_xlibrary_node*)node, indent); + break; + + default: + fprintf(stderr, "Error: Type 0x%x (%s) is not handled!\n", + (unsigned int)node->type, orcad_type2str(node->type)); + break; + } +} + +void orcad_dump(struct orcad_node* const root) +{ + orcad_dump_node(root, 0); +} Index: tags/1.0.5/src/plugins/io_orcad/read_fio.c =================================================================== --- tags/1.0.5/src/plugins/io_orcad/read_fio.c (nonexistent) +++ tags/1.0.5/src/plugins/io_orcad/read_fio.c (revision 10414) @@ -0,0 +1,42 @@ +#include "read_fio.h" +#include +#include + +int fio_fopen(io_orcad_rctx_t* const rctx, const char* filename) +{ + return -1; +} + +long fio_fread(io_orcad_rctx_t* const rctx, char* dst, long len) +{ + if (!rctx->has_fp) + return -1; + + if (rctx->cheat_offs + len > rctx->cheat_len) + len = rctx->cheat_len - rctx->cheat_offs; + + if (len < 0) + return -1; + if (len == 0) + return 0; + + memcpy(dst, rctx->cheat_buf + rctx->cheat_offs, len); + rctx->cheat_offs += len; + return len; + + return ucdf_fread(&rctx->fp, dst, len); +} + +int fio_fseek(io_orcad_rctx_t* const rctx, long offs) +{ + if (!rctx->has_fp) + return -1; + rctx->cheat_offs = offs; + return 0; + return ucdf_fseek(&rctx->fp, offs); +} + +int fio_fclose(io_orcad_rctx_t* const rctx) +{ + return 0; +} Property changes on: tags/1.0.5/src/plugins/io_orcad/read_fio.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Index: tags/1.0.5/src/plugins/io_orcad/read_fio.h =================================================================== --- tags/1.0.5/src/plugins/io_orcad/read_fio.h (nonexistent) +++ tags/1.0.5/src/plugins/io_orcad/read_fio.h (revision 10414) @@ -0,0 +1,49 @@ +#ifndef FIO_H +#define FIO_H + +#include + +#include "read.h" +#include +#include +#include + +typedef struct io_orcad_rctx_s { + const char *fn; + csch_alien_read_ctx_t alien; + ucdf_ctx_t ucdf; + ucdf_file_t fp; + unsigned has_fp:1; + + char *cheat_buf; + long cheat_offs, cheat_len; + + ucdf_direntry_t *next_page; + + /* high level */ + struct orcad_page_node *page_root; + struct orcad_xcache_node *cache_root; + struct orcad_xlibrary_node *library_root; + struct { /* look up a few commonly used strings in library_root->names and cache their indices to speed up lookups */ + unsigned long part_ref; + unsigned long value; + unsigned long name; + } hwpropnames; + + /* per file */ + htsp_t syms; /* symbols loaded from the Cache file; key: symbol name; val: (cache_sym_t *) */ + unsigned cache_loaded:1; /* 1 if the Cache file got loaded and ->syms got initialized */ + unsigned library_loaded:1; /* 1 if the Library file got loaded and ->library_root got initialized and hwpropnames initialized */ + + + /* per page */ + htip_t wirenets; /* cache of net_id -> wirenet (csch_cgrp_t *) */ + htip_t pinconns; /* cache of net_id -> terminal (csch_cgrp_t *) */ +} io_orcad_rctx_t; + +int fio_fopen(io_orcad_rctx_t* const rctx, const char* filename); +long fio_fread(io_orcad_rctx_t* const rctx, char* dst, long len); +int fio_fseek(io_orcad_rctx_t* const rctx, long offs); +int fio_fclose(io_orcad_rctx_t* const rctx); /* not in libucdf */ + +#endif /* FIO_H */ Property changes on: tags/1.0.5/src/plugins/io_orcad/read_fio.h ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Index: tags/1.0.5/src/plugins/io_orcad/read_free.c =================================================================== --- tags/1.0.5/src/plugins/io_orcad/read_free.c (nonexistent) +++ tags/1.0.5/src/plugins/io_orcad/read_free.c (revision 10414) @@ -0,0 +1,540 @@ +#ifdef ORCAD_TESTER +# include "tester/read_fio.h" +#else +# include "read_fio.h" +#endif + +#include "read_common.h" +#include +#include +#include + +#define free_node_array(tag) \ + orcad_free_node_array((struct orcad_node**)node->tag##s, \ + node->num_##tag##s) + +static void orcad_free_node(struct orcad_node* const node); +static void orcad_free_prim(struct orcad_prim* const prim); + +static void orcad_free_node_array(struct orcad_node** array, size_t count) +{ + while(0<(count--)) + { + orcad_free_node(array[count]); + } + + free(array); +} + +static void orcad_free_text_prim(struct orcad_text_prim* const node) +{ + free(node->text); +} + +static void orcad_free_polygon_prim(struct orcad_polygon_prim* const node) +{ + free(node->points); +} + +static void orcad_free_polyline_prim(struct orcad_polyline_prim* const node) +{ + free(node->points); +} + +static void orcad_free_bezier_prim(struct orcad_bezier_prim* const node) +{ + free(node->segments); +} + +static void orcad_free_symbolvector_prim( + struct orcad_symbolvector_prim* const node) +{ + orcad_uint16_t i; + + if(NULL!=node->primitives) + { + for(i=0;inum_primitives;++i) + { + orcad_free_prim(node->primitives[i]); + } + + free(node->primitives); + } + + free(node->name); +} + +static void orcad_free_prim(struct orcad_prim* const prim) +{ + if(NULL==prim) + { + return; + } + + switch(prim->type) + { + case ORCAD_PRIMITIVE_RECT: + case ORCAD_PRIMITIVE_LINE: + case ORCAD_PRIMITIVE_ARC: + case ORCAD_PRIMITIVE_ELLIPSE: + break; + + case ORCAD_PRIMITIVE_POLYGON: + orcad_free_polygon_prim((struct orcad_polygon_prim*)prim); + break; + + case ORCAD_PRIMITIVE_POLYLINE: + orcad_free_polyline_prim((struct orcad_polyline_prim*)prim); + break; + + case ORCAD_PRIMITIVE_TEXT: + orcad_free_text_prim((struct orcad_text_prim*)prim); + break; + + case ORCAD_PRIMITIVE_BEZIER: + orcad_free_bezier_prim((struct orcad_bezier_prim*)prim); + break; + + case ORCAD_PRIMITIVE_SYMBOLVECTOR: + orcad_free_symbolvector_prim((struct orcad_symbolvector_prim*)prim); + break; + + default: + fprintf(stderr, "Error: Primitive 0x%x is not freed!\n", + (unsigned int)prim->type); + break; + } + + free(prim); +} + +static void orcad_free_xnetalias(struct orcad_xnetalias_node* const node) +{ + free(node->alias); +} + +static void orcad_free_symbolpin(struct orcad_symbolpin_node* const node) +{ + free(node->pin_name); + free_node_array(displayprop); +} + +static void orcad_free_pinidxmapping( + struct orcad_pinidxmapping_node* const node) +{ + orcad_uint16_t i; + + free(node->unit_ref); + free(node->symname); + + for(i=0;inum_pins;++i) + { + struct orcad_pin* const pin = node->pins[i]; + + if(NULL!=pin) + { + free(pin->pin_name); + free(pin); + } + } + free(node->pins); +} + +static void orcad_free_page(struct orcad_page_node* const node) +{ + free(node->page_name); + free(node->page_size); + + free_node_array(netprop); + free_node_array(busprop); + orcad_free_node_array((struct orcad_node**)node->netaliases, + node->num_netaliases); + free_node_array(wire); + free_node_array(partinst); + free_node_array(port); + free_node_array(global); + free_node_array(offpageconn); + free_node_array(graphicinst); +} + +static void orcad_free__graphic_inline(struct orcad_graphic_inline* const node) +{ + free(node->name); + free_node_array(displayprop); + + if(NULL!=node->obj) + { + orcad_free_node((struct orcad_node*)node->obj); + } +} + +static void orcad_free_global(struct orcad_global_node* const node) +{ + orcad_free__graphic_inline(&node->graphic); +} + +static void orcad_free_offpageconn(struct orcad_offpageconn_node* const node) +{ + orcad_free__graphic_inline(&node->graphic); +} + +static void orcad_free_port(struct orcad_port_node* const node) +{ + orcad_free__graphic_inline(&node->graphic); +} + +static void orcad_free_partinst(struct orcad_partinst_node* const node) +{ + free(node->name); + free(node->refdes); + free_node_array(pinconnection); + free_node_array(displayprop); + free(node->symname); +} + +static void orcad_free_wire(struct orcad_wire_node* const node) +{ + free_node_array(displayprop); +} + +static void orcad_free_pinconnection( + struct orcad_pinconnection_node* const node) +{ + free_node_array(displayprop); +} + +static void orcad_free_graphicinst(struct orcad_graphicinst_node* const node) +{ + orcad_free__graphic_inline(&node->graphic); +} + +static void orcad_free_inlinepageobject( + struct orcad_inlinepageobject_node* const node) +{ + orcad_uint16_t i; + + free(node->name); + free(node->unk_str); + + for(i=0;inum_primitives;++i) + { + orcad_free_prim(node->primitives[i]); + } + free(node->primitives); +} + +static void orcad_free_symbol_common( + const struct orcad_symbol_common* const common) +{ + free(common->name); + free(common->source); +} + +static void orcad_free_titleblocksymbol( + struct orcad_titleblocksymbol_node* const node) +{ + orcad_uint16_t i; + + orcad_free_symbol_common(&node->sym_common); + + free_node_array(symbolpin); + free_node_array(displayprop); + + for(i=0;inum_primitives;++i) + { + orcad_free_prim(node->primitives[i]); + } + free(node->primitives); +} + +static void orcad_free_symbolgraphic( + struct orcad_symbolgraphic_node* const node) +{ + orcad_uint16_t i; + + orcad_free_symbol_common(&node->sym_common); + + for(i=0;inum_primitives;++i) + { + orcad_free_prim(node->primitives[i]); + } + free(node->primitives); + + free_node_array(symbolpin); + free_node_array(displayprop); + free(node->sym_prefix); + free(node->unk_str0); + free(node->unk_str1); + free(node->unk_str2); +} + +static void orcad_free_properties( + struct orcad_properties_node* const node) +{ + orcad_uint16_t i; + + orcad_free_symbol_common(&node->sym_common); + + for(i=0;inum_partnames;++i) + { + free(node->partnames[i]); + } + free(node->partnames); +} + +static void orcad_free_symbolpinmapping( + struct orcad_symbolpinmapping_node* const node) +{ + orcad_free_symbol_common(&node->sym_common); + + free(node->sym_prefix); + free(node->unk_str0); + free(node->unk_str1); + free_node_array(pinidxmapping); +} + +static void orcad_free_busprop(struct orcad_busprop_node* const node) +{ + free(node->busnetids); +} + +static void orcad_free_globalsymbol( + struct orcad_globalsymbol_node* const node) +{ + orcad_uint16_t i; + + orcad_free_symbol_common(&node->sym_common); + + for(i=0;inum_primitives;++i) + { + orcad_free_prim(node->primitives[i]); + } + free(node->primitives); + + free_node_array(symbolpin); + free_node_array(displayprop); +} + +static void orcad_free_ercsymbol(struct orcad_ercsymbol_node* const node) +{ + orcad_uint16_t i; + + orcad_free_symbol_common(&node->sym_common); + + for(i=0;inum_primitives;++i) + { + orcad_free_prim(node->primitives[i]); + } + free(node->primitives); +} + +static void orcad_free_xcache(struct orcad_xcache_node* const node) +{ + orcad_free_node((struct orcad_node*)node->titleblocks); + orcad_free_node((struct orcad_node*)node->symbolgraphics); + orcad_free_node((struct orcad_node*)node->symbolproperties); + orcad_free_node((struct orcad_node*)node->symbolpinmappings); +} + +static void orcad_free_xsymbolgroup( + struct orcad_xsymbolgroup_node* const node) +{ + free_node_array(symbol); +} + +static void orcad_free_xcachesymbol( + struct orcad_xcachesymbol_node* const node) +{ + free(node->symname); + free_node_array(variant); +} + +static void orcad_free_xcachesymvariant( + struct orcad_xcachesymvariant_node* const node) +{ + free(node->lib_path); + + if(NULL!=node->obj) + { + orcad_free_node(node->obj); + } +} + +static void orcad_free_xlibrary(struct orcad_xlibrary_node* const node) +{ + size_t i; + + free(node->fonts); + free(node->unks); + + for(i=0;i<(sizeof(node->partfields)/sizeof(node->partfields[0]));++i) + { + free(node->partfields[i]); + } + + if(NULL!=node->names) + { + for(i=0;inum_names;++i) + { + free(node->names[i]); + } + + free(node->names); + } + + if(NULL!=node->aliases) + { + for(i=0;inum_aliases;++i) + { + free(node->aliases[i].alias); + free(node->aliases[i].package); + } + + free(node->aliases); + } + + free(node->sch_name); +} + +static void orcad_free_node(struct orcad_node* const node) +{ + if(NULL==node) + { + return; + } + + switch(node->type) + { + case ORCAD_TYPE_INLINEPAGEOBJECT: + orcad_free_inlinepageobject((struct orcad_inlinepageobject_node*)node); + break; + + case ORCAD_TYPE_PROPERTIES: + orcad_free_properties((struct orcad_properties_node*)node); + break; + + case ORCAD_TYPE_PAGE: + orcad_free_page((struct orcad_page_node*)node); + break; + + case ORCAD_TYPE_PARTINST: + orcad_free_partinst((struct orcad_partinst_node*)node); + break; + + case ORCAD_TYPE_PINCONNECTION: + orcad_free_pinconnection((struct orcad_pinconnection_node*)node); + break; + + case ORCAD_TYPE_WIRE: + orcad_free_wire((struct orcad_wire_node*)node); + break; + + case ORCAD_TYPE_PORT: + orcad_free_port((struct orcad_port_node*)node); + break; + + case ORCAD_TYPE_SYMBOLGRAPHIC: + orcad_free_symbolgraphic((struct orcad_symbolgraphic_node*)node); + break; + + case ORCAD_TYPE_SYMBOLPIN: + orcad_free_symbolpin((struct orcad_symbolpin_node*)node); + break; + + case ORCAD_TYPE_SYMBOLPINMAPPING: + orcad_free_symbolpinmapping((struct orcad_symbolpinmapping_node*)node); + break; + + case ORCAD_TYPE_PINIDXMAPPING: + orcad_free_pinidxmapping((struct orcad_pinidxmapping_node*)node); + break; + + case ORCAD_TYPE_GLOBALSYMBOL: + case ORCAD_TYPE_PORTSYMBOL: + case ORCAD_TYPE_OFFPAGECONNSYMBOL: + orcad_free_globalsymbol((struct orcad_globalsymbol_node*)node); + break; + + case ORCAD_TYPE_GLOBAL: + orcad_free_global((struct orcad_global_node*)node); + break; + + case ORCAD_TYPE_OFFPAGECONN: + orcad_free_offpageconn((struct orcad_offpageconn_node*)node); + break; + + case ORCAD_TYPE_SYMBOLDISPLAYPROP: + case ORCAD_TYPE_NETPROP: + /* nothing */ + break; + + case ORCAD_TYPE_BUSPROP: + orcad_free_busprop((struct orcad_busprop_node*)node); + break; + + case ORCAD_TYPE_GRAPHICBOXINST: + case ORCAD_TYPE_GRAPHICLINEINST: + case ORCAD_TYPE_GRAPHICARCINST: + case ORCAD_TYPE_GRAPHICELLIPSEINST: + case ORCAD_TYPE_GRAPHICPOLYGONINST: + case ORCAD_TYPE_GRAPHICTEXTINST: + case ORCAD_TYPE_GRAPHICBEZIERINST: + orcad_free_graphicinst((struct orcad_graphicinst_node*)node); + break; + + case ORCAD_TYPE_TITLEBLOCKSYMBOL: + orcad_free_titleblocksymbol((struct orcad_titleblocksymbol_node*)node); + break; + + /* + case ORCAD_TYPE_TITLEBLOCK: + */ + + case ORCAD_TYPE_ERCSYMBOL: + orcad_free_ercsymbol((struct orcad_ercsymbol_node*)node); + break; + + case ORCAD_TYPE_X_NETALIAS: + orcad_free_xnetalias((struct orcad_xnetalias_node*)node); + break; + + case ORCAD_TYPE_X_CACHE: + orcad_free_xcache((struct orcad_xcache_node*)node); + break; + + case ORCAD_TYPE_X_SYMBOLGROUP: + orcad_free_xsymbolgroup((struct orcad_xsymbolgroup_node*)node); + break; + + case ORCAD_TYPE_X_CACHESYMBOL: + orcad_free_xcachesymbol((struct orcad_xcachesymbol_node*)node); + break; + + case ORCAD_TYPE_X_CACHESYMVARIANT: + orcad_free_xcachesymvariant((struct orcad_xcachesymvariant_node*)node); + break; + + case ORCAD_TYPE_X_LIBRARY: + orcad_free_xlibrary((struct orcad_xlibrary_node*)node); + break; + + default: + fprintf(stderr, "Error: Type 0x%x (%s) is not freed!\n", node->type, + orcad_type2str(node->type)); + break; + } + + free(node->namemappings); + free(node); +} + +void orcad_free_primitive(struct orcad_prim* const prim) +{ + /* forward it to the internal function */ + orcad_free_prim(prim); +} + +void orcad_free(struct orcad_node* const root) +{ + orcad_free_node(root); +} Index: tags/1.0.5/src/plugins/io_orcad/read_library.c =================================================================== --- tags/1.0.5/src/plugins/io_orcad/read_library.c (nonexistent) +++ tags/1.0.5/src/plugins/io_orcad/read_library.c (revision 10414) @@ -0,0 +1,250 @@ +#ifdef ORCAD_TESTER +# include "tester/read_fio.h" +#else +# include "read_fio.h" +#endif +#include "read_common.h" +#include +#include +#include + +static long orcad_read_xlibraryfont__(struct io_orcad_rctx_s* const rctx, + long offs, struct orcad_xlibraryfont* const font) +{ + vread_u32(font->height); + vread_u32(font->width); + vread_u32(font->escapement); + vread_u32(font->orientation); + vread_u32(font->weight); + vread_u8(font->italic); + vread_u8(font->underline); + vread_u8(font->strikeout); + vread_u8(font->charset); + vread_u8(font->outprecision); + vread_u8(font->clipprecision); + vread_u8(font->quality); + vread_u8(font->pitchandfamily); + + if(sizeof(font->facename)!=fio_fread(rctx, font->facename, + sizeof(font->facename))) + { + fprintf(stderr, "Error: Could not read font facename\n"); + return -1; + } + + offs += sizeof(font->facename); + + return offs; +} + +static long orcad_read_xlibrary_num_names__( + struct io_orcad_rctx_s* const rctx, long offs, + struct orcad_xlibrary_node* const node) +{ + if(3==node->ver_major && 2==node->ver_minor) + { + orcad_uint32_t n; + vread_u32(n); + node->num_names = n; + } + else + { + fprintf(stderr, "Error: Could not read 'num_names': Unhandled " + "version: v%u.%u\n", + (unsigned int)node->ver_major, (unsigned int)node->ver_minor); + return -1; + } + + return offs; +} + +static long orcad_read_library__(struct io_orcad_rctx_s* const rctx, + long offs, struct orcad_node** const out_node) +{ + orcad_uint16_t i; + + struct orcad_node* const parent = NULL; + + orcad_create_xnode(struct orcad_xlibrary_node, ORCAD_TYPE_X_LIBRARY); + + if(sizeof(node->introduction)!=fio_fread(rctx, node->introduction, + sizeof(node->introduction))) + { + fprintf(stderr, "Error: Could not read introduction\n"); + return -1; + } + + offs += sizeof(node->introduction); + + read_u16(ver_major); + read_u16(ver_minor); + read_u32(ctime); + read_u32(mtime); + + if(0>(offs=orcad_skip_field_32(rctx, offs, 0x00000000))) + { + fprintf(stderr, "Error: Unknown 32-bit field is not 0x00000000!\n"); + return -1; + } + + read_u16(num_fonts); + + if(0==node->num_fonts) + { + fprintf(stderr, "Error: Value of 'num_fonts' cannot be zero!\n"); + return -1; + } + + /* number of fonts stored in the file is off-by-one!!! */ + --node->num_fonts; + + if(NULL==(node->fonts=(struct orcad_xlibraryfont*)calloc(node->num_fonts, + sizeof(struct orcad_xlibraryfont)))) + { + fprintf(stderr, "Error: Could not allocate fonts\n"); + return -1; + } + + for(i=0;inum_fonts;++i) + { + if(0>(offs=orcad_read_xlibraryfont__(rctx, offs, &node->fonts[i]))) + { + fprintf(stderr, "Error: Could not read fonts[%u]\n", + (unsigned int)i); + return -1; + } + } + + read_u16(num_unks); + + if(NULL==(node->unks=(orcad_uint16_t*)calloc(node->num_unks, + sizeof(orcad_uint16_t)))) + { + fprintf(stderr, "Error: Could not allocate 'unks'\n"); + return -1; + } + + for(i=0;inum_unks;++i) + { + if(0>(offs=orcad_read_field_u16(rctx, offs, &node->unks[i]))) + { + fprintf(stderr, "Error: Could not read unks[%u]\n", + (unsigned int)i); + return -1; + } + } + + read_u32(unknown_0); + read_u32(unknown_1); + + for(i=0;i<(sizeof(node->partfields)/sizeof(node->partfields[0]));++i) + { + if(0>(offs=orcad_read_string2(rctx, offs, &node->partfields[i]))) + { + fprintf(stderr, "Error: Could not read partfields[%u]\n", + (unsigned int)i); + return -1; + } + } + + if(0>(offs=orcad_read_pagesettings(rctx, offs, &node->settings))) + { + orcad_error_backtrace__(&node->node, "read 'pagesettings'"); + return -1; + } + + if(0>(offs=orcad_read_xlibrary_num_names__(rctx, offs, node))) + { + fprintf(stderr, "Error: Could not read 'num_names'\n"); + return -1; + } + + if(NULL==(node->names=(char**)calloc(node->num_names, sizeof(char*)))) + { + fprintf(stderr, "Error: Could not allocate 'names'\n"); + return -1; + } + + for(i=0;inum_names;++i) + { + if(0>(offs=orcad_read_string2(rctx, offs, &node->names[i]))) + { + fprintf(stderr, "Error: Could not read names[%u]\n", + (unsigned int)i); + return -1; + } + } + + read_u16(num_aliases); + + if(NULL==(node->aliases=(struct orcad_xlibraryalias*)calloc( + node->num_aliases, sizeof(struct orcad_xlibraryalias)))) + { + fprintf(stderr, "Error: Could not allocate 'aliases'\n"); + return -1; + } + + for(i=0;inum_aliases;++i) + { + if(0>(offs=orcad_read_string2(rctx, offs, &node->aliases[i].alias))) + { + fprintf(stderr, "Error: Could not read aliases[%u].alias\n", + (unsigned int)i); + return -1; + } + + if(0>(offs=orcad_read_string2(rctx, offs, &node->aliases[i].package))) + { + fprintf(stderr, "Error: Could not read aliases[%u].package\n", + (unsigned int)i); + return -1; + } + } + + read_u32(unknown_2); + read_u32(unknown_3); + + if(0>(offs=orcad_read_string2(rctx, offs, &node->sch_name))) + { + fprintf(stderr, "Error: Could not read schematic name\n"); + return -1; + } + + return offs; +} + +struct orcad_node* orcad_read_library(struct io_orcad_rctx_s* const rctx) +{ + struct orcad_node* res = NULL; + + long offs = orcad_read_library__(rctx, 0, &res); + + if(0>offs) + { + if(NULL!=res) + { + orcad_free(res); + } + + return NULL; + } + + { + char c; + + if(0 +#include +#include +#include + +long orcad_dump_titleblocks(io_orcad_rctx_t* const rctx, long offs, + int indent, int count, char* buf, const size_t bufsz) +{ + /* for now we just skip the title blocks, they have only a little */ + /* added value, while title block is a quite complex structures */ + + return orcad_skip_objects(rctx, offs, count); +} + +long orcad_read_netalias(io_orcad_rctx_t* const rctx, long offs, + struct orcad_node* const parent, struct orcad_node** const out_node) +{ + orcad_create_xnode(struct orcad_xnetalias_node, ORCAD_TYPE_X_NETALIAS); + + if(0>(offs=orcad_read_string2(rctx, offs, &node->alias))) + { + orcad_error_backtrace__(&node->node, "read net name"); + return -1; + } + + read_u32(net_id); + + return offs; +} + +long orcad_read_wire(io_orcad_rctx_t* const rctx, long offs, + struct orcad_node* const parent, struct orcad_node** const out_node) +{ + /* + 14 3d 00 00 00 00 00 00 00 header_1 + 14 0b 00 00 00 00 00 00 00 header_2 + 14 00 00 ff e4 5c 39 00 00 00 00 header_3 + 11 00 00 00 unk[0] + 45 00 00 00 net_id + 30 00 00 00 color + 5a 00 00 00 start_x + 32 00 00 00 start_y + 82 00 00 00 end_x + 32 00 00 00 end_y + 00 unk[1] + 00 00 num of Alias + 00 00 num of SymbolDisplayProps + 03 00 00 00 linewidth + 05 00 00 00 linestyle + */ + + orcad_uint8_t type; + + if(0>(offs=orcad_peek_field_u8(rctx, offs, &type))) + { + return -1; + } + + switch(type) + { + case ORCAD_TYPE_WIRE: + case 0x15: /* TODO: maybe bus? or bus entry? */ + break; + + default: + fprintf(stderr, "ERROR: Expected WIRE object, got 0x%x\n", + (unsigned int)type); + return -1; + } + + { + orcad_create_node(struct orcad_wire_node, type); + node->node.type = ORCAD_TYPE_WIRE; /* hack it! */ + + read_u32(wire_id); + read_u32(net_id); + read_u32(color); + read_u32(start_x); + read_u32(start_y); + read_u32(end_x); + read_u32(end_y); + read_u8(unknown_0); + + read_u16(num_alias); + + if(0>(offs=orcad_skip_objects(rctx, offs, node->num_alias))) + { + fprintf(stderr, "Error: Could not skip alias objects\n"); + return -1; + } + + read_node_array(displayprop, orcad_read_symboldisplayprop); + + read_u32(line_width); + read_u32(line_style); + } + + return offs; +} + +long orcad_read_netprop(io_orcad_rctx_t* const rctx, long offs, + struct orcad_node* const parent, struct orcad_node** const out_node) +{ + /* + 34 17 00 00 00 00 00 00 00 + 45 00 00 00 net_id + 00 00 00 00 00 00 00 unk[0..6] + 30 00 00 00 color + 05 00 00 00 linewidth + 03 00 00 00 linestyle + */ + + orcad_create_node(struct orcad_netprop_node, ORCAD_TYPE_NETPROP); + + read_u32(net_id); + read_u8(unknown[0]); + read_u8(unknown[1]); + read_u8(unknown[2]); + read_u8(unknown[3]); + read_u8(unknown[4]); + read_u8(unknown[5]); + read_u8(unknown[6]); + read_u32(color); + read_u32(line_width); + read_u32(line_style); + + return offs; +} + +long orcad_read_busprop(io_orcad_rctx_t* const rctx, long offs, + struct orcad_node* const parent, struct orcad_node** const out_node) +{ + orcad_uint16_t i; + + orcad_create_node(struct orcad_busprop_node, ORCAD_TYPE_BUSPROP); + + read_u32(net_id); + read_u8(unknown[0]); + read_u8(unknown[1]); + read_u8(unknown[2]); + read_u8(unknown[3]); + read_u8(unknown[4]); + read_u8(unknown[5]); + read_u8(unknown[6]); + read_u32(color); + read_u32(line_width); + read_u32(line_style); + read_u16(num_busnetids); + + if(NULL==(node->busnetids=(orcad_uint32_t*)calloc(node->num_busnetids, + sizeof(orcad_uint32_t)))) + { + fprintf(stderr, "Error: Could not allocate memory for busnetids\n"); + return -1; + } + + for(i=0;inum_busnetids;++i) + { + read_u32(busnetids[i]); + } + + return offs; +} + +static long orcad_read_graphicinst_inline(io_orcad_rctx_t* const rctx, + long offs, struct orcad_graphicinst_node* const node, + const orcad_uint32_t size) +{ + orcad_uint8_t type; + + read_u32(graphic.instname_idx); + read_u32(graphic.libpath_idx); + + if(0>(offs=orcad_read_string2(rctx, offs, &node->graphic.name))) + { + fprintf(stderr, "Error: Could not read name\n"); + return -1; + } + + read_u32(graphic.db_id); + read_i16(graphic.y1); + read_i16(graphic.x1); + read_i16(graphic.y2); + read_i16(graphic.x2); + read_i16(graphic.x); + read_i16(graphic.y); + read_u8(graphic.color); + read_u8(graphic.rotation); + read_u8(graphic.unknown_2); + read_u8(graphic.unknown_3); + + if(0x4 & node->graphic.rotation) + { + node->graphic.mirrored = 1; + node->graphic.rotation ^= 0x4; + } + + read_u16(graphic.num_displayprops); + if(0>(offs=orcad_read_nodes__(rctx, offs, &node->node, + (struct orcad_node***)&node->graphic.displayprops, + node->graphic.num_displayprops, orcad_read_symboldisplayprop))) + { + orcad_error_backtrace__(&node->node, "read 'displayprops'"); + return -1; + } + + if(sizeof(type)!=fio_fread(rctx, (char*)&type, sizeof(type))) + { + fprintf(stderr, "Error: Could not read type field\n"); + return -1; + } + + offs += sizeof(type); + + switch(type) + { + case ORCAD_TYPE_INLINEPAGEOBJECT: + if(0>(offs=orcad_read_inlinepageobject(rctx, offs, &node->node, + (struct orcad_node**)&node->graphic.obj))) + { + return -1; + } + break; + + case ORCAD_TYPE_GLOBALSYMBOL: + case ORCAD_TYPE_OFFPAGECONNSYMBOL: + case ORCAD_TYPE_PORTSYMBOL: + break; + + default: + fprintf(stderr, "Error: Unexpected graphic object type: 0x%x\n", + (unsigned int)type); + return -1; + } + + node->graphic.type = type; + + return offs; +} + +long orcad_read_global(io_orcad_rctx_t* const rctx, long offs, + struct orcad_node* const parent, struct orcad_node** const out_node) +{ + /* + 25 39 00 00 00 00 00 00 00 header-1 + 25 0b 00 00 00 00 00 00 00 header-2 + 25 00 00 ff e4 5c 39 00 00 00 00 header-3 + 19 00 00 00 unk-0 + 0e 00 00 00 unk-1 + 03 00 47 4e 44 00 name + 9c 00 00 00 db_id + 46 00 y1 + 50 00 x1 + 50 00 y2 + 64 00 x2 + 50 00 x + 46 00 y + 30 color + 00 rotation + 25 unk-2 (seems to be always 0x25) + 2d unk-3 + 00 00 num_displayprops + 21 unk-4 (seems to be always 0x21) + + extra 5 bytes, after the object + a2 00 00 00 wire_id + 00 x-unk-0 + */ + + orcad_create_node(struct orcad_global_node, ORCAD_TYPE_GLOBAL); + + if(0>(offs=orcad_read_graphicinst_inline(rctx, offs, + (struct orcad_graphicinst_node*)node, node->node.size-5))) + { + return -1; + } + + /* this is a nasty object, it has 5 extra bytes after the object */ + /* (why it is not part of the object then?) */ + + read_u32(wire_id); + read_u8(unknown_0); + + return offs; +} + +long orcad_read_offpageconn(io_orcad_rctx_t* const rctx, long offs, + struct orcad_node* const parent, struct orcad_node** const out_node) +{ + orcad_create_node(struct orcad_offpageconn_node, ORCAD_TYPE_OFFPAGECONN); + + if(0>(offs=orcad_read_graphicinst_inline(rctx, offs, + (struct orcad_graphicinst_node*)node, node->node.size-5))) + { + return -1; + } + + /* this is a nasty object, it has 5 extra bytes after the object */ + /* (why it is not part of the object then?) */ + + read_u32(wire_id); + read_u8(unknown_0); + + return offs; +} + +long orcad_read_graphicinst(io_orcad_rctx_t* const rctx, long offs, + struct orcad_node* const parent, struct orcad_node** const out_node) +{ + struct orcad_header hdr; + struct orcad_namemapping_info nmi; + + if(0>(offs=orcad_parse_header(rctx, offs, &hdr, &nmi))) + { + fprintf(stderr, "Error: Could not read graphicinst header\n"); + return -1; + } + + switch(hdr.type) + { + case ORCAD_TYPE_GRAPHICBOXINST: + case ORCAD_TYPE_GRAPHICLINEINST: + case ORCAD_TYPE_GRAPHICARCINST: + case ORCAD_TYPE_GRAPHICELLIPSEINST: + case ORCAD_TYPE_GRAPHICPOLYGONINST: + case ORCAD_TYPE_GRAPHICTEXTINST: + case ORCAD_TYPE_GRAPHICBEZIERINST: + break; + + default: + fprintf(stderr, "Error: Unhandled graphic instance type: 0x%x\n", + (unsigned int)hdr.type); + return -1; + } + + { + orcad_create_node_from(struct orcad_graphicinst_node, hdr.type, &hdr, + &nmi); + + if(0>(offs=orcad_read_graphicinst_inline(rctx, offs, + (struct orcad_graphicinst_node*)node, node->node.size))) + { + return -1; + } + } + + return offs; +} + +long orcad_read_pinconnection(io_orcad_rctx_t* const rctx, long offs, + struct orcad_node* const parent, struct orcad_node** const out_node) +{ + orcad_int16_t idx; + + orcad_create_node(struct orcad_pinconnection_node, + ORCAD_TYPE_PINCONNECTION); + + if(0>(offs=orcad_read_field_i16(rctx, offs, &idx))) + { + fprintf(stderr, "Error: Could not read pin_idx field\n"); + return -1; + } + + if(0<=idx) + { + node->nc = 0; + node->idx = idx; + } + else + { + node->nc = 1; + node->idx = -idx; + } + + read_u16(x); + read_u16(y); + read_i32(wire_id); + read_u32(net_id); + + read_node_array(displayprop, orcad_read_symboldisplayprop); + + return offs; +} + +long orcad_read_partinst(io_orcad_rctx_t* const rctx, long offs, + struct orcad_node* const parent, struct orcad_node** const out_node) +{ + orcad_create_node(struct orcad_partinst_node, ORCAD_TYPE_PARTINST); + + read_u32(instname_idx); + read_u32(libpath_idx); + + if(0>(offs=orcad_read_string2(rctx, offs, &node->name))) + { + fprintf(stderr, "Error: Could not read name\n"); + return -1; + } + + read_u32(db_id); + read_i16(y1); + read_i16(x1); + read_i16(y2); + read_i16(x2); + read_i16(x); + read_i16(y); + read_u8(color); + read_u8(rotation); + read_u16(unknown_4); + + if(0x4 & node->rotation) + { + node->mirrored = 1; + node->rotation ^= 0x4; + } + + read_node_array(displayprop, orcad_read_symboldisplayprop); + + read_u8(unknown_5); + + if(0>(offs=orcad_read_string2(rctx, offs, &node->refdes))) + { + fprintf(stderr, "Error: Could not read refdes\n"); + return -1; + } + + read_u32(value_idx); + read_u32(unknown_7); + read_u32(unknown_8); + read_u16(flags); + node->power_pins_visible = !!(0x8000 & node->flags); + node->primitive = 0x3 & node->flags; + + read_node_array(pinconnection, orcad_read_pinconnection); + + if(0>(offs=orcad_read_string2(rctx, offs, &node->symname))) + { + fprintf(stderr, "Error: Could not read symname\n"); + return -1; + } + + read_u16(pim_idx); + + return offs; +} + +long orcad_read_port(io_orcad_rctx_t* const rctx, long offs, + struct orcad_node* const parent, struct orcad_node** const out_node) +{ + orcad_create_node(struct orcad_port_node, ORCAD_TYPE_PORT); + + if(0>(offs=orcad_read_graphicinst_inline(rctx, offs, + (struct orcad_graphicinst_node*)node, node->node.size-9))) + { + return -1; + } + + read_u32(wire_id); + read_u8(unknown_0); + read_u32(unknown_1); + + return offs; +} + +static int orcad_cmp_netalias(const void* p_lhs, const void* p_rhs) +{ + const struct orcad_xnetalias_node* const lhs = + *(const struct orcad_xnetalias_node**)p_lhs; + + const struct orcad_xnetalias_node* const rhs = + *(const struct orcad_xnetalias_node**)p_rhs; + + return strcmp(lhs->alias, rhs->alias); +} + +long orcad_read_page(io_orcad_rctx_t* const rctx, long offs, + struct orcad_node** const out_node, const struct orcad_header* const p_hdr, + struct orcad_namemapping_info* const nmi) +{ + orcad_uint16_t i; + + struct orcad_node* const parent = NULL; + + orcad_create_node_from(struct orcad_page_node, ORCAD_TYPE_PAGE, p_hdr, + nmi); + + /* ---- page name and size */ + + if(0>(offs=orcad_read_string2(rctx, offs, &node->page_name))) + { + fprintf(stderr, "Error: Could not read page name\n"); + return -1; + } + + if(0>(offs=orcad_read_string2(rctx, offs, &node->page_size))) + { + fprintf(stderr, "Error: Could not read page size\n"); + return -1; + } + + /* ---- page settings */ + + if(0>(offs=orcad_read_pagesettings(rctx, offs, &node->settings))) + { + orcad_error_backtrace__(&node->node, "read 'pagesettings'"); + return -1; + } + + /* ---- objects */ + + /* title blocks */ + + read_u16(num_titleblocks); + if(0>(offs=orcad_skip_objects(rctx, offs, node->num_titleblocks))) + { + fprintf(stderr, "Error: Could not skip titleblocks\n"); + return -1; + } + + /* net properties */ + + read_node_array(netprop, orcad_read_netprop); + + /* bus properties */ + + read_node_array(netprop, orcad_read_busprop); + + /* netalias-ID pairs */ + + read_u16(num_netaliases); + if(NULL==(node->netaliases=(struct orcad_xnetalias_node**)calloc( + node->num_netaliases, sizeof(struct orcad_xnetalias_node*)))) + { + fprintf(stderr, "Error: Could not allocate memory for netaliases\n"); + return -1; + } + for(i=0;inum_netaliases;++i) + { + if(0>(offs=orcad_read_netalias(rctx, offs, &node->node, + (struct orcad_node**)&node->netaliases[i]))) + { + return -1; + } + } + /* netaliases are placed into the file in random order, and the order */ + /* can change from save to save, so better to sort them */ + qsort(node->netaliases, node->num_netaliases, sizeof(node->netaliases[0]), + orcad_cmp_netalias); + + /* wires */ + + read_node_array(wire, orcad_read_wire); + + /* part instances */ + + read_node_array(partinst, orcad_read_partinst); + + /* ports */ + + read_node_array(port, orcad_read_port); + + /* globals */ + + read_node_array(global, orcad_read_global); + + /* off-page connectors */ + + read_node_array(offpageconn, orcad_read_offpageconn); + + /* ERC symbols instances */ + + read_u16(num_ercsymbolinsts); + if(0>(offs=orcad_skip_objects(rctx, offs, node->num_ercsymbolinsts))) + { + fprintf(stderr, "Error: Could not read ercsymbolinsts\n"); + return -1; + } + + /* busentries */ + + read_u16(num_busentries); + if(0>(offs=orcad_skip_objects(rctx, offs, node->num_busentries))) + { + fprintf(stderr, "Error: Could not read busentries\n"); + return -1; + } + + /* graphic instances */ + + read_node_array(graphicinst, orcad_read_graphicinst); + + /* unknown #10 */ + + read_u16(num_unk10); + if(0>(offs=orcad_skip_objects(rctx, offs, node->num_unk10))) + { + fprintf(stderr, "Error: Could not skip unk10 objects\n"); + return -1; + } + + /* unknown #11 */ + + read_u16(num_unk11); + if(0>(offs=orcad_skip_objects(rctx, offs, node->num_unk11))) + { + fprintf(stderr, "Error: Could not skip unk11 objects\n"); + return -1; + } + + return offs; +} + +struct orcad_node* orcad_read(io_orcad_rctx_t* const rctx) +{ + struct orcad_node* res; + struct orcad_header hdr; + struct orcad_namemapping_info nmi; + long offs = orcad_parse_header(rctx, 0, &hdr, &nmi); + + if(0>offs) + { + fprintf(stderr, "Error: Could not parse the initial header of '%s'\n", + rctx->fn); + return NULL; + } + + res = NULL; + + switch(hdr.type) + { + case ORCAD_TYPE_PAGE: + offs = orcad_read_page(rctx, offs, &res, &hdr, &nmi); + break; + + default: + fprintf(stderr, "Error: '%s' has an unknown root header type: 0x%x\n", + rctx->fn, (unsigned int)hdr.type); + return NULL; + } + + if(0>offs) + { + fprintf(stderr, "Error: Reading '%s' failed\n", rctx->fn); + + if(NULL!=res) + { + orcad_free(res); + } + + return NULL; + } + + { + char c; + + if(0 +#include +#include +#include +#include + +static long orcad_read_primitive__(io_orcad_rctx_t* const rctx, long offs, + struct orcad_prim** const out_prim, const int with_zerobyte); + +static long test_remaining_size(io_orcad_rctx_t* const rctx, const long offs, + const long end, const size_t size) +{ + const long target_offs = offs + size; + + if(0!=fio_fseek(rctx, target_offs)) + { + return -1; + } + + if(orcad_is_end_or_magic(rctx, target_offs, end)) + { + if(0!=fio_fseek(rctx, offs)) + { + return -1; + } + + return offs; + } + + return -1; +} + +static long orcad_read_point(io_orcad_rctx_t* const rctx, long offs, + struct orcad_point* const pt) +{ + /* points are in Y,X order! */ + + if(0>(offs=orcad_read_field_i16(rctx, offs, &pt->y)) || + 0>(offs=orcad_read_field_i16(rctx, offs, &pt->x))) + { + return -1; + } + + return offs; +} + +#define create_prim(_typename_, _primtype_) \ + _typename_* const prim = (_typename_*)malloc(sizeof(_typename_)); \ + if(NULL==prim) \ + { \ + fprintf(stderr, "Error: Could not allocate primitive: %s\n", \ + #_primtype_); \ + return -1; \ + } \ + *out_prim = &prim->prim; \ + memset(prim, 0, sizeof(*prim)); \ + prim->prim.type = (_primtype_); \ + prim->prim.offs = offs + +static long orcad_read_prim_text(io_orcad_rctx_t* const rctx, long offs, + orcad_uint32_t size, struct orcad_prim** const out_prim) +{ + create_prim(struct orcad_text_prim, ORCAD_PRIMITIVE_TEXT); + + vread_i32(prim->x); + vread_i32(prim->y); + vread_i32(prim->x2); + vread_i32(prim->y2); + vread_i32(prim->x1); + vread_i32(prim->y1); + vread_u16(prim->font_id); + vread_u16(prim->unknown_0); + + if(0>(offs=orcad_read_string2(rctx, offs, &prim->text))) + { + fprintf(stderr, "Error: Could not read name\n"); + return -1; + } + + return offs; +} + +static long orcad_read_prim_line(io_orcad_rctx_t* const rctx, long offs, + orcad_uint32_t size, struct orcad_prim** const out_prim) +{ + const long end = offs+size; + + create_prim(struct orcad_line_prim, ORCAD_PRIMITIVE_LINE); + + vread_i32(prim->x1); + vread_i32(prim->y1); + vread_i32(prim->x2); + vread_i32(prim->y2); + + if(!orcad_is_end_or_magic(rctx, offs, end)) + { + prim->have_line_style = 1; + vread_u32(prim->line_style); + vread_u32(prim->line_width); + } + + return offs; +} + +static long orcad_read_prim_rect(io_orcad_rctx_t* const rctx, long offs, + orcad_uint32_t size, struct orcad_prim** const out_prim) +{ + const long end = offs+size; + + create_prim(struct orcad_rect_prim, ORCAD_PRIMITIVE_RECT); + + vread_i32(prim->x1); + vread_i32(prim->y1); + vread_i32(prim->x2); + vread_i32(prim->y2); + + if(!orcad_is_end_or_magic(rctx, offs, end)) + { + prim->have_line_style = 1; + vread_u32(prim->line_style); + vread_u32(prim->line_width); + } + + if(!orcad_is_end_or_magic(rctx, offs, end)) + { + prim->have_fill_style = 1; + vread_u32(prim->fill_style); + vread_u32(prim->hatch_style); + } + + return offs; +} + +static long orcad_read_prim_arc(io_orcad_rctx_t* const rctx, long offs, + orcad_uint32_t size, struct orcad_prim** const out_prim) +{ + const long end = offs+size; + + create_prim(struct orcad_arc_prim, ORCAD_PRIMITIVE_ARC); + + vread_i32(prim->x1); + vread_i32(prim->y1); + vread_i32(prim->x2); + vread_i32(prim->y2); + vread_i32(prim->start_x); + vread_i32(prim->start_y); + vread_i32(prim->end_x); + vread_i32(prim->end_y); + + if(!orcad_is_end_or_magic(rctx, offs, end)) + { + prim->have_line_style = 1; + vread_u32(prim->line_style); + vread_u32(prim->line_width); + } + + return offs; +} + +static long orcad_read_prim_ellipse(io_orcad_rctx_t* const rctx, long offs, + orcad_uint32_t size, struct orcad_prim** const out_prim) +{ + const long end = offs+size; + + create_prim(struct orcad_ellipse_prim, ORCAD_PRIMITIVE_ELLIPSE); + + vread_i32(prim->x1); + vread_i32(prim->y1); + vread_i32(prim->x2); + vread_i32(prim->y2); + + if(!orcad_is_end_or_magic(rctx, offs, end)) + { + prim->have_line_style = 1; + vread_u32(prim->line_style); + vread_u32(prim->line_width); + } + + if(!orcad_is_end_or_magic(rctx, offs, end)) + { + prim->have_fill_style = 1; + vread_u32(prim->fill_style); + vread_u32(prim->hatch_style); + } + + return offs; +} + +/* + -- polygon -- + + there are 3 versions: + + (1) + POINT_COUNT_16 [Y X]... + + (2) + LINE_STYLE_32 LINE_WIDTH_32 POINT_COUNT_16 [Y X]... + + (3) + LINE_STYLE_32 LINE_WIDTH_32 FILL_STYLE_32 HATCH_STYLE_32 POINT_COUNT_16 [Y X]... +*/ + +static const int orcad_polygon_num_V = 3; + +static long orcad_read_prim_polygon_V(io_orcad_rctx_t* const rctx, long offs, + orcad_uint32_t size, struct orcad_prim** const out_prim, const int V) +{ + const long end = offs+size; + + orcad_uint16_t cnt; + orcad_uint16_t i; + orcad_uint32_t line_style; + orcad_uint32_t line_width; + orcad_uint32_t fill_style; + orcad_uint32_t hatch_style; + + if(0!=fio_fseek(rctx, offs)) + { + fprintf(stderr, "Error: Seek to polygon payload (offs %ld) failed\n", + offs); + return -1; + } + + if(1(offs=orcad_read_field_u32(rctx, offs, &line_style)) || + 0>(offs=orcad_read_field_u32(rctx, offs, &line_width))) + { + fprintf(stderr, "Error: Could not read polygon style\n"); + return -1; + } + } + + if(2(offs=orcad_read_field_u32(rctx, offs, &fill_style)) || + 0>(offs=orcad_read_field_u32(rctx, offs, &hatch_style))) + { + fprintf(stderr, "Error: Could not read polygon style\n"); + return -1; + } + } + + if(0>(offs=orcad_read_field_u16(rctx, offs, &cnt))) + { + fprintf(stderr, "Error: Could not read polygon point count\n"); + return -1; + } + + /* 2 coords, 2 byte each, 'cnt' count */ + if(0>(offs=test_remaining_size(rctx, offs, end, 2*2*cnt))) + { + /* invariant violation */ + return -1; + } + + { + create_prim(struct orcad_polygon_prim, ORCAD_PRIMITIVE_POLYGON); + + if(1have_line_style = 1; + prim->line_style = line_style; + prim->line_width = line_width; + } + + if(2have_fill_style = 1; + prim->fill_style = fill_style; + prim->hatch_style = hatch_style; + } + + prim->num_points = cnt; + + if(NULL==(prim->points=(struct orcad_point*)calloc(cnt, + sizeof(struct orcad_point)))) + { + fprintf(stderr, "Error: Coult not allocate memory for polygon " + "points\n"); + orcad_free_primitive(&prim->prim); + *out_prim = NULL; + return -1; + } + + for(i=0;i(offs=orcad_read_point(rctx, offs, &prim->points[i]))) + { + fprintf(stderr, "Error: Could not read point of polygon prim\n"); + orcad_free_primitive(&prim->prim); + *out_prim = NULL; + return -1; + } + } + } + + return offs; +} + +static long orcad_read_prim_polygon(io_orcad_rctx_t* const rctx, long offs, + orcad_uint32_t size, struct orcad_prim** const out_prim) +{ + long offs2; + int v; + + for(v=1;v<=orcad_polygon_num_V;++v) + { + if(0<=(offs2=orcad_read_prim_polygon_V(rctx, offs, size, out_prim, v))) + { + break; + } + } + + if(orcad_polygon_num_V(offs=orcad_read_field_u32(rctx, offs, &line_style)) || + 0>(offs=orcad_read_field_u32(rctx, offs, &line_width))) + { + fprintf(stderr, "Error: Could not read polyline style\n"); + return -1; + } + } + + if(0>(offs=orcad_read_field_u16(rctx, offs, &cnt))) + { + fprintf(stderr, "Error: Could not read polyline point count\n"); + return -1; + } + + /* 2 coords, 2 byte each, 'cnt' count */ + if(0>(offs=test_remaining_size(rctx, offs, end, 2*2*cnt))) + { + /* invariant violation */ + return -1; + } + + { + create_prim(struct orcad_polyline_prim, ORCAD_PRIMITIVE_POLYLINE); + + if(1have_line_style = 1; + prim->line_style = line_style; + prim->line_width = line_width; + } + + prim->num_points = cnt; + + if(NULL==(prim->points=(struct orcad_point*)calloc(cnt, + sizeof(struct orcad_point)))) + { + fprintf(stderr, "Error: Coult not allocate memory for polyline " + "points\n"); + orcad_free_primitive(&prim->prim); + *out_prim = NULL; + return -1; + } + + for(i=0;i(offs=orcad_read_point(rctx, offs, &prim->points[i]))) + { + fprintf(stderr, "Error: Could not read point of polyline prim\n"); + orcad_free_primitive(&prim->prim); + *out_prim = NULL; + return -1; + } + } + } + + return offs; +} + +static long orcad_read_prim_polyline(io_orcad_rctx_t* const rctx, long offs, + orcad_uint32_t size, struct orcad_prim** const out_prim) +{ + long offs2; + int v; + + for(v=1;v<=orcad_polyline_num_V;++v) + { + if(0<=(offs2=orcad_read_prim_polyline_V(rctx, offs, size, out_prim, v))) + { + break; + } + } + + if(orcad_polyline_num_V(offs=orcad_read_field_u32(rctx, offs, &line_style)) || + 0>(offs=orcad_read_field_u32(rctx, offs, &line_width))) + { + fprintf(stderr, "Error: Could not read bezier style\n"); + return -1; + } + } + + if(0>(offs=orcad_read_field_u16(rctx, offs, &cnt))) + { + fprintf(stderr, "Error: Could not read bezier point count\n"); + return -1; + } + + /* 2 coords, 2 byte each, 'cnt' count */ + if(4>cnt || 0!=((cnt-1)%3) || 0>(offs=test_remaining_size(rctx, offs, end, + 2*2*cnt))) + { + /* invariant violation */ + return -1; + } + + { + create_prim(struct orcad_bezier_prim, ORCAD_PRIMITIVE_BEZIER); + + if(1have_line_style = 1; + prim->line_style = line_style; + prim->line_width = line_width; + } + + prim->num_segments = (cnt - 1) / 3; + + if(NULL==(prim->segments=(struct orcad_bsegment*)calloc( + prim->num_segments, sizeof(struct orcad_bsegment)))) + { + orcad_free_primitive(&prim->prim); + *out_prim = NULL; + return -1; + } + + /* + adjacent bezier segments share 1 point: end point of a segment is + the start point of the subsequent bezier segment -- this is done + in the code below + */ + + if(0>(offs=orcad_read_point(rctx, offs, &p))) + { + fprintf(stderr, "Error: Could not read first point of bezier prim\n"); + orcad_free_primitive(&prim->prim); + *out_prim = NULL; + return -1; + } + + for(i=0;inum_segments;++i) + { + memcpy(&prim->segments[i].p1, &p, sizeof(p)); + + if(0>(offs=orcad_read_point(rctx, offs, &prim->segments[i].p2)) || + 0>(offs=orcad_read_point(rctx, offs, &prim->segments[i].p3)) || + 0>(offs=orcad_read_point(rctx, offs, &prim->segments[i].p4))) + { + fprintf(stderr, "Error: Could not read points of bezier prim\n"); + orcad_free_primitive(&prim->prim); + *out_prim = NULL; + return -1; + } + + /* copy shared start/end point */ + memcpy(&p, &prim->segments[i].p4, sizeof(p)); + } + } + + return offs; +} + +static long orcad_read_prim_bezier(io_orcad_rctx_t* const rctx, long offs, + orcad_uint32_t size, struct orcad_prim** const out_prim) +{ + long offs2; + int v; + + for(v=1;v<=orcad_bezier_num_V;++v) + { + if(0<=(offs2=orcad_read_prim_bezier_V(rctx, offs, size, out_prim, v))) + { + break; + } + } + + if(orcad_bezier_num_Vx); + vread_i16(prim->y); + vread_u16(prim->num_primitives); + + if(NULL==(prim->primitives=(struct orcad_prim**)calloc( + prim->num_primitives, sizeof(struct orcad_prim*)))) + { + fprintf(stderr, "Error: Could not allocate memory for primitives\n"); + return -1; + } + + for(i=0;inum_primitives;++i) + { + if(0>(offs=orcad_read_primitive__(rctx, offs, &prim->primitives[i], 1))) + { + fprintf(stderr, "Error: Could not read primitive #%lu\n", + (unsigned long)i); + return -1; + } + } + + if(0>(offs=orcad_read_string2(rctx, offs, &prim->name))) + { + fprintf(stderr, "Error: Could not read name\n"); + return -1; + } + + return offs; +} + +static long orcad_read_primitive__(io_orcad_rctx_t* const rctx, long offs, + struct orcad_prim** const out_prim, const int with_zerobyte) +{ + const long start_offs = offs; + + orcad_uint8_t ptype; + + struct orcad_header hdr; + struct orcad_namemapping_info nmi; + + /* it seems, the primitve type is stored twice */ + + if(sizeof(ptype)!=fio_fread(rctx, (char*)&ptype, sizeof(ptype))) + { + fprintf(stderr, "Error: Could not read primitive type\n"); + return -1; + } + + offs += sizeof(ptype); + + if(with_zerobyte) + { + if(0>(offs=orcad_skip_field_8(rctx, offs, 0x00))) + { + fprintf(stderr, "Error: Could not skip 0x00 byte before prim " + "header\n"); + return -1; + } + } + + if(0>(offs=orcad_parse_header(rctx, offs, &hdr, &nmi))) + { + fprintf(stderr, "Error: Could not parse prim header\n"); + return -1; + } + + if(ptype!=hdr.type) + { + fprintf(stderr, "Error: Primitive types do not match\n"); + return -1; + } + + switch(hdr.type) + { + case ORCAD_PRIMITIVE_TEXT: + offs = orcad_read_prim_text(rctx, offs, hdr.size, out_prim); + break; + + case ORCAD_PRIMITIVE_LINE: + offs = orcad_read_prim_line(rctx, offs, hdr.size, out_prim); + break; + + case ORCAD_PRIMITIVE_RECT: + offs = orcad_read_prim_rect(rctx, offs, hdr.size, out_prim); + break; + + case ORCAD_PRIMITIVE_ARC: + offs = orcad_read_prim_arc(rctx, offs, hdr.size, out_prim); + break; + + case ORCAD_PRIMITIVE_ELLIPSE: + offs = orcad_read_prim_ellipse(rctx, offs, hdr.size, out_prim); + break; + + case ORCAD_PRIMITIVE_POLYGON: + offs = orcad_read_prim_polygon(rctx, offs, hdr.size, out_prim); + break; + + case ORCAD_PRIMITIVE_POLYLINE: + offs = orcad_read_prim_polyline(rctx, offs, hdr.size, out_prim); + break; + + case ORCAD_PRIMITIVE_BEZIER: + offs = orcad_read_prim_bezier(rctx, offs, hdr.size, out_prim); + break; + + case ORCAD_PRIMITIVE_SYMBOLVECTOR: + offs = orcad_read_prim_symbolvector(rctx, offs, hdr.size, out_prim); + break; + + default: + fprintf(stderr, + "Error: Unhandled primitive type: 0x%x, (offs: 0x%lx)\n", + (unsigned int)hdr.type, start_offs); + return -1; + } + + if(0>offs) + { + return offs; + } + + return orcad_skip_magic(rctx, offs); +} + +long orcad_read_primitive(io_orcad_rctx_t* const rctx, long offs, + struct orcad_prim** const out_prim) +{ + return orcad_read_primitive__(rctx, offs, out_prim, 0); +} Property changes on: tags/1.0.5/src/plugins/io_orcad/read_prim.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Index: tags/1.0.5/src/plugins/io_orcad/tester/Makefile =================================================================== --- tags/1.0.5/src/plugins/io_orcad/tester/Makefile (nonexistent) +++ tags/1.0.5/src/plugins/io_orcad/tester/Makefile (revision 10414) @@ -0,0 +1,57 @@ +OBJS_COMMON=read_fio.o read_common.o read_prim.o read_dump.o read_free.o +OBJS_PAGE=page.o read_page.o +OBJS_CACHE=cache.o read_cache.o +OBJS_LIBRARY=library.o read_library.o +CFLAGS=-g -DORCAD_TESTER -I.. -I. + +default: all + +all: page cache library + +clean: + rm -f $(OBJS_COMMON) + rm -f page $(OBJS_PAGE) + rm -f cache $(OBJS_CACHE) + rm -f library $(OBJS_LIBRARY) + +page: $(OBJS_PAGE) $(OBJS_COMMON) + $(CC) -o page $(OBJS_PAGE) $(OBJS_COMMON) + +cache: $(OBJS_CACHE) $(OBJS_COMMON) + $(CC) -o cache $(OBJS_CACHE) $(OBJS_COMMON) + +library: $(OBJS_LIBRARY) $(OBJS_COMMON) + $(CC) -o library $(OBJS_LIBRARY) $(OBJS_COMMON) + +read_fio.o: read_fio.c read_fio.h + $(CC) $(CFLAGS) -o read_fio.o -c read_fio.c + +page.o: page.c read_fio.h ../read_parse.h + $(CC) $(CFLAGS) -o page.o -c page.c + +read_common.o: ../read_common.c ../read_common.h read_fio.h + $(CC) $(CFLAGS) -o read_common.o -c ../read_common.c + +read_prim.o: ../read_prim.c ../read_common.h read_fio.h + $(CC) $(CFLAGS) -o read_prim.o -c ../read_prim.c + +read_page.o: ../read_page.c ../read_common.h read_fio.h + $(CC) $(CFLAGS) -o read_page.o -c ../read_page.c + +read_cache.o: ../read_cache.c ../read_common.h read_fio.h + $(CC) $(CFLAGS) -o read_cache.o -c ../read_cache.c + +read_dump.o: ../read_dump.c ../read_common.h + $(CC) $(CFLAGS) -o read_dump.o -c ../read_dump.c + +read_free.o: ../read_free.c ../read_common.h + $(CC) $(CFLAGS) -o read_free.o -c ../read_free.c + +cache.o: cache.c ../read_common.h read_fio.h + $(CC) $(CFLAGS) -o cache.o -c cache.c + +library.o: library.c ../read_common.h read_fio.h + $(CC) $(CFLAGS) -o library.o -c library.c + +read_library.o: ../read_library.c ../read_common.h + $(CC) $(CFLAGS) -o read_library.o -c ../read_library.c Property changes on: tags/1.0.5/src/plugins/io_orcad/tester/Makefile ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Index: tags/1.0.5/src/plugins/io_orcad/tester/cache.c =================================================================== --- tags/1.0.5/src/plugins/io_orcad/tester/cache.c (nonexistent) +++ tags/1.0.5/src/plugins/io_orcad/tester/cache.c (revision 10414) @@ -0,0 +1,43 @@ +#include "read_fio.h" +#include "read_parse.h" +#include +#include + +int main(int argc, char* argv[]) +{ + int i; + + if(1>=argc) + { + fprintf(stderr, "Usage: %s ORCAD_CACHE_FILE...\n", argv[0]); + return 1; + } + + for(i=1;i +#include + +int main(int argc, char* argv[]) +{ + int i; + + if(1>=argc) + { + fprintf(stderr, "Usage: %s ORCAD_LIBRARY_FILE...\n", argv[0]); + return 1; + } + + for(i=1;i +#include + +int main(int argc, char* argv[]) +{ + int i; + + if(1>=argc) + { + fprintf(stderr, "Usage: %s ORCAD_PAGE_FILE...\n", argv[0]); + return 1; + } + + for(i=1;i +#include + +int fio_fopen(io_orcad_rctx_t* const rctx, const char* filename) +{ + if(NULL!=(rctx->file=fopen(filename, "rb"))) + { + return 0; + } + + rctx->err = errno; + + return -1; +} + +long fio_fread(io_orcad_rctx_t* const rctx, char* dst, long len) +{ + return fread(dst, 1, len, rctx->file); +} + +int fio_fseek(io_orcad_rctx_t* const rctx, long offs) +{ + return fseek(rctx->file, offs, SEEK_SET); +} + +int fio_fclose(io_orcad_rctx_t* const rctx) +{ + fclose(rctx->file); +} Property changes on: tags/1.0.5/src/plugins/io_orcad/tester/read_fio.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Index: tags/1.0.5/src/plugins/io_orcad/tester/read_fio.h =================================================================== --- tags/1.0.5/src/plugins/io_orcad/tester/read_fio.h (nonexistent) +++ tags/1.0.5/src/plugins/io_orcad/tester/read_fio.h (revision 10414) @@ -0,0 +1,24 @@ +#ifndef FIO_H +#define FIO_H + +#include +#undef fopen + +/* similar API to libucdf/ucdf.h */ + +#include + +typedef struct io_orcad_rctx_s +{ + const char* fn; + + FILE* file; + int err; /* libucdf have err in ctx, but we don't have ctx */ +} io_orcad_rctx_t; + +int fio_fopen(io_orcad_rctx_t* const rctx, const char* filename); +long fio_fread(io_orcad_rctx_t* const rctx, char* dst, long len); +int fio_fseek(io_orcad_rctx_t* const rctx, long offs); +int fio_fclose(io_orcad_rctx_t* const rctx); /* not in libucdf */ + +#endif /* FIO_H */ Property changes on: tags/1.0.5/src/plugins/io_orcad/tester/read_fio.h ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Index: tags/1.0.5/src/plugins/io_tinycad/Makefile =================================================================== --- tags/1.0.5/src/plugins/io_tinycad/Makefile (nonexistent) +++ tags/1.0.5/src/plugins/io_tinycad/Makefile (revision 10414) @@ -0,0 +1,2 @@ +all: + cd ../../sch-rnd && make mod_io_tinycad Index: tags/1.0.5/src/plugins/io_tinycad/Plug.tmpasm =================================================================== --- tags/1.0.5/src/plugins/io_tinycad/Plug.tmpasm (nonexistent) +++ tags/1.0.5/src/plugins/io_tinycad/Plug.tmpasm (revision 10414) @@ -0,0 +1,23 @@ +put /local/rnd/mod {io_tinycad} +put /local/rnd/mod/OBJS [@ + $(PLUGDIR)/io_tinycad/io_tinycad.o + $(PLUGDIR)/io_tinycad/read.o +@] + +put /local/rnd/mod/CONFFILE {io_tinycad.conf} +put /local/rnd/mod/CONF {$(PLUGDIR)/io_tinycad/io_tinycad_conf.h} +put /local/rnd/mod/CONFVAR {io_tinycad_conf_internal} + +switch /local/module/io_tinycad/controls + case {disable} end; + default + put /local/rnd/mod/CFLAGS /target/libs/sul/libxml2/cflags + put /local/rnd/mod/LDFLAGS /target/libs/sul/libxml2/ldflags + end +end + +switch /local/module/io_tinycad/controls + case {buildin} include /local/csch/tmpasm/buildin; end; + case {plugin} include /local/csch/tmpasm/plugin; end; + case {disable} include /local/csch/tmpasm/disable; end; +end Index: tags/1.0.5/src/plugins/io_tinycad/io_tinycad.c =================================================================== --- tags/1.0.5/src/plugins/io_tinycad/io_tinycad.c (nonexistent) +++ tags/1.0.5/src/plugins/io_tinycad/io_tinycad.c (revision 10414) @@ -0,0 +1,85 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - tinycad file format support + * Copyright (C) 2022, 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022 and Entrust in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + + +#include +#include +#include +#include +#include +#include "read.h" + +#include "io_tinycad_conf.h" +#include "conf_internal.c" + +conf_io_tinycad_t io_tinycad_conf; +static csch_plug_io_t tinycad; +static char tinycad_cookie[] = "io_tinycad"; + +static int io_tinycad_load_prio(const char *fn, const char *fmt, csch_plug_io_type_t type) +{ + if (fmt != NULL) { + if (!strstr(fmt, "tinycad") && !strstr(fmt, "tinycad") && !strstr(fmt, "sch")) + return 0; + } + if (type == CSCH_IOTYP_SHEET) + return 90; + return 0; +} + +int pplg_check_ver_io_tinycad(int ver_needed) { return 0; } + +void pplg_uninit_io_tinycad(void) +{ + csch_plug_io_unregister(&tinycad); + rnd_conf_plug_unreg("plugins/io_tinycad/", io_tinycad_conf_internal, tinycad_cookie); +} + +int pplg_init_io_tinycad(void) +{ + RND_API_CHK_VER; + + tinycad.name = "tinycad schematics sheet v2 or symbol v1"; + tinycad.load_prio = io_tinycad_load_prio; + + tinycad.test_parse_bundled = io_tinycad_test_parse_bundled; + tinycad.load_sheet_bundled = io_tinycad_load_sheet_bundled; + tinycad.end_bundled = io_tinycad_end_bundled; + + + tinycad.ext_save_sheet = "dsn"; + csch_plug_io_register(&tinycad); + + rnd_conf_plug_reg(io_tinycad_conf, io_tinycad_conf_internal, tinycad_cookie); +#define conf_reg(field,isarray,type_name,cpath,cname,desc,flags) \ + rnd_conf_reg_field(io_tinycad_conf, field,isarray,type_name,cpath,cname,desc,flags); +#include "io_tinycad_conf_fields.h" + + return 0; +} + Index: tags/1.0.5/src/plugins/io_tinycad/io_tinycad.conf =================================================================== --- tags/1.0.5/src/plugins/io_tinycad/io_tinycad.conf (nonexistent) +++ tags/1.0.5/src/plugins/io_tinycad/io_tinycad.conf (revision 10414) @@ -0,0 +1,19 @@ +li:pcb-rnd-conf-v1 { + ha:overwrite { + ha:plugins { + ha:io_tinycad { + coord_mult = 1000 + auto_normalize = 1 + emulate_text_ang_180 = 1 + li:postproc_sheet_load { + {(@.a.Package != "")}; {propset(@, rename/a/Package, footprint)} + {(@.type == TEXT) && (@.parent.type != GRP_REF) && (@.text == "%../A.Package%")}; {propset(@, p/text/text, "%../A.footprint%")} + {(@.a.Ref != "")}; {propset(@, rename/a/Ref, name)} + {(@.type == TEXT) && (@.parent.type != GRP_REF) && (@.text == "%../A.Ref%")}; {propset(@, p/text/text, "%../A.name%")} + {(@.a.Value != "")}; {propset(@, rename/a/Value, value)} + {(@.type == TEXT) && (@.parent.type != GRP_REF) && (@.text == "%../A.Value%")}; {propset(@, p/text/text, "%../A.value%")} + } + } + } + } +} Index: tags/1.0.5/src/plugins/io_tinycad/io_tinycad.pup =================================================================== --- tags/1.0.5/src/plugins/io_tinycad/io_tinycad.pup (nonexistent) +++ tags/1.0.5/src/plugins/io_tinycad/io_tinycad.pup (revision 10414) @@ -0,0 +1,10 @@ +$class io +$short TinyCAD schematics +$long Load schematics from TinyCAD .dsn xml format. +$state works +$fmt-feature-r TinyCAD schematics +$package io-alien +$extdeps libxml2 +dep lib_alien +default buildin +autoload 1 Index: tags/1.0.5/src/plugins/io_tinycad/io_tinycad_conf.h =================================================================== --- tags/1.0.5/src/plugins/io_tinycad/io_tinycad_conf.h (nonexistent) +++ tags/1.0.5/src/plugins/io_tinycad/io_tinycad_conf.h (revision 10414) @@ -0,0 +1,19 @@ +#ifndef SCH_RND_IO_TINYCAD_CONF_H +#define SCH_RND_IO_TINYCAD_CONF_H + +#include + +typedef struct { + const struct { + const struct { + RND_CFT_REAL coord_mult; /* all tinycad coordinates are multiplied by this value to get sch-rnd coords */ + RND_CFT_BOOLEAN emulate_text_ang_180; /* gschem displays text objects with angle==180 with an extra 180 degree rotation; it's a display hack sch-rnd doesn't have; when this emulation is enabled, the loader adds a +180 degree rotation in such text (changing data!) to match the behavior */ + RND_CFT_BOOLEAN auto_normalize; /* move all objects so that starting coords are near 0;0 */ + RND_CFT_LIST postproc_sheet_load; /* pattern;action pairs for object transformations after a succesful load; mostly used for attribute editing */ + } io_tinycad; + } plugins; +} conf_io_tinycad_t; + +extern conf_io_tinycad_t io_tinycad_conf; + +#endif Index: tags/1.0.5/src/plugins/io_tinycad/read.c =================================================================== --- tags/1.0.5/src/plugins/io_tinycad/read.c (nonexistent) +++ tags/1.0.5/src/plugins/io_tinycad/read.c (revision 10414) @@ -0,0 +1,1765 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - tinycad file format support + * Copyright (C) 2022, 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022 and Entrust in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "io_tinycad_conf.h" + +extern conf_io_tinycad_t io_tinycad_conf; + + +#include "read.h" + +#define error(node, args) \ + do { \ + if (!ctx->silent) { \ + rnd_message(RND_MSG_ERROR, "tinycad parse error at %s:%ld:\n", ctx->fn, (long)(node)->line); \ + rnd_msg_error args; \ + } \ + } while(0) + +typedef struct read_ctx_s { + const char *fn; + xmlDoc *doc; + xmlNode *root, *next_sheet_nd; + csch_alien_read_ctx_t alien; + csch_cgrp_t *loclib_sym; /* 'symbol' master group in sheet->indirect */ + csch_cgrp_t *symdef; /* symdef we are reading at the moment */ + double symdef_dx, symdef_dy; + double symdef_dx_power, symdef_dy_power; + double symdef_attr_dx, symdef_attr_dy; + int parent_rot; /* used in some contexts to remember parent rotation while calling parsers on the children */ + htpp_t sym2xml; /* key: (csch_cgrp_t *); value: (xmlNode *) */ + unsigned silent:1; + unsigned symdef_dxy_power_valid:1; /* whether symdef_d[xy]_power got loaded */ + long sheetno; +} read_ctx_t; + +#define PROP(node, propname) \ + ((const char *)xmlGetProp((node), (const xmlChar *)(propname))) + +/* Return 1 if nd->name matches expected */ +static int node_name_eq(xmlNode *nd, const char *expected) +{ + return (xmlStrcmp(nd->name, (const unsigned char *)expected) == 0); +} + +#define PINATTR_SLOT "io_tinycad_slot" +#define PINATTR_POWER "io_tinycad_power" +#define SYMATTR_DX_POWER "io_tinycad_dx_power" +#define SYMATTR_DY_POWER "io_tinycad_dy_power" +#define SYMATTR_SYM_DXBB "io_tinycad_dx_bbox" +#define SYMATTR_SYM_DYBB "io_tinycad_dy_bbox" + +static int parse_coords(read_ctx_t *ctx, xmlNode *nd, const char *str, double *x, double *y) +{ + char *end; + *x = strtod(str, &end); + if (*end != ',') { + error(nd, ("Missing comma in coords\n")); + return -1; + } + *y = strtod(end+1, &end); + if (*end != '\0') { + error(nd, ("Invalid y coord (need numeric)\n")); + return -1; + } + return 0; +} + +static const char *parse_text(read_ctx_t *ctx, xmlNode *nd, int mandatory) +{ + if (nd->children == NULL) { + if (mandatory) + error(nd, ("Missing text child\n")); + return NULL; + } + return (const char *)nd->children->content; +} + +static int parse_bool(read_ctx_t *ctx, xmlNode *nd, const char *inp) +{ + if (inp == NULL) return 0; + if ((inp[0] == '1') && (inp[1] == '\0')) return 1; + if ((inp[0] == '0') && (inp[1] == '\0')) return 0; + error(nd, ("Invalid boolean value %s; expected 0 or 1\n", inp)); + return -1; +} + +/* Parse integer, overwrite dst if inp is not NULL */ +static int parse_long(read_ctx_t *ctx, xmlNode *nd, const char *inp, long *dst, int mandatory) +{ + char *end; + long tmp; + + if (inp == NULL) { + if (mandatory) { + error(nd, ("missing integer data\n")); + return -1; + } + return 0; + } + + tmp = strtol(inp, &end, 10); + if (*end != '\0') { + if (mandatory) + error(nd, ("Invalid integer value '%s' (should be decimal)\n", inp)); + return -1; + } + + *dst = tmp; + return 0; +} + +/* Parse decimal, overwrite dst if inp is not NULL */ +static int parse_double(read_ctx_t *ctx, xmlNode *nd, const char *inp, double *dst, int mandatory) +{ + char *end; + double tmp; + + if (inp == NULL) { + if (mandatory) { + error(nd, ("missing decimal data\n")); + return -1; + } + return 0; + } + + tmp = strtod(inp, &end); + if (*end != '\0') { + if (mandatory) + error(nd, ("Invalid decimal value '%s'\n", inp)); + return -1; + } + + *dst = tmp; + return 0; +} + +static double rot2deg(read_ctx_t *ctx, xmlNode *nd, int rot) +{ + switch(rot) { + case 0: return 0; + case 1: return 180; + case 2: return 270; + case 3: return 90; + } + error(nd, ("Invalid rotation value %d: should be 0..3\n", rot)); + return rot2deg(ctx, nd, rot % 4); +} + +static int dir2dxy(read_ctx_t *ctx, xmlNode *root, int dir, double *dx, double *dy, double len) +{ + switch(dir) { + case 0: *dy = -len; break; + case 1: *dy = len; break; + case 2: *dx = -len; break; + case 3: *dx = +len; break; + default: + error(root, ("Invalid direction %d: must be 0..3\n", dir)); + return -1; + } + return 0; +} + +/* Calculate sym placement; dx and dy are multiplier (0 or +-1) for moving + by (non-floater) bbox w and h; swbb is set to 1 if bbox w and h need to + be swapped (if used before rot+mir applied, which is not the case, so + it is safe to ignore swbb). */ +static void rot2sym(read_ctx_t *ctx, xmlNode *nd, int rotin, double *rot_out, int *mirx, int *miry, int *dx, int *dy, int *swbb) +{ + switch(rotin) { + case 0: *mirx = 0; *miry = 0; *rot_out = 0; *dx = 0; *dy = 0; *swbb=0; return; + case 1: *mirx = 0; *miry = 1; *rot_out = 0; *dx = 0; *dy = 1; *swbb=0; return; + case 2: *mirx = 0; *miry = 1; *rot_out = 90; *dx = 0; *dy = 0; *swbb=0; return; + case 3: *mirx = 0; *miry = 0; *rot_out = -90; *dx = -1; *dy = 0; *swbb=1; return; + + case 4: *mirx = 1; *miry = 0; *rot_out = 0; *dx = -1; *dy = 0; *swbb=0; return; + case 5: *mirx = 1; *miry = 1; *rot_out = 0; *dx = -1; *dy = 1; *swbb=0; return; + case 6: *mirx = 1; *miry = 1; *rot_out = -90; *dx = 0; *dy = 1; *swbb=1; return; + case 7: *mirx = 1; *miry = 0; *rot_out = 90; *dx = -1; *dy = 1; *swbb=1; return; + } + *mirx = *miry = 0; + *rot_out = 0; + *dx = *dy = 0; + *swbb = 0; + error(nd, ("Invalid rotation value %d: should be 0..7\n", rotin)); +} + + +typedef struct { + const char *nodename; + int (*cb)(read_ctx_t *ctx, void *dst, xmlNode *root); +} parser_t; + +static int parse_all(read_ctx_t *ctx, void *dst, xmlNode *root, const parser_t *parsers) +{ + const parser_t *p; + xmlNode *n; + int res; + + for(n = root->children; n != NULL; n = n->next) { + for(p = parsers; p->nodename != NULL; p++) { + if (xmlStrcmp(n->name, (const unsigned char *)p->nodename) == 0) { + res = p->cb(ctx, dst, n); + if (res != 0) + return res; + } + } + } + + return 0; +} + +/* Convert line 'style' proeprty to a sheet-decor pen, allocating new pen + as needed */ +static int parse_pen_style2sheet_decor(read_ctx_t *ctx, xmlNode *root, char penname[32]) +{ + const char *sstyle = PROP(root, "style"); + long style = 2; + + if (parse_long(ctx, root, sstyle, &style, 0) != 0) + return -1; + + strcpy(penname, "sheet-decor"); + if (style > 2) { + csch_cpen_t *pen, *dpen; + sprintf(penname+11, "-%ld", style); + pen = csch_pen_get(ctx->alien.sheet, &ctx->alien.sheet->direct, penname); + if (pen == NULL) { + dpen = csch_pen_get(ctx->alien.sheet, &ctx->alien.sheet->direct, "sheet-decor"); + if (dpen != NULL) + pen = csch_pen_dup2(ctx->alien.sheet, &ctx->alien.sheet->direct, dpen, penname); + else + pen = csch_pen_alloc(ctx->alien.sheet, &ctx->alien.sheet->direct, penname); + pen->size = (style - 1) * 125; + } + } + + return 0; +} + + +static int parse_name(read_ctx_t *ctx, void *dst, xmlNode *root) +{ + ctx->alien.sheet->hidlib.loadname = rnd_strdup(parse_text(ctx, root, 0)); + return 0; +} + +static int parse_detail_size(read_ctx_t *ctx, void *dst, xmlNode *root) +{ + const char *sw = PROP(root, "width"), *sh = PROP(root, "height"); + char tmp[64]; + long lw, lh; + csch_coord_t w, h; + csch_source_arg_t *src; + csch_sheet_t *sheet = dst; + + if (parse_long(ctx, root, sw, &lw, 1) != 0) return -1; + if (parse_long(ctx, root, sh, &lh, 1) != 0) return -1; + + w = csch_alien_coord(&ctx->alien, lw)/5; + h = csch_alien_coord(&ctx->alien, lh)/5; + + sprintf(tmp, "%ld", w); + src = csch_attrib_src_c(ctx->fn, root->line, 0, NULL); + csch_attrib_set(&sheet->direct.attr, CSCH_ATP_USER_DEFAULT, "drawing_min_width", tmp, src, NULL); + + sprintf(tmp, "%ld", h); + src = csch_attrib_src_c(ctx->fn, root->line, 0, NULL); + csch_attrib_set(&sheet->direct.attr, CSCH_ATP_USER_DEFAULT, "drawing_min_height", tmp, src, NULL); + + ctx->alien.oy = lh/5; + return 0; +} + +static int parse_detail_attr(read_ctx_t *ctx, void *dst, xmlNode *root) +{ + const char *key, *val; + csch_source_arg_t *src; + csch_sheet_t *sheet = dst; + + switch(root->name[0]) { + case 'T': key = "title"; break; + case 'A': key = "maintainer"; break; + case 'S': key = "page"; break; + default: return 0; /* shouldn't get here: parse_all ran strcmp() on the name */ + } + + val = parse_text(ctx, root, 0); + if (val == NULL) + val = ""; + + src = csch_attrib_src_c(ctx->fn, root->line, 0, NULL); + csch_attrib_set(&sheet->direct.attr, CSCH_ATP_USER_DEFAULT, key, val, src, NULL); + return 0; +} + + +static int parse_details(read_ctx_t *ctx, void *dst, xmlNode *root) +{ + static const parser_t parsers[] = { + {"Size", parse_detail_size}, + {"TITLE", parse_detail_attr}, + {"AUTHOR", parse_detail_attr}, + {"SHEETS", parse_detail_attr}, + /*{"SHOWS", parse_detail_...}, this tells whether the titlebox is shown */ + {NULL, NULL} + }; + + return parse_all(ctx, dst, root, parsers); +} + + +/*** symdef and sym ***/ + +static int parse_symdef_ref(read_ctx_t *ctx, void *dst, xmlNode *root) +{ + char *ref; + csch_source_arg_t *src; + + if (root->children == NULL) { + error(root, ("Invalid symdef ref name: empty subtree, no text node\n")); + return -1; + } + ref = (char *)root->children->content; + if ((ref == NULL) || (*ref == '\0')) { + error(root, ("Invalid symdef ref name: empty string\n")); + return -1; + } + + src = csch_attrib_src_c(ctx->fn, root->line, 0, NULL); + csch_attrib_set(&ctx->symdef->attr, CSCH_ATP_USER_DEFAULT, "name", ref, src, NULL); + + return 0; +} + +static int parse_symdef_field(read_ctx_t *ctx, void *dst, xmlNode *root) +{ + const char *key = NULL, *val = NULL; + double x = 0, y = 0; + csch_source_arg_t *src; + xmlNode *n; + + for(n = root->children; n != NULL; n = n->next) { + if (node_name_eq(n, "NAME")) key = parse_text(ctx, n, 1); + if (node_name_eq(n, "VALUE")) val = parse_text(ctx, n, 0); + if (node_name_eq(n, "POS")) parse_coords(ctx, n, parse_text(ctx, n, 0), &x, &y); + } + + if ((key == NULL) || (val == NULL) || (*val == '\0')) + return 0; /* don't create empty attributes */ + + src = csch_attrib_src_c(ctx->fn, root->line, 0, NULL); + csch_attrib_set(&ctx->symdef->attr, CSCH_ATP_USER_DEFAULT, key, val, src, NULL); + return 0; +} + +static int parse_symdef_ref_point(read_ctx_t *ctx, void *dst, xmlNode *root) +{ + const char *pos = PROP(root, "pos"), *spower = PROP(root, "power"); + double x, y; + + if (parse_coords(ctx, root, pos, &x, &y) != 0) + return -1; + + + if ((spower != NULL) && (spower[0] == '0')) { + /* power=0 is our true origin */ + ctx->symdef_dx = -x; + ctx->symdef_dy = -y; + } + else { + /* remember the power=1 variant for later */ + ctx->symdef_dx_power = -x; + ctx->symdef_dy_power = -y; + ctx->symdef_dxy_power_valid = 1; + } + return 0; +} + +static int parse_symdef_pin(read_ctx_t *ctx, void *dst, xmlNode *root) +{ + const char *spos = PROP(root, "pos"), *sdir = PROP(root, "direction"); + const char *slen = PROP(root, "length"), *snum = PROP(root, "number"); + const char *sshow = PROP(root, "show"), *swhich = PROP(root, "which"); + const char *part = PROP(root, "part"), *selec = PROP(root, "elec"); + long dir, llen, num, which, show, elec; + double ox, oy, Dx = 0, Dy = 0, dx = 0, tdx = 0, dy = 0, shorten = 0, len; + csch_cgrp_t *pin; + csch_source_arg_t *src; + const char *pinlab = NULL; + int fonth = 3000; + + if (parse_coords(ctx, root, spos, &ox, &oy) != 0) return -1; + if (parse_long(ctx, root, sdir, &dir, 1) != 0) return -1; + if (parse_long(ctx, root, slen, &llen, 1) != 0) return -1; + if (parse_long(ctx, root, snum, &num, 1) != 0) return -1; + if (parse_long(ctx, root, swhich, &which, 1) != 0) return -1; + if (parse_long(ctx, root, selec, &elec, 1) != 0) return -1; + if (parse_long(ctx, root, sshow, &show, 1) != 0) return -1; + pinlab = parse_text(ctx, root, 0); + + if (which != 6) + len = (double)llen/5.0; + else + len = 0; + + if (dir2dxy(ctx, root, dir, &dx, &dy, 1) != 0) + return -1; + + Dx = dx * len; + Dy = dy * len; + + ox += ctx->symdef_dx; oy += ctx->symdef_dy; + + + /* shorten pin to make room for decoration */ + if ((which == 1) || (which == 3)) + shorten = 2; + + src = csch_attrib_src_c(ctx->fn, root->line, 0, NULL); + pin = (csch_cgrp_t *)csch_alien_mkpin_line(&ctx->alien, src, ctx->symdef, ox, oy, ox+Dx-shorten*dx, oy+Dy-shorten*dy); + + /* decoration */ + if ((which == 1) || (which == 3)) /* circle on the inner end */ + csch_alien_mkarc(&ctx->alien, pin, +ox+Dx-dx*1, -oy-Dy+dy*1, 1, 0, 360, "term-decor"); + if ((which == 2) || (which == 3)) { /* arrow beyond the inner end */ + csch_alien_mkline(&ctx->alien, pin, ox+Dx + dy*+1, +oy+Dy + dx*+1, ox+Dx + dy*-1, +oy+Dy + dx*-1, "term-decor"); + csch_alien_mkline(&ctx->alien, pin, ox+Dx + dy*+1, +oy+Dy + dx*+1, ox+Dx + dx*+2, +oy+Dy + dy*+2, "term-decor"); + csch_alien_mkline(&ctx->alien, pin, ox+Dx + dy*-1, +oy+Dy + dx*-1, ox+Dx + dx*+2, +oy+Dy + dy*+2, "term-decor"); + tdx = 2; + } + if ((which == 6) || (elec == 6)) { /* X mark on the outer end */ + csch_alien_mkline(&ctx->alien, pin, ox + dy*+1 + dx, +oy + dx*+1 + dy, ox + dy*-1 - dx, +oy + dx*-1 - dy, "term-decor"); + csch_alien_mkline(&ctx->alien, pin, ox + dy*+1 - dx, +oy + dx*+1 + dy, ox + dy*-1 + dx, +oy + dx*-1 - dy, "term-decor"); + } + if (which == 6) + tdx = dx * (double)llen/5.0 + 2; + + + /* validate and remember slotting info */ + if (part != NULL) { + long tmp; + src = csch_attrib_src_c(ctx->fn, root->line, 0, NULL); + csch_attrib_set(&pin->attr, CSCH_ATP_USER_DEFAULT, PINATTR_SLOT, part, src, NULL); + + /* make sure it's valid data so we can throw the error here, on the right node, not later when we use the attrib */ + if (parse_long(ctx, root, part, &tmp, 1) < 0) + return -1; + } + + /* labels and attributes */ + src = csch_attrib_src_c(ctx->fn, root->line, 0, NULL); + csch_attrib_set(&pin->attr, CSCH_ATP_USER_DEFAULT, "name", snum, src, NULL); + + /* show is a bitfield */ + if (show & 0x01) { /* show pin name (inside the box) */ + if (pinlab != NULL) { + csch_text_t *text = (csch_text_t *)csch_alien_mktext(&ctx->alien, pin, ox+Dx+tdx, oy+Dy, "sym-decor"); + text->text = rnd_strdup(pinlab); + switch(dir) { + case 0: text->spec1.x += fonth/2; text->spec1.y += fonth/6; text->spec_rot = 90; break; /* sticking out downward */ + case 1: text->spec1.x += fonth/2; text->spec1.y -= fonth/6; text->spec_rot = -90; text->spec_mirx = 1; break; /* sticking out upward */ + case 2: text->spec1.x -= fonth/6; text->spec1.y -= fonth/2; text->spec_mirx = 1; break; /* sticking out to the right */ + case 3: text->spec1.x += fonth/6; text->spec1.y -= fonth/2; break; /* sticking out to the left */ + } + } + } + + + if (show & 0x02) { /* show pin number */ + csch_text_t *text = (csch_text_t *)csch_alien_mktext(&ctx->alien, pin, ox, oy, "term-primary"); + text->text = rnd_strdup("%../a.display/name%"); + text->dyntext = 1; + switch(dir) { + case 0: text->spec_rot = 90; break; /* sticking out downward */ + case 1: text->spec_rot = -90; text->spec_mirx = 1; break; /* sticking out upward */ + case 2: text->spec_mirx = 1; break; /* sticking out to the right */ + case 3: break; /* sticking out to the left */ + } + } + + + if (which == 4) { + src = csch_attrib_src_c(ctx->fn, root->line, 0, NULL); + csch_attrib_set(&pin->attr, CSCH_ATP_USER_DEFAULT, PINATTR_POWER, "1", src, NULL); + } + + return 0; +} + +static int parse_polygon(read_ctx_t *ctx, void *dst, xmlNode *root) +{ + const char *spos = PROP(root, "pos"); + const char *sfill = PROP(root, "fill"), *spoly = PROP(root, "polygon"); + double ox, oy; + int fill, poly; + long len; + xmlNode *n; + csch_cgrp_t *grp = dst; + + fill = parse_bool(ctx, root, sfill); + poly = parse_bool(ctx, root, spoly); + if (parse_coords(ctx, root, spos, &ox, &oy) != 0) + return -1; + +TODO("TYC#3: fill is really an enum with different hatching, see ppfill.dsn"); + if (fill) + poly = 1; /* required by the format */ + + if (grp == ctx->symdef) { + ox += ctx->symdef_dx; + oy += ctx->symdef_dy; + } + + /* verify and count points */ + for(n = root->children, len = 0; n != NULL; n = n->next, len++) { + if (node_name_eq(n, "text")) { + /* ignore */ + } + else if (node_name_eq(n, "POINT")) { + len++; + } + else{ + error(n, ("Invalid node in polygon: must be POINT, not '%s'\n", n->name)); + return -1; + } + + } + + if (len == 1) { + error(n, ("Invalid polygon: must contain more than one POINTs\n")); + return -1; + } + + if (fill) { /* real polygon */ + csch_chdr_t *poly = csch_alien_mkpoly(&ctx->alien, grp, "sym-decor", NULL); + csch_cpoly_t *cp; + double lx, ly, x, y; + int first = 1; + for(n = root->children; n != NULL; n = n->next) { + if (node_name_eq(n, "POINT")) { + const char *spos = PROP(n, "pos"); + + if (parse_coords(ctx, n, spos, &x, &y) != 0) + return -1; + + x += ox; y += oy; + + if (!first && ((x != lx) || (y != ly))) + csch_alien_append_poly_line(&ctx->alien, poly, lx, ly, x, y); + + lx = x; ly = y; + first = 0; + } + } + cp = (csch_cpoly_t *)poly; + cp->has_fill = 1; + cp->hdr.fill_name = cp->hdr.stroke_name; + } + else { /* polyline */ + double lx, ly, fx, fy, x, y; + int first = 1; + for(n = root->children; n != NULL; n = n->next) { + if (node_name_eq(n, "POINT")) { + const char *spos = PROP(n, "pos"); + + if (parse_coords(ctx, n, spos, &x, &y) != 0) + return -1; + + x += ox; y += oy; + + if (first) { + fx = x; fy = y; + } + else + csch_alien_mkline(&ctx->alien, grp, lx, ly, x, y, "sym-decor"); + + lx = x; ly = y; + first = 0; + } + } + if (poly) /* close polygon */ + csch_alien_mkline(&ctx->alien, grp, lx, ly, fx, fy, "sym-decor"); + } + + return 0; +} + +static int parse_symdef_polygon(read_ctx_t *ctx, void *dst, xmlNode *root) +{ + return parse_polygon(ctx, ctx->symdef, root); +} + +static int parse_sheet_polygon(read_ctx_t *ctx, void *dst, xmlNode *root) +{ + return parse_polygon(ctx, &ctx->alien.sheet->direct, root); +} + + +static int parse_rectangle(read_ctx_t *ctx, void *dst, xmlNode *root, const char *penname) +{ + const char *sa = PROP(root, "a"), *sb = PROP(root, "b"); + const char *sfill = PROP(root, "fill"); + double ax, ay, bx, by; + csch_cgrp_t *grp = dst; + csch_chdr_t *poly; + long fill; + + if (parse_long(ctx, root, sfill, &fill, 1) != 0) return -1; + if (parse_coords(ctx, root, sa, &ax, &ay) != 0) return -1; + if (parse_coords(ctx, root, sb, &bx, &by) != 0) return -1; + + if (grp == ctx->symdef) { + ax += ctx->symdef_dx; ay += ctx->symdef_dy; + bx += ctx->symdef_dx; by += ctx->symdef_dy; + } + + TODO("TYC#4: fill is for different hatching, see rectfill.dsn"); + + poly = csch_alien_mkpoly(&ctx->alien, ctx->symdef == NULL ? grp : ctx->symdef, penname, (fill ? penname : NULL)); + csch_alien_append_poly_line(&ctx->alien, poly, ax, ay, bx, ay); + csch_alien_append_poly_line(&ctx->alien, poly, bx, ay, bx, by); + csch_alien_append_poly_line(&ctx->alien, poly, bx, by, ax, by); + csch_alien_append_poly_line(&ctx->alien, poly, ax, by, ax, ay); + + return 0; +} + +static int parse_symdef_rectangle(read_ctx_t *ctx, void *dst, xmlNode *root) +{ + return parse_rectangle(ctx, ctx->symdef, root, "sym-decor"); +} + +static int parse_sheet_rectangle(read_ctx_t *ctx, void *dst, xmlNode *root) +{ + char penname[32]; + if (parse_pen_style2sheet_decor(ctx, root, penname) != 0) return -1; + return parse_rectangle(ctx, &ctx->alien.sheet->direct, root, penname); +} + +static int parse_ellipse(read_ctx_t *ctx, void *dst, xmlNode *root, const char *penname) +{ + const char *sa = PROP(root, "a"), *sb = PROP(root, "b"); + const char *sfill = PROP(root, "fill"); + double ax, ay, bx, by, cx, cy, rx, ry; + csch_cgrp_t *grp = dst; + long fill; + + if (parse_long(ctx, root, sfill, &fill, 1) != 0) return -1; + if (parse_coords(ctx, root, sa, &ax, &ay) != 0) return -1; + if (parse_coords(ctx, root, sb, &bx, &by) != 0) return -1; + + if (grp == ctx->symdef) { + ax += ctx->symdef_dx; ay += ctx->symdef_dy; + bx += ctx->symdef_dx; by += ctx->symdef_dy; + } + + rx = fabs(ax - bx) / 2; + ry = fabs(ay - by) / 2; + cx = (ax+bx)/2; + cy = (ay+by)/2; + + csch_alien_mkearc(&ctx->alien, ctx->symdef == NULL ? grp : ctx->symdef, + cx, cy, rx, ry, 0, 8, penname, (fill ? penname : NULL)); + + return 0; +} + +static int parse_sheet_noconnect(read_ctx_t *ctx, void *dst, xmlNode *root) +{ + csch_sheet_t *sheet = dst; + const char *pos = PROP(root, "pos"); + double x, y; + csch_cgrp_t *sym; + csch_alien_read_ctx_t a0 = {0}; + + a0.sheet = ctx->alien.sheet; + a0.fmt_prefix = ctx->alien.fmt_prefix; + a0.coord_factor = ctx->alien.coord_factor; + + if (parse_coords(ctx, root, pos, &x, &y) != 0) return -1; + + sym = csch_cgrp_alloc(dst, &sheet->direct, csch_oid_new(dst, &sheet->direct)); + if (sym == NULL) { + error(root, ("Failed to allocate symbol for noconnect\n")); + return -1; + } + + sym->x = csch_alien_coord_x(&ctx->alien, x); + sym->y = csch_alien_coord_y(&ctx->alien, y); + + csch_alien_mkline(&a0, sym, -1, -1, +1, +1, "sheet-decor"); + csch_alien_mkline(&a0, sym, +1, -1, -1, +1, "sheet-decor"); + + return 0; +} + +static int parse_symdef_ellipse(read_ctx_t *ctx, void *dst, xmlNode *root) +{ + return parse_ellipse(ctx, ctx->symdef, root, "sym-decor"); +} + + +static int parse_sheet_ellipse(read_ctx_t *ctx, void *dst, xmlNode *root) +{ + char penname[32]; + if (parse_pen_style2sheet_decor(ctx, root, penname) != 0) return -1; + return parse_ellipse(ctx, &ctx->alien.sheet->direct, root, penname); +} + + +static int parse_symdef_drawing(read_ctx_t *ctx, void *dst, xmlNode *root) +{ + int res; + double save; + + static const parser_t parsers[] = { + {"PIN", parse_symdef_pin}, + {"POLYGON", parse_symdef_polygon}, + {"RECTANGLE", parse_symdef_rectangle}, + {"ELLIPSE", parse_symdef_ellipse}, + {NULL, NULL} + }; + + save = ctx->alien.oy; + ctx->alien.oy = 0; + res = parse_all(ctx, dst, root, parsers); + ctx->alien.oy = save; + + return res; +} + + +static int parse_symdef(read_ctx_t *ctx, void *dst, xmlNode *root) +{ + long oid; + int res; + const char *sid = PROP(root, "id"); + char *end; + csch_source_arg_t *src; + csch_sheet_t *sheet = dst; + static const parser_t parsers1[] = { + {"REF_POINT", parse_symdef_ref_point}, + {NULL, NULL} + }; + static const parser_t parsers2[] = { + {"REF", parse_symdef_ref}, + {"FIELD", parse_symdef_field}, + {"TinyCAD", parse_symdef_drawing}, + {NULL, NULL} + }; + + oid = strtol(sid, &end, 10); + if (*end != '\0') { + error(root, ("Invalid symdef id: must be an integer\n")); + return -1; + } + if (oid <= 0) { + error(root, ("Invalid symdef id: must be greater than zero\n")); + return -1; + } + + /* make sure symbol loclib is available - need to create all symdefs there */ + if (ctx->loclib_sym == NULL) { + int alloced; + src = csch_attrib_src_c(ctx->fn, root->line, 0, NULL); + ctx->loclib_sym = csch_loclib_get_root_by_name(sheet, "symbol", src, 1, &alloced); + if (ctx->loclib_sym == NULL) { + error(root, ("Failed to allocate symbol local lib (root)\n")); + return -1; + } + } + + ctx->symdef_dxy_power_valid = 0; + ctx->symdef = csch_cgrp_alloc(dst, ctx->loclib_sym, oid); + if (ctx->symdef == NULL) { + error(root, ("Failed to allocate symdef in local lib (symdef)\n")); + return -1; + } + + src = csch_attrib_src_c(ctx->fn, root->line, 0, NULL); + csch_attrib_set(&ctx->symdef->attr, CSCH_ATP_USER_DEFAULT, "role", "symbol", src, NULL); + csch_attr_side_effects(ctx->symdef, "role"); + + res = parse_all(ctx, dst, root, parsers1); /* need to get the reference first for the offsets */ + res = parse_all(ctx, dst, root, parsers2); + + /* calculate origin-difference for the case when power pins are shown */ + if (ctx->symdef_dxy_power_valid) { + double dx = ctx->symdef_dx_power - ctx->symdef_dx; + double dy = ctx->symdef_dy_power - ctx->symdef_dy; + char tmp[64]; + + sprintf(tmp, "%f", dx); + src = csch_attrib_src_c(ctx->fn, root->line, 0, NULL); + csch_attrib_set(&ctx->symdef->attr, CSCH_ATP_USER_DEFAULT, SYMATTR_DX_POWER, tmp, src, NULL); + + sprintf(tmp, "%f", dy); + src = csch_attrib_src_c(ctx->fn, root->line, 0, NULL); + csch_attrib_set(&ctx->symdef->attr, CSCH_ATP_USER_DEFAULT, SYMATTR_DY_POWER, tmp, src, NULL); + } + + ctx->symdef = NULL; + return res; +} + +/* Return dyntext in the referee group rgrp that prints attribute key sdesc */ +static csch_text_t *grp_ref_attr_text(read_ctx_t *ctx, csch_cgrp_t *rgrp, const char *sdesc, int alloc) +{ + char *tmp = rnd_strdup_printf("%%../A.%s%%", sdesc); + csch_text_t *text; + htip_entry_t *e; + int isref; + + /* Note on placement: the local lib variant should have all text objects + ever used, then references would move or remove those. The local lib + symbol should have text labels at 0;0 and symbol instantiation + should always move the text object to its final place. Tinycad ignores + coords in symdef fields, see symdef_fldcrd*.dsn. */ + + /* find existing dyntext matching attribute template */ + for(e = htip_first(&rgrp->id2obj); e != NULL; e = htip_next(&rgrp->id2obj, e)) { + text = e->value; + if (text->hdr.type == CSCH_CTYPE_TEXT) { + if (text->dyntext && (strcmp(text->text, tmp) == 0)) { + free(tmp); + return text; + } + } + } + + if (!alloc) + return NULL; + + /* not found, need to create */ + isref = (strcmp(sdesc, "Ref") == 0); + text = (csch_text_t *)csch_alien_mktext(&ctx->alien, rgrp, 0, 0, (isref ? "sym-primary" : "sym-secondary")); + text->spec1.x = text->spec1.y = 0; /* override to drop sheet transformation */ + text->text = tmp; + text->dyntext = 1; + text->hdr.floater = 1; + + return text; +} + +static int parse_sym_field(read_ctx_t *ctx, void *dst, xmlNode *root) +{ + const char *spos = PROP(root, "pos"), *sshow = PROP(root, "show"); + const char *sdesc = PROP(root, "description"), *sval = PROP(root, "value"); + /* attributes that we can't figure: type */ + double ox, oy; + long show; + csch_source_arg_t *src; + csch_cgrp_t *sym = (csch_cgrp_t *)dst; + csch_coord_t bbx, bby, fonth = 3000; + + if (parse_coords(ctx, root, spos, &ox, &oy) != 0) return -1; + if (parse_long(ctx, root, sshow, &show, 1) != 0) return -1; + + if ((sdesc == NULL) || (*sdesc == '\0')) + return 0; + + if ((sval[0] == '.') && (sval[1] == '.') && (sval[2] == '\0') && !show) + return 0; + + src = csch_attrib_src_c(ctx->fn, root->line, 0, NULL); + csch_attrib_set(&sym->attr, CSCH_ATP_USER_DEFAULT, sdesc, sval, src, NULL); + + if (show) { + csch_text_t *text = grp_ref_attr_text(ctx, sym->data.ref.grp, sdesc, 1); + csch_child_xform_t *xf = calloc(sizeof(csch_child_xform_t), 1); + + bbx = (ctx->symdef->hdr.bbox.x2 - ctx->symdef->hdr.bbox.x1); + bby = (ctx->symdef->hdr.bbox.y2 - ctx->symdef->hdr.bbox.y1); + ox = csch_alien_coord(&ctx->alien, ox - ctx->symdef_attr_dx); + oy = csch_alien_coord(&ctx->alien, oy - ctx->symdef_attr_dy); + + csch_vtoid_append(&xf->path.vt, text->hdr.oid); + + switch(ctx->parent_rot) { + case 0: xf->rot = 0; xf->mirx = 0; xf->miry = 0; xf->movex = ox; xf->movey = -oy; break; + case 1: xf->rot = 0; xf->mirx = 0; xf->miry = 0; xf->movex = ox; xf->movey = bby+oy-fonth; break; + case 2: xf->rot = -90; xf->mirx = 0; xf->miry = 0; xf->movex = oy-fonth; xf->movey = -ox; break; + case 3: xf->rot = +90; xf->mirx = 0; xf->miry = 0; xf->movex = oy; xf->movey = -ox-bby; break; + + case 4: xf->rot = 0; xf->mirx = 1; xf->miry = 0; xf->movex = ox+bbx; xf->movey = -oy; break; + case 5: xf->rot = 0; xf->mirx = 1; xf->miry = 0; xf->movex = ox+bbx; xf->movey = bby+oy-fonth; break; + case 6: xf->rot = -90; xf->mirx = 1; xf->miry = 0; xf->movex = -oy-bby; xf->movey = -ox; break; + case 7: xf->rot = +90; xf->mirx = 1; xf->miry = 0; xf->movex = -oy-bby; xf->movey = -ox-bby; break; + } + + vtp0_append(&sym->data.ref.child_xform, xf); + } + + return 0; +} + +static int parse_sym(read_ctx_t *ctx, void *dst, xmlNode *root) +{ + const char *spos = PROP(root, "pos"); + const char *sid = PROP(root, "id"); + const char *sscx = PROP(root, "scale_x"), *sscy = PROP(root, "scale_y"); + const char *srot = PROP(root, "rotate"); + const char *sshow_power = PROP(root, "show_power"); + csch_cgrp_t *symdef = NULL, *sym; + csch_coord_t bbw, bbh; + double ox, oy, scx, scy; + long id, rot; + int mx, my, dx, dy, swbb, res, show_power = 0; + csch_sheet_t *sheet = dst; + static const parser_t parsers[] = { + {"FIELD", parse_sym_field}, + {NULL, NULL} + }; + + + if (parse_coords(ctx, root, spos, &ox, &oy) != 0) return -1; + if (parse_long(ctx, root, sid, &id, 1) != 0) return -1; + if (parse_double(ctx, root, sscx, &scx, 1) != 0) return -1; + if (parse_double(ctx, root, sscy, &scy, 1) != 0) return -1; + if (parse_long(ctx, root, srot, &rot, 1) != 0) return -1; + + if (sshow_power != NULL) { + show_power = parse_bool(ctx, root, sshow_power); + if (show_power < 0) + return -1; + } + + + if ((scx != 1.0) || (scy != 1.0)) { + error(root, ("Scaled symbols are not yet supported\n")); + return -1; + } + + if (ctx->loclib_sym != NULL) + symdef = htip_get(&ctx->loclib_sym->id2obj, id); + if (symdef == NULL) { + error(root, ("Can not find symbol def id %ld\n", id)); + return -1; + } + + sym = csch_cgrp_ref_alloc(dst, &sheet->direct, csch_oid_new(dst, &sheet->direct)); + if (sym == NULL) { + error(root, ("Failed to create blank symbol\n")); + return -1; + } + + csch_cgrp_update(sheet, symdef, 1); + bbw = symdef->hdr.bbox.x2 - symdef->hdr.bbox.x1; + bbh = symdef->hdr.bbox.y2 - symdef->hdr.bbox.y1; + + rot2sym(ctx, root, rot, &sym->spec_rot, &mx, &my, &dx, &dy, &swbb); + if (swbb) + rnd_swap(csch_coord_t, bbw, bbh); + + ctx->symdef_attr_dx = ctx->symdef_attr_dy = 0; + + /* show_power = 1 needs to use a different placement ref, compensate for that */ + if (show_power) { + const char *spx = csch_attrib_get_str(&symdef->attr, SYMATTR_DX_POWER); + const char *spy = csch_attrib_get_str(&symdef->attr, SYMATTR_DY_POWER); + if ((spx != NULL) && (spy != NULL)) { + double px = strtol(spx, NULL, 10), py = strtol(spy, NULL, 10); /* syntax checked when the attribute got written */ + if (sym->spec_rot != 0) { + int steps = 0; + if (sym->spec_rot == 90) steps = 1; + else if (sym->spec_rot == -90) steps = 3; + RND_COORD_ROTATE90(px, py, 0, 0, steps); + } + if (mx) px = -px; + if (my) py = -py; + ctx->symdef_attr_dx = px; + ctx->symdef_attr_dy = py; +/* rnd_trace("NKD#1 px %f %f | ox %f %f bb=%d %d (%d) bbflt=%d %d\n", px, py, ox, oy, bbw, bbh, swbb, bbw, bbh, symdef->bbox_flt.x2 - symdef->bbox_flt.x1, symdef->bbox_flt.y2 - symdef->bbox_flt.y1);*/ + ox += px; + oy += py; + } + } + + sym->mirx = mx; + sym->miry = my; + sym->data.ref.grp = symdef; + +/* rnd_trace("symdef bbox NKD#2: %d*%ld %d*%ld\n", dx, bbw, dy, bbh);*/ + sym->x = csch_alien_coord_x(&ctx->alien, ox) /*+ dx * bbw*/; + sym->y = csch_alien_coord_y(&ctx->alien, oy) /*+ dy * bbh*/; + + /* save dx and dy here and postpone the actual translation, because + the final bounding box depends on what pins are shown which is + figured only in postprocessing; do sym->x += dx*bbw and sym-yx += dy*bbw there */ + { + csch_source_arg_t *src; + char tmp[32]; + + if (dx != 0) { + sprintf(tmp, "%d", dx); + src = csch_attrib_src_c(ctx->fn, root->line, 0, NULL); + csch_attrib_set(&sym->attr, CSCH_ATP_USER_DEFAULT, SYMATTR_SYM_DXBB, tmp, src, NULL); + } + + if (dy != 0) { + sprintf(tmp, "%d", dy); + src = csch_attrib_src_c(ctx->fn, root->line, 0, NULL); + csch_attrib_set(&sym->attr, CSCH_ATP_USER_DEFAULT, SYMATTR_SYM_DYBB, tmp, src, NULL); + } + } + + /* do not ref-embed here, let postprocessor do that */ + + htpp_set(&ctx->sym2xml, sym, root); + + ctx->symdef = symdef; + ctx->parent_rot = rot; + + res = parse_all(ctx, sym, root, parsers); + + ctx->symdef = NULL; + ctx->parent_rot = 0; + + return res; +} + +/*** wires and other drawing objects ***/ + +static int parse_wire(read_ctx_t *ctx, void *dst, xmlNode *root) +{ + double x1, y1, x2, y2; + const char *a = PROP(root, "a"), *b = PROP(root, "b"); + csch_sheet_t *sheet = dst; + + if ((parse_coords(ctx, root, a, &x1, &y1) != 0) || (parse_coords(ctx, root, b, &x2, &y2) != 0)) + return -1; + + csch_alien_mknet(&ctx->alien, &sheet->direct, x1, y1, x2, y2); + return 0; +} + +/* Adjust test mirx and rotate for style:dir */ +static void text_adjust_dir(csch_text_t *text, int style, int dir) +{ + if ((dir == 1) || (dir == 2)) + text->spec_mirx = 1; + if (dir == 0) + text->spec_rot = 90; + else if (dir == 1) + text->spec_rot = -90; +} + + +static void create_net_label(read_ctx_t *ctx, csch_line_t *wire, xmlNode *root, const char *textstr, double ox, double oy, int style, int dir) +{ + csch_sheet_t *sheet = ctx->alien.sheet; + csch_coord_t cox, coy; + csch_text_t *text; + csch_source_arg_t *src; + csch_cgrp_t *parent; + const char *templ; + long tw, th, thy; + double w, h, step; + + if (dir == 4) + return; + + if (style != 0) { + parent = csch_cgrp_alloc(sheet, wire->hdr.parent, csch_oid_new(sheet, wire->hdr.parent)); + parent->hdr.floater = 1; + templ = "%../../A.name%"; + } + else { + parent = wire->hdr.parent; + templ = "%../A.name%"; + } + + text = (csch_text_t *)csch_alien_mktext(&ctx->alien, parent, ox, oy, "wire"); + text->text = rnd_strdup(templ); + text->dyntext = 1; + text->hdr.floater = 1; + src = csch_attrib_src_c(ctx->fn, root->line, 0, NULL); + csch_attrib_set(&wire->hdr.parent->attr, CSCH_ATP_USER_DEFAULT, "name", textstr, src, NULL); + + if (style == 0) { + text_adjust_dir(text, style, dir); + return; + } + + + csch_text_update(sheet, text, 1); + tw = (text->hdr.bbox.x2 - text->hdr.bbox.x1); + th = (text->hdr.bbox.y2 - text->hdr.bbox.y1); + w = (double)tw / ctx->alien.coord_factor; + h = (double)th / ctx->alien.coord_factor; + step = h / 2; + + thy = th; + if ((dir == 1) || (dir == 2)) thy = -thy; + + switch(style) { + case 1: /* input: right arrow */ + text->spec_mirx = 1; + text->spec1.x -= th/2; + text->spec1.y -= thy/2; + csch_alien_mkline(&ctx->alien, parent, ox, oy, ox-step, oy-step, "sheet-decor"); + csch_alien_mkline(&ctx->alien, parent, ox, oy, ox-step, oy+step, "sheet-decor"); + csch_alien_mkline(&ctx->alien, parent, ox-step, oy+step, ox-step*1.25-w, oy+step, "sheet-decor"); + csch_alien_mkline(&ctx->alien, parent, ox-step, oy-step, ox-step*1.25-w, oy-step, "sheet-decor"); + csch_alien_mkline(&ctx->alien, parent, ox-step*1.25-w, oy-step, ox-step*1.25-w, oy+step, "sheet-decor"); + break; + case 2: /* output: left arrow */ + text->spec_mirx = 1; + text->spec1.y -= thy/2; + csch_alien_mkline(&ctx->alien, parent, ox, oy-step, ox, oy+step, "sheet-decor"); + csch_alien_mkline(&ctx->alien, parent, ox, oy-step, ox-w-step, oy-step, "sheet-decor"); + csch_alien_mkline(&ctx->alien, parent, ox, oy+step, ox-w-step, oy+step, "sheet-decor"); + csch_alien_mkline(&ctx->alien, parent, ox-w-step, oy+step, ox-w-step*2, oy, "sheet-decor"); + csch_alien_mkline(&ctx->alien, parent, ox-w-step, oy-step, ox-w-step*2, oy, "sheet-decor"); + break; + case 3: /* io: dual arrow */ + text->spec_mirx = 1; + text->spec1.x -= th/2; + text->spec1.y -= thy/2; + csch_alien_mkline(&ctx->alien, parent, ox, oy, ox-step, oy-step, "sheet-decor"); + csch_alien_mkline(&ctx->alien, parent, ox, oy, ox-step, oy+step, "sheet-decor"); + csch_alien_mkline(&ctx->alien, parent, ox-step, oy+step, ox-step*1.25-w, oy+step, "sheet-decor"); + csch_alien_mkline(&ctx->alien, parent, ox-step, oy-step, ox-step*1.25-w, oy-step, "sheet-decor"); + csch_alien_mkline(&ctx->alien, parent, ox-step*1.25-w, oy-step, ox-step*2.25-w, oy, "sheet-decor"); + csch_alien_mkline(&ctx->alien, parent, ox-step*1.25-w, oy+step, ox-step*2.25-w, oy, "sheet-decor"); + break; + } + + /* rotate the whole label group and adjust the text object */ + + cox = csch_alien_coord_x(&ctx->alien, ox); + coy = csch_alien_coord_y(&ctx->alien, oy); + + switch(dir) { + case 0: + csch_rotate90(sheet, &parent->hdr, cox, coy, 1, 0); + break; + case 1: + csch_rotate90(sheet, &parent->hdr, cox, coy, 3, 0); + text->spec_mirx = 0; + text->spec_rot = 180; + break; + case 2: + csch_rotate90(sheet, &parent->hdr, cox, coy, 2, 0); + text->spec_mirx = 0; + text->spec_rot = 180; + break; + case 3: break; + case 4: break; + default: + error(root, ("invalid label direction")); + break; + } +} + +static int parse_label(read_ctx_t *ctx, void *dst, xmlNode *root) +{ + const char *spos = PROP(root, "pos"), *sdir = PROP(root, "direction"); + const char *sstyle = PROP(root, "style"); + const char *textstr; + csch_line_t *wire; + csch_text_t *text; + csch_rtree_it_t it; + csch_rtree_box_t bbox; + csch_sheet_t *sheet = dst; + double ox, oy; + long dir, style; + + + if (parse_coords(ctx, root, spos, &ox, &oy) != 0) return -1; + if (parse_long(ctx, root, sdir, &dir, 1) != 0) return -1; + if (parse_long(ctx, root, sstyle, &style, 1) != 0) return -1; + if ((textstr = parse_text(ctx, root, 1)) == NULL) return -1; +/* double rot = rot2deg(ctx, root, dir);*/ + + bbox.x1 = csch_alien_coord_x(&ctx->alien, ox) - 1; + bbox.y1 = csch_alien_coord_y(&ctx->alien, oy) - 1; + bbox.x2 = bbox.x1 + 2; + bbox.y2 = bbox.y1 + 2; + for(wire = csch_rtree_first(&it, &sheet->dsply[CSCH_DSPLY_WIRE], &bbox); wire != NULL; wire = csch_rtree_next(&it)) + if ((wire->hdr.type == CSCH_CTYPE_LINE) && (wire->hdr.parent->role == CSCH_ROLE_WIRE_NET)) + break; + + if (wire == NULL) { /* create text object */ + text = (csch_text_t *)csch_alien_mktext(&ctx->alien, &sheet->direct, ox, oy, "sheet-decor"); + text->text = rnd_strdup(textstr); + text_adjust_dir(text, style, dir); + } + else /* create floater */ + create_net_label(ctx, wire, root, textstr, ox, oy, style, dir); + + return 0; +} + +static csch_text_t *parse_text_obj_in(read_ctx_t *ctx, void *dst, xmlNode *root, const char *posname, csch_cgrp_t *parent) +{ + const char *spos = PROP(root, posname), *sdir = PROP(root, "direction"); + const char *sstyle = PROP(root, "style"); + const char *textstr; + csch_text_t *text; + double ox, oy; + long dir, style = 0; + + if (parse_coords(ctx, root, spos, &ox, &oy) != 0) return NULL; + if (parse_long(ctx, root, sdir, &dir, 1) != 0) return NULL; + if (parse_long(ctx, root, sstyle, &style, 0) != 0) return NULL; + if ((textstr = parse_text(ctx, root, 1)) == NULL) return NULL; +/* double rot = rot2deg(ctx, root, dir);*/ + + text = (csch_text_t *)csch_alien_mktext(&ctx->alien, parent, ox, oy, "sheet-decor"); + text->text = rnd_strdup(textstr); + + text_adjust_dir(text, style, dir); + + return text; +} + +static int parse_text_obj(read_ctx_t *ctx, void *dst, xmlNode *root) +{ + csch_sheet_t *sheet = dst; + if (parse_text_obj_in(ctx, dst, root, "pos", &sheet->direct) == NULL) + return -1; + return 0; +} + +#include + +static int parse_note(read_ctx_t *ctx, void *dst, xmlNode *root) +{ + csch_cgrp_t *grp; + const char *sa = PROP(root, "a"), *sb = PROP(root, "b"); + double x1, y1, x2, y2; + csch_sheet_t *sheet = dst; + csch_text_t *text; + + if (parse_coords(ctx, root, sa, &x1, &y1) != 0) return -1; + if (parse_coords(ctx, root, sb, &x2, &y2) != 0) return -1; + + grp = csch_cgrp_alloc(dst, &sheet->direct, csch_oid_new(dst, &sheet->direct)); + csch_alien_mkrect(&ctx->alien, grp, x1, y1, x2, y2, "sheet-decor", "note-fill"); + text = parse_text_obj_in(ctx, dst, root, "a", grp); + if (text == NULL) + return -1; + + csch_cobj_update_pen(&text->hdr); + text->spec1.y -= text->hdr.stroke->font_height; + + + TODO("TYC#1: Multiline text is not yet supported; ojjects.dsn"); + + return 0; +} + +static csch_cgrp_t *power_sym(read_ctx_t *ctx, void *dst, xmlNode *root, const char *netname) +{ + csch_cgrp_t *sym; + csch_source_arg_t *src; + csch_sheet_t *sheet = dst; + static const char *forge[] = { + "delete,forge/tmp", + "scalar,forge/tmp", + "sub,^,1:,forge/tmp", + "suba,$,rail,forge/tmp", + "array,connect", + "append,connect,forge/tmp", + NULL + }; + + sym = csch_cgrp_alloc(dst, &sheet->direct, csch_oid_new(dst, &sheet->direct)); + if (sym == NULL) { + error(root, ("Failed to allocate symbol for power\n")); + return NULL; + } + src = csch_attrib_src_c(ctx->fn, root->line, 0, NULL); + csch_attrib_set(&sym->attr, CSCH_ATP_USER_DEFAULT, "role", "symbol", src, NULL); + csch_attr_side_effects(sym, "role"); + src = csch_attrib_src_c(ctx->fn, root->line, 0, NULL); + csch_attrib_set(&sym->attr, CSCH_ATP_USER_DEFAULT, "rail", netname, src, NULL); + src = csch_attrib_src_c(ctx->fn, root->line, 0, NULL); + csch_attrib_set_arr_c(&sym->attr, CSCH_ATP_USER_DEFAULT, "forge", forge, src, NULL); + + return sym; +} + +static int parse_power(read_ctx_t *ctx, void *dst, xmlNode *root) +{ + const char *netname = parse_text(ctx, root, 0); + const char *spos = PROP(root, "pos"), *sdir = PROP(root, "direction"); + const char *swhich = PROP(root, "which"); + double ox, oy, ty = 0, tym, tcx = 0, tcx2 = 0, tcy = 0; + const double dx = 1, dy = 1; + long which, dir, fonth = 3000; + csch_cgrp_t *sym; + csch_source_arg_t *src; + csch_text_t *text; + csch_alien_read_ctx_t a0 = {0}; + + a0.sheet = ctx->alien.sheet; + a0.fmt_prefix = ctx->alien.fmt_prefix; + a0.coord_factor = ctx->alien.coord_factor; + + if (parse_coords(ctx, root, spos, &ox, &oy) != 0) return -1; + if (parse_long(ctx, root, swhich, &which, 1) != 0) return -1; + if (parse_long(ctx, root, sdir, &dir, 1) != 0) return -1; + + if (netname == NULL) + netname = "unknown"; + + sym = power_sym(ctx, dst, root, netname); + if (sym == NULL) + return -1; + + sym->spec_rot = -rot2deg(ctx, root, dir); + sym->x = csch_alien_coord_x(&ctx->alien, ox); + sym->y = csch_alien_coord_y(&ctx->alien, oy); + + + /* graphics: terminal */ + src = csch_attrib_src_c(ctx->fn, root->line, 0, NULL); + csch_alien_mkpin_line(&a0, src, sym, 0, 0, 0, +dy*3); + + /* graphics: text */ + switch(which) { + case 0: ty = 6; break; + case 1: ty = 8; break; + case 2: ty = 8; break; + case 3: ty = 8; break; + case 4: ty = 8; break; + default: + error(root, ("unhandled power 'which'\n")); + } + + + switch(dir) { + case 0: /* pointing up (text is above) */ + tym = (sym->spec_rot >= 180) ? 0 : -(double)fonth/ctx->alien.coord_factor; + tcx = -8*dx; + tcx2 = +8*dx; + tcy = ty*dy+tym; + break; + case 1: /* pointing down (text is under) */ + tcx = +8*dx; + tcx2 = +24*dx; + tcy = ty*dy; + break; + case 2: /* pointing left (text is to the left) */ + tcx = ((double)-fonth/2.0) / ctx->alien.coord_factor; + tcx2 = ((double)-fonth/2.0+fonth) / ctx->alien.coord_factor; + tcy = ty*dy; + break; + case 3: /* pointing right (text is to the right) */ + tcx = (fonth / 2.0) / ctx->alien.coord_factor; + tcx2 = ((fonth / 2.0) + fonth) / ctx->alien.coord_factor; + tcy = ty*dy - (double)fonth / ctx->alien.coord_factor; + break; + default: + error(root, ("unhandled power direction\n")); + } + + text = (csch_text_t *)csch_alien_mktext(&a0, sym, tcx, tcy, "sym-primary"); + text->text = rnd_strdup("%../A.rail%"); + text->dyntext = 1; + text->has_bbox = 1; + text->spec2.x = csch_alien_coord_x(&a0, tcx2); + text->spec2.y = text->spec1.y+fonth; + text->halign = CSCH_HALIGN_CENTER; + text->spec_rot = -sym->spec_rot; + text->spec_mirx = (sym->spec_rot >= 180); + + /* graphics: decoration */ + switch(which) { + case 0: /* T */ + csch_alien_mkline(&a0, sym, -1*dx, +3*dy, +1*dx, +3*dy, "sym-decor"); + break; + case 1: /* circ */ + csch_alien_mkarc(&a0, sym, 0, +4*dy, +1, 0, 360, "sym-decor"); + break; + case 2: /* wave */ + csch_alien_mkarc(&a0, sym, +1*dx, +4*dy, +1, 0, 180, "sym-decor"); + csch_alien_mkarc(&a0, sym, -1*dx, +4*dy, +1, 0, -180, "sym-decor"); + break; + case 3: /* arrow */ + csch_alien_mkline(&a0, sym, -1*dx, +3*dy, +1*dx, +3*dy, "sym-decor"); + csch_alien_mkline(&a0, sym, -1*dx, +3*dy, 0, +5*dy, "sym-decor"); + csch_alien_mkline(&a0, sym, +1*dx, +3*dy, 0, +5*dy, "sym-decor"); + break; + case 4: /* earth */ + csch_alien_mkline(&a0, sym, -1*dx, +3*dy, +1*dx, +3*dy, "sym-decor"); + csch_alien_mkline(&a0, sym, -0.70*dx, +4*dy, +0.70*dx, +4*dy, "sym-decor"); + csch_alien_mkline(&a0, sym, -0.30*dx, +5*dy, +0.30*dx, +5*dy, "sym-decor"); + break; + default: + error(root, ("Failed to create power: unknown style which=%s\n", swhich)); + return -1; + } + return 0; +} + +#define TEXT_SYM_ATTR_HANDLED(text) ((text)->tmp[0].l) + +/* Remove a child object using child_xform in the group_ref sym */ +static void sym_child_hide(read_ctx_t *ctx, csch_cgrp_t *sym, csch_chdr_t *child) +{ + csch_child_xform_t *xf = calloc(sizeof(csch_child_xform_t), 1); + csch_vtoid_append(&xf->path.vt, child->oid); + xf->remove = 1; + vtp0_append(&sym->data.ref.child_xform, xf); +} + +/* Finalize attribute visibility: delete inivisible attribute printouts */ +static int sym_attr_vis(read_ctx_t *ctx, csch_cgrp_t *sym) +{ + xmlNode *n, *root = htpp_get(&ctx->sym2xml, sym); + csch_cgrp_t *symdef = sym->data.ref.grp; + htip_entry_t *e; + + + if (root == NULL) { + rnd_message(RND_MSG_ERROR, "io_tinycad: internal error: no xml node in sym_attr_vis()\n"); + return -1; + } + + /* check each FIELD and if it's show=0 and has a floater text, child-remove it */ + for(n = root->children; n != NULL; n = n->next) { + if (xmlStrcmp(n->name, (const unsigned char *)"FIELD") == 0) { + const char *sdesc = PROP(n, "description"), *sshow = PROP(n, "show"); + int show = parse_bool(ctx, n, sshow); + csch_text_t *text = grp_ref_attr_text(ctx, sym->data.ref.grp, sdesc, 0); + + if (text == NULL) continue; + + TEXT_SYM_ATTR_HANDLED(text) = 1; /* mark the text handled so it doesn't get removed below */ + + if (!show) /* attr text created, remove it */ + sym_child_hide(ctx, sym, &text->hdr); + } + } + + /* check each text object and delete unhandled text objects. Example when + this happens: a sheet has R1 and R2 from a common symdef; R1 refers to + symdef defined fields only, but R2 creates a new field called 'foo' with + show=1. The new dyntext object needs to be added in the common symdef + because group_refs can havve their own children. In turn, R1 gets the + same 'foo' text object which needs to be removed. The above loop doesn't + remove it because in R1 or in the common symdef field 'foo' is not listed. + However, anything shown at R1 needs to have an explicit field tag in + the xml with show=1, so it is marked as handled above; any text object not + marked so can be safely removed */ + for(e = htip_first(&symdef->id2obj); e != NULL; e = htip_next(&symdef->id2obj, e)) { + csch_text_t *text = e->value; + if ((text->hdr.type == CSCH_CTYPE_TEXT) && (!TEXT_SYM_ATTR_HANDLED(text))) + sym_child_hide(ctx, sym, &text->hdr); + } + + return 0; +} + +/* Finalize pin visibility: sym decides whether power pins are shown and + slotted symbols should hide any non-power-pin that's not in the sym's slot */ +static int sym_pin_vis(read_ctx_t *ctx, csch_cgrp_t *sym) +{ + xmlNode *root = htpp_get(&ctx->sym2xml, sym); + csch_cgrp_t *symdef = sym->data.ref.grp; + htip_entry_t *e; + const char *spart = PROP(root, "part"); + const char *sshowpwr = PROP(root, "show_power"); + int showpwr = 0; + long part = 0; + + /* fetch power pin and slot control of the symbol instance */ + if (sshowpwr != NULL) { + showpwr = parse_bool(ctx, root, sshowpwr); + if (showpwr < 0) + return -1; + } + + if (parse_long(ctx, root, spart, &part, 0) < 0) + return -1; + + + /* check each "pin" and xform-remove those that should not be shown (hidden + power pins and other-slot pins) */ + for(e = htip_first(&symdef->id2obj); e != NULL; e = htip_next(&symdef->id2obj, e)) { + csch_cgrp_t *pin = e->value; + if ((pin->hdr.type == CSCH_CTYPE_GRP) && (pin->role == CSCH_ROLE_TERMINAL)) { + const char *spin_part, *spin_power = csch_attrib_get_str(&pin->attr, PINATTR_POWER); + + if ((spin_power != NULL) && (spin_power[0] == '1')) { /* power pins are special case; this is a power pin */ + if (!showpwr) + sym_child_hide(ctx, sym, &pin->hdr); + } + else if (spart != NULL) { /* slotted sym: hide anyhting that's not in this slow */ + spin_part = csch_attrib_get_str(&pin->attr, PINATTR_SLOT); + if (spin_part != NULL) { + long pin_part = strtol(spin_part, NULL, 10); /* syntax already checked in symdef read code */ + if (pin_part != part) + sym_child_hide(ctx, sym, &pin->hdr); + } + } + } + } + return 0; +} + +static void postproc_sym_placement(read_ctx_t *ctx, csch_cgrp_t *sym) +{ + int dx = 0, dy = 0; + csch_coord_t bbw, bbh; + const char *tmp; + csch_rtree_box_t bb; + + tmp = csch_attrib_get_str(&sym->attr, SYMATTR_SYM_DXBB); + if (tmp != NULL) dx = strtol(tmp, NULL, 10); /* always valid (code generated) */ + tmp = csch_attrib_get_str(&sym->attr, SYMATTR_SYM_DYBB); + if (tmp != NULL) dy = strtol(tmp, NULL, 10); /* always valid (code generated) */ + + if ((dx == 0) && (dy == 0)) + return; + + /* get all objects rendered for and centerline bbox calculated */ + csch_cgrp_ref_render(ctx->alien.sheet, sym); + csch_alien_centerline_bbox(&ctx->alien, &sym->hdr, &bb); + bbw = bb.x2 - bb.x1; + bbh = bb.y2 - bb.y1; +/* if (swbb) rnd_swap(csch_coord_t, bbw, bbh);*/ + +/* rnd_trace("NKD#5: d=%d;%d bb=%d;%d sw=%d\n", dx, dy, (int)bbw, (int)bbh, swbb);*/ + + + sym->x += dx * bbw; + sym->y += dy * bbh; +} + +static int postproc_slot(read_ctx_t *ctx, csch_cgrp_t *grp) +{ + htip_entry_t *e; + + if ((grp->role == CSCH_ROLE_SYMBOL) || (grp->hdr.type == CSCH_CTYPE_GRP_REF)) { + if ((grp->hdr.type == CSCH_CTYPE_GRP_REF) && (sym_attr_vis(ctx, grp) != 0)) + return -1; + if ((grp->hdr.type == CSCH_CTYPE_GRP_REF) && (sym_pin_vis(ctx, grp) != 0)) + return -1; + } + + for(e = htip_first(&grp->id2obj); e != NULL; e = htip_next(&grp->id2obj, e)) { + csch_cgrp_t *child = e->value; + if (csch_obj_is_grp(&child->hdr)) { + if (postproc_slot(ctx, child) != 0) + return -1; + } + } + + if (grp->hdr.type == CSCH_CTYPE_GRP_REF) + postproc_sym_placement(ctx, grp); + + return 0; +} + + +static int parse_sheet(read_ctx_t *ctx, void *dst, xmlNode *root) +{ + int res; + + static const parser_t parsers0[] = { /* read details first so that page size is known (for the mirroring) */ + {"DETAILS", parse_details}, + {NULL, NULL} + }; + static const parser_t parsers1[] = { + {"NAME", parse_name}, + {"SYMBOLDEF", parse_symdef}, + {"SYMBOL", parse_sym}, + {"WIRE", parse_wire}, + {"TEXT", parse_text_obj}, + {"NOTE_TEXT", parse_note}, + {"POWER", parse_power}, + {"POLYGON", parse_sheet_polygon}, + {"RECTANGLE", parse_sheet_rectangle}, + {"ELLIPSE", parse_sheet_ellipse}, + {"NOCONNECT", parse_sheet_noconnect}, + {NULL, NULL} + }; + static const parser_t parsers2[] = { + {"LABEL", parse_label}, /* labels are placed on wires, best if wires already exist */ + {NULL, NULL} + }; + + res = parse_all(ctx, dst, root, parsers0) || parse_all(ctx, dst, root, parsers1) || parse_all(ctx, dst, root, parsers2); + + if (res == 0) + postproc_slot(ctx, &ctx->alien.sheet->direct); + + /* clear cache so the next sheet doesn't inherit current sheet's */ + ctx->loclib_sym = NULL; + + return res; +} + +/*** file level parsing and entry points ***/ +static int io_tinycad_load_sheet(read_ctx_t *ctx, xmlNode *sheet_node, const char *fn, csch_sheet_t *dst) +{ + int res; + + res = parse_sheet(ctx, dst, sheet_node); + if (res == 0) { + csch_cgrp_render_all(dst, &dst->direct); + res = csch_alien_postproc_sheet(&ctx->alien); + + csch_cgrp_update(dst, &dst->direct, 1); + csch_alien_update_conns(&ctx->alien); + + if (io_tinycad_conf.plugins.io_tinycad.emulate_text_ang_180) + csch_alien_postproc_text_autorot(&ctx->alien, &dst->direct, 1, 1); + + if ((res == 0) && io_tinycad_conf.plugins.io_tinycad.auto_normalize) + csch_alien_postproc_normalize(&ctx->alien); + } + + return res; +} + +static int io_tinycad_test_parse(FILE *f, const char *fn, const char *fmt, csch_plug_io_type_t type) +{ + char line[512], *s; + int n; + + if (type != CSCH_IOTYP_SHEET) + return -1; + + s = fgets(line, sizeof(line), f); + if ((s == NULL) || (strncmp(s, "") != NULL) + return 0; + } + return -1; +} + +/* Start from next_sheet_nd; if it's a sheet, return; else keep stepping on + ->next until it's a sheet or NULL */ +static void io_tinycad_seek_next(read_ctx_t *ctx) +{ + for(;ctx->next_sheet_nd != NULL; ctx->next_sheet_nd = ctx->next_sheet_nd->next) { + if (xmlStrcmp(ctx->next_sheet_nd->name, (const unsigned char *)"TinyCAD") == 0) + return; + } +} + +void *io_tinycad_test_parse_bundled(FILE *f, const char *fn, const char *fmt, csch_plug_io_type_t type) +{ + if (io_tinycad_test_parse(f, fn, fmt, type) == 0) { + read_ctx_t *ctx = calloc(sizeof(read_ctx_t), 1); + + ctx->alien.fmt_prefix = "io_tinycad"; + ctx->alien.flip_y = 1; + ctx->fn = fn; + ctx->doc = xmlReadFile(fn, NULL, 0); + + if (ctx->doc == NULL) { + rnd_message(RND_MSG_ERROR, "io_tinycad: xml parsing error on file %s\n", fn); + free(ctx); + return NULL; + } + + ctx->root = xmlDocGetRootElement(ctx->doc); + if (xmlStrcmp(ctx->root->name, (xmlChar *)"TinyCADSheets") != 0) { + rnd_message(RND_MSG_ERROR, "io_tinycad: xml error: root is not \n"); + xmlFreeDoc(ctx->doc); + free(ctx); + return NULL; + } + + ctx->next_sheet_nd = ctx->root->children; + io_tinycad_seek_next(ctx); + if (ctx->next_sheet_nd == NULL) { + rnd_message(RND_MSG_ERROR, "io_tinycad: xml error: no sheets under \n"); + xmlFreeDoc(ctx->doc); + free(ctx); + return NULL; + } + + htpp_init(&ctx->sym2xml, ptrhash, ptrkeyeq); + return ctx; + } + return NULL; +} + +int io_tinycad_load_sheet_bundled(void *cookie, FILE *f, const char *fn, csch_sheet_t *dst) +{ + read_ctx_t *ctx = cookie; + + ctx->alien.sheet = dst; + ctx->alien.coord_factor = io_tinycad_conf.plugins.io_tinycad.coord_mult; + csch_alien_sheet_setup(&ctx->alien, 1); + if (io_tinycad_load_sheet(ctx, ctx->next_sheet_nd, fn, dst) != 0) + return -1; + ctx->alien.sheet->hidlib.fullpath = rnd_strdup_printf("%s_%ld.rs", fn, ++ctx->sheetno); + ctx->alien.sheet = NULL; + + /* return 1 on no more sheet */ + ctx->next_sheet_nd = ctx->next_sheet_nd->next; + io_tinycad_seek_next(ctx); + return (ctx->next_sheet_nd == NULL) ? 1 : 0; +} + +void io_tinycad_end_bundled(void *cookie, const char *fn) +{ + read_ctx_t *ctx = cookie; + + htpp_uninit(&ctx->sym2xml); + xmlFreeDoc(ctx->doc); + free(ctx); +} Index: tags/1.0.5/src/plugins/io_tinycad/read.h =================================================================== --- tags/1.0.5/src/plugins/io_tinycad/read.h (nonexistent) +++ tags/1.0.5/src/plugins/io_tinycad/read.h (revision 10414) @@ -0,0 +1,5 @@ +#include +void *io_tinycad_test_parse_bundled(FILE *f, const char *fn, const char *fmt, csch_plug_io_type_t type); +int io_tinycad_load_sheet_bundled(void *cookie, FILE *f, const char *fn, csch_sheet_t *dst); +void io_tinycad_end_bundled(void *cookie, const char *fn); + Index: tags/1.0.5/src/plugins/lib_alien/Makefile =================================================================== --- tags/1.0.5/src/plugins/lib_alien/Makefile (nonexistent) +++ tags/1.0.5/src/plugins/lib_alien/Makefile (revision 10414) @@ -0,0 +1,2 @@ +all: + cd ../../sch-rnd && make mod_lib_alien Index: tags/1.0.5/src/plugins/lib_alien/Plug.tmpasm =================================================================== --- tags/1.0.5/src/plugins/lib_alien/Plug.tmpasm (nonexistent) +++ tags/1.0.5/src/plugins/lib_alien/Plug.tmpasm (revision 10414) @@ -0,0 +1,11 @@ +put /local/rnd/mod {lib_alien} +put /local/rnd/mod/OBJS [@ + $(PLUGDIR)/lib_alien/lib_alien.o + $(PLUGDIR)/lib_alien/read_helper.o +@] + +switch /local/module/lib_alien/controls + case {buildin} include /local/csch/tmpasm/buildin; end; + case {plugin} include /local/csch/tmpasm/plugin; end; + case {disable} include /local/csch/tmpasm/disable; end; +end Index: tags/1.0.5/src/plugins/lib_alien/lib_alien.c =================================================================== --- tags/1.0.5/src/plugins/lib_alien/lib_alien.c (nonexistent) +++ tags/1.0.5/src/plugins/lib_alien/lib_alien.c (revision 10414) @@ -0,0 +1,44 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - alien format support + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + + +#include +#include +#include + +int pplg_check_ver_lib_alien(int ver_needed) { return 0; } + +void pplg_uninit_lib_alien(void) +{ +} + +int pplg_init_lib_alien(void) +{ + RND_API_CHK_VER; + + return 0; +} + Index: tags/1.0.5/src/plugins/lib_alien/lib_alien.pup =================================================================== --- tags/1.0.5/src/plugins/lib_alien/lib_alien.pup (nonexistent) +++ tags/1.0.5/src/plugins/lib_alien/lib_alien.pup (revision 10414) @@ -0,0 +1,8 @@ +$class io +$short alien format helper +$long Format-independent helper functions for reading alien files +$state works +$package io-alien +default buildin +dep query +autoload 1 Index: tags/1.0.5/src/plugins/lib_alien/read_helper.c =================================================================== --- tags/1.0.5/src/plugins/lib_alien/read_helper.c (nonexistent) +++ tags/1.0.5/src/plugins/lib_alien/read_helper.c (revision 10414) @@ -0,0 +1,478 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - alien file format helpers + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include "read_helper.h" + +/* Warn once per context if coords are too large for the GUI */ +RND_INLINE double csch_alien_chk_range(csch_alien_read_ctx_t *ctx, double crd) +{ +#define RMAX (RND_COORD_MAX/4.0/1024.0-1) +#define RMIN (-RMAX) + + if ((crd > RMAX) || (crd < RMIN)) { + if (!ctx->warned_coord_range) { + rnd_message(RND_MSG_ERROR, "Drawing has coordinates too large. Try recompiling librnd for 64 bit coords.\n"); + ctx->warned_coord_range = 1; + } + } + + return crd; +#undef RMAX +#undef RMIN +} + +#define CRD(crd) \ + (((ctx->coord_factor != 0) && (ctx->coord_factor != 1)) ? rnd_round(csch_alien_chk_range(ctx, (crd) * ctx->coord_factor)) : csch_alien_chk_range(ctx, ((crd)))) + +#define CRDX(crd) CRD((ctx->flip_x ? -(crd) : (crd)) + ctx->ox) +#define CRDY(crd) CRD((ctx->flip_y ? -(crd) : (crd)) + ctx->oy) + +csch_coord_t csch_alien_coord_x(csch_alien_read_ctx_t *ctx, double crd) +{ + return CRDX(crd); +} + +csch_coord_t csch_alien_coord_y(csch_alien_read_ctx_t *ctx, double crd) +{ + return CRDY(crd); +} + +csch_coord_t csch_alien_coord(csch_alien_read_ctx_t *ctx, double crd) +{ + return CRD(crd); +} + + +csch_chdr_t *csch_alien_mknet(csch_alien_read_ctx_t *ctx, csch_cgrp_t *parent, double x1, double y1, double x2, double y2) +{ + if (parent != &ctx->sheet->direct) { + rnd_message(RND_MSG_ERROR, "csch_alien_mknet(): can not create wire within a group at the moment\n"); + return NULL; + } + + return csch_wirenet_draw(ctx->sheet, csch_comm_str(ctx->sheet, "wire", 1), CRDX(x1), CRDY(y1), CRDX(x2), CRDY(y2)); +} + +csch_chdr_t *csch_alien_mkline(csch_alien_read_ctx_t *ctx, csch_cgrp_t *parent, double x1, double y1, double x2, double y2, const char *penname) +{ + csch_line_t *line; + + line = csch_line_alloc(ctx->sheet, parent, csch_oid_new(ctx->sheet, parent)); + line->spec.p1.x = CRDX(x1); + line->spec.p1.y = CRDY(y1); + line->spec.p2.x = CRDX(x2); + line->spec.p2.y = CRDY(y2); + line->hdr.stroke_name = csch_comm_str(ctx->sheet, penname, 1); + + return &line->hdr; +} + +RND_INLINE void poly_line(csch_cpoly_t *poly, csch_coord_t x1, csch_coord_t y1, csch_coord_t x2, csch_coord_t y2) +{ + csch_coutline_t *dst = csch_vtcoutline_alloc_append(&poly->outline, 1); + csch_line_t *line = &dst->line; + + line->hdr.type = CSCH_CTYPE_LINE; + line->spec.p1.x = x1; line->spec.p1.y = y1; + line->spec.p2.x = x2; line->spec.p2.y = y2; +} + +csch_chdr_t *csch_alien_mkrect(csch_alien_read_ctx_t *ctx, csch_cgrp_t *parent, double x1, double y1, double x2, double y2, const char *stroke_penname, const char *fill_penname) +{ + csch_cpoly_t *poly; + + x1 = CRDX(x1); y1 = CRDY(y1); + x2 = CRDX(x2); y2 = CRDY(y2); + + poly = csch_cpoly_alloc(ctx->sheet, parent, csch_oid_new(ctx->sheet, parent)); + poly_line(poly, x1, y1, x1, y2); + poly_line(poly, x1, y2, x2, y2); + poly_line(poly, x2, y2, x2, y1); + poly_line(poly, x2, y1, x1, y1); + + if (stroke_penname != NULL) { + poly->hdr.stroke_name = csch_comm_str(ctx->sheet, stroke_penname, 1); + poly->has_stroke = 1; + } + else + poly->has_stroke = 0; + + if (fill_penname != NULL) { + poly->hdr.fill_name = csch_comm_str(ctx->sheet, fill_penname, 1); + poly->has_fill = 1; + } + else + poly->has_fill = 0; + + return &poly->hdr; +} + +csch_chdr_t *csch_alien_mkpin_line(csch_alien_read_ctx_t *ctx, csch_source_arg_t *src, csch_cgrp_t *parent, double x1, double y1, double x2, double y2) +{ + csch_cgrp_t *pin; + csch_line_t *line; + + pin = csch_cgrp_alloc(ctx->sheet, parent, csch_oid_new(ctx->sheet, parent)); + csch_cobj_attrib_set(ctx->sheet, pin, CSCH_ATP_HARDWIRED, "role", "terminal", src); + + line = csch_line_alloc(ctx->sheet, pin, csch_oid_new(ctx->sheet, pin)); + line->spec.p1.x = CRDX(x1); + line->spec.p1.y = CRDY(y1); + line->spec.p2.x = CRDX(x2); + line->spec.p2.y = CRDY(y2); + line->hdr.stroke_name = csch_comm_str(ctx->sheet, "term-primary", 1); + + return &pin->hdr; +} + +static void csch_alien_mkbezier_(csch_alien_read_ctx_t *ctx, csch_cgrp_t *parent_grp, csch_cpoly_t *parent_poly, double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, const char *penname) +{ + double len, step, t; + double lx, ly, x, y; + csch_line_t *line; + csch_comm_str_t pen = csch_comm_str(ctx->sheet, penname, 1); + csch_coutline_t *dst; + + len = rnd_distance(x1, y1, x2, y2) + rnd_distance(x2, y2, x3, y3) + rnd_distance(x3, y3, x4, y4); + step = (1000.0 / (len + 3000.0)) / 5.0; + + x1 = CRDX(x1); y1 = CRDY(y1); + x2 = CRDX(x2); y2 = CRDY(y2); + x3 = CRDX(x3); y3 = CRDY(y3); + x4 = CRDX(x4); y4 = CRDY(y4); + + lx = x1; ly = y1; + + for(t = step; t < 1; t += step) { + double mt = 1-t; + double a = mt*mt*mt, b = 3*mt*mt*t, c = 3*mt*t*t, d = t*t*t; + /* B(t) = (1-t)^3*P0 + 3*(1-t)^2*t*P1 + 3*(1-t)*t^2*P2 + t^3*P3 @ 0 <= t <= 1 */ + + x = a*x1 + b*x2 + c*x3 + d*x4; + y = a*y1 + b*y2 + c*y3 + d*y4; + + if ((lx != x) || (ly != y)) { + if (parent_grp == NULL) { + dst = csch_vtcoutline_alloc_append(&parent_poly->outline, 1); + dst->hdr = parent_poly->hdr; + dst->hdr.type = CSCH_CTYPE_LINE; + line = &dst->line; + } + else { + line = csch_line_alloc(ctx->sheet, parent_grp, csch_oid_new(ctx->sheet, parent_grp)); + line->hdr.stroke_name = pen; + } + + line->spec.p1.x = rnd_round(lx); + line->spec.p1.y = rnd_round(ly); + line->spec.p2.x = rnd_round(x); + line->spec.p2.y = rnd_round(y); + + lx = x; + ly = y; + } + } + + if ((lx != x4) || (ly != y4)) { + if (parent_grp == NULL) { + dst = csch_vtcoutline_alloc_append(&parent_poly->outline, 1); + dst->hdr = parent_poly->hdr; + dst->hdr.type = CSCH_CTYPE_LINE; + line = &dst->line; + } + else { + line = csch_line_alloc(ctx->sheet, parent_grp, csch_oid_new(ctx->sheet, parent_grp)); + line->hdr.stroke_name = pen; + } + line->spec.p1.x = rnd_round(lx); + line->spec.p1.y = rnd_round(ly); + line->spec.p2.x = rnd_round(x4); + line->spec.p2.y = rnd_round(y4); + } +} + +void csch_alien_mkbezier(csch_alien_read_ctx_t *ctx, csch_cgrp_t *parent, double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, const char *penname) +{ + csch_alien_mkbezier_(ctx, parent, NULL, x1, y1, x2, y2, x3, y3, x4, y4, penname); +} + +void csch_alien_append_poly_bezier(csch_alien_read_ctx_t *ctx, csch_chdr_t *poly_, double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4) +{ + csch_alien_mkbezier_(ctx, NULL, (csch_cpoly_t *)poly_, x1, y1, x2, y2, x3, y3, x4, y4, NULL); +} + + +csch_chdr_t *csch_alien_mkarc(csch_alien_read_ctx_t *ctx, csch_cgrp_t *parent, double cx, double cy, double r, double sa, double da, const char *penname) +{ + csch_arc_t *arc; + + cx = CRDX(cx); cy = CRDY(cy); + r = CRD(r); + + arc = csch_arc_alloc(ctx->sheet, parent, csch_oid_new(ctx->sheet, parent)); + arc->spec.c.x = rnd_round(cx); + arc->spec.c.y = rnd_round(cy); + arc->spec.r = rnd_round(r); + arc->spec.start = sa / RND_RAD_TO_DEG; + arc->spec.delta = da / RND_RAD_TO_DEG; + arc->hdr.stroke_name = csch_comm_str(ctx->sheet, penname, 1); + + return &arc->hdr; +} + + +csch_chdr_t *csch_alien_mkearc(csch_alien_read_ctx_t *ctx, csch_cgrp_t *parent, double cx, double cy, double rx, double ry, double sa, double da, const char *stroke, const char *fill) +{ + csch_chdr_t *poly = csch_alien_mkpoly(ctx, parent, stroke, fill); + double a, ea = sa+da, d, tmp, lx, ly, x, y; + int first = 1; + + d = 1.0/((rx+ry)/2.0); + if (d > 0.2) + d = 0.2; + + if ((da > 2*M_PI) || (da < -2*M_PI)) { + ea = 2*M_PI; + sa = 0; + } + + /* swap if necessary, so iteration is always positive */ + if (da < 0) { + tmp = sa; + sa = ea; + ea = tmp; + da = -da; + } + + /* degenerate case: need at least two points so we don't end up with an empty poly */ + if (d > da/2.0) + d = da/2.0; + + for(a = sa; a < ea; a += d) { + x = cx + cos(a) * rx; + y = cy + sin(a) * ry; + if (!first) + csch_alien_append_poly_line(ctx, poly, lx, ly, x, y); + lx = x; + ly = y; + first = 0; + } + + /* close */ + if (!first) { + x = cx + cos(ea) * rx; + y = cy + sin(ea) * ry; + if ((x != lx) || (y != ly)) + csch_alien_append_poly_line(ctx, poly, lx, ly, x, y); + } + + return poly; +} + + +void csch_alien_append_poly_arc(csch_alien_read_ctx_t *ctx, csch_chdr_t *poly_, double cx, double cy, double r, double sa, double da) +{ + csch_cpoly_t *poly = (csch_cpoly_t *)poly_; + csch_coutline_t *dst = csch_vtcoutline_alloc_append(&poly->outline, 1); + dst->hdr = poly->hdr; + dst->hdr.type = CSCH_CTYPE_ARC; + dst->arc.spec.c.x = rnd_round(CRDX(cx)); + dst->arc.spec.c.y = rnd_round(CRDY(cy)); + dst->arc.spec.r = rnd_round(CRD(r)); + dst->arc.spec.start = sa / RND_RAD_TO_DEG; + dst->arc.spec.delta = da / RND_RAD_TO_DEG; +} + +csch_chdr_t *csch_alien_mktext(csch_alien_read_ctx_t *ctx, csch_cgrp_t *parent, double x, double y, const char *penname) +{ + csch_text_t *text = csch_text_alloc(ctx->sheet, parent, csch_oid_new(ctx->sheet, parent)); + + text->spec1.x = CRDX(x); + text->spec1.y = CRDY(y); + text->hdr.stroke_name = csch_comm_str(ctx->sheet, penname, 1); + + return &text->hdr; +} + + +csch_chdr_t *csch_alien_mkpoly(csch_alien_read_ctx_t *ctx, csch_cgrp_t *parent, const char *stroke_name, const char *fill_name) +{ + csch_cpoly_t *poly = csch_cpoly_alloc(ctx->sheet, parent, csch_oid_new(ctx->sheet, parent)); + + if (stroke_name != NULL) { + poly->hdr.stroke_name = csch_comm_str(ctx->sheet, stroke_name, 1); + poly->has_stroke = 1; + } + if (fill_name != NULL) { + poly->hdr.fill_name = csch_comm_str(ctx->sheet, fill_name, 1); + poly->has_fill = 1; + } + + return &poly->hdr; +} + +void csch_alien_append_poly_line(csch_alien_read_ctx_t *ctx, csch_chdr_t *poly_, double x1, double y1, double x2, double y2) +{ + csch_cpoly_t *poly = (csch_cpoly_t *)poly_; + csch_coutline_t *dst = csch_vtcoutline_alloc_append(&poly->outline, 1); + dst->hdr = poly->hdr; + dst->hdr.type = CSCH_CTYPE_LINE; + dst->line.spec.p1.x = CRDX(x1); + dst->line.spec.p1.y = CRDY(y1); + dst->line.spec.p2.x = CRDX(x2); + dst->line.spec.p2.y = CRDY(y2); +} + +void csch_alien_sheet_setup(csch_alien_read_ctx_t *ctx, int pen) +{ + sch_rnd_sheet_setup(ctx->sheet, (pen ? SCH_RND_SSC_PENS : 0) | SCH_RND_SSC_UUID, NULL, NULL); +} + +csch_cgrp_t *csch_alien_convert_to_grp(csch_alien_read_ctx_t *ctx, csch_chdr_t **obj) +{ + csch_cgrp_t *grp; + csch_chdr_t *newo; + + if (csch_obj_is_grp(*obj)) + return (csch_cgrp_t *)(*obj); + + grp = csch_cgrp_alloc(ctx->sheet, (*obj)->parent, csch_oid_new(ctx->sheet, (*obj)->parent)); + + csch_cnc_remove(ctx->sheet, (*obj)); + newo = csch_cobj_dup(ctx->sheet, grp, (*obj), 0, 0); + csch_cobj_update(ctx->sheet, newo, 0); +/* csch_op_inserted(sheet, dst, newo);*/ + *obj = newo; + return grp; +} + +csch_cgrp_t *csch_alien_attr_grp(csch_alien_read_ctx_t *ctx, csch_chdr_t **obj) +{ + csch_cgrp_t *parent = (*obj)->parent; + + if (csch_obj_is_grp(*obj)) + return (csch_cgrp_t *)(*obj); + + if ((parent->role == CSCH_ROLE_WIRE_NET) || (parent->role == CSCH_ROLE_SYMBOL)) + return parent; + + return csch_alien_convert_to_grp(ctx, obj); +} + +static void alien_collect_conns(csch_alien_read_ctx_t *ctx, vtp0_t *dst, csch_cgrp_t *grp) +{ + htip_entry_t *e; + + for(e = htip_first(&grp->id2obj); e != NULL; e = htip_next(&grp->id2obj, e)) { + csch_cgrp_t *g = e->value; + if (csch_obj_is_grp(&g->hdr)) { + if (g->role == CSCH_ROLE_TERMINAL) + vtp0_append(dst, g); + else + alien_collect_conns(ctx, dst, g); + } + } +} + +void csch_alien_update_conns(csch_alien_read_ctx_t *ctx) +{ + vtp0_t grps = {0}; + long n; + + /* collect all terminal groups recursively */ + alien_collect_conns(ctx, &grps, &ctx->sheet->direct); + + for(n = 0; n < grps.used; n++) + csch_conn_auto_recalc(ctx->sheet, grps.array[n]); + + vtp0_uninit(&grps); +} + +static int centerline_bbox(csch_alien_read_ctx_t *ctx, csch_chdr_t *src, csch_rtree_box_t *dst) +{ + switch(src->type) { + case CSCH_CTYPE_LINE: csch_line_center_bbox(ctx->sheet, (csch_line_t *)src, dst); return 1; + case CSCH_CTYPE_ARC: csch_arc_center_bbox(ctx->sheet, (csch_arc_t *)src, dst); return 1; + case CSCH_CTYPE_POLY: csch_cpoly_center_bbox(ctx->sheet, (csch_cpoly_t *)src, dst); return 1; + case CSCH_CTYPE_GRP: + case CSCH_CTYPE_GRP_REF: + { + htip_entry_t *e; + csch_rtree_box_t tmp; + csch_cgrp_t *grp = (csch_cgrp_t *)src; + + for(e = htip_first(&grp->id2obj); e != NULL; e = htip_next(&grp->id2obj, e)) { + csch_bbox_reset(&tmp); + if (centerline_bbox(ctx, e->value, &tmp)) { + csch_bbox_bump(dst, x, tmp.x1); + csch_bbox_bump(dst, y, tmp.y1); + csch_bbox_bump(dst, x, tmp.x2); + csch_bbox_bump(dst, y, tmp.y2); + } + } + } + return 1; + default: + break; + } + return 0; +} + +void csch_alien_centerline_bbox(csch_alien_read_ctx_t *ctx, csch_chdr_t *src, csch_rtree_box_t *dst) +{ + csch_bbox_reset(dst); + centerline_bbox(ctx, src, dst); +} + + +#include "read_postproc.c" Index: tags/1.0.5/src/plugins/lib_alien/read_helper.h =================================================================== --- tags/1.0.5/src/plugins/lib_alien/read_helper.h (nonexistent) +++ tags/1.0.5/src/plugins/lib_alien/read_helper.h (revision 10414) @@ -0,0 +1,95 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - alien file format helpers + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#ifndef SCH_RND_LIB_ALIEN_READ_HELPER_H +#define SCH_RND_LIB_ALIEN_READ_HELPER_H + +#include + +typedef struct csch_alien_read_ctx_s { + csch_sheet_t *sheet; + const char *fmt_prefix; /* for postproc actions */ + double coord_factor; + double ox, oy; /* in original format coords */ + unsigned flip_x:1; + unsigned flip_y:1; + + /* print errors only once */ + unsigned warned_coord_range:1; +} csch_alien_read_ctx_t; + +/* Set up ctx->sheet: + - if pen is non-zero, copy default pens +*/ +void csch_alien_sheet_setup(csch_alien_read_ctx_t *ctx, int pen); + +/* Return the group attributes should be set in for obj; may create a new + group around obj. */ +csch_cgrp_t *csch_alien_attr_grp(csch_alien_read_ctx_t *ctx, csch_chdr_t **obj); + +/* If obj is not a group, create a group around it and return it (else + return obj). Useful when attributes are to be attached. Obj ptr + may change in the process (when mvoed into a new group). */ +csch_cgrp_t *csch_alien_convert_to_grp(csch_alien_read_ctx_t *ctx, csch_chdr_t **obj); + +csch_chdr_t *csch_alien_mknet(csch_alien_read_ctx_t *ctx, csch_cgrp_t *parent, double x1, double y1, double x2, double y2); +csch_chdr_t *csch_alien_mkline(csch_alien_read_ctx_t *ctx, csch_cgrp_t *parent, double x1, double y1, double x2, double y2, const char *penname); +csch_chdr_t *csch_alien_mkarc(csch_alien_read_ctx_t *ctx, csch_cgrp_t *parent, double cx, double cy, double r, double sa, double da, const char *penname); +csch_chdr_t *csch_alien_mkrect(csch_alien_read_ctx_t *ctx, csch_cgrp_t *parent, double x1, double y1, double x2, double y2, const char *stroke_penname, const char *fill_penname); +csch_chdr_t *csch_alien_mktext(csch_alien_read_ctx_t *ctx, csch_cgrp_t *parent, double x, double y, const char *penname); + +/* Elliptical arc is emulated using a polygon and line approximation; + sa and da are in radians for start and delta angle. */ +csch_chdr_t *csch_alien_mkearc(csch_alien_read_ctx_t *ctx, csch_cgrp_t *parent, double cx, double cy, double rx, double ry, double sa, double da, const char *stroke, const char *fill); + + +csch_chdr_t *csch_alien_mkpoly(csch_alien_read_ctx_t *ctx, csch_cgrp_t *parent, const char *stroke_name, const char *fill_name); +void csch_alien_append_poly_line(csch_alien_read_ctx_t *ctx, csch_chdr_t *poly, double x1, double y1, double x2, double y2); +void csch_alien_append_poly_arc(csch_alien_read_ctx_t *ctx, csch_chdr_t *poly_, double cx, double cy, double r, double sa, double da); +void csch_alien_append_poly_bezier(csch_alien_read_ctx_t *ctx, csch_chdr_t *poly_, double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4); + +/* Frees src */ +csch_chdr_t *csch_alien_mkpin_line(csch_alien_read_ctx_t *ctx, csch_source_arg_t *src, csch_cgrp_t *parent, double x1, double y1, double x2, double y2); + +void csch_alien_mkbezier(csch_alien_read_ctx_t *ctx, csch_cgrp_t *parent, double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, const char *penname); + + +/* Convert coordinate to cschem model */ +csch_coord_t csch_alien_coord_x(csch_alien_read_ctx_t *ctx, double crd); +csch_coord_t csch_alien_coord_y(csch_alien_read_ctx_t *ctx, double crd); +csch_coord_t csch_alien_coord(csch_alien_read_ctx_t *ctx, double crd); + + +/* Update connection on every single terminal group on the sheet */ +void csch_alien_update_conns(csch_alien_read_ctx_t *ctx); + +/* Calculate the centerline bbox of lines, arcs, polygons and groups; ignores + anything else. Centerline ignores pen thickness. */ +void csch_alien_centerline_bbox(csch_alien_read_ctx_t *ctx, csch_chdr_t *src, csch_rtree_box_t *dst); + +#endif Index: tags/1.0.5/src/plugins/lib_alien/read_postproc.c =================================================================== --- tags/1.0.5/src/plugins/lib_alien/read_postproc.c (nonexistent) +++ tags/1.0.5/src/plugins/lib_alien/read_postproc.c (revision 10414) @@ -0,0 +1,291 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - alien file format helpers + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/* #included from read_helper.c */ + +/* Execute the generic, per format, user provideed postprocessor action, e.g. + io_geda_postporc_sheet_load, if it is defined. Returns 0 on success. */ +static int alien_postproc_sheet_act(csch_alien_read_ctx_t *ctx) +{ + fgw_func_t *af; + char *aname = rnd_concat(ctx->fmt_prefix, "_postproc_sheet_load", NULL); + int res = 0; + + af = rnd_act_lookup(aname); + if (af != NULL) + res = rnd_action(&ctx->sheet->hidlib, aname); + + free(aname); + return res; +} + +typedef struct { + int res; + const char *act; + csch_sheet_t *sheet; + long changed; +} alien_postproc_sheet_conf_t; + +static void alien_postproc_sheet_conf_cb(void *user_ctx, pcb_qry_val_t *res, csch_chdr_t *current) +{ + alien_postproc_sheet_conf_t *ppctx = user_ctx; + int bv; + + if (res->type == PCBQ_VT_COORD) + bv = res->data.crd != 0; + else if (res->type == PCBQ_VT_LONG) + bv = res->data.lng != 0; + else if (res->type == PCBQ_VT_LST) + bv = res->data.lst.used > 0; + else if (res->type == PCBQ_VT_OBJ) + bv = res->data.obj != NULL; + else + return; + + if (!bv) + return; + + ppctx->sheet->currobj = current; + current->selected = 1; + ppctx->res |= rnd_parse_command(&ppctx->sheet->hidlib, ppctx->act, 0) < 0; + current->selected = 0; + ppctx->sheet->currobj = NULL; + + ppctx->changed++; +} + +static int alien_postproc_sheet_conf_exec(csch_alien_read_ctx_t *ctx, const char *pat, const char *act, int *needs_indir_rend) +{ + pcb_qry_exec_t qctx = {0}; + int qres; + alien_postproc_sheet_conf_t ppctx; + + ppctx.res = 0; + ppctx.act = act; + ppctx.sheet = ctx->sheet; + ppctx.changed = 0; + + pcb_qry_init(&qctx, ctx->sheet, NULL, -2); + qres = pcb_qry_run_script(&qctx, ctx->sheet, pat, "sheet-indirect", alien_postproc_sheet_conf_cb, &ppctx); + pcb_qry_uninit(&qctx); + + if (ppctx.changed) + *needs_indir_rend = 1; + + pcb_qry_init(&qctx, ctx->sheet, NULL, -1); + qres |= pcb_qry_run_script(&qctx, ctx->sheet, pat, "sheet", alien_postproc_sheet_conf_cb, &ppctx); + pcb_qry_uninit(&qctx); + + return (qres < 0) | ppctx.res; +} + +static int alien_postproc_sheet_conf(csch_alien_read_ctx_t *ctx) +{ + char *path; + rnd_conf_native_t *nat; + rnd_conflist_t *list; + rnd_conf_listitem_t *i; + const char *pat, *act; + int idx, needs_indir_rend = 0; + + path = rnd_concat("plugins/", ctx->fmt_prefix, "/postproc_sheet_load", NULL); + nat = rnd_conf_get_field(path); + if (nat == NULL) { + free(path); + return 0; + } + + if (nat->type != RND_CFN_LIST) { + rnd_message(RND_MSG_ERROR, "Invalid config node type %s: should be a list\n", path); + free(path); + return -1; + } + + list = nat->val.list; + for(i = rnd_conf_list_first_str(list, &pat, &idx); i != NULL; i = rnd_conf_list_next_str(i, &pat, &idx)) { + if (i == NULL) { + rnd_message(RND_MSG_ERROR, "Invalid config node %s: missing action (odd number of list items)\n", path); + free(path); + return -1; + } + i = rnd_conf_list_next_str(i, &act, &idx); + if (alien_postproc_sheet_conf_exec(ctx, pat, act, &needs_indir_rend) != 0) { + rnd_message(RND_MSG_ERROR, "Failed to execute %s\n", path); + free(path); + return -1; + } + } + + /* if indirect objects have been modified, need to re-render all instances + to get the modifications visible */ + if (needs_indir_rend) + csch_cgrp_render_all(ctx->sheet, &ctx->sheet->direct); + + free(path); + return 0; +} + +int csch_alien_postproc_sheet(csch_alien_read_ctx_t *ctx) +{ + + if (ctx->fmt_prefix == NULL) { + rnd_message(RND_MSG_ERROR, "csch_alien_postproc_sheet(): fmt_prefix not available\n"); + return -1; + } + + if (alien_postproc_sheet_conf(ctx) != 0) + return -1; + + return alien_postproc_sheet_act(ctx); +} + +void csch_alien_postproc_normalize(csch_alien_read_ctx_t *ctx) +{ + htip_entry_t *e; + csch_coord_t dx = ctx->sheet->bbox.x1, dy = ctx->sheet->bbox.y1; + + dx = dx / 4000 * 4000; + dy = dy / 4000 * 4000; + + for(e = htip_first(&ctx->sheet->direct.id2obj); e != NULL; e = htip_next(&ctx->sheet->direct.id2obj, e)) { + csch_chdr_t *o = e->value; + csch_move(ctx->sheet, o, -dx, -dy, 0); + } +} + +static int is_text_rot_180(csch_text_t *t) +{ + int res = (fabs((fabs(t->inst_raw_rot) - 180.0)) < 0.01); /* +- 180 */ + /*rnd_trace("T180: '%s' '%s' rot=%f %f mir=%d %d -> %d %f\n", t->text, t->rtext, t->inst_rot, t->inst_raw_rot, t->inst_mirx, t->inst_miry, res, fabs((fabs(t->inst_rot) - 180.0)));*/ + return res; +} + +static int is_text_rot_270(csch_text_t *t) +{ + if ((fabs(t->inst_raw_rot - 270.0)) < 0.01) return 1; /* 270 */ + if ((fabs(t->inst_raw_rot + 90.0)) < 0.01) return 1; /* -90 */ + return 0; +} + +static void csch_alien_postproc_text_autorot_(csch_alien_read_ctx_t *ctx, csch_cgrp_t *grp, int inref, int fix180, int fix270) +{ + htip_entry_t *e; + + for(e = htip_first(&grp->id2obj); e != NULL; e = htip_next(&grp->id2obj, e)) { + csch_chdr_t *o = e->value; + if (o->type == CSCH_CTYPE_TEXT) { + csch_text_t *t = (csch_text_t *)o; + if (fix180 && is_text_rot_180(t)) + csch_rotate90(ctx->sheet, o, (o->bbox.x1+o->bbox.x2)/2, (o->bbox.y1+o->bbox.y2)/2, 2, 0); + if (fix270 && is_text_rot_270(t)) + csch_rotate90(ctx->sheet, o, (o->bbox.x1+o->bbox.x2)/2, (o->bbox.y1+o->bbox.y2)/2, 2, 0); + } + else if (o->type == CSCH_CTYPE_GRP) + csch_alien_postproc_text_autorot_(ctx, (csch_cgrp_t *)o, inref, fix180, fix270); + else if (o->type == CSCH_CTYPE_GRP_REF) + csch_alien_postproc_text_autorot_(ctx, (csch_cgrp_t *)o, 1, fix180, fix270); + } +} + +void csch_alien_postproc_text_autorot(csch_alien_read_ctx_t *ctx, csch_cgrp_t *grp, int fix180, int fix270) +{ + csch_alien_postproc_text_autorot_(ctx, grp, 0, fix180, fix270); +} + +RND_INLINE void rename_sym_redundant_terms(csch_alien_read_ctx_t *ctx, csch_cgrp_t *sym, vtp0_t *tmp, gds_t *stmp) +{ + htip_entry_t *e, *e2; + long n; + + tmp->used = 0; + + /* Find redundant names with O(n^2) - expect only a few terminals */ + for(e = htip_first(&sym->id2obj); e != NULL; e = htip_next(&sym->id2obj, e)) { + csch_cgrp_t *term = e->value; + + if (csch_obj_is_grp(&term->hdr) && (term->role == CSCH_ROLE_TERMINAL)) { + const char *name = csch_attrib_get_str(&term->attr, "name"); + + if ((name == NULL) || (*name == '\0')) + continue; + + for(e2 = htip_first(&sym->id2obj); e2 != NULL; e2 = htip_next(&sym->id2obj, e2)) { + csch_cgrp_t *term2 = e2->value; + + if (csch_obj_is_grp(&term2->hdr) && (term2->role == CSCH_ROLE_TERMINAL)) { + const char *name2 = csch_attrib_get_str(&term2->attr, "name"); + + if ((name2 == NULL) || (*name2 == '\0')) + continue; + + if ((e != e2) && (strcmp(name, name2) == 0)) { + vtp0_append(tmp, term); + break; + } + } + } + } + } + + for(n = 0; n < tmp->used; n++) { + csch_cgrp_t *term =tmp->array[n]; + csch_attrib_t *a = csch_attrib_get(&term->attr, "name"); + char suffix[64]; + csch_source_arg_t *src; + + stmp->used = 0; + gds_append_str(stmp, a->val); + gds_append_str(stmp, "__"); + sprintf(suffix, "%d", term->hdr.oid); + gds_append_str(stmp, suffix); + + free(a->val); + a->val = stmp->array; + stmp->array = NULL; + stmp->used = stmp->alloced = 0; + + src = csch_attrib_src_c(NULL, 0, 0, "Alien import: redundant terminal names changed"); + csch_attrib_append_src(a, a->prio, src, 0); + } +} + +void csch_alien_postproc_rename_redundant_terms(csch_alien_read_ctx_t *ctx) +{ + htip_entry_t *e; + vtp0_t tmp = {0}; + gds_t stmp = {0}; + + for(e = htip_first(&ctx->sheet->direct.id2obj); e != NULL; e = htip_next(&ctx->sheet->direct.id2obj, e)) { + csch_cgrp_t *g = e->value; + if ((g->hdr.type == CSCH_CTYPE_GRP) && (g->role == CSCH_ROLE_SYMBOL)) + rename_sym_redundant_terms(ctx, g, &tmp, &stmp); + } + + vtp0_uninit(&tmp); + gds_uninit(&stmp); +} Index: tags/1.0.5/src/plugins/lib_alien/read_postproc.h =================================================================== --- tags/1.0.5/src/plugins/lib_alien/read_postproc.h (nonexistent) +++ tags/1.0.5/src/plugins/lib_alien/read_postproc.h (revision 10414) @@ -0,0 +1,46 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - alien file format helpers + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#ifndef SCH_RND_LIB_ALIEN_READ_POSTPROC_H +#define SCH_RND_LIB_ALIEN_READ_POSTPROC_H + +/* Standard alien file format postprocessing. Returns 0 on success */ +int csch_alien_postproc_sheet(csch_alien_read_ctx_t *ctx); + +/* Rebase origin: move sheet's bbox x1;y1 to 0;0 */ +void csch_alien_postproc_normalize(csch_alien_read_ctx_t *ctx); + +/* recursively emulate tune text rotation; 0 and 90 degree text is always + kept; 180 or 270 degree text is adjusted depending on the arguments */ +void csch_alien_postproc_text_autorot(csch_alien_read_ctx_t *ctx, csch_cgrp_t *grp, int fix180, int fix270); + +/* Search for terminals that have the same name within groups (but not group + refs) and rename them to unique name */ +void csch_alien_postproc_rename_redundant_terms(csch_alien_read_ctx_t *ctx); + +#endif Index: tags/1.0.5/src/plugins/lib_anymap/Makefile =================================================================== --- tags/1.0.5/src/plugins/lib_anymap/Makefile (nonexistent) +++ tags/1.0.5/src/plugins/lib_anymap/Makefile (revision 10414) @@ -0,0 +1,2 @@ +all: + cd ../../sch-rnd && make mod_lib_anymap Index: tags/1.0.5/src/plugins/lib_anymap/Plug.tmpasm =================================================================== --- tags/1.0.5/src/plugins/lib_anymap/Plug.tmpasm (nonexistent) +++ tags/1.0.5/src/plugins/lib_anymap/Plug.tmpasm (revision 10414) @@ -0,0 +1,10 @@ +put /local/rnd/mod {lib_anymap} +put /local/rnd/mod/OBJS [@ + $(PLUGDIR)/lib_anymap/lib_anymap.o +@] + +switch /local/module/lib_anymap/controls + case {buildin} include /local/csch/tmpasm/buildin; end; + case {plugin} include /local/csch/tmpasm/plugin; end; + case {disable} include /local/csch/tmpasm/disable; end; +end Index: tags/1.0.5/src/plugins/lib_anymap/lib_anymap.c =================================================================== --- tags/1.0.5/src/plugins/lib_anymap/lib_anymap.c (nonexistent) +++ tags/1.0.5/src/plugins/lib_anymap/lib_anymap.c (revision 10414) @@ -0,0 +1,66 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - any map helpers (e.g. devmap/funcmap) + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/* Maintain a cache of parsed comp/net/conn objects and compile abstract + model from them */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "lib_anymap.h" + +#include "loclib.c" +#include "libs.c" +#include "preview.c" + +/*** plugin ***/ + +int pplg_check_ver_lib_anymap(int ver_needed) { return 0; } + +void pplg_uninit_lib_anymap(void) +{ +} + +int pplg_init_lib_anymap(void) +{ + RND_API_CHK_VER; + + return 0; +} + Index: tags/1.0.5/src/plugins/lib_anymap/lib_anymap.h =================================================================== --- tags/1.0.5/src/plugins/lib_anymap/lib_anymap.h (nonexistent) +++ tags/1.0.5/src/plugins/lib_anymap/lib_anymap.h (revision 10414) @@ -0,0 +1,61 @@ +#ifndef SCH_RND_LIB_ANYMAP_H +#define SCH_RND_LIB_ANYMAP_H + +#include +#include +#include + +typedef struct anymap_ctx_s anymap_ctx_t; /* per view data */ +struct anymap_ctx_s { + const char *name; /* name of the map (e.g. "devmap", for error messages) */ + const char *attr_key; /* name of the symbol attribute used to address the map, usually matches ->name */ + const char *eng_src_name; /* engine name used in attribute sources, e.g. "std_devmap" */ + ldch_ctx_t maps; + ldch_low_parser_t *low_parser; + ldch_high_parser_t *high_parser; + vtp0_t ssyms; /* temporary cache between calls to save on mallocs - not persistent */ + csch_lib_backend_t *be; + void (*sheet_init)(anymap_ctx_t *actx, csch_sheet_t *sheet, csch_lib_t **root_dir_out, int alloc); +}; /* per view data */ + +typedef struct anymap_obj_s { + csch_attribs_t comp_attribs; +} anymap_obj_t; + + +/*** loclib ***/ + +/* hash: a htsi_t, keyed with indirect devmap groups are stored in the + indirect/purpose=devmap group's backend_data->ptr[0]; this is used + for quick lookup of mapobj_name -> grp; key is grp->loclib_name (not + alloced/free'd for the hash table). backend_data->ptr[0] points + to the indirect/purpose=devmap grp */ +void anymap_sheet_init_(anymap_ctx_t *actx, rnd_design_t *hl, csch_lib_t *root_dir, const csch_cgrp_t *maproot); + +int anymap_loc_list(csch_sheet_t *sheet, csch_lib_t *src, const char *attr_key); + +int anymap_loc_refresh_from_ext(anymap_ctx_t *actx, csch_sheet_t *sheet, csch_lib_t *src); + +csch_attribs_t *anymap_get_from_loclib(anymap_ctx_t *actx, csch_sheet_t *sheet, const char *mapobj_name); + +void anymap_lht_free(csch_lib_t *src); + + +/*** libs ***/ + +csch_attribs_t *anymap_get_extlib(anymap_ctx_t *ctx, const char *mapobj_name, csch_hook_call_ctx_t *cctx, int save_in_local); + +/* Look up and return component attributes for the component's mapobj name: + - first look in the local lib; if present, load from there + - if not, look in the library and import into the local lib + - return NULL if both fail */ +csch_attribs_t *anymap_get_from_any_lib(anymap_ctx_t *actx, csch_acomp_t *comp, csch_attrib_t *adm, void *ucallctx); + + +/*** preview ***/ + +char *anymap_lht_preview_text(anymap_ctx_t *actx, csch_sheet_t *sheet, csch_lib_t *src, const char *parametric); + + + +#endif Index: tags/1.0.5/src/plugins/lib_anymap/lib_anymap.pup =================================================================== --- tags/1.0.5/src/plugins/lib_anymap/lib_anymap.pup (nonexistent) +++ tags/1.0.5/src/plugins/lib_anymap/lib_anymap.pup (revision 10414) @@ -0,0 +1,7 @@ +$class export +$short devmap, funcmap common code +$long Common code usable for map-like engine plugins +$state works +$package (core) +default buildin +autoload 1 Index: tags/1.0.5/src/plugins/lib_anymap/libs.c =================================================================== --- tags/1.0.5/src/plugins/lib_anymap/libs.c (nonexistent) +++ tags/1.0.5/src/plugins/lib_anymap/libs.c (revision 10414) @@ -0,0 +1,161 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - any map helpers (e.g. devmap/funcmap) + * Copyright (C) 2022,2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust Fund in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/*** devmap library handling ***/ + +static void anymap_save_in_local(anymap_ctx_t *ctx, const char *anyobj_name, csch_attribs_t *dma) +{ + long n; + +/* rnd_trace("anymap: inserting %s in local libs:\n", anyobj_name);*/ + for(n = 0; n < ctx->ssyms.used; n++) { + csch_cgrp_t *sym = ctx->ssyms.array[n]; + csch_attribs_t *existing; +/* rnd_trace(" %s\n", sym->hdr.sheet->hidlib.fullpath);*/ + existing = anymap_get_from_loclib(ctx, sym->hdr.sheet, anyobj_name); + if (existing == NULL) { + rnd_message(RND_MSG_INFO, "%s: inserting %s in local lib of %s\n", ctx->name, anyobj_name, sym->hdr.sheet->hidlib.fullpath); + anymap_set_in_loclib(ctx, sym->hdr.sheet, anyobj_name, dma); + } + } +} + +/* Load (and cache-parse) a mapobj from the external libs */ +csch_attribs_t *anymap_get_extlib(anymap_ctx_t *ctx, const char *mapobj_name, csch_hook_call_ctx_t *cctx, int save_in_local) +{ + ldch_data_t *data; + anymap_obj_t *mapobj; + csch_attribs_t *res; + + data = ldch_load_(&ctx->maps, mapobj_name, ctx->low_parser, ctx->high_parser, NULL, cctx); + if (data == NULL) + return NULL; + + mapobj = (anymap_obj_t *)&data->payload; + res = &mapobj->comp_attribs; + + if (save_in_local) + anymap_save_in_local(ctx, mapobj_name, res); + + return res; +} + +/* INTERNAL CALL + Look up and return component attributes for the component's mapobj name: + look in the local lib; if present, load from there + - if not, look in the library and import into the local lib + - if that fails, set *get_name_from_ext to the mapobj name that should be + imported from the external lib by the caller + - return NULL if both fail +*/ +static csch_attribs_t *anymap_get_from_int_lib(anymap_ctx_t *actx, csch_acomp_t *comp, csch_attrib_t *adm, void *ucallctx, const char **get_name_from_ext) +{ + csch_attribs_t *res = NULL, *loc_dm; + csch_cgrp_t *res_sym = NULL; + const char *mapobj_name; + long n; + + *get_name_from_ext = 0; + + if ((adm == NULL) || (adm->deleted)) return NULL; + mapobj_name = adm->val; + + if (mapobj_name == NULL) { + rnd_message(RND_MSG_ERROR, "Devmap attribute should be a string in component %s\n", comp->name); + return NULL; + } + + if (*mapobj_name == '\0') /* empty value is okay, it means no mapobj */ + return NULL; + + /* figure which symbol(s) have this mapobj */ + actx->ssyms.used = 0; + for(n = 0; n < comp->hdr.srcs.used; n++) { + csch_cgrp_t *sym = comp->hdr.srcs.array[n]; + const char *cdmn; + + if (sym == NULL) + continue; + + cdmn = csch_attrib_get_str(&sym->attr, actx->attr_key); +/*rnd_trace("anymap: comp: %s devmap: %s sym's: '%s'\n", comp->name, mapobj_name, cdmn);*/ + if ((cdmn == NULL) || (strcmp(cdmn, mapobj_name) != 0)) + continue; + + vtp0_append(&actx->ssyms, sym); + } + + if (actx->ssyms.used == 0) { + rnd_message(RND_MSG_ERROR, "%s internal error in component %s: no source symbol has the right %s attribute\n", actx->name, comp->name, actx->name); + return NULL; + } + + /* if there are more than one, compare the relevant ones and remember the first */ + for(n = 0; n < actx->ssyms.used; n++) { + csch_cgrp_t *sym = actx->ssyms.array[n]; + + loc_dm = anymap_get_from_loclib(actx, sym->hdr.sheet, mapobj_name); + if (res != NULL) { + if ((loc_dm != NULL) && (!csch_attrib_eq(res, loc_dm))) { + rnd_message(RND_MSG_ERROR, "%s local lib sync error sheet %s and %s has different copy of %s %s\nPlease sync your local libs before compiling!\n", actx->name, sym->hdr.sheet->hidlib.fullpath, res_sym->hdr.sheet->hidlib.fullpath, actx->name, mapobj_name); + return NULL; + } + } + else { + res = loc_dm; + if (res != NULL) + res_sym = sym; + } + } + + if (res != NULL) { +/* rnd_trace("anymap: served %s from local lib of sheet %s\n", mapobj_name, res_sym->hdr.sheet->hidlib.fullpath);*/ + return res; + } + + *get_name_from_ext = mapobj_name; + return res; +} + + +csch_attribs_t *anymap_get_from_any_lib(anymap_ctx_t *actx, csch_acomp_t *comp, csch_attrib_t *adm, void *ucallctx) +{ + const char *get_from_ext; + csch_attribs_t *res = anymap_get_from_int_lib(actx, comp, adm, ucallctx, &get_from_ext); + + if (get_from_ext != NULL) { +/* rnd_trace("anymap: %s is not in our local libs\n", get_from_ext);*/ + res = anymap_get_extlib(actx, get_from_ext, ucallctx, 1); + if (res == NULL) { + rnd_message(RND_MSG_ERROR, "%s %s not found in the library for component %s\n(Hint: after creating the %s in the lib: file menu, maintenance, re-scan devmap)\n", actx->name, get_from_ext, comp->name, actx->name); + return NULL; + } + } + return res; +} + Index: tags/1.0.5/src/plugins/lib_anymap/loclib.c =================================================================== --- tags/1.0.5/src/plugins/lib_anymap/loclib.c (nonexistent) +++ tags/1.0.5/src/plugins/lib_anymap/loclib.c (revision 10414) @@ -0,0 +1,236 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - any map helpers (e.g. devmap/funcmap) + * Copyright (C) 2022,2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust Fund in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/*** local lib support ***/ + +static void anymap_local_ins(anymap_ctx_t *actx, htsp_t *map, csch_lib_t *root_dir, csch_cgrp_t *grp) +{ + csch_lib_t *newent; + + htsp_set(map, grp->loclib_name, grp); + + newent = csch_lib_alloc_append(actx->be, root_dir, rnd_strdup(grp->loclib_name), CSCH_SLIB_STATIC); + newent->backend_data.lng[0] = grp->hdr.oid; +} + +static void anymap_sheet_uninit(csch_lib_t *root_dir) +{ + csch_cgrp_t *symlib = root_dir->backend_data.ptr[1]; + + if (symlib == NULL) return; + + htsp_free(root_dir->backend_data.ptr[0]); + + root_dir->backend_data.ptr[0] = NULL; + root_dir->backend_data.ptr[1] = NULL; +} + +void anymap_sheet_init_(anymap_ctx_t *actx, rnd_design_t *hl, csch_lib_t *root_dir, const csch_cgrp_t *maproot) +{ + if (root_dir->backend_data.ptr[0] == NULL) { + htip_entry_t *e; + htsp_t *map; + + map = root_dir->backend_data.ptr[0] = htsp_alloc(strhash, strkeyeq); + root_dir->backend_data.ptr[1] = (void *)maproot; + + if (root_dir->backend == NULL) { + static csch_lib_backend_t anymap_be_sheet_free; + anymap_be_sheet_free.name = "anymap_be_sheet_free"; + anymap_be_sheet_free.free = anymap_sheet_uninit; + root_dir->backend = &anymap_be_sheet_free; + } + + for(e = htip_first(&maproot->id2obj); e != NULL; e = htip_next(&maproot->id2obj, e)) { + csch_cgrp_t *grp = e->value; + if (grp->hdr.type == CSCH_CTYPE_GRP) + anymap_local_ins(actx, map, root_dir, grp); + } + } +} + + +void anymap_lht_free(csch_lib_t *src) +{ + csch_lib_t *root_dir = src->parent; + if (root_dir != NULL) { + htsp_t *map = root_dir->backend_data.ptr[0]; + if (map != NULL) + htsp_pop(map, src->name); + } + else + anymap_sheet_uninit(src); /* src is a root dir */ +} + + +csch_attribs_t *anymap_get_from_loclib(anymap_ctx_t *actx, csch_sheet_t *sheet, const char *mapobj_name) +{ + csch_lib_t *root_dir; + csch_cgrp_t *gd; + htsp_t *map; + + actx->sheet_init(actx, sheet, &root_dir, 0); + + if ((root_dir == NULL) || (root_dir->backend_data.ptr[0] == NULL)) + return NULL; + + map = root_dir->backend_data.ptr[0]; + + gd = htsp_get(map, mapobj_name); +/*rnd_trace("*** get: map=%p '%s' -> %p\n", map, mapobj_name, gd);*/ + if (gd == NULL) + return NULL; + + return &gd->attr; +} + +static void anymap_set_attr_in_loclib(anymap_ctx_t *ctx, csch_sheet_t *sheet, csch_cgrp_t *dst, csch_attribs_t *dma) +{ + csch_source_arg_t *src = csch_attrib_src_p(ctx->eng_src_name, "external lib"); + + csch_attrib_apply(&dst->attr, dma, src, NULL); + csch_sheet_set_changed(sheet, 1); +} + +void anymap_set_in_loclib(anymap_ctx_t *ctx, csch_sheet_t *sheet, const char *mapobj_name, csch_attribs_t *dma) +{ + csch_lib_t *root_dir; + csch_cgrp_t *maproot; + htsp_t *map; + csch_cgrp_t *gd; + + ctx->sheet_init(ctx, sheet, &root_dir, 1); + + map = root_dir->backend_data.ptr[0]; + maproot = root_dir->backend_data.ptr[1]; + + if ((map == NULL) || (maproot == NULL)) { + rnd_message(RND_MSG_ERROR, "Failed to create %s local lib root for sheet %s\nNot building a local lib, sheet is not portable.\n", ctx->name, sheet->hidlib.loadname); + return; + } + + gd = csch_cgrp_alloc(sheet, maproot, csch_oid_new(sheet, maproot)); + if (gd == NULL) { + rnd_message(RND_MSG_ERROR, "Failed to create %s local lib entry for %s in sheet %s\nNot building a local lib, sheet is not portable.\n", ctx->name, mapobj_name, sheet->hidlib.loadname); + return; + } + + + gd->loclib_name = rnd_strdup(mapobj_name); + anymap_set_attr_in_loclib(ctx, sheet, gd, dma); + + anymap_local_ins(ctx, map, root_dir, gd); + rnd_event(&sheet->hidlib, CSCH_EVENT_LIBRARY_CHANGED, NULL); + +/*rnd_trace("*** set: map=%p '%s' -> %p\n", map, gd->loclib_name, gd);*/ + + +} + + +/* Return a map object */ +static void *anymap_refresh_from_ext_get(anymap_ctx_t *actx, csch_sheet_t *sheet, csch_lib_t *src, csch_cgrp_t **old_out) +{ + csch_lib_t *root_dir = src->parent; + htsp_t *map; + ldch_data_t *data; + csch_hook_call_ctx_t cctx = {0}; + csch_cgrp_t *old; + + map = root_dir->backend_data.ptr[0]; + *old_out = old = htsp_get(map, src->name); + if (old == NULL) { + rnd_message(RND_MSG_ERROR, "%s loclib internal error: can't find %s '%s'\n", actx->name, actx->name, src->name); + return NULL; + } + + /* check if it is loadable from the external lib */ + data = ldch_load_(&actx->maps, src->name, actx->low_parser, actx->high_parser, NULL, &cctx); + if (data == NULL) { + rnd_message(RND_MSG_ERROR, "Can't find %s '%s' in the external %s lib\n", actx->name, src->name, actx->name); + return NULL; + } + + return &data->payload; +} + +int anymap_loc_refresh_from_ext(anymap_ctx_t *actx, csch_sheet_t *sheet, csch_lib_t *src) +{ + csch_cgrp_t *old; + anymap_obj_t *mapobj = (anymap_obj_t *)anymap_refresh_from_ext_get(actx, sheet, src, &old); + + if (mapobj == NULL) + return -1; + + anymap_set_attr_in_loclib(actx, sheet, old, &mapobj->comp_attribs); + return 0; +} + + +static long anymap_loc_list_recurse(csch_cgrp_t *grp, const char *mapobj_name, vtp0_t *res, const char *attr_key) +{ + long sum = 0; + htip_entry_t *e; + const char *devmapa; + + devmapa = csch_attrib_get_str(&grp->attr, attr_key); + if ((devmapa != NULL) && (strcmp(devmapa, mapobj_name) == 0)) { + vtp0_append(res, grp); + sum++; + } + + for(e = htip_first(&grp->id2obj); e != NULL; e = htip_next(&grp->id2obj, e)) { + csch_cgrp_t *child = e->value; + if (csch_obj_is_grp(&child->hdr)) + sum += anymap_loc_list_recurse(child, mapobj_name, res, attr_key); + } + return sum; +} + + +int anymap_loc_list(csch_sheet_t *sheet, csch_lib_t *src, const char *attr_key) +{ + long cnt; + vtp0_t arr = {0}; + + cnt = anymap_loc_list_recurse(&sheet->direct, src->name, &arr, attr_key); + rnd_message(RND_MSG_INFO, "Found %ld references to %s\n", cnt, src->name); + + if (cnt > 0) { + fgw_arg_t args[4], ares; + + args[1].type = FGW_STR; args[1].val.str = "objarr"; + fgw_ptr_reg(&rnd_fgw, &args[2], CSCH_PTR_DOMAIN_COBJ_ARR, FGW_PTR | FGW_STRUCT, &arr); + rnd_actionv_bin(&sheet->hidlib, "TreeDialog", &ares, 3, args); + fgw_ptr_unreg(&rnd_fgw, &args[2], CSCH_PTR_DOMAIN_COBJ_ARR); + vtp0_uninit(&arr); + } + + return 0; +} + Index: tags/1.0.5/src/plugins/lib_anymap/preview.c =================================================================== --- tags/1.0.5/src/plugins/lib_anymap/preview.c (nonexistent) +++ tags/1.0.5/src/plugins/lib_anymap/preview.c (revision 10414) @@ -0,0 +1,132 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - any map helpers (e.g. devmap/funcmap) + * Copyright (C) 2022,2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust Fund in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/* copied from io_lihata write.c */ +static int attr_cmp(const void *v1, const void *v2) +{ + csch_attrib_t * const *a1 = v1, * const *a2 = v2; + return strcmp((*a1)->key, (*a2)->key); +} + +/* copied from io_lihata write.c */ +static void lht_print_str(gds_t *tmp, const char *s) +{ + if (s == NULL) { + gds_append_str(tmp, "{}"); + return; + } + if (!lht_need_brace(LHT_TEXT, s, 0)) { + gds_append_str(tmp, s); + return; + } + gds_append(tmp, '{'); + for(; *s != '\0'; s++) { + if ((*s == '\\') || (*s == '}')) + gds_append(tmp, '\\'); + gds_append(tmp, *s); + } + gds_append(tmp, '}'); +} + +static char *print_attribs(csch_attribs_t *attr) +{ + gds_t tmp = {0}; + htsp_entry_t *e; + vtp0_t ord; + long n; + + memset(&ord, 0, sizeof(ord)); + + /* copied from io_lihata write.c */ + for(e = htsp_first(attr); e != NULL; e = htsp_next(attr, e)) + vtp0_append(&ord, e->value); + if (ord.used > 0) { + qsort(ord.array, ord.used, sizeof(void *), attr_cmp); + for(n = 0; n < ord.used; n++) { + const csch_attrib_t *a = ord.array[n]; + if (a->val != NULL) { + if (a->prio != CSCH_ATP_USER_DEFAULT) { + rnd_append_printf(&tmp, "ha:%s = { value=", a->key); + lht_print_str(&tmp, a->val); + rnd_append_printf(&tmp, "; prio=%d; }\n", a->prio); + } + else { + rnd_append_printf(&tmp, "%s=", a->key); + lht_print_str(&tmp, a->val); + rnd_append_printf(&tmp, "\n"); + } + } + else { + long n; + + if (a->prio != CSCH_ATP_USER_DEFAULT) + rnd_append_printf(&tmp, "ha:%s = { li:value = {\n", a->key); + else + rnd_append_printf(&tmp, "li:%s {\n", a->key); + + for(n = 0; n < a->arr.used; n++) { + rnd_append_printf(&tmp, " "); + lht_print_str(&tmp, a->arr.array[n]); + rnd_append_printf(&tmp, "\n"); + } + if (a->prio != CSCH_ATP_USER_DEFAULT) { + rnd_append_printf(&tmp, "}\n"); + rnd_append_printf(&tmp, "prio=%d; }\n", a->prio); + } + else + rnd_append_printf(&tmp, "}\n"); + } + } + } + vtp0_uninit(&ord); + return tmp.array; +} + +char *anymap_lht_preview_text(anymap_ctx_t *actx, csch_sheet_t *sheet, csch_lib_t *src, const char *parametric) +{ + csch_attribs_t *attr = NULL; + long oid = src->backend_data.lng[0]; + + if (oid == 0) { + /* external lib */ + csch_hook_call_ctx_t cctx = {0}; + + cctx.project = (csch_project_t *)sheet->hidlib.project; + attr = anymap_get_extlib(actx, src->realpath, &cctx, 0); + } + else { + /* local lib */ + attr = anymap_get_from_loclib(actx, sheet, src->name); + } + + if (attr == NULL) + return rnd_strdup(""); + + return print_attribs(attr); +} + Index: tags/1.0.5/src/plugins/lib_netlist_exp/Makefile =================================================================== --- tags/1.0.5/src/plugins/lib_netlist_exp/Makefile (nonexistent) +++ tags/1.0.5/src/plugins/lib_netlist_exp/Makefile (revision 10414) @@ -0,0 +1,2 @@ +all: + cd ../../sch-rnd && make mod_lib_netlist_exp Index: tags/1.0.5/src/plugins/lib_netlist_exp/Plug.tmpasm =================================================================== --- tags/1.0.5/src/plugins/lib_netlist_exp/Plug.tmpasm (nonexistent) +++ tags/1.0.5/src/plugins/lib_netlist_exp/Plug.tmpasm (revision 10414) @@ -0,0 +1,10 @@ +put /local/rnd/mod {lib_netlist_exp} +put /local/rnd/mod/OBJS [@ + $(PLUGDIR)/lib_netlist_exp/lib_netlist_exp.o +@] + +switch /local/module/lib_netlist_exp/controls + case {buildin} include /local/csch/tmpasm/buildin; end; + case {plugin} include /local/csch/tmpasm/plugin; end; + case {disable} include /local/csch/tmpasm/disable; end; +end Index: tags/1.0.5/src/plugins/lib_netlist_exp/lib_netlist_exp.c =================================================================== --- tags/1.0.5/src/plugins/lib_netlist_exp/lib_netlist_exp.c (nonexistent) +++ tags/1.0.5/src/plugins/lib_netlist_exp/lib_netlist_exp.c (revision 10414) @@ -0,0 +1,126 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - netlist export helpers + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/* Maintain a cache of parsed comp/net/conn objects and compile abstract + model from them */ + +#include + +#include +#include +#include + +#include "lib_netlist_exp.h" + +const char *sch_nle_get_refdes(const csch_acomp_t *comp) +{ + const char *refdes, *aname; + + refdes = csch_attrib_get_str(&comp->hdr.attr, "display/name"); + if (refdes != NULL) + return refdes; + + refdes = csch_attrib_get_str(&comp->hdr.attr, "display/refdes"); + if (refdes != NULL) + return refdes; + + aname = csch_attrib_get_str(&comp->hdr.attr, "name"); + if (aname == NULL) { + /* Either refdes or no name means do not export; this is to avoid + returning comp->name in case the user did not want this component + on the output */ + if (refdes == NULL) refdes = csch_attrib_get_str(&comp->hdr.attr, "refdes"); + return refdes; + } + + if (comp->hdepth == 0) { + if (refdes == NULL) refdes = aname; + if (refdes == NULL) refdes = csch_attrib_get_str(&comp->hdr.attr, "refdes"); + } + else + refdes = comp->name; + + return refdes; +} + +const char *sch_nle_get_pinnum(const csch_aport_t *port) +{ + const char *pinnum; + pinnum = csch_attrib_get_str(&port->hdr.attr, "display/name"); + if (pinnum == NULL) pinnum = csch_attrib_get_str(&port->hdr.attr, "display/pinnum"); + if (pinnum == NULL) pinnum = csch_attrib_get_str(&port->hdr.attr, "name"); + if (pinnum == NULL) pinnum = csch_attrib_get_str(&port->hdr.attr, "pinnum"); + if (pinnum == NULL) pinnum = port->name; + return pinnum; +} + +const char *sch_nle_get_netname(const csch_anet_t *net) +{ + const char *netname; + netname = csch_attrib_get_str(&net->hdr.attr, "display/name"); + if ((netname == NULL) && (net->hdepth == 0)) netname = csch_attrib_get_str(&net->hdr.attr, "name"); + if (netname == NULL) netname = net->name; + return netname; +} + + +const char *sch_nle_get_alt_attr(const csch_attribs_t *attribs, ...) +{ + const char *val = NULL; + va_list ap; + + va_start(ap, attribs); + for(;;) { + const char *key = va_arg(ap, const char *); + if (key == NULL) + break; + val = csch_attrib_get_str(attribs, key); + if (val != NULL) + break; + } + va_end(ap); + return val; +} + + + +/*** plugin ***/ + +int pplg_check_ver_lib_netlist_exp(int ver_needed) { return 0; } + +void pplg_uninit_lib_netlist_exp(void) +{ +} + +int pplg_init_lib_netlist_exp(void) +{ + RND_API_CHK_VER; + + return 0; +} + Index: tags/1.0.5/src/plugins/lib_netlist_exp/lib_netlist_exp.h =================================================================== --- tags/1.0.5/src/plugins/lib_netlist_exp/lib_netlist_exp.h (nonexistent) +++ tags/1.0.5/src/plugins/lib_netlist_exp/lib_netlist_exp.h (revision 10414) @@ -0,0 +1,11 @@ +#include + +/* Get the output refdes/pinnum/netname from abstract attributes */ +const char *sch_nle_get_refdes(const csch_acomp_t *comp); +const char *sch_nle_get_pinnum(const csch_aport_t *port); +const char *sch_nle_get_netname(const csch_anet_t *net); + +/* Pass a NULL terminated list of attribute const char *keys in the order + of preference; returns the first attribute value that exists or NULL + if none found. */ +const char *sch_nle_get_alt_attr(const csch_attribs_t *attribs, ...); Index: tags/1.0.5/src/plugins/lib_netlist_exp/lib_netlist_exp.pup =================================================================== --- tags/1.0.5/src/plugins/lib_netlist_exp/lib_netlist_exp.pup (nonexistent) +++ tags/1.0.5/src/plugins/lib_netlist_exp/lib_netlist_exp.pup (revision 10414) @@ -0,0 +1,7 @@ +$class export +$short netlist export helper +$long Helper functions for exporting netlists +$state works +$package (core) +default buildin +autoload 1 Index: tags/1.0.5/src/plugins/lib_ngrp/Makefile =================================================================== --- tags/1.0.5/src/plugins/lib_ngrp/Makefile (nonexistent) +++ tags/1.0.5/src/plugins/lib_ngrp/Makefile (revision 10414) @@ -0,0 +1,2 @@ +all: + cd ../../sch-rnd && make mod_lib_ngrp Index: tags/1.0.5/src/plugins/lib_ngrp/Plug.tmpasm =================================================================== --- tags/1.0.5/src/plugins/lib_ngrp/Plug.tmpasm (nonexistent) +++ tags/1.0.5/src/plugins/lib_ngrp/Plug.tmpasm (revision 10414) @@ -0,0 +1,10 @@ +put /local/rnd/mod {lib_ngrp} +put /local/rnd/mod/OBJS [@ + $(PLUGDIR)/lib_ngrp/lib_ngrp.o +@] + +switch /local/module/lib_ngrp/controls + case {buildin} include /local/csch/tmpasm/buildin; end; + case {plugin} include /local/csch/tmpasm/plugin; end; + case {disable} include /local/csch/tmpasm/disable; end; +end Index: tags/1.0.5/src/plugins/lib_ngrp/lib_ngrp.c =================================================================== --- tags/1.0.5/src/plugins/lib_ngrp/lib_ngrp.c (nonexistent) +++ tags/1.0.5/src/plugins/lib_ngrp/lib_ngrp.c (revision 10414) @@ -0,0 +1,359 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - non-graphical sheet helpers + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/* Maintain a cache of parsed comp/net/conn objects and compile abstract + model from them */ + +#include + +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "lib_ngrp.h" + +/*** context ***/ +static void sch_ngrp_free_attribs(sch_ngrp_attrib_t *a) +{ + sch_ngrp_attrib_t *next; + for(; a != NULL; a = next) { + next = a->next; + free(a); + } +} + +static void sch_ngrp_free_objs(sch_ngrp_obj_t *o) +{ + sch_ngrp_obj_t *next; + for(; o != NULL; o = next) { + next = o->next; + sch_ngrp_free_attribs(o->attr_head); + free(o); + } +} + +static void sch_ngrp_free_conns(sch_ngrp_conn_t *c) +{ + sch_ngrp_conn_t *next; + for(; c != NULL; c = next) { + next = c->next; + free(c); + } +} + +void sch_ngrp_clean_cache(sch_ngrp_t *ctx) +{ + sch_ngrp_free_objs(ctx->comps); + sch_ngrp_free_objs(ctx->nets); + sch_ngrp_free_conns(ctx->conns); + ctx->comps = NULL; + ctx->nets = NULL; + ctx->conns = NULL; +} + +void sch_ngrp_free(sch_ngrp_t *ctx) +{ + sch_ngrp_clean_cache(ctx); + vtp0_uninit(&ctx->lines); + gds_uninit(&ctx->text); + free(ctx); +} + +void sch_ngrp_add_attr(sch_ngrp_attrib_t **head, const char *key, const char *val, int vl, long lineno) +{ + int kl = strlen(key); + sch_ngrp_attrib_t *a; + + if (vl < 0) + vl = strlen(val); + + a = malloc(sizeof(sch_ngrp_attrib_t) + kl + vl + 2); + memcpy(a->key, key, kl+1); + a->val = a->key+kl+1; + memcpy(a->val, val, vl); + a->val[vl] = '\0'; + + a->lineno = lineno; + a->next = *head; + *head = a; +} + +sch_ngrp_obj_t *sch_ngrp_add_obj(sch_ngrp_obj_t **head, const char *name, long lineno) +{ + int nl = strlen(name); + sch_ngrp_obj_t *o = malloc(sizeof(sch_ngrp_obj_t) + nl + 1); + memcpy(o->name, name, nl+1); + o->attr_head = NULL; + + o->lineno = lineno; + o->next = *head; + *head = o; + + return o; +} + +sch_ngrp_conn_t *sch_ngrp_add_conn(sch_ngrp_conn_t **head, const char *netname, const char *comp, const char *port, long lineno) +{ + int nl = strlen(netname), cl = strlen(comp), pl = strlen(port); + sch_ngrp_conn_t *c = malloc(sizeof(sch_ngrp_conn_t) + nl + cl + pl + 3); + memcpy(c->netname, netname, nl+1); + c->comp = c->netname+nl+1; + memcpy(c->comp, comp, cl+1); + c->port = c->comp+cl+1; + memcpy(c->port, port, pl+1); + + c->lineno = lineno; + c->next = *head; + *head = c; + + return c; +} + +static void comp_add_attrs(const csch_sheet_t *sheet, csch_ahdr_t *dst, const sch_ngrp_attrib_t *attr_src) +{ + const sch_ngrp_attrib_t *s; + + for(s = attr_src; s != NULL; s = s->next) { + csch_source_arg_t *src; + + src = csch_attrib_src_c(sheet->hidlib.fullpath, s->lineno, 0, "non-graphical: tEDAx"); + csch_attrib_set(&dst->attr, CSCH_ATP_USER_DEFAULT, s->key, s->val, src, NULL); + } +} + + +/*** compile ***/ + +static csch_cgrp_t *get_src_oid(const csch_sheet_t *sheet_, long *src_oid) +{ + csch_sheet_t *sheet = (csch_sheet_t *)sheet_; + csch_cgrp_t *cgrp; + + (*src_oid)++; + cgrp = htip_get(&sheet->direct.id2obj, *src_oid); + + if (cgrp == NULL) { + cgrp = calloc(sizeof(csch_cgrp_t), 1); + csch_cobj_init(&cgrp->hdr, sheet, &sheet->direct, *src_oid, 0); + } + + return cgrp; +} + +int sch_ngrp_compile_sheet(csch_abstract_t *dst, int viewid, csch_hier_path_t *hpath, const csch_sheet_t *src, sch_ngrp_t *ctx) +{ + sch_ngrp_conn_t *cn; + sch_ngrp_comp_t *c; + sch_ngrp_net_t *n; + long src_oid = 0, tmp_len; + csch_ascope_t scope; + gds_t tmp = {0}; + + gds_append_len(&tmp, hpath->prefix.array, hpath->prefix.used); + tmp_len = hpath->prefix.used; + + /* create components */ + for(c = ctx->comps; c != NULL; c = c->next) { + csch_acomp_t *acomp = csch_acomp_new(dst, dst->hroot, CSCH_ASCOPE_GLOBAL, c->name, c->name); + csch_cgrp_t *cgrp = get_src_oid(src, &src_oid); + + csch_compile_add_source(cgrp, &acomp->hdr); + comp_add_attrs(src, &acomp->hdr, c->attr_head); + c->ahdr = &acomp->hdr; + } + + /* create nets */ + for(n = ctx->nets; n != NULL; n = n->next) { + csch_anet_t *anet; + csch_cgrp_t *cgrp; + const char *orig_name = n->name; + + scope = csch_split_name_scope(&orig_name); + tmp.used = tmp_len; + gds_append_str(&tmp, orig_name); + + anet = csch_anet_get_at(dst, hpath->hlev, scope, orig_name); + if (anet == NULL) + anet = csch_anet_new(dst, hpath->hlev, scope, tmp.array, orig_name, 1); + + cgrp = get_src_oid(src, &src_oid);; + csch_compile_add_source(cgrp, &anet->hdr); + comp_add_attrs(src, &anet->hdr, n->attr_head); + } + + /* create connections */ + for(cn = ctx->conns; cn != NULL; cn = cn->next) { + csch_acomp_t *acomp; + csch_aport_t *aport; + csch_cgrp_t *cgrp = get_src_oid(src, &src_oid); + csch_anet_t *anet; + const char *orig_name; + + + acomp = csch_acomp_get(dst, cn->comp); + if (acomp == NULL) + acomp = csch_acomp_new(dst, dst->hroot, CSCH_ASCOPE_GLOBAL, cn->comp, cn->comp); + aport = csch_aport_get(dst, acomp, cn->port, 1); + + orig_name = cn->netname; + scope = csch_split_name_scope(&orig_name); + tmp.used = tmp_len; + gds_append_str(&tmp, orig_name); + + anet = csch_anet_get_at(dst, hpath->hlev, scope, orig_name); + if (anet == NULL) + anet = csch_anet_new(dst, hpath->hlev, scope, tmp.array, orig_name, 1); + + csch_compile_add_source(cgrp, &aport->hdr); + csch_compile_connect_net_to(&anet, &aport->hdr, 1); + } + +#if 0 + /* descend into hierarchic subsheets */ + for(c = ctx->comps; c != NULL; c = c->next) { + csch_acomp_t *acomp = (csch_acomp_t *)c->ahdr; + const sch_ngrp_attrib_t *s; + const char *chuuid = NULL, *chname = NULL, *chpath = NULL; + csch_sheet_t *child_out = NULL; + int hres; + + c->ahdr = NULL; + + for(s = c->attr_head; s != NULL; s = s->next) { + if ((s->key[0] == 'c') && (strncmp(s->key, "cschem/child/", 13) == 0)) { + const char *key = s->key + 13; + if (strcmp(key, "uuid") == 0) chuuid = s->val; + else if (strcmp(key, "name") == 0) chname = s->val; + else if (strcmp(key, "path") == 0) chpath = s->val; + } + } + + hres = csch_hier_find_child(src, chuuid, chname, chpath, &child_out, 0); + if (hres < 0) + return -1; + + if (hres == 1) { + TODO("DESCEND: call csch_compile_descend()"); + TODO("then bind ports like in compile.c compile_symbol_child_sheet() at ''Bind sheet ref sym terminals to child sheet terminals''"); + } + } +#endif + + + gds_uninit(&tmp); + return 0; +} + + + +/*** read ***/ + +int sch_ngrp_load_file(csch_sheet_t *sheet, sch_ngrp_t *ctx, const char *fn) +{ + long len, got; + char *s; + FILE *f; + + len = rnd_file_size(&sheet->hidlib, fn); + if (len < 0) + return -1; + + f = rnd_fopen(&sheet->hidlib, fn, "r"); + if (f == NULL) + return -1; + + if ((len > ctx->text.alloced) || (len < ctx->text.used*0.9)) { + gds_uninit(&ctx->text); + gds_enlarge(&ctx->text, len); + } + + got = fread(ctx->text.array, 1, len, f); + ctx->text.array[got] = '\0'; + fclose(f); + + ctx->lines.used = 0; + vtp0_append(&ctx->lines, ctx->text.array); + for(s = ctx->text.array; *s != '\0'; s++) { + if ((s[0] == '\n') && (s[1] != '\0')) + vtp0_append(&ctx->lines, s+1); + } + + return sch_draw_setup_non_graphical(sheet, ctx->lines.used); +} + +char *sch_ngrp_draw_getline(sch_ngrp_t *ctx, long *cnt, void **cookie) +{ + char *nl = *cookie, *res; + long next; + + if (nl != NULL) + *nl = '\n'; /* restore previous \n */ + + if (*cnt >= ctx->lines.used) + return NULL; + + *cookie = NULL; + next = (*cnt) + 1; + if (next < ctx->lines.used) { + nl = ctx->lines.array[next]; + nl--; + if (*nl == '\n') { + *cookie = nl; + *nl = '\0'; /* terminate string if it ends in \n */ + } + } + + res = ctx->lines.array[*cnt]; + (*cnt)++; + return res; +} + +/*** plugin ***/ + +int pplg_check_ver_lib_ngrp(int ver_needed) { return 0; } + +void pplg_uninit_lib_ngrp(void) +{ +} + +int pplg_init_lib_ngrp(void) +{ + RND_API_CHK_VER; + + return 0; +} + Index: tags/1.0.5/src/plugins/lib_ngrp/lib_ngrp.h =================================================================== --- tags/1.0.5/src/plugins/lib_ngrp/lib_ngrp.h (nonexistent) +++ tags/1.0.5/src/plugins/lib_ngrp/lib_ngrp.h (revision 10414) @@ -0,0 +1,98 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - non-graphical sheet helpers + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/* Maintain a cache of parsed comp/net/conn objects and compile abstract + model from them */ + +#include +#include +#include + +typedef struct sch_ngrp_attrib_s sch_ngrp_attrib_t; +typedef struct sch_ngrp_obj_s sch_ngrp_obj_t; +typedef struct sch_ngrp_obj_s sch_ngrp_comp_t; +typedef struct sch_ngrp_obj_s sch_ngrp_net_t; +typedef struct sch_ngrp_conn_s sch_ngrp_conn_t; + +struct sch_ngrp_attrib_s { + char *val; + long lineno; + sch_ngrp_attrib_t *next; /* singly linked list */ + char key[1]; /* overallocated to hold both key and val */ +}; + +struct sch_ngrp_obj_s { + sch_ngrp_attrib_t *attr_head; + long lineno; + sch_ngrp_obj_t *next; /* singly linked list */ + csch_ahdr_t *ahdr; /* used temporarily during sheet compilation */ + char name[1]; /* overallocated */ +}; + +struct sch_ngrp_conn_s { + char *comp; + char *port; + long lineno; + sch_ngrp_conn_t *next; /* singly linked list */ + char netname[1]; /* overallocated to hold all net, comp and port */ +}; + +typedef struct { + csch_sheet_t *sheet; + gds_t text; /* raw text from the file */ + vtp0_t lines; /* pointer to the first char of each line */ + + /* cache: precompiled */ + sch_ngrp_comp_t *comps; /* head of linked list */ + sch_ngrp_net_t *nets; /* head of linked list */ + sch_ngrp_conn_t *conns; /* head of linked list */ +} sch_ngrp_t; + +/* Standard non-graphical sheet callback for compiling a sheet */ +int sch_ngrp_compile_sheet(csch_abstract_t *dst, int viewid, csch_hier_path_t *hpath, const csch_sheet_t *src, sch_ngrp_t *ctx); + + +/* Free all cache fields in ctx, set them to NULL */ +void sch_ngrp_clean_cache(sch_ngrp_t *ctx); + +/* Free all fields of ctx and ctx itself as well */ +void sch_ngrp_free(sch_ngrp_t *ctx); + + +/* Store different objects in the cache, allocating and linking in a new item; + if val_len is -1, calls strlen(val). */ +sch_ngrp_obj_t *sch_ngrp_add_obj(sch_ngrp_obj_t **head, const char *name, long lineno); +void sch_ngrp_add_attr(sch_ngrp_attrib_t **head, const char *key, const char *val, int val_len, long lineno); +sch_ngrp_conn_t *sch_ngrp_add_conn(sch_ngrp_conn_t **head, const char *netname, const char *comp, const char *port, long lineno); + + +/* Load a text file into ctx */ +int sch_ngrp_load_file(csch_sheet_t *sheet, sch_ngrp_t *ctx, const char *fn); + +/* Return text lines for the rendering code */ +char *sch_ngrp_draw_getline(sch_ngrp_t *ctx, long *cnt, void **cookie); Index: tags/1.0.5/src/plugins/lib_ngrp/lib_ngrp.pup =================================================================== --- tags/1.0.5/src/plugins/lib_ngrp/lib_ngrp.pup (nonexistent) +++ tags/1.0.5/src/plugins/lib_ngrp/lib_ngrp.pup (revision 10414) @@ -0,0 +1,7 @@ +$class io +$short non-graphical seet helper +$long Helper functions for handling non-graphical sheets +$state works +$package (core) +default buildin +autoload 1 Index: tags/1.0.5/src/plugins/lib_plot/Makefile =================================================================== --- tags/1.0.5/src/plugins/lib_plot/Makefile (nonexistent) +++ tags/1.0.5/src/plugins/lib_plot/Makefile (revision 10414) @@ -0,0 +1,2 @@ +all: + cd ../../sch-rnd && make mod_lib_plot Index: tags/1.0.5/src/plugins/lib_plot/Plug.tmpasm =================================================================== --- tags/1.0.5/src/plugins/lib_plot/Plug.tmpasm (nonexistent) +++ tags/1.0.5/src/plugins/lib_plot/Plug.tmpasm (revision 10414) @@ -0,0 +1,12 @@ +put /local/rnd/mod {lib_plot} +put /local/rnd/mod/OBJS [@ + $(PLUGDIR)/lib_plot/lib_plot.o + $(PLUGDIR)/lib_plot/plot_data.o + $(PLUGDIR)/lib_plot/plot_preview.o +@] + +switch /local/module/lib_plot/controls + case {buildin} include /local/csch/tmpasm/buildin; end; + case {plugin} include /local/csch/tmpasm/plugin; end; + case {disable} include /local/csch/tmpasm/disable; end; +end Index: tags/1.0.5/src/plugins/lib_plot/lib_plot.c =================================================================== --- tags/1.0.5/src/plugins/lib_plot/lib_plot.c (nonexistent) +++ tags/1.0.5/src/plugins/lib_plot/lib_plot.c (revision 10414) @@ -0,0 +1,46 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - generic graph plotting + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + + +#include +#include +#include + +int pplg_check_ver_lib_plot(int ver_needed) { return 0; } + +void pplg_uninit_lib_plot(void) +{ +} + +int pplg_init_lib_plot(void) +{ + RND_API_CHK_VER; + + return 0; +} + Index: tags/1.0.5/src/plugins/lib_plot/lib_plot.pup =================================================================== --- tags/1.0.5/src/plugins/lib_plot/lib_plot.pup (nonexistent) +++ tags/1.0.5/src/plugins/lib_plot/lib_plot.pup (revision 10414) @@ -0,0 +1,8 @@ +$class gui +$short graph plotting +$long subdialog for plotting and navigating graphs +$state works +$package lib-gui +default disable-all +dep query +autoload 1 Index: tags/1.0.5/src/plugins/lib_plot/plot_data.c =================================================================== --- tags/1.0.5/src/plugins/lib_plot/plot_data.c (nonexistent) +++ tags/1.0.5/src/plugins/lib_plot/plot_data.c (revision 10414) @@ -0,0 +1,250 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - generic graph plotting + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include +#include +#include +#include "plot_data.h" + +static void raw_alloc(plot_raw_t *dst, FILE *f, long num_pts) +{ + double d = 0; + + fseek(f, 0, SEEK_END); + fgetpos(f, &dst->start_offs); + fseek(f, (num_pts-1) * sizeof(double), SEEK_CUR); + fwrite(&d, sizeof(d), 1, f); + + dst->len = num_pts; +} + +void plot_raw_seek(plot_raw_t *raw, FILE *f, long idx) +{ + fsetpos(f, &raw->start_offs); + if (idx > 0) + fseek(f, idx * sizeof(double), SEEK_CUR); +} + + +plot_trdata_t *plot_trdata_alloc(plot_trace_t *trace, long level, long num_pts) +{ + plot_trdata_t *td = malloc(sizeof(plot_trdata_t)); + + td->level = level; + raw_alloc(&td->main, trace->f, num_pts); + if (level > 0) { + raw_alloc(&td->min, trace->f, num_pts); + raw_alloc(&td->max, trace->f, num_pts); + } + else + td->min.len = td->max.len = 0; + + htip_set(&trace->trdata, level, td); + return td; +} + +void plot_trace_init(plot_trace_t *tr, FILE *f) +{ + tr->f = f; + htip_init(&tr->trdata, longhash, longkeyeq); +} + +void plot_data_init(plot_data_t *pd, int num_traces) +{ + pd->num_traces = num_traces; + pd->trace = calloc(sizeof(plot_trace_t), num_traces); +} + +plot_data_t *plot_data_alloc(int num_traces) +{ + plot_data_t *pd = malloc(sizeof(plot_data_t)); + plot_data_init(pd, num_traces); + return pd; +} + +void plot_trdata_free(plot_trdata_t *td) +{ + free(td); +} + +void plot_trace_uninit(plot_trace_t *tr) +{ + genht_uninit_deep(htip, &tr->trdata, { + plot_trdata_free(htent->value); + }); +} + +void plot_data_uninit(plot_data_t *pd) +{ + int n; + for(n = 0; n < pd->num_traces; n++) { + plot_trace_uninit(&pd->trace[n]); + if (pd->trace_name != NULL) + free(pd->trace_name[n]); + } + free(pd->trace); + pd->trace = NULL; + + free(pd->trace_name); + pd->trace_name = NULL; + + if (pd->x_labels != NULL) { + for(n = 0; n < pd->num_x_labels; n++) + free(pd->x_labels[n].text); + free(pd->x_labels); + pd->x_labels = NULL; + } + + if (pd->y_labels != NULL) { + for(n = 0; n < pd->num_y_labels; n++) + free(pd->y_labels[n].text); + free(pd->y_labels); + pd->y_labels = NULL; + } + + free(pd->x_axis_name); + free(pd->y_axis_name); + pd->x_axis_name = pd->y_axis_name = NULL; +} + +void plot_data_free(plot_data_t *pd) +{ + plot_data_uninit(pd); + free(pd); +} + +int plot_trdata_set_arr(plot_trace_t *tr, plot_trdata_t *trdata, plot_which_t which, const double *data, long from, long len) +{ + plot_raw_t *raw; + + switch(which) { + case PLOT_MAIN: raw = &trdata->main; break; + case PLOT_MIN: raw = &trdata->min; break; + case PLOT_MAX: raw = &trdata->max; break; + default: return -1; + } + + if (from+len > raw->len) + return -1; + plot_raw_seek(raw, tr->f, from); + fwrite(data, sizeof(double), len, tr->f); + return 0; +} + +int plot_trdata_get_arr(plot_trace_t *tr, plot_trdata_t *trdata, plot_which_t which, double *data, long from, long len) +{ + plot_raw_t *raw; + + switch(which) { + case PLOT_MAIN: raw = &trdata->main; break; + case PLOT_MIN: raw = &trdata->min; break; + case PLOT_MAX: raw = &trdata->max; break; + default: return -1; + } + + if (from+len > raw->len) + return -1; + plot_raw_seek(raw, tr->f, from); + fread(data, sizeof(double), len, tr->f); + return 0; +} + +plot_trdata_t *plot_trdata_get(plot_trace_t *trace, long level, int alloc_gen) +{ + plot_trdata_t *td = htip_get(&trace->trdata, level); + + if ((level == 0) || (td != NULL) || !alloc_gen) + return td; + + /* allocate and generate zoom level */ + return plot_trdata_generate(trace, level); +} + +#define BUFSIZE 1024 + +plot_trdata_t *plot_trdata_generate(plot_trace_t *trace, long level) +{ + plot_trdata_t *src, *dst; + long num_pts, runlen, got, n; + double br[BUFSIZE], bw[BUFSIZE], bmin[BUFSIZE], bmax[BUFSIZE], min, max, avg, pt; + plot_pos_t pr, pwmain, pwmin, pwmax; + + src = plot_trdata_get(trace, 0, 0); + if (src == NULL) + return NULL; + + if (plot_read_init(&pr, trace, src, PLOT_MAIN, 0, 0, br, sizeof(br)/sizeof(br[0])) != 0) + return NULL; + + runlen = (1 << level); + num_pts = src->main.len / runlen + 1; + dst = plot_trdata_alloc(trace, level, num_pts); + + if (plot_write_init(&pwmain, trace, dst, PLOT_MAIN, 0, 0, bw, sizeof(bw)/sizeof(bw[0])) != 0) + return NULL; + if (plot_write_init(&pwmin, trace, dst, PLOT_MIN, 0, 0, bmin, sizeof(bmin)/sizeof(bmin[0])) != 0) + return NULL; + if (plot_write_init(&pwmax, trace, dst, PLOT_MAX, 0, 0, bmax, sizeof(bmax)/sizeof(bmax[0])) != 0) + return NULL; + + n = 0; + while(plot_read(&pr, &pt) == 0) { + if ((n % runlen) == 0) { + if (n > 0) { + plot_write(&pwmain, avg / got); + plot_write(&pwmin, min); + plot_write(&pwmax, max); + } + avg = min = max = pt; + got = 1; + } + else { + avg += pt; + if (pt < min) min = pt; + if (pt > max) max = pt; + got++; + } + n++; + } + + /* The last block may be partial, write it if there's any pending data */ + if (got > 0) { + plot_write(&pwmain, avg / got); + plot_write(&pwmin, min); + plot_write(&pwmax, max); + } + + /* flush output buffers */ + plot_flush(&pwmain); + plot_flush(&pwmin); + plot_flush(&pwmax); + + return dst; +} + + Index: tags/1.0.5/src/plugins/lib_plot/plot_data.h =================================================================== --- tags/1.0.5/src/plugins/lib_plot/plot_data.h (nonexistent) +++ tags/1.0.5/src/plugins/lib_plot/plot_data.h (revision 10414) @@ -0,0 +1,243 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - generic graph plotting + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#ifndef RND_INLINE +#include +#endif + +#include +#include + +typedef struct plot_raw_s { + fpos_t start_offs; /* in bytes, from the start of the cache file */ + long len; /* in number of doubles */ +} plot_raw_t; + +typedef enum plot_which_e { + PLOT_MAIN, PLOT_MIN, PLOT_MAX +} plot_which_t; + +typedef struct plot_trdata_s { + long level; /* 0 means original input; else zommed out, number of data is len/(1< 0 */ +} plot_trdata_t; + +typedef enum plot_axis_type_e { + PLAXTY_LINEAR, + PLAXTY_DECADE, /* logarithmic, 10 tick per div, 10, 100, 1000 */ + PLAXTY_OCTAVE /* logarithmic, 8 tick per div */ +} plot_axis_type_t; + +typedef struct plot_trace_s { + FILE *f; /* cache; binary file with doubles */ + htip_t trdata; /* key is level, data is (plot_trdata_t *) */ + + /* user data: used and specified by the caller */ + plot_axis_type_t type_y; + double zoom_y; /* per trace y zoom factor */ +} plot_trace_t; + +/* labels on an axis */ +typedef struct plot_alabel_s { + double plot_val; + double print_val; /* not printed if -> text != NULL */ + char *text; /* may be NULL */ +} plot_alabel_t; + +/* A plot is a collection of traces drawn on the same diagram */ +typedef struct plot_data_s { + int num_traces; + plot_trace_t *trace; + char **trace_name; + + long num_x_labels, num_y_labels; + plot_alabel_t *x_labels, *y_labels; + + char *x_axis_name, *y_axis_name; +} plot_data_t; + +/* _alloc: Allocate trace data for num_pts points and store trdata in trace's + for level. If level > 0 also allocates min/max within trdata. + _free: Frees all memory used by the trace data (typically no need to call; + called from plot_data_free()) */ +plot_trdata_t *plot_trdata_alloc(plot_trace_t *trace, long level, long num_pts); +void plot_trdata_free(plot_trdata_t *trdata); + +/* _init: Initialize trace memory, remember user provided cache file for the trace + _uninit: Frees all memory used by the trace (typically no need to call; + called from plot_data_free()) */ +void plot_trace_init(plot_trace_t *tr, FILE *f); +void plot_trace_uninit(plot_trace_t *trace); + +/* _alloc: allocate plot data for a number of traces; each ->trace[] + needs to be initialized using plot_trace_init() + _free: free all traces of the plot */ +plot_data_t *plot_data_alloc(int num_traces); +void plot_data_free(plot_data_t *data); + +void plot_data_init(plot_data_t *pd, int num_traces); +void plot_data_uninit(plot_data_t *pd); + + +/* Unbuffered read/write an array of data from/into a specific + trace's main/min/max storage. Return 0 on success. */ +int plot_trdata_set_arr(plot_trace_t *tr, plot_trdata_t *trdata, plot_which_t which, const double *data, long from, long len); +int plot_trdata_get_arr(plot_trace_t *tr, plot_trdata_t *trdata, plot_which_t which, double *data, long from, long len); + +/* Return the trace data for a trace:level. If trace data does not exist + on the given level: if alloc_gen is 1, allocate and generate it (from + level 0) automatically, else return NULL. */ +plot_trdata_t *plot_trdata_get(plot_trace_t *trace, long level, int alloc_gen); + +/* Generate and insert a given trace:level from level 0. Normally no need + to call this direclty: plot_trdata_get() with alloc_gen==1 handles this. */ +plot_trdata_t *plot_trdata_generate(plot_trace_t *trace, long level); + + +/*** Buffered sequential read/write ***/ + +/* Buffer data in user provided memory to batch reads/writes (with their + associated seek) */ +typedef struct plot_pos_s { + plot_trace_t *tr; + plot_raw_t *raw; + long idx, remaining; + double *buffer; + long bufflen, buffi; +} plot_pos_t; + + +/* Prepare for read at most "len" points from trace starting at index "from"; + if len is 0, read the whole trace. Return 0 on success */ +RND_INLINE int plot_read_init(plot_pos_t *pos, plot_trace_t *tr, plot_trdata_t *trdata, plot_which_t which, long from, long len, double *buff, long bufflen); + +/* Read next data into dst. Return 0 on success, -1 on error or eof */ +RND_INLINE int plot_read(plot_pos_t *pos, double *dst); + + +/* Prepare for write at most "len" points from trace starting at index "from"; + if len is 0, write the whole trace. Return 0 on success */ +RND_INLINE int plot_write_init(plot_pos_t *pos, plot_trace_t *tr, plot_trdata_t *trdata, plot_which_t which, long from, long len, double *buff, long bufflen); + +/* Write next data from src. Return 0 on success, -1 on error or eof */ +RND_INLINE int plot_write(plot_pos_t *pos, double src); + +/* Write out pending data from the pos buffer */ +RND_INLINE void plot_flush(plot_pos_t *pos); + + +/*** internal and implementation ***/ +void plot_raw_seek(plot_raw_t *raw, FILE *f, long idx); + +RND_INLINE int plot_rw_init(plot_pos_t *pos, plot_trace_t *tr, plot_trdata_t *trdata, plot_which_t which, long from, long len, double *buff, long bufflen) +{ + pos->tr = tr; + + switch(which) { + case PLOT_MAIN: pos->raw = &trdata->main; break; + case PLOT_MIN: pos->raw = &trdata->min; break; + case PLOT_MAX: pos->raw = &trdata->max; break; + default: return -1; + } + + pos->remaining = ((len == 0) ? trdata->main.len : len); + pos->idx = from; + if (from >= pos->raw->len) + return -1; + + pos->buffer = buff; + pos->bufflen = bufflen; + return 0; +} + +RND_INLINE int plot_read_init(plot_pos_t *pos, plot_trace_t *tr, plot_trdata_t *trdata, plot_which_t which, long from, long len, double *buff, long bufflen) +{ + int res = plot_rw_init(pos, tr, trdata, which, from, len, buff, bufflen); + pos->buffi = bufflen; + return res; +} + +RND_INLINE int plot_write_init(plot_pos_t *pos, plot_trace_t *tr, plot_trdata_t *trdata, plot_which_t which, long from, long len, double *buff, long bufflen) +{ + int res = plot_rw_init(pos, tr, trdata, which, from, len, buff, bufflen); + pos->buffi = 0; + return res; +} + + +RND_INLINE int plot_read(plot_pos_t *pos, double *dst) +{ + /* end of query */ + if (pos->remaining <= 0) + return -1; + + /* read next batch if needed */ + if (pos->buffi >= pos->bufflen) { + long fill_len = pos->remaining < pos->bufflen ? pos->remaining : pos->bufflen; + plot_raw_seek(pos->raw, pos->tr->f, pos->idx); + fread(pos->buffer, sizeof(double), fill_len, pos->tr->f); + pos->buffi = 0; + } + + /* serve next data from the buffer */ + *dst = pos->buffer[pos->buffi]; + pos->buffi++; + pos->idx++; + pos->remaining--; + return 0; +} + + +RND_INLINE void plot_flush(plot_pos_t *pos) +{ + long fill_len = pos->buffi; + if (fill_len <= 0) + return; + plot_raw_seek(pos->raw, pos->tr->f, pos->idx - fill_len); + fwrite(pos->buffer, sizeof(double), fill_len, pos->tr->f); + pos->buffi = 0; +} + +RND_INLINE int plot_write(plot_pos_t *pos, double src) +{ + /* end of query */ + if (pos->remaining <= 0) + return -1; + + /* write next batch if needed */ + if (pos->buffi >= pos->bufflen) + plot_flush(pos); + + /* serve next data from the buffer */ + pos->buffer[pos->buffi] = src; + pos->buffi++; + pos->idx++; + pos->remaining--; + return 0; +} Index: tags/1.0.5/src/plugins/lib_plot/plot_preview.c =================================================================== --- tags/1.0.5/src/plugins/lib_plot/plot_preview.c (nonexistent) +++ tags/1.0.5/src/plugins/lib_plot/plot_preview.c (revision 10414) @@ -0,0 +1,451 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - generic graph plotting + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include "plot_preview.h" + +#include +#include +#include + +#include + +/* low level transformations for librnd; can't be 1 because of text rendering */ +#define PL2PX(crd) ((crd)*4) +#define PX2PL(crd) ((crd)/4) + +/* text height passed down to the text renderer */ +#define TEXT_HGHT (plt->e->coord_per_pix < 1 ? (1.0/80000.0) : ((double)plt->e->coord_per_pix/80000.0)) + +/* when two text objects are closer than this on the axes, don't draw one of them */ +#define TEXT_SPACING (20 * plt->e->coord_per_pix) + +/* high level transformation: convert raw trace data to graphical plot data */ +RND_INLINE double data2plot_y(plot_preview_t *ctx, double y_raw) +{ + if (ctx->zoom_y != 0) + y_raw = y_raw * ctx->zoom_y; + return y_raw; +} + +RND_INLINE double data2plot_x(plot_preview_t *ctx, double x_raw) +{ + switch(ctx->type_x) { + case PLAXTY_LINEAR: break; + case PLAXTY_OCTAVE: + case PLAXTY_DECADE: x_raw = x_raw * 5; break; /* stretch the graph a bit because there won't be too many points anyway */ + } + return x_raw; +} + +RND_INLINE double plot2data_x(plot_preview_t *ctx, double x_raw) +{ + switch(ctx->type_x) { + case PLAXTY_LINEAR: break; + case PLAXTY_OCTAVE: + case PLAXTY_DECADE: x_raw = x_raw / 5; break; /* stretch the graph a bit because there won't be too many points anyway */ + } + return x_raw; +} + +#define F 255U +#define T 191U +#define H 127U +#define Q 64U +static rnd_color_t trace_colors[] = { + {F, 0, 0}, {0, T, 0}, {0, 0, F}, + {F, H, H}, {Q, T, Q}, {Q, H, T}, + {H, H, H}, {H, Q, T}, {F, T, 0} +}; +static int num_trace_colors = 0; +#undef F +#undef T +#undef H +#undef Q + + +static void plot_preview_color_init(void) +{ + int n; + + num_trace_colors = sizeof(trace_colors) / sizeof(trace_colors[0]); + + for(n = 0; n < num_trace_colors; n++) + rnd_color_load_int(&trace_colors[n], trace_colors[n].r, trace_colors[n].g, trace_colors[n].b, 255); +} + +typedef struct plot_info_s { + rnd_hid_gc_t gc; + void *font; + rnd_hid_expose_ctx_t *e; + const rnd_color_t *grid_color; + + double miny, maxy; /* untransformed y bounds, extended to 0 as needed, margin added as needed */ + double my; /* y margin (per side); already added to miny and maxy */ + double laby, labdy;/* labels at the right side end of the x axis: current y coord and y increment */ + double labx; /* labels at the right side end of the x axis: x start coord */ +} plot_info_t; + +static void plot_draw_trace(plot_preview_t *ctx, plot_info_t *plt, int tridx, plot_trace_t *tr, int level) +{ + double buff[1024]; + long n, x, lastx = -1, trx; + double lasty; + plot_trdata_t *td; + plot_pos_t pos; + long wsx = plot2data_x(ctx, PX2PL(plt->e->view.X2 - plt->e->view.X1))+5; + long wox = plot2data_x(ctx, PX2PL(plt->e->view.X1)); + + td = plot_trdata_get(tr, level, 1); + trx = (wox < 0 ? 0 : wox); + if (plot_read_init(&pos, tr, td, PLOT_MAIN, trx, wsx, buff, sizeof(buff) / sizeof(buff[0])) != 0) + return; + + rnd_render->set_color(plt->gc, &trace_colors[tridx % num_trace_colors]); + + x = wox, n = 0; + if (x < 0) { + x -= wox; + n -= wox; + } + + for(; (n < wsx) && (trx < td->main.len); x++,n++,trx++) { + double px, py, y_raw; + if (plot_read(&pos, &y_raw) == 0) { + py = data2plot_y(ctx, y_raw); + px = data2plot_x(ctx, x); + if (lastx >= 0) + rnd_render->draw_line(plt->gc, PL2PX(lastx), PL2PX(lasty), PL2PX(px), PL2PX(py)); + lastx = px; + lasty = py; + } + } + + if ((ctx->pdata.trace_name != NULL) && (ctx->pdata.trace_name[tridx] != 0)) { + sch_rnd_render_text_string_scrotmir(plt->gc, plt->font, PL2PX(plt->labx), PL2PX(plt->laby), TEXT_HGHT, 0, 1, (const unsigned char *)ctx->pdata.trace_name[tridx]); + plt->laby += plt->labdy; + } + +TODO("LIBRND41: when we get zoom and calculated level != 0, draw a polygon for min-max"); +} + +/* rnd_printf won't do %.03f, zero truncation works only on %m formats */ +static void snprintf_trunc0(char *dst, int maxlen, const char *fmt, double val) +{ + int len = rnd_snprintf(dst, maxlen, fmt, val); + if (len > 1) { + len--; + while((len > 0) && (dst[len] == '0')) { + dst[len] = '\0'; + len--; + } + if (dst[len] == '.') { + dst[len] = '\0'; + len--; + } + } +} + + +void plot_draw_marks_y(plot_preview_t *ctx, plot_info_t *plt) +{ + long n; + double maxx, tx, ty, last_ty = -CSCH_COORD_MAX; + + maxx = data2plot_x(ctx, ctx->maxx * 1.1); + + rnd_render->set_color(plt->gc, plt->grid_color); + + for(n = 0; n < ctx->pdata.num_y_labels; n++) { + double y = data2plot_y(ctx, ctx->pdata.y_labels[n].plot_val); + rnd_render->draw_line(plt->gc, PL2PX(0), PL2PX(y), PL2PX(maxx), PL2PX(y)); + } + + tx = -TEXT_HGHT * 3000000; + + rnd_render->set_color(plt->gc, rnd_color_black); + for(n = 0; n < ctx->pdata.num_y_labels; n++) { + char tmp[256]; + double y = data2plot_y(ctx, ctx->pdata.y_labels[n].plot_val); + + ty = PL2PX(y+4); + if ((ty - last_ty) < TEXT_SPACING) + continue; + + snprintf_trunc0(tmp, sizeof(tmp), "%.9f", ctx->pdata.y_labels[n].print_val); + sch_rnd_render_text_string_scrotmir(plt->gc, plt->font, tx, ty, TEXT_HGHT, 0, 1, (const unsigned char *)tmp); + last_ty = ty; + } + rnd_hid_set_line_width(plt->gc, 1); +} + +void plot_draw_marks_x(plot_preview_t *ctx, plot_info_t *plt) +{ + long n; + double tx, last_tx = -CSCH_COORD_MAX, ty, miny, maxy; + + miny = PL2PX(data2plot_y(ctx, plt->miny)); + maxy = PL2PX(data2plot_y(ctx, plt->maxy)); + + rnd_render->set_color(plt->gc, plt->grid_color); + + for(n = 0; n < ctx->pdata.num_x_labels; n++) { + double x = PL2PX(data2plot_x(ctx, ctx->pdata.x_labels[n].plot_val)); + rnd_render->draw_line(plt->gc, x, miny, x, maxy); + } + + + ty = ctx->maxy < 0 ? 3 : -40; + rnd_render->set_color(plt->gc, rnd_color_black); + + for(n = 0; n < ctx->pdata.num_x_labels; n++) { + char tmp[256]; + double x = data2plot_x(ctx, ctx->pdata.x_labels[n].plot_val); + + tx = PL2PX(x-4); + if ((tx - last_tx) < TEXT_SPACING) + continue; + + snprintf_trunc0(tmp, sizeof(tmp), "%.9f", ctx->pdata.x_labels[n].print_val); + sch_rnd_render_text_string_scrotmir(plt->gc, plt->font, tx, PL2PX(ty), TEXT_HGHT, 90, 1, (const unsigned char *)tmp); + last_tx = tx; + } + rnd_hid_set_line_width(plt->gc, 1); +} + + +void plot_draw_axes(plot_preview_t *ctx, plot_info_t *plt) +{ + long maxx = ctx->maxx * 1.1; + double ylaby, arl; + + /* arrow length */ + arl = 2.0 * plt->e->coord_per_pix; + if (arl > 8) + arl = 8; + + if (ctx->maxy > 0) + ylaby = ctx->maxy; + else + ylaby = ctx->miny; + + rnd_render->set_color(plt->gc, rnd_color_black); + + rnd_render->draw_line(plt->gc, PL2PX(0), PL2PX(0), PL2PX(data2plot_x(ctx, maxx)), PL2PX(0)); + rnd_render->draw_line(plt->gc, PL2PX(0), PL2PX(data2plot_y(ctx, plt->miny)), PL2PX(0), PL2PX(data2plot_y(ctx, plt->maxy))); + + /* arrow on x */ + rnd_render->draw_line(plt->gc, PL2PX(data2plot_x(ctx, maxx)), PL2PX(data2plot_y(ctx, plt->maxy)-arl), PL2PX(data2plot_x(ctx, maxx)+arl), PL2PX(data2plot_y(ctx, plt->maxy))); + rnd_render->draw_line(plt->gc, PL2PX(data2plot_x(ctx, maxx)), PL2PX(data2plot_y(ctx, plt->maxy)+arl), PL2PX(data2plot_x(ctx, maxx)+arl), PL2PX(data2plot_y(ctx, plt->maxy))); + rnd_render->draw_line(plt->gc, PL2PX(data2plot_x(ctx, maxx)), PL2PX(data2plot_y(ctx, plt->maxy)+arl), PL2PX(data2plot_x(ctx, maxx)), PL2PX(data2plot_y(ctx, plt->maxy)-arl)); + + if (ctx->pdata.x_axis_name != NULL) + sch_rnd_render_text_string_scrotmir(plt->gc, plt->font, PL2PX(plt->labx), PL2PX(plt->laby), TEXT_HGHT, 0, 1, (const unsigned char *)ctx->pdata.x_axis_name); + + if (ctx->pdata.y_axis_name != NULL) { + sch_rnd_render_text_string_scrotmir(plt->gc, plt->font, PL2PX(0), PL2PX(data2plot_y(ctx, ylaby)), TEXT_HGHT, 90, 1, (const unsigned char *)ctx->pdata.y_axis_name); + plt->laby += plt->labdy; + } +} + +void plot_preview_expose_init(plot_preview_t *ctx, rnd_hid_attribute_t *attrib) +{ + plot_pos_t pos; + double buff[1024]; + fgw_arg_t args[2]; + int i, n; + + ctx->miny = +10000000000000; + ctx->maxy = -10000000000000; + + for(i = 0; i < ctx->pdata.num_traces; i++) { + plot_trace_t *tr = &ctx->pdata.trace[i]; + plot_trdata_t *td = plot_trdata_get(tr, 0, 0); + + if (plot_read_init(&pos, tr, td, PLOT_MAIN, 0, 0, buff, sizeof(buff) / sizeof(buff[0])) == 0) { + for(n = 0; n < td->main.len; n++) { + double y; + if (plot_read(&pos, &y) == 0) { + if (y < ctx->miny) ctx->miny = y; + if (y > ctx->maxy) ctx->maxy = y; + } + } + } + } + + ctx->inited = 1; + + args[0].type = FGW_STR; args[0].val.cstr = "min_zoom"; + args[1].type = FGW_INT; args[1].val.nat_int = 1; + rnd_gui->attr_dlg_widget_poke(ctx->hid_ctx, ctx->widget_idx, 2, args); + + args[0].type = FGW_STR; args[0].val.cstr = "yflip"; + args[1].type = FGW_INT; args[1].val.nat_int = 1; + rnd_gui->attr_dlg_widget_poke(ctx->hid_ctx, ctx->widget_idx, 2, args); + + { /* set initial zoom for the flip settings */ + long mx = (ctx->maxx)/20; + double my = (ctx->maxy - ctx->miny) / 20; + plot_zoomto(attrib, ctx, 0-mx, ctx->miny-my, ctx->maxx+mx, ctx->maxy+my); + } +} + +RND_INLINE void plt_init(plot_preview_t *ctx, plot_info_t *plt) +{ + static rnd_color_t grid_color_tmp; + static int grid_color_tmp_inited = 0; + static void *font_cache = NULL; + + + /* init y coords */ + plt->miny = ctx->miny; + plt->maxy = ctx->maxy; + plt->my = (ctx->maxy - ctx->miny) / 20.0; + + if (plt->miny > 0) + plt->miny = 0; + else + plt->miny -= plt->my; + + if (plt->maxy < 0) + plt->maxy = 0; + else + plt->maxy += plt->my; + + if (plt->maxy < 0) { + plt->laby = +8; + plt->labdy = +8; + } + else { + plt->laby = -4; + plt->labdy = -8; + } + + plt->labdy *= plt->e->coord_per_pix; + plt->labx = data2plot_x(ctx, ctx->maxx + 6); + + /* init colors */ + if (num_trace_colors == 0) + plot_preview_color_init(); + + if (ctx->grid_color == NULL) { + if (!grid_color_tmp_inited) { + rnd_color_load_str(&grid_color_tmp, "#AAAAAA"); + grid_color_tmp_inited = 1; + } + plt->grid_color = &grid_color_tmp; + } + else + plt->grid_color = ctx->grid_color; + + /* init font */ + if (font_cache == NULL) + font_cache = sch_rnd_font_lookup("sans", ""); + plt->font = font_cache; +} + +void plot_preview_expose_cb(rnd_hid_attribute_t *attrib, rnd_hid_preview_t *prv, rnd_hid_gc_t gc, rnd_hid_expose_ctx_t *e) +{ + int n; + plot_preview_t *ctx = prv->user_ctx; + plot_info_t plt; + int level = /*floor(PX2PL(e->coord_per_px));*/ 0; + TODO("LIBRND41 e->coords_per_px should be part of e, and level should be calculated with a logarithm"); + + if (!ctx->inited) { + plot_preview_expose_init(ctx, attrib); + return; /* plot_zoomto() in the above call already triggered a draw */ + } + + plt.gc = gc; + plt.e = e; + plt_init(ctx, &plt); + + rnd_hid_set_line_cap(gc, rnd_cap_round); + rnd_hid_set_line_width(gc, 1); + + plot_draw_marks_y(ctx, &plt); + plot_draw_marks_x(ctx, &plt); + plot_draw_axes(ctx, &plt); + + for(n = 0; n < ctx->pdata.num_traces; n++) + plot_draw_trace(ctx, &plt, n, &ctx->pdata.trace[n], level); +} + + +rnd_bool plot_mouse_cb(rnd_hid_attribute_t *attrib, rnd_hid_preview_t *prv, rnd_hid_mouse_ev_t kind, rnd_coord_t x, rnd_coord_t y) +{ + int n; + plot_pos_t pos; + double buff[1]; + plot_preview_t *ctx = prv->user_ctx; + + + if ((x < 0) || (kind != RND_HID_MOUSE_PRESS) || (ctx->readout_cb == NULL)) + goto skip; + + x = rnd_round(plot2data_x(ctx, PX2PL(x))); + + if (ctx->readout_begin_cb != NULL) + ctx->readout_begin_cb(ctx, x); + + for(n = 0; n < ctx->pdata.num_traces; n++) { + plot_trace_t *tr = &ctx->pdata.trace[n]; + plot_trdata_t *td = plot_trdata_get(tr, 0, 0); + + if (plot_read_init(&pos, tr, td, PLOT_MAIN, x, 2, buff, sizeof(buff) / sizeof(buff[0])) == 0) { + double y; + if (plot_read(&pos, &y) == 0) + ctx->readout_cb(ctx, n, x, y); + } + } + + if (ctx->readout_end_cb != NULL) + ctx->readout_end_cb(ctx, x); + + + skip:; + return 0; /* no redraw is needed */ +} + +void plot_zoomto(rnd_hid_attribute_t *attrib, plot_preview_t *ctx, double x1, double y1, double x2, double y2) +{ + rnd_box_t view; + + view.X1 = PL2PX(data2plot_x(ctx, x1)); + view.X2 = PL2PX(data2plot_x(ctx, x2)); + view.Y2 = PL2PX(data2plot_y(ctx, y1)); + view.Y1 = PL2PX(data2plot_y(ctx, y2)); + + rnd_dad_preview_zoomto(attrib, &view); +} + +void plot_redraw(rnd_hid_attribute_t *attrib) +{ + rnd_dad_preview_zoomto(attrib, NULL); +} + Index: tags/1.0.5/src/plugins/lib_plot/plot_preview.h =================================================================== --- tags/1.0.5/src/plugins/lib_plot/plot_preview.h (nonexistent) +++ tags/1.0.5/src/plugins/lib_plot/plot_preview.h (revision 10414) @@ -0,0 +1,68 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - generic graph plotting + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include +#include +#include + +typedef struct plot_preview_s plot_preview_t; + +struct plot_preview_s { + /* config */ + plot_axis_type_t type_x; + plot_data_t pdata; + void (*readout_cb)(plot_preview_t *ctx, int trace_idx, long x, double y); + void (*readout_begin_cb)(plot_preview_t *ctx, long x); /* optional: called on a readout for an x, before the first trace */ + void (*readout_end_cb)(plot_preview_t *ctx, long x); /* optional: called on a readout for an x, after the last trace */ + void *user_data; + void *hid_ctx; /* caller needs to fill this in before the first draw */ + int widget_idx; /* caller needs to fill this in before the first draw (RND_DAD_CURRENT()) */ + const rnd_color_t *grid_color; /* x;y value background grid; use default if NULL */ + + /* runtime state */ + double miny, maxy; + long maxx; + unsigned inited:1; + + double zoom_y; /* y zoom is independent of the number of data points (x direction); multiplier */ + +}; + +/* This is the expose function to be bound to the preview widget, with + user_ctx_ pointing to csch_plot_preview_t */ +void plot_preview_expose_cb(rnd_hid_attribute_t *attrib, rnd_hid_preview_t *prv, rnd_hid_gc_t gc, rnd_hid_expose_ctx_t *e); + + +/* Performs a readoutat coords clicked */ +rnd_bool plot_mouse_cb(rnd_hid_attribute_t *attrib, rnd_hid_preview_t *prv, rnd_hid_mouse_ev_t kind, rnd_coord_t x, rnd_coord_t y); + +/* Zoom to window; x1;y1 < x2;y2 */ +void plot_zoomto(rnd_hid_attribute_t *attrib, plot_preview_t *ctx, double x1, double y1, double x2, double y2); + +/* Redraw content of the plot, keeping zoom/pan; useful when data or config changes */ +void plot_redraw(rnd_hid_attribute_t *attrib); Index: tags/1.0.5/src/plugins/lib_target/Makefile =================================================================== --- tags/1.0.5/src/plugins/lib_target/Makefile (nonexistent) +++ tags/1.0.5/src/plugins/lib_target/Makefile (revision 10414) @@ -0,0 +1,2 @@ +all: + cd ../../sch-rnd && make mod_lib_target Index: tags/1.0.5/src/plugins/lib_target/Plug.tmpasm =================================================================== --- tags/1.0.5/src/plugins/lib_target/Plug.tmpasm (nonexistent) +++ tags/1.0.5/src/plugins/lib_target/Plug.tmpasm (revision 10414) @@ -0,0 +1,10 @@ +put /local/rnd/mod {lib_target} +put /local/rnd/mod/OBJS [@ + $(PLUGDIR)/lib_target/lib_target.o +@] + +switch /local/module/lib_target/controls + case {buildin} include /local/csch/tmpasm/buildin; end; + case {plugin} include /local/csch/tmpasm/plugin; end; + case {disable} include /local/csch/tmpasm/disable; end; +end Index: tags/1.0.5/src/plugins/lib_target/lib_target.c =================================================================== --- tags/1.0.5/src/plugins/lib_target/lib_target.c (nonexistent) +++ tags/1.0.5/src/plugins/lib_target/lib_target.c (revision 10414) @@ -0,0 +1,186 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - target plugin helper + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/* Maintain a cache of parsed comp/net/conn objects and compile abstract + model from them */ + +#include + +#include +#include +#include +#include +#include +#include + +#include "lib_target.h" + +static char dflt[] = "default"; + + +const char *sch_trgt_copy_alt_attrib(csch_ahdr_t *obj, int prio, const char *src_desc, const char *dst_name, ...) +{ + const char *val = NULL, *key; + va_list ap; + + va_start(ap, dst_name); + for(;;) { + key = va_arg(ap, const char *); + if (key == NULL) + break; + val = csch_attrib_get_str(&obj->attr, key); + if (val != NULL) { + csch_source_arg_t *src; + src = csch_attrib_src_pa(obj, key, src_desc, NULL); + csch_attrib_set(&obj->attr, prio, dst_name, val, src, NULL); + break; + } + } + va_end(ap); + return key; +} + + +void sch_trgt_ctx_init(sch_trgt_ctx_t *ctx, const rnd_conflist_t *whitelist, const rnd_conflist_t *blacklist, const char *flow_prefix, const char *sw_prefix) +{ + rnd_conf_listitem_t *item_li; + const char *item_str; + int idx; + + ctx->flow_prefix = flow_prefix; + ctx->sw_prefix = sw_prefix; + if (flow_prefix != NULL) ctx->flow_prefix_len = strlen(flow_prefix); + if (sw_prefix != NULL) ctx->sw_prefix_len = strlen(sw_prefix); + + ctx->has_white = (whitelist != NULL) && (rnd_conflist_length(whitelist) > 0); + ctx->has_black = (blacklist != NULL) && (rnd_conflist_length(blacklist) > 0); + + if (ctx->has_white) { + htss_init(&ctx->white, strhash, strkeyeq); + rnd_conf_loop_list_str(whitelist, item_li, item_str, idx) { + char *sep = strchr(item_str, '>'); + if ((sep != NULL) && ((sep > item_str) || (sep[-1] == '-'))) { + int seppos = sep - item_str - 1; + char *key = rnd_strdup(item_str), *val; + key[seppos] = '\0'; + val = key + seppos + 2; + htss_set(&ctx->white, key, val); + } + else + htss_set(&ctx->white, (char *)item_str, dflt); + } + } + + if (ctx->has_black) { + htss_init(&ctx->black, strhash, strkeyeq); + rnd_conf_loop_list_str(blacklist, item_li, item_str, idx) { + htss_set(&ctx->white, (char *)item_str, dflt); + } + } +} + +RND_INLINE int match_prefix_len(const char *key, const char *prefix, int prefix_len) +{ + if (memcmp(key, prefix, prefix_len) != 0) return 0; + if (key[prefix_len] != ':') return 0; + return 1; +} + +void sch_trgt_export_attrs(sch_trgt_ctx_t *ctx, csch_ahdr_t *obj) +{ + htsp_entry_t *e; + + /* config says we shouldn't do anything */ + if (!ctx->has_white && !ctx->has_black && (ctx->flow_prefix == NULL) && (ctx->sw_prefix == NULL)) + return; + + for(e = htsp_first(&obj->attr); e != NULL; e = htsp_next(&obj->attr, e)) { + const char *export_name = NULL; + csch_attrib_t *a = e->value; + + if (ctx->has_white) { + const char *wh = htss_get(&ctx->white, e->key); + if (wh == dflt) export_name = e->key; + else if (wh != NULL) export_name = wh; + } + + if ((ctx->sw_prefix != NULL) && match_prefix_len(e->key, ctx->sw_prefix, ctx->sw_prefix_len)) + export_name = e->key + ctx->sw_prefix_len + 1; + if ((ctx->flow_prefix != NULL) && match_prefix_len(e->key, ctx->flow_prefix, ctx->flow_prefix_len)) + export_name = e->key + ctx->flow_prefix_len + 1; + + /* black list: remove export name even if it was set by some other plugin beforehand */ + if (ctx->has_black) { + const char *wh = htss_get(&ctx->black, e->key); + if (wh != dflt) { + if (a->export_name != NULL) { + free(a->export_name); + a->export_name = NULL; + } + continue; + } + } + + if (export_name != NULL) + csch_attrib_set_export_name(a, export_name); + } +} + +void sch_trgt_ctx_uninit(sch_trgt_ctx_t *ctx) +{ + if (ctx->has_white) { + genht_uninit_deep(htss, &ctx->white, { + /* key has been allocated only if there was a value as well */ + if (htent->value != dflt) + free(htent->key); + }); + ctx->has_white = 0; + } + + if (ctx->has_black) { + htss_uninit(&ctx->black); + ctx->has_black = 0; + } +} + + +/*** plugin ***/ + +int pplg_check_ver_lib_target(int ver_needed) { return 0; } + +void pplg_uninit_lib_target(void) +{ +} + +int pplg_init_lib_target(void) +{ + RND_API_CHK_VER; + + return 0; +} + Index: tags/1.0.5/src/plugins/lib_target/lib_target.h =================================================================== --- tags/1.0.5/src/plugins/lib_target/lib_target.h (nonexistent) +++ tags/1.0.5/src/plugins/lib_target/lib_target.h (revision 10414) @@ -0,0 +1,23 @@ +#include +#include +#include + +/* Look at each attribute key in the varag list in obj's attribs; the first + that is found is copied as dst_name in the same obj, using prio and src_desc + for the source. Works on string attributes only. Returns the source + attribute key used or NULL if not copied. */ +const char *sch_trgt_copy_alt_attrib(csch_ahdr_t *obj, int prio, const char *src_desc, const char *dst_name, ...); + + +typedef struct sch_trgt_ctx_s { + htss_t white, black; + unsigned has_white:1; + unsigned has_black:1; + const char *flow_prefix, *sw_prefix; + int flow_prefix_len, sw_prefix_len; +} sch_trgt_ctx_t; + +void sch_trgt_ctx_init(sch_trgt_ctx_t *ctx, const rnd_conflist_t *white, const rnd_conflist_t *black, const char *flow_prefix, const char *sw_prefix); +void sch_trgt_export_attrs(sch_trgt_ctx_t *ctx, csch_ahdr_t *obj); +void sch_trgt_ctx_uninit(sch_trgt_ctx_t *ctx); + Index: tags/1.0.5/src/plugins/lib_target/lib_target.pup =================================================================== --- tags/1.0.5/src/plugins/lib_target/lib_target.pup (nonexistent) +++ tags/1.0.5/src/plugins/lib_target/lib_target.pup (revision 10414) @@ -0,0 +1,7 @@ +$class export +$short target plugin helper +$long Helper functions for implementing target plugins +$state works +$package (core) +default buildin +autoload 1 Index: tags/1.0.5/src/plugins/lib_tedax/Makefile =================================================================== --- tags/1.0.5/src/plugins/lib_tedax/Makefile (nonexistent) +++ tags/1.0.5/src/plugins/lib_tedax/Makefile (revision 10414) @@ -0,0 +1,2 @@ +all: + cd ../../sch-rnd && make mod_lib_tedax Index: tags/1.0.5/src/plugins/lib_tedax/Plug.tmpasm =================================================================== --- tags/1.0.5/src/plugins/lib_tedax/Plug.tmpasm (nonexistent) +++ tags/1.0.5/src/plugins/lib_tedax/Plug.tmpasm (revision 10414) @@ -0,0 +1,10 @@ +put /local/rnd/mod {lib_tedax} +put /local/rnd/mod/OBJS [@ + $(PLUGDIR)/lib_tedax/lib_tedax.o +@] + +switch /local/module/lib_tedax/controls + case {buildin} include /local/csch/tmpasm/buildin; end; + case {plugin} include /local/csch/tmpasm/plugin; end; + case {disable} include /local/csch/tmpasm/disable; end; +end Index: tags/1.0.5/src/plugins/lib_tedax/lib_tedax.c =================================================================== --- tags/1.0.5/src/plugins/lib_tedax/lib_tedax.c (nonexistent) +++ tags/1.0.5/src/plugins/lib_tedax/lib_tedax.c (revision 10414) @@ -0,0 +1,55 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - generic tEDAx parser + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/* low level tEDAx file format helpers */ + +#include + +#include +#include +#include + +#include "lib_tedax.h" + +/*** plugin ***/ + +#include "parse.c" + +int pplg_check_ver_lib_tedax(int ver_needed) { return 0; } + +void pplg_uninit_lib_tedax(void) +{ +} + +int pplg_init_lib_tedax(void) +{ + RND_API_CHK_VER; + + return 0; +} + Index: tags/1.0.5/src/plugins/lib_tedax/lib_tedax.h =================================================================== Index: tags/1.0.5/src/plugins/lib_tedax/lib_tedax.pup =================================================================== --- tags/1.0.5/src/plugins/lib_tedax/lib_tedax.pup (nonexistent) +++ tags/1.0.5/src/plugins/lib_tedax/lib_tedax.pup (revision 10414) @@ -0,0 +1,7 @@ +$class io +$short low level tEDAx support +$long Helper functions for implementing parsing and writing tEDAx files +$state works +$package (core) +default buildin +autoload 1 Index: tags/1.0.5/src/plugins/lib_tedax/parse.c =================================================================== --- tags/1.0.5/src/plugins/lib_tedax/parse.c (nonexistent) +++ tags/1.0.5/src/plugins/lib_tedax/parse.c (revision 10414) @@ -0,0 +1,145 @@ +/* + * COPYRIGHT + * + * tedax IO plugin - low level parser, similar to the reference implementation + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * pcb-rnd Copyright (C) 2017 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + + +#include +#include +#include + +#include "parse.h" +#include +#include + +/* remove leading whitespace */ +#define ltrim(s) while(isspace(*s)) s++ + +/* remove trailing newline;; trailing backslash is an error */ +#define rtrim(s, slen) \ + do { \ + char *end; \ + for(end = s + slen - 1; (end >= s) && ((*end == '\r') || (*end == '\n')); end--) \ + *end = '\0'; \ + if ((end[0] == '\\') && ((end == s) || (end[-1] != '\\'))) \ + return -1; \ + } while(0) + +static char *tedax_get_line_mem(char *dst, int dst_len, char **src, int *len_out) +{ + char *sep; + int len; + + sep = strpbrk(*src, "\r\n"); + if (sep == NULL) + len = strlen(*src); + else + len = sep - *src; + + if (len > dst_len) { + /* line too long */ + return NULL; + } + + memcpy(dst, *src, len); + dst[len] = '\0'; + + (*src) += len; + while((**src == '\r')) (*src)++; + if((**src == '\n')) (*src)++; + + *len_out = len; + return dst; +} + +int tedax_getline_mem(char **src, char *buff, int buff_size, char *argv[], int argv_size) +{ + int argc, len; + + for(;;) { + char *s, *o; + + + while(**src == '\r') (*src)++; + + if (**src == '\n') { + (*src)++; + goto empty; /* have to return empty line for line counting */ + } + + if (tedax_get_line_mem(buff, buff_size, src, &len) == NULL) + return -1; + + s = buff; + if (*s == '#') /* comment */ + goto empty; + ltrim(s); + rtrim(s, len); + if (*s == '\0') /* empty line */ + goto empty; + + /* argv split */ + for(argc = 0, o = argv[0] = s; *s != '\0';) { + if (*s == '\\') { + s++; + switch(*s) { + case 'r': *o = '\r'; break; + case 'n': *o = '\n'; break; + case 't': *o = '\t'; break; + default: *o = *s; + } + o++; + s++; + continue; + } + if ((argc+1 < argv_size) && ((*s == ' ') || (*s == '\t'))) { + *o = *s = '\0'; + s++; + o++; + while((*s == ' ') || (*s == '\t')) + s++; + argc++; + argv[argc] = o; + } + else { + *o = *s; + s++; + o++; + } + } + *o = '\0'; + return argc+1; /* valid line, split up */ + } + + return -1; /* can't get here */ + + empty:; + *buff = '\0'; + argv[0] = NULL; + return 0; +} + Index: tags/1.0.5/src/plugins/lib_tedax/parse.h =================================================================== --- tags/1.0.5/src/plugins/lib_tedax/parse.h (nonexistent) +++ tags/1.0.5/src/plugins/lib_tedax/parse.h (revision 10414) @@ -0,0 +1,4 @@ +/* Low level tEDAx parser */ + +int tedax_getline_mem(char **src, char *buff, int buff_size, char *argv[], int argv_size); + Index: tags/1.0.5/src/plugins/lib_ucdf/Makefile =================================================================== --- tags/1.0.5/src/plugins/lib_ucdf/Makefile (nonexistent) +++ tags/1.0.5/src/plugins/lib_ucdf/Makefile (revision 10414) @@ -0,0 +1,2 @@ +all: + cd ../../sch-rnd && make mod_lib_ucdf Index: tags/1.0.5/src/plugins/lib_ucdf/Plug.tmpasm =================================================================== --- tags/1.0.5/src/plugins/lib_ucdf/Plug.tmpasm (nonexistent) +++ tags/1.0.5/src/plugins/lib_ucdf/Plug.tmpasm (revision 10414) @@ -0,0 +1,11 @@ +put /local/rnd/mod {lib_ucdf} +put /local/rnd/mod/OBJS [@ + $(PLUGDIR)/lib_ucdf/lib_ucdf.o + ../../src_3rd/libucdf/ucdf.o +@] + +switch /local/module/lib_ucdf/controls + case {buildin} include /local/csch/tmpasm/buildin; end; + case {plugin} include /local/csch/tmpasm/plugin; end; + case {disable} include /local/csch/tmpasm/disable; end; +end Index: tags/1.0.5/src/plugins/lib_ucdf/lib_ucdf.c =================================================================== --- tags/1.0.5/src/plugins/lib_ucdf/lib_ucdf.c (nonexistent) +++ tags/1.0.5/src/plugins/lib_ucdf/lib_ucdf.c (revision 10414) @@ -0,0 +1,51 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - wrapper around libucdf + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/* Wrap libucdf so multiple plugins can use it */ + +#include + +#include +#include +#include + +/*** plugin ***/ + +int pplg_check_ver_lib_ucdf(int ver_needed) { return 0; } + +void pplg_uninit_lib_ucdf(void) +{ +} + +int pplg_init_lib_ucdf(void) +{ + RND_API_CHK_VER; + + return 0; +} + Index: tags/1.0.5/src/plugins/lib_ucdf/lib_ucdf.pup =================================================================== --- tags/1.0.5/src/plugins/lib_ucdf/lib_ucdf.pup (nonexistent) +++ tags/1.0.5/src/plugins/lib_ucdf/lib_ucdf.pup (revision 10414) @@ -0,0 +1,7 @@ +$class io +$short read ucdf files +$long Helper functions for reading (unpacking) ucdf files +$state works +$package io-alien +default buildin +autoload 1 Index: tags/1.0.5/src/plugins/map_plugins.sh =================================================================== --- tags/1.0.5/src/plugins/map_plugins.sh (nonexistent) +++ tags/1.0.5/src/plugins/map_plugins.sh (revision 10414) @@ -0,0 +1,64 @@ +#!/bin/sh + +# Run this script after changing or adding .pup files. +# WARNING: this script requires a fair amount of tools - it is intended to +# run on developers' machines, not on users' + +. ../libcschem/config.sh + +export LANG=C +PUPLUG=$librnd_libdir/puplug +SCCONF=../../scconfig + + +# generate scconfig's 3 state plugin list +$PUPLUG findpups . '%$class$|%N|%3|%A|%$short$\n' | sed ' +s/^lib/1|lib/ +s/^feature/2|feature/ +s/^engine/2|engine/ +s/^symlib/3|symlib/ +s/^import/4|import/ +s/^export/5|export/ +s/^io/6|io/ +s/^hid/7|hid/ +s/^gui/7|gui/ +' | sort | awk -F "[|]" ' +BEGIN { + HDR["lib"] = "Library plugins" + HDR["feature"] = "Feature plugins" + HDR["engine"] = "Engine plugins (concrete->abstract compilation)" + HDR["symlib"] = "Symbol library accessors" + HDR["import"] = "Import plugins" + HDR["export"] = "Export plugins" + HDR["io"] = "IO plugins (file formats)" + HDR["gui"] = "GUI" + print "/******************************************************************************" + print " Auto-generated by plugins/map_plugins.sh - do NOT edit," + print " run make map_plugins in sch-rnd/ - to change any of the data below," + print " edit plugins/PLUGIN/PLUGIN.pup" + print "******************************************************************************/" +} + +function q(s) { return "\"" s "\"," } + +($2 != last) { + print "\nplugin_header(\"\\n" HDR[$2] ":\\n\")" + last = $2 +} + +{ + if ($4 == "") + print "Error: invalid default in plugin: " $3 > "/dev/stderr" + printf("plugin_def(%-20s%-35s%-10s%s)\n", q($3), q($6), $4 "," , $5) +} + +END { print "\n" } + +' > $SCCONF/plugins.h + +$PUPLUG findpups . "" 'plugin_dep("%N", "%m")\n' | sort >> $SCCONF/plugins.h + + +# Generate the plugin list +echo "# List of all plugins - generated by make map_plugins - do NOT edit" > plugins_ALL.tmpasm +$PUPLUG findpups . "include {../src/plugins/%D/Plug.tmpasm}\n" | sort >> plugins_ALL.tmpasm Property changes on: tags/1.0.5/src/plugins/map_plugins.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/1.0.5/src/plugins/place/Makefile =================================================================== --- tags/1.0.5/src/plugins/place/Makefile (nonexistent) +++ tags/1.0.5/src/plugins/place/Makefile (revision 10414) @@ -0,0 +1,2 @@ +all: + cd ../../sch-rnd && make mod_place Index: tags/1.0.5/src/plugins/place/Plug.tmpasm =================================================================== --- tags/1.0.5/src/plugins/place/Plug.tmpasm (nonexistent) +++ tags/1.0.5/src/plugins/place/Plug.tmpasm (revision 10414) @@ -0,0 +1,10 @@ +put /local/rnd/mod {place} +put /local/rnd/mod/OBJS [@ + $(PLUGDIR)/place/place.o +@] + +switch /local/module/place/controls + case {buildin} include /local/csch/tmpasm/buildin; end; + case {plugin} include /local/csch/tmpasm/plugin; end; + case {disable} include /local/csch/tmpasm/disable; end; +end Index: tags/1.0.5/src/plugins/place/attrib.c =================================================================== --- tags/1.0.5/src/plugins/place/attrib.c (nonexistent) +++ tags/1.0.5/src/plugins/place/attrib.c (revision 10414) @@ -0,0 +1,98 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - place predefined groups + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include +#include +#include +#include +#include + +#include + +static int place_attrib(csch_sheet_t *sheet, csch_cgrp_t *parent, csch_coord_t ox, csch_coord_t oy) +{ + csch_text_t *text; + const char *penname = NULL; + csch_cpen_t *stroke; + + /* if we are on the sheet, look for a host group */ + if (parent == &sheet->direct) { + csch_rtree_box_t box; + + box.x1 = ox - sch_rnd_slop; box.y1 = oy - sch_rnd_slop; + box.x2 = ox + sch_rnd_slop; box.y2 = oy + sch_rnd_slop; + + parent = (csch_cgrp_t *)csch_search_first_mask(sheet, &box, CSCH_CMASK_ANY_GRP); + if (parent == NULL) + parent = &sheet->direct; + assert(csch_obj_is_grp(&parent->hdr)); + } + + + + text = (csch_text_t *)csch_op_create(sheet, parent, CSCH_CTYPE_TEXT); + text->spec1.x = ox - parent->x; + text->spec1.y = oy - parent->y; + text->hdr.floater = 1; + text->dyntext = 1; + + switch(parent->role) { + case CSCH_ROLE_BUS_NET: penname = "bus"; break; + case CSCH_ROLE_BUS_TERMINAL: penname = "busterm-secondary"; break; + case CSCH_ROLE_WIRE_NET: penname = "wire"; break; + case CSCH_ROLE_HUB_POINT: penname = "wire"; break; + case CSCH_ROLE_SYMBOL: penname = "sym-secondary"; break; + case CSCH_ROLE_TERMINAL: penname = "term-secondary"; break; + case CSCH_ROLE_JUNCTION: penname = "junction"; break; + + case CSCH_ROLE_invalid: + case CSCH_ROLE_empty: + penname = "sheet-decor"; + break; + } + + text->text = "%../A.key%"; + + stroke = csch_pen_resolve(parent, penname); + if (stroke == NULL) + stroke = &csch_pen_default_unknown; + text->hdr.stroke_name = csch_comm_str(sheet, stroke->name.str, 1); + + csch_text_update(sheet, text, 1); + + csch_sheet_set_changed(sheet, 1); + + return 0; +} + +static const char csch_acts_PlaceAttrib[] = "PlaceAttrib([sheet|buffer])\n"; +static const char csch_acth_PlaceAttrib[] = "Place an attribute floater dyntext"; +static fgw_error_t csch_act_PlaceAttrib(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + return place_action(res, argc, argv, place_attrib); +} Index: tags/1.0.5/src/plugins/place/place.c =================================================================== --- tags/1.0.5/src/plugins/place/place.c (nonexistent) +++ tags/1.0.5/src/plugins/place/place.c (revision 10414) @@ -0,0 +1,107 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - place predefined groups + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + + +#include + +#include + +#include +#include +#include +#include + +#include +#include +#include + +static const char sch_place_cookie[] = "place plugin"; + + +static fgw_error_t place_action(fgw_arg_t *res, int argc, fgw_arg_t *argv, int (*placer)(csch_sheet_t *sheet, csch_cgrp_t *parent, csch_coord_t ox, csch_coord_t oy)) +{ + rnd_design_t *hidlib = RND_ACT_DESIGN; + csch_sheet_t *sheet = (csch_sheet_t *)hidlib; + csch_cgrp_t *parent; + csch_coord_t x = 0, y = 0; + int rv = -1, target = F_Sheet; + + if (argc > 1) + target = fgw_keyword(&argv[1]); + + uundo_freeze_serial(&sheet->undo); + switch(target) { + case F_Buffer: + rnd_message(RND_MSG_ERROR, "not yet implemented, sorry\n"); + goto error; + case F_Sheet: + parent = &sheet->direct; + x = P2C(sch_rnd_crosshair_x); + y = P2C(sch_rnd_crosshair_y); + break; + + default: + rnd_message(RND_MSG_ERROR, "PlaceTerminal: wrong first arg\n"); + goto error; + } + + rv = placer(sheet, parent, x, y); + + error:; + + uundo_unfreeze_serial(&sheet->undo); + if (rv == 0) + uundo_inc_serial(&sheet->undo); + + RND_ACT_IRES(rv); + return 0; +} + +#include "attrib.c" +#include "terminal.c" + +static rnd_action_t sch_place_action_list[] = { + {"PlaceAttrib", csch_act_PlaceAttrib, csch_acth_PlaceAttrib, csch_acts_PlaceAttrib}, + {"PlaceTerminal", csch_act_PlaceTerminal, csch_acth_PlaceTerminal, csch_acts_PlaceTerminal} +}; + +int pplg_check_ver_place(int ver_needed) { return 0; } + +void pplg_uninit_place(void) +{ + rnd_remove_actions_by_cookie(sch_place_cookie); +} + +int pplg_init_place(void) +{ + RND_API_CHK_VER; + + RND_REGISTER_ACTIONS(sch_place_action_list, sch_place_cookie); + return 0; +} + Index: tags/1.0.5/src/plugins/place/place.pup =================================================================== --- tags/1.0.5/src/plugins/place/place.pup (nonexistent) +++ tags/1.0.5/src/plugins/place/place.pup (revision 10414) @@ -0,0 +1,7 @@ +$class feature +$short place complex objects +$long place complex objects such as terminals from template +$state works +$package (core) +default buildin +autoload 1 Index: tags/1.0.5/src/plugins/place/terminal.c =================================================================== --- tags/1.0.5/src/plugins/place/terminal.c (nonexistent) +++ tags/1.0.5/src/plugins/place/terminal.c (revision 10414) @@ -0,0 +1,62 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - place predefined groups + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include +#include +#include +#include + +static int place_terminal(csch_sheet_t *sheet, csch_cgrp_t *parent, csch_coord_t ox, csch_coord_t oy) +{ + csch_cgrp_t *grp = (csch_cgrp_t *)csch_op_create(sheet, parent, CSCH_CTYPE_GRP); + csch_line_t *line = (csch_line_t *)csch_op_create(sheet, grp, CSCH_CTYPE_LINE); + + grp->x = ox; + grp->y = oy; + + line->spec.p1.x = 0; line->spec.p1.y = 0; + line->spec.p2.x = -1 * 4000; line->spec.p2.y = 0; + + line->hdr.stroke_name = csch_comm_str(sheet, "term-decor", 1); + csch_line_update(sheet, line, 1); + csch_cgrp_update(sheet, grp, 1); + + csch_cgrp_role_side_effects(sheet, grp, CSCH_ROLE_TERMINAL); + csch_cgrp_update(sheet, grp, 1); + + csch_sheet_set_changed(sheet, 1); + + return 0; +} + +static const char csch_acts_PlaceTerminal[] = "PlaceTerminal([sheet|buffer])\n"; +static const char csch_acth_PlaceTerminal[] = "Place a terminal group template "; +static fgw_error_t csch_act_PlaceTerminal(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + return place_action(res, argc, argv, place_terminal); +} Index: tags/1.0.5/src/plugins/plugins_ALL.tmpasm =================================================================== --- tags/1.0.5/src/plugins/plugins_ALL.tmpasm (nonexistent) +++ tags/1.0.5/src/plugins/plugins_ALL.tmpasm (revision 10414) @@ -0,0 +1,50 @@ +# List of all plugins - generated by make map_plugins - do NOT edit +include {../src/plugins/act_draw/Plug.tmpasm} +include {../src/plugins/act_read/Plug.tmpasm} +include {../src/plugins/backann/Plug.tmpasm} +include {../src/plugins/construct/Plug.tmpasm} +include {../src/plugins/diag/Plug.tmpasm} +include {../src/plugins/export_abst/Plug.tmpasm} +include {../src/plugins/export_bom/Plug.tmpasm} +include {../src/plugins/export_lpr/Plug.tmpasm} +include {../src/plugins/export_png/Plug.tmpasm} +include {../src/plugins/export_ps/Plug.tmpasm} +include {../src/plugins/export_spice/Plug.tmpasm} +include {../src/plugins/export_svg/Plug.tmpasm} +include {../src/plugins/export_tedax/Plug.tmpasm} +include {../src/plugins/export_tedax_footprint/Plug.tmpasm} +include {../src/plugins/funcmap/Plug.tmpasm} +include {../src/plugins/gui/Plug.tmpasm} +include {../src/plugins/hlibrary_fs/Plug.tmpasm} +include {../src/plugins/io_altium/Plug.tmpasm} +include {../src/plugins/io_geda/Plug.tmpasm} +include {../src/plugins/io_lihata/Plug.tmpasm} +include {../src/plugins/io_ngrp_fawk/Plug.tmpasm} +include {../src/plugins/io_ngrp_tedax/Plug.tmpasm} +include {../src/plugins/io_orcad/Plug.tmpasm} +include {../src/plugins/io_tinycad/Plug.tmpasm} +include {../src/plugins/lib_alien/Plug.tmpasm} +include {../src/plugins/lib_anymap/Plug.tmpasm} +include {../src/plugins/lib_netlist_exp/Plug.tmpasm} +include {../src/plugins/lib_ngrp/Plug.tmpasm} +include {../src/plugins/lib_plot/Plug.tmpasm} +include {../src/plugins/lib_target/Plug.tmpasm} +include {../src/plugins/lib_tedax/Plug.tmpasm} +include {../src/plugins/lib_ucdf/Plug.tmpasm} +include {../src/plugins/place/Plug.tmpasm} +include {../src/plugins/propedit/Plug.tmpasm} +include {../src/plugins/query/Plug.tmpasm} +include {../src/plugins/renumber/Plug.tmpasm} +include {../src/plugins/sch_dialogs/Plug.tmpasm} +include {../src/plugins/sim/Plug.tmpasm} +include {../src/plugins/sim_gui/Plug.tmpasm} +include {../src/plugins/sim_ngspice/Plug.tmpasm} +include {../src/plugins/std_cschem/Plug.tmpasm} +include {../src/plugins/std_devmap/Plug.tmpasm} +include {../src/plugins/std_forge/Plug.tmpasm} +include {../src/plugins/std_tools/Plug.tmpasm} +include {../src/plugins/symlib_fs/Plug.tmpasm} +include {../src/plugins/symlib_local/Plug.tmpasm} +include {../src/plugins/target_none/Plug.tmpasm} +include {../src/plugins/target_pcb/Plug.tmpasm} +include {../src/plugins/target_spice/Plug.tmpasm} Index: tags/1.0.5/src/plugins/propedit/Makefile =================================================================== --- tags/1.0.5/src/plugins/propedit/Makefile (nonexistent) +++ tags/1.0.5/src/plugins/propedit/Makefile (revision 10414) @@ -0,0 +1,2 @@ +all: + cd ../../sch-rnd && make mod_propedit Index: tags/1.0.5/src/plugins/propedit/Plug.tmpasm =================================================================== --- tags/1.0.5/src/plugins/propedit/Plug.tmpasm (nonexistent) +++ tags/1.0.5/src/plugins/propedit/Plug.tmpasm (revision 10414) @@ -0,0 +1,13 @@ +put /local/rnd/mod {propedit} +put /local/rnd/mod/OBJS [@ + $(PLUGDIR)/propedit/propedit.o + $(PLUGDIR)/propedit/props.o + $(PLUGDIR)/propedit/propsel.o + $(PLUGDIR)/propedit/propdlg.o +@] + +switch /local/module/propedit/controls + case {buildin} include /local/csch/tmpasm/buildin; end; + case {plugin} include /local/csch/tmpasm/plugin; end; + case {disable} include /local/csch/tmpasm/disable; end; +end Index: tags/1.0.5/src/plugins/propedit/propdlg.c =================================================================== --- tags/1.0.5/src/plugins/propedit/propdlg.c (nonexistent) +++ tags/1.0.5/src/plugins/propedit/propdlg.c (revision 10414) @@ -0,0 +1,1050 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - property editor plugin + * Copyright (C) 2022,2023 Tibor 'Igor2' Palinkas + * (Adapted from propsel code in pcb-rnd by the same author) + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "props.h" +#include "propsel.h" + +extern const char csch_propedit_cookie[]; + +typedef struct{ + RND_DAD_DECL_NOINIT(dlg) + csch_sheet_t *sheet; + csch_propedit_t pe; + int wtree, wfilter, wtype, wvals, wscope, wprev, whelptxt, wquickattr; + int wabs[CSCH_PROPT_max], wedit[CSCH_PROPT_max]; + unsigned lock:1; /* do not refresh while editing */ + gdl_elem_t link; +} propdlg_t; + +gdl_list_t propdlgs; + +static void prop_refresh(propdlg_t *ctx); + +static void propdlgclose_cb(void *caller_data, rnd_hid_attr_ev_t ev) +{ + propdlg_t *ctx = caller_data; + gdl_remove(&propdlgs, ctx, link); + csch_props_uninit(&ctx->pe); + RND_DAD_FREE(ctx->dlg); + free(ctx); +} + +static void prop_filter_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr_ign) +{ + propdlg_t *ctx = caller_data; + rnd_hid_attribute_t *attr, *attr_inp; + rnd_hid_tree_t *tree; + const char *text; + int have_filter_text; + + attr = &ctx->dlg[ctx->wtree]; + attr_inp = &ctx->dlg[ctx->wfilter]; + tree = attr->wdata; + text = attr_inp->val.str; + have_filter_text = (text != NULL) && (*text != '\0'); + + /* hide or unhide everything */ + rnd_dad_tree_hide_all(tree, &tree->rows, have_filter_text); + + if (have_filter_text) /* unhide hits and all their parents */ + rnd_dad_tree_unhide_filter(tree, &tree->rows, 0, text); + + rnd_dad_tree_update_hide(attr); +} + +static void prop_sch2dlg(propdlg_t *ctx) +{ + rnd_hid_attribute_t *attr = &ctx->dlg[ctx->wtree]; + rnd_hid_tree_t *tree = attr->wdata; + rnd_hid_row_t *r; + htsp_entry_t *sorted, *e; + char *cursor_path = NULL; + + /* remember cursor */ + r = rnd_dad_tree_get_selected(attr); + if (r != NULL) + cursor_path = rnd_strdup(r->path); + + rnd_dad_tree_clear(tree); + + csch_props_clear(&ctx->pe); + csch_propsel_map_core(&ctx->pe); + sorted = csch_props_sort(&ctx->pe); + for(e = sorted; e->key != NULL; e++) { + char *cell[6] = {NULL}; + csch_props_t *p = e->value; + csch_propval_t com, min, max, avg; + + if ((p->type == CSCH_PROPT_STRING) || (p->type == CSCH_PROPT_COMMS) || (p->type == CSCH_PROPT_ENUM) || (p->type == CSCH_PROPT_UUID)) { + csch_props_stat(&ctx->pe, p, &com, NULL, NULL, NULL); + } + else { + csch_props_stat(&ctx->pe, p, &com, &min, &max, &avg); + cell[2] = csch_propsel_printval(p, &min); + cell[3] = csch_propsel_printval(p, &max); + cell[4] = csch_propsel_printval(p, &avg); + } + + cell[0] = rnd_strdup(e->key); + cell[1] = csch_propsel_printval(p, &com); + + r = rnd_dad_tree_mkdirp(tree, cell[0], cell); + r->user_data = e->key; + } + free(sorted); + prop_filter_cb(ctx->dlg_hid_ctx, ctx, NULL); + + rnd_dad_tree_expcoll(attr, NULL, 1, 1); + + /* restore cursor */ + if (cursor_path != NULL) { + rnd_hid_attr_val_t hv; + hv.str = cursor_path; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wtree, &hv); + free(cursor_path); + } + + /* set scope */ + { + rnd_hid_attr_val_t hv; + gds_t scope; + int inv; + csch_oidpath_t *idp; + + gds_init(&scope); + if (ctx->pe.use_sheet) + gds_append_str(&scope, "sheet, "); + if (ctx->pe.use_selection) + gds_append_str(&scope, "selected objects, "); + + inv = 0; + for(idp = csch_oidpath_list_first(&ctx->pe.objs); idp != NULL; idp = csch_oidpath_list_next(idp)) { + csch_chdr_t *o = csch_oidpath_resolve(ctx->pe.sheet, idp); + if (o != NULL) + rnd_append_printf(&scope, "%s #%ld, ", csch_ctype_name(o->type), o->oid); + else + inv++; + } + if (inv > 0) + rnd_append_printf(&scope, "%d invalid objects, ", inv); + + gds_truncate(&scope, gds_len(&scope)-2); + + hv.str = scope.array; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wscope, &hv); + gds_uninit(&scope); + } +} + +static void (*help_expose)(rnd_hid_attribute_t *attrib, rnd_hid_preview_t *prv, rnd_hid_gc_t gc, rnd_hid_expose_ctx_t *e) = NULL; + +static void prop_nil_expose_cb(rnd_hid_attribute_t *attrib, rnd_hid_preview_t *prv, rnd_hid_gc_t gc, rnd_hid_expose_ctx_t *e) +{ +} + +static void prop_prv_expose_cb(rnd_hid_attribute_t *attrib, rnd_hid_preview_t *prv, rnd_hid_gc_t gc, rnd_hid_expose_ctx_t *e) +{ + if (help_expose != NULL) + help_expose(attrib, prv, gc, e); +} + + +static rnd_bool prop_prv_mouse_cb(rnd_hid_attribute_t *attrib, rnd_hid_preview_t *prv, rnd_hid_mouse_ev_t kind, rnd_coord_t x, rnd_coord_t y) +{ + return rnd_false; /* don't redraw */ +} + +static void prop_valedit_update(propdlg_t *ctx, csch_props_t *p, csch_propval_t *pv) +{ + rnd_hid_attr_val_t hv; + minuid_str_t utmp; + + /* do not update the value if widget is numeric and the user wants a relative value */ + switch(p->type) { + case CSCH_PROPT_COORD: + case CSCH_PROPT_ANGLE: + case CSCH_PROPT_DOUBLE: + case CSCH_PROPT_INT: + if (!ctx->dlg[ctx->wabs[p->type]].val.lng) + return; + default: break; + } + + + memset(&hv, 0, sizeof(hv)); + switch(p->type) { + case CSCH_PROPT_STRING: hv.str = pv->string == NULL ? "" : pv->string; break; + case CSCH_PROPT_COORD: hv.crd = C2P(pv->coord); break; + case CSCH_PROPT_ANGLE: hv.dbl = pv->angle; break; + case CSCH_PROPT_DOUBLE: hv.dbl = pv->d; break; + case CSCH_PROPT_BOOL: + case CSCH_PROPT_INT: hv.lng = pv->i; break; + case CSCH_PROPT_COMMS: hv.str = pv->comms.str == NULL ? "" : pv->comms.str; break; + case CSCH_PROPT_ENUM: hv.str = p->enum_names[pv->i]; break; + case CSCH_PROPT_ATTRARR: + return; /* can't update directly */ + case CSCH_PROPT_UUID: minuid_bin2str(utmp, pv->u); hv.str = utmp; break; + + case CSCH_PROPT_invalid: + case CSCH_PROPT_max: return; + } + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wedit[p->type], &hv); +} + +typedef struct { + csch_propval_t *val; + unsigned int cnt; +} pvsort_t; + +static int sort_pv(const void *pv1_, const void *pv2_) +{ + const pvsort_t *pv1 = pv1_, *pv2 = pv2_; + return pv1->cnt > pv2->cnt ? -1 : +1; +} + +static void prop_vals_update(propdlg_t *ctx, csch_props_t *p) +{ + rnd_hid_attr_val_t hv; + rnd_hid_attribute_t *attr = &ctx->dlg[ctx->wvals]; + rnd_hid_tree_t *tree = attr->wdata; + htprop_entry_t *e; + pvsort_t *pvs; + char *cell[3] = {NULL, NULL, NULL}; + int n; + + rnd_dad_tree_clear(tree); + + if (p == NULL) { /* deselect or not found */ + hv.lng = 0; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wtype, &hv); + return; + } + + /* get a sorted list of all values, by frequency */ + pvs = malloc(sizeof(pvsort_t) * p->values.used); + for (e = htprop_first(&p->values), n = 0; e; e = htprop_next(&p->values, e), n++) { + pvs[n].val = &e->key; + pvs[n].cnt = e->value; + } + qsort(pvs, p->values.used, sizeof(pvsort_t), sort_pv); + + for(n = 0; n < p->values.used; n++) { + rnd_hid_row_t *r; + cell[0] = rnd_strdup_printf("%ld", pvs[n].cnt); + cell[1] = csch_propsel_printval(p, pvs[n].val); + r = rnd_dad_tree_append(attr, NULL, cell); + r->user_data = pvs[n].val; + } + + hv.lng = p->type; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wtype, &hv); + + prop_valedit_update(ctx, p, pvs[0].val); + + free(pvs); +} + +static void prop_select_node_cb(rnd_hid_attribute_t *attrib, void *hid_ctx, rnd_hid_row_t *row) +{ + rnd_design_t *hidlib = rnd_gui->get_dad_design(hid_ctx); + rnd_hid_tree_t *tree = attrib->wdata; + propdlg_t *ctx = tree->user_ctx; + csch_props_t *p = NULL; + void (*last_help)(rnd_hid_attribute_t *attrib, rnd_hid_preview_t *prv, rnd_hid_gc_t gc, rnd_hid_expose_ctx_t *e) = NULL; + const char *helptxt = NULL; + int enable_quick_attr = 0; + + last_help = help_expose; + help_expose = NULL; + + if (row != NULL) { + p = csch_props_get(&ctx->pe, row->user_data); + + /* update the help preview */ + if (strcmp(row->path, "p/grp/mirx") == 0) helptxt = "Horizontal mirror the group."; + else if (strcmp(row->path, "p/grp/miry") == 0) helptxt = "Vertical mirror the group."; + else if (strcmp(row->path, "p/grp/rot") == 0) helptxt = "Rotate the group, counter\nclockwise. Mirroring inverts\ndirection of rotation.\nSpecified in degrees."; + else if (strcmp(row->path, "p/grp/uuid") == 0) helptxt = "Universally unique ID of\nthe group. Also\ncalled instance UID.\nGenerated using libminuid."; + else if (strcmp(row->path, "p/grp/src_uuid") == 0) helptxt = "The p/grp/uuid field of\nthe original group\nthis one is a copy of."; + else if (strcmp(row->path, "p/floater") == 0) helptxt = "When true, object can\nbe selected and moved\neven if it is in an atomic group."; + else if (strcmp(row->path, "p/lock") == 0) helptxt = "When true, object can\nNOT be selected and moved."; + else if (strcmp(row->path, "p/stroke") == 0) helptxt = "Name of the pen\nused for drawing the\noutline of the object."; + else if (strcmp(row->path, "p/fill") == 0) helptxt = "Name of the pen\nused for filling the\nobject. May be empty."; + else if (strcmp(row->path, "p/has_fill") == 0) helptxt = "If true, fill the\nobject using the fill_pen"; + else if (strcmp(row->path, "p/has_stroke") == 0) helptxt = "If true, draw the\noutline of the object\nusing the stroke_pen"; + else if (strcmp(row->path, "p/text/dyntext") == 0) helptxt = "If true, allow substitution of\n%patterns% in text field\nwhen rendering"; + else if (strcmp(row->path, "p/text/has_bbox") == 0) helptxt = "If true, scale text\nso it best fits the bounding\nbox specified; else\nuse font with size (height)\nspecified in stroke pen."; + else if (strcmp(row->path, "p/text/rot") == 0) helptxt = "Rotate the text object, counter\nclockwise. Mirroring inverts\ndirection of rotation.\nSpecified in degrees."; + else if (strcmp(row->path, "p/text/text") == 0) helptxt = "String to print.\nIf dyntext is enabled,\n%patterns% are replaced\nbefore rendering."; + else if (strcmp(row->path, "a/name") == 0) helptxt = "Name of the object.\nTypical use cases:\nsymbol refdes,\nterminal name\n..."; + else if (strcmp(row->path, "a/role") == 0) helptxt = "The program understood\nrole of the group.\nTypical values:\nsymbol\nterminal\nwire-net\n..."; + } + + if (last_help != help_expose) { + rnd_hid_attr_val_t hv; + hv.str = NULL; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wprev, &hv); + } + + if (helptxt != NULL) { + rnd_hid_attr_val_t hv; + + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wprev, 1); + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->whelptxt, 0); + + hv.str = helptxt; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->whelptxt, &hv); + } + else { + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->whelptxt, 1); + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wprev, 0); + } + + + if (ctx->wquickattr != 0) { + if ((row != NULL) && (row->path != NULL) && (row->path[0] == 'a') && (row->path[1] == '/')) { + const char *key = row->path+2; + csch_oidpath_t *idp = prop_scope_single_obj(&ctx->pe); + if (idp != NULL) { + gds_t tmp = {0}; + gds_append_str(&tmp, "object:"); + csch_oidpath_to_str_append(&tmp, idp); + enable_quick_attr = rnd_actionva(hidlib, "quickattreditable", tmp.array, key, NULL); + gds_uninit(&tmp); + } + } + rnd_gui->attr_dlg_widget_state(ctx->dlg_hid_ctx, ctx->wquickattr, enable_quick_attr); + } + + prop_vals_update(ctx, p); +} + + +static void prop_data_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr, int force_update) +{ + propdlg_t *ctx = caller_data; + rnd_hid_row_t *r = rnd_dad_tree_get_selected(&ctx->dlg[ctx->wtree]); + csch_props_t *p = NULL; + csch_propset_ctx_t sctx; + + if (r == NULL) + return; + p = csch_props_get(&ctx->pe, r->user_data); + if (p == NULL) + return; + + memset(&sctx, 0, sizeof(sctx)); + switch(p->type) { + case CSCH_PROPT_invalid: + case CSCH_PROPT_max: + return; + case CSCH_PROPT_STRING: + sctx.s = ctx->dlg[ctx->wedit[p->type]].val.str; + force_update = 1; + break; + case CSCH_PROPT_COORD: + sctx.c = P2C(ctx->dlg[ctx->wedit[p->type]].val.crd); + sctx.c_absolute = ctx->dlg[ctx->wabs[p->type]].val.lng; + sctx.c_valid = 1; + break; + case CSCH_PROPT_ANGLE: + sctx.d = ctx->dlg[ctx->wedit[p->type]].val.dbl; + sctx.d_absolute = ctx->dlg[ctx->wabs[p->type]].val.lng; + sctx.d_valid = 1; + break; + case CSCH_PROPT_DOUBLE: + sctx.d = ctx->dlg[ctx->wedit[p->type]].val.dbl; + sctx.d_absolute = ctx->dlg[ctx->wabs[p->type]].val.lng; + sctx.d_valid = 1; + break; + case CSCH_PROPT_ENUM: + case CSCH_PROPT_INT: + sctx.c = ctx->dlg[ctx->wedit[p->type]].val.lng; + sctx.c_absolute = ctx->dlg[ctx->wabs[p->type]].val.lng; + sctx.c_valid = 1; + break; + case CSCH_PROPT_BOOL: + sctx.c = ctx->dlg[ctx->wedit[p->type]].val.lng; + sctx.c_absolute = ctx->dlg[ctx->wabs[p->type]].val.lng; + sctx.c_valid = 1; + break; + case CSCH_PROPT_COMMS: + sctx.comms = csch_comm_str(ctx->pe.sheet, ctx->dlg[ctx->wedit[p->type]].val.str, 1); + force_update = 1; + break; + case CSCH_PROPT_UUID: + minuid_gen(&csch_minuid, sctx.u); + force_update = 1; + break; + case CSCH_PROPT_ATTRARR: + break; + } + + if (force_update || ctx->dlg[ctx->wabs[p->type]].val.lng) { + ctx->lock = 1; + csch_propsel_set(&ctx->pe, r->user_data, &sctx); + prop_refresh(ctx); + rnd_gui->invalidate_all(rnd_gui); + ctx->lock = 0; + } +} + +static void prop_data_auto_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + prop_data_cb(hid_ctx, caller_data, attr, 0); +} + +static void prop_data_force_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + prop_data_cb(hid_ctx, caller_data, attr, 1); +} + +static void prop_change_comms_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + propdlg_t *ctx = caller_data; + rnd_hid_row_t *r = rnd_dad_tree_get_selected(&ctx->dlg[ctx->wtree]); + csch_props_t *p = NULL; + csch_sheet_t *sheet = ctx->pe.sheet; + const char *pen_name = NULL; + fgw_error_t rv; + fgw_arg_t res, args[6]; + + if (r == NULL) + return; + p = csch_props_get(&ctx->pe, r->user_data); + if (p == NULL) + return; + + switch(p->comms_type) { + case CSCH_PROPCT_STRING: + rnd_message(RND_MSG_ERROR, "Internal error: CSCH_PROPCT_STRING is not yet implemented in prop_change_comms_cb()\n"); + break; + case CSCH_PROPCT_PEN: + + args[1].type = FGW_STR; args[1].val.str = "object:/2"; /* sheet->direct */ + args[2].type = FGW_STR; args[2].val.str = "modal"; + args[3].type = FGW_STR; args[3].val.str = "recursive"; + args[4].type = FGW_STR; args[4].val.str = "ret_name"; + args[5].type = FGW_STR; args[5].val.str = r->cell[1]; + + rv = rnd_actionv_bin(&sheet->hidlib, "pendialog", &res, 6, args); + if ((rv == 0) && ((res.type & FGW_STR) == FGW_STR)) + pen_name = res.val.str; + + if (pen_name != NULL) { + rnd_hid_attr_val_t hv; + hv.str = pen_name; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, attr - ctx->dlg, &hv); + prop_data_cb(hid_ctx, caller_data, attr, 1); + } + + fgw_arg_free(&rnd_fgw, &res); + break; + default: + rnd_message(RND_MSG_ERROR, "Internal error: invalid CSCH_PROPCT in prop_change_comms_cb()\n"); + break; + } +} + +static void prop_change_enum_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + RND_DAD_DECL(dlg) + propdlg_t *ctx = caller_data; + rnd_hid_row_t *r = rnd_dad_tree_get_selected(&ctx->dlg[ctx->wtree]); + csch_props_t *p = NULL; +/* csch_sheet_t *sheet = ctx->pe.sheet;*/ + const char **en, *currv; + int defv = -1, wval, failed; + rnd_hid_dad_buttons_t clbtn[] = {{"Cancel", -1}, {"Apply selected", 0}, {NULL, 0}}; + + if (r == NULL) + return; + p = csch_props_get(&ctx->pe, r->user_data); + if (p == NULL) + return; + + /* figure initial index value for the combo box */ + currv = ctx->dlg[ctx->wedit[8]].val.str; + if (currv != NULL) { + int n; + for(n = 0, en = p->enum_names; *en != NULL; en++,n++) { + if (strcmp(currv, *en) == 0) { + defv = n; + break; + } + } + } + + RND_DAD_BEGIN_VBOX(dlg); + RND_DAD_BEGIN_HBOX(dlg); + RND_DAD_LABEL(dlg, "Select a value for"); + RND_DAD_LABEL(dlg, r->cell[0]); + RND_DAD_END(dlg); + RND_DAD_ENUM(dlg, p->enum_names); + wval = RND_DAD_CURRENT(dlg); + RND_DAD_DEFAULT_NUM(dlg, defv); + RND_DAD_BUTTON_CLOSES(dlg, clbtn); + RND_DAD_END(dlg); + + RND_DAD_AUTORUN("propedit_enum", dlg, "Propedit: edit enum value", NULL, failed); + + if (failed == 0) { + csch_propsel_set_str(&ctx->pe, r->user_data, p->enum_names[dlg[wval].val.lng]); + prop_refresh(ctx); + } + RND_DAD_FREE(dlg); + + return; +} + +static void prop_change_attrarr_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + propdlg_t *ctx = caller_data; + rnd_hid_row_t *r = rnd_dad_tree_get_selected(&ctx->dlg[ctx->wtree]); +/* csch_sheet_t *sheet = ctx->pe.sheet;*/ + csch_oidpath_t *idp; + rnd_design_t *hl = rnd_gui->get_dad_design(hid_ctx); + + + idp = prop_scope_single_obj(&ctx->pe); + if (idp != NULL) { + gds_t tmp = {0}; + gds_append_str(&tmp, "object:"); + csch_oidpath_to_str_append(&tmp, idp); + rnd_actionva(hl, "AttributeDialog", tmp.array, r->cell[0], NULL); + gds_uninit(&tmp); + } + else + rnd_message(RND_MSG_ERROR, "Attribute-editing array is supported only for single-object propedit\nThis propedit has a scope of multiple objects.\n"); +} + +static void prop_attrdlg_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + propdlg_t *ctx = caller_data; + csch_oidpath_t *idp; + rnd_design_t *hl = rnd_gui->get_dad_design(hid_ctx); + + idp = prop_scope_single_obj(&ctx->pe); + if (idp != NULL) { + gds_t tmp = {0}; + gds_append_str(&tmp, "object:"); + csch_oidpath_to_str_append(&tmp, idp); + rnd_actionva(hl, "AttributeDialog", tmp.array, NULL); + gds_uninit(&tmp); + } + else + rnd_message(RND_MSG_ERROR, "Attribute-editing array is supported only for single-object propedit\nThis propedit has a scope of multiple objects.\n"); +} + +static void prop_quickattr_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + rnd_design_t *hidlib = rnd_gui->get_dad_design(hid_ctx); + propdlg_t *ctx = caller_data; + csch_oidpath_t *idp; + + idp = prop_scope_single_obj(&ctx->pe); + if (idp != NULL) { + csch_chdr_t *obj = csch_oidpath_resolve(ctx->sheet, idp); + if (obj != NULL) { + rnd_hid_row_t *r = rnd_dad_tree_get_selected(&ctx->dlg[ctx->wtree]); + const char *key = r->cell[0]; + gds_t tmp = {0}; + + gds_append_str(&tmp, "object:"); + csch_oidpath_to_str_append(&tmp, idp); + rnd_actionva(hidlib, "quickattr", tmp.array, key, NULL); + gds_uninit(&tmp); + } + else + rnd_message(RND_MSG_ERROR, "Internal error: object not found in prop_quickattr_cb().\n"); + } + else + rnd_message(RND_MSG_ERROR, "Attribute-editing array is supported only for single-object propedit\nThis propedit has a scope of multiple objects.\n"); +} + +static void prop_attr_enter_pressed_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + rnd_dad_retovr_t **retovr = caller_data; + rnd_hid_dad_close(hid_ctx, *retovr, 0); +} + +static void prop_add_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + RND_DAD_DECL(dlg) + propdlg_t *ctx = caller_data; + const char *key; + int wkey, wval, failed; + rnd_hid_dad_buttons_t clbtn[] = {{"Cancel", -1}, {"OK", 0}, {NULL, 0}}; + + RND_DAD_BEGIN_VBOX(dlg); + RND_DAD_BEGIN_TABLE(dlg, 2); + RND_DAD_COMPFLAG(dlg, RND_HATF_EXPFILL); + RND_DAD_LABEL(dlg, "Attribute key:"); + RND_DAD_STRING(dlg); + wkey = RND_DAD_CURRENT(dlg); + RND_DAD_LABEL(dlg, "Attribute value:"); + RND_DAD_STRING(dlg); + wval = RND_DAD_CURRENT(dlg); + RND_DAD_ENTER_CB(dlg, prop_attr_enter_pressed_cb); + RND_DAD_END(dlg); + RND_DAD_BUTTON_CLOSES(dlg, clbtn); + RND_DAD_END(dlg); + RND_DAD_AUTORUN("propedit_add", dlg, "Propedit: add new attribute", &dlg_ret_override, failed); + + key = dlg[wkey].val.str; + if (key == NULL) key = ""; + while(isspace(*key)) key++; + + if ((failed == 0) && (*key != '\0')) { + char *path = rnd_strdup_printf("a/%s", key); + ctx->lock = 1; + csch_propsel_set_str(&ctx->pe, path, dlg[wval].val.str); + free(path); + prop_refresh(ctx); + ctx->lock = 0; + } + RND_DAD_FREE(dlg); +} + +static void prop_del_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + propdlg_t *ctx = caller_data; + rnd_hid_row_t *r = rnd_dad_tree_get_selected(&ctx->dlg[ctx->wtree]); + if (r == NULL) { + rnd_message(RND_MSG_ERROR, "can not delete: no attribute selected\n"); + return; + } + if (r->path[0] != 'a') { + rnd_message(RND_MSG_ERROR, "Only atributes (a/ subtree) can be deleted.\n"); + return; + } + + ctx->lock = 1; + if (csch_propsel_del(&ctx->pe, r->path) < 1) { + ctx->lock = 0; + rnd_message(RND_MSG_ERROR, "Failed to remove the attribute from any object.\n"); + return; + } + prop_refresh(ctx); + ctx->lock = 0; +} + +static void prop_preset_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + propdlg_t *ctx = caller_data; + rnd_hid_row_t *rv = rnd_dad_tree_get_selected(&ctx->dlg[ctx->wvals]); + rnd_hid_row_t *rp = rnd_dad_tree_get_selected(&ctx->dlg[ctx->wtree]); + csch_props_t *p; + + if ((rv == NULL) || (rv->user_data == NULL) || (rp == NULL)) + return; + + p = csch_props_get(&ctx->pe, rp->user_data); + if (p != NULL) + prop_valedit_update(ctx, p, rv->user_data); +} + + +static void prop_refresh_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + prop_refresh((propdlg_t *)caller_data); +} + + +static void prop_refresh(propdlg_t *ctx) +{ + rnd_hid_attribute_t *attr = &ctx->dlg[ctx->wtree]; + prop_sch2dlg(ctx); + prop_select_node_cb(attr, ctx->dlg_hid_ctx, rnd_dad_tree_get_selected(attr)); +} + + +static void build_propval(propdlg_t *ctx) +{ + static const char *type_tabs[] = {"none", "string", "coord", "angle", "double", "int", NULL}; + static const char *abshelp = "When unticked each apply is a relative change added to\nthe current value of each object"; + + RND_DAD_BEGIN_TABBED(ctx->dlg, type_tabs); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_HIDE_TABLAB); + ctx->wtype = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "(nothing to edit)"); + ctx->wabs[0] = 0; + ctx->wedit[0] = 0; + RND_DAD_END(ctx->dlg); + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Data type: string"); + RND_DAD_STRING(ctx->dlg); + ctx->wedit[1] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_ENTER_CB(ctx->dlg, prop_data_auto_cb); + RND_DAD_BEGIN_HBOX(ctx->dlg); + ctx->wabs[1] = 0; + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_END(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "apply"); + RND_DAD_CHANGE_CB(ctx->dlg, prop_data_force_cb); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Data type: coord"); + RND_DAD_CSCH_COORD(ctx->dlg); + ctx->wedit[2] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_ENTER_CB(ctx->dlg, prop_data_auto_cb); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "abs"); + RND_DAD_BOOL(ctx->dlg); + ctx->wabs[2] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_HELP(ctx->dlg, abshelp); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_END(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "apply"); + RND_DAD_CHANGE_CB(ctx->dlg, prop_data_force_cb); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Data type: angle"); + RND_DAD_REAL(ctx->dlg); + ctx->wedit[3] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_MINMAX(ctx->dlg, -360.0, +360.0); + RND_DAD_ENTER_CB(ctx->dlg, prop_data_auto_cb); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "abs"); + RND_DAD_BOOL(ctx->dlg); + ctx->wabs[3] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_HELP(ctx->dlg, abshelp); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_END(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "apply"); + RND_DAD_CHANGE_CB(ctx->dlg, prop_data_force_cb); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Data type: double"); + RND_DAD_REAL(ctx->dlg); + ctx->wedit[4] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_MINMAX(ctx->dlg, -1000, +1000); + RND_DAD_ENTER_CB(ctx->dlg, prop_data_auto_cb); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "abs"); + RND_DAD_BOOL(ctx->dlg); + ctx->wabs[4] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_HELP(ctx->dlg, abshelp); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_END(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "apply"); + RND_DAD_CHANGE_CB(ctx->dlg, prop_data_force_cb); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + + + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Data type: int"); + RND_DAD_INTEGER(ctx->dlg); + ctx->wedit[5] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_ENTER_CB(ctx->dlg, prop_data_auto_cb); + RND_DAD_MINMAX(ctx->dlg, -(1<<30), 1<<30); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "abs"); + RND_DAD_BOOL(ctx->dlg); + ctx->wabs[5] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_HELP(ctx->dlg, abshelp); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_END(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "apply"); + RND_DAD_CHANGE_CB(ctx->dlg, prop_data_force_cb); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Data type: boolean"); + RND_DAD_BOOL(ctx->dlg); + ctx->wedit[6] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_BEGIN_HBOX(ctx->dlg); + ctx->wabs[6] = 0; + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_END(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "apply"); + RND_DAD_CHANGE_CB(ctx->dlg, prop_data_force_cb); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Data type: common string"); + RND_DAD_BUTTON(ctx->dlg, ""); + ctx->wedit[7] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_CHANGE_CB(ctx->dlg, prop_change_comms_cb); + RND_DAD_BEGIN_HBOX(ctx->dlg); + ctx->wabs[7] = 0; + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_END(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "apply"); + RND_DAD_CHANGE_CB(ctx->dlg, prop_data_force_cb); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Data type: enum"); + RND_DAD_BUTTON(ctx->dlg, ""); + ctx->wedit[8] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_CHANGE_CB(ctx->dlg, prop_change_enum_cb); + RND_DAD_BEGIN_HBOX(ctx->dlg); + ctx->wabs[8] = 0; + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_END(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "apply"); + RND_DAD_CHANGE_CB(ctx->dlg, prop_data_force_cb); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Data type: array"); + RND_DAD_BUTTON(ctx->dlg, "Edit..."); + ctx->wedit[9] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_CHANGE_CB(ctx->dlg, prop_change_attrarr_cb); + RND_DAD_END(ctx->dlg); + + + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Data type: UUID"); + RND_DAD_BUTTON(ctx->dlg, "Replace"); + ctx->wedit[10] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_CHANGE_CB(ctx->dlg, prop_data_force_cb); + RND_DAD_END(ctx->dlg); + + + RND_DAD_END(ctx->dlg); +} + +static void csch_dlg_propdlg(propdlg_t *ctx) +{ + const char *hdr[] = {"property", "common", "min", "max", "avg", NULL}; + const char *hdr_val[] = {"use", "values"}; + rnd_hid_dad_buttons_t clbtn[] = {{"Close", 0}, {NULL, 0}}; + static rnd_box_t prvbb = {0, 0, RND_MM_TO_COORD(10), RND_MM_TO_COORD(10)}; + int n; + rnd_hid_attr_val_t hv; + + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_BEGIN_HPANE(ctx->dlg, "left-right"); + + /* left: property tree and filter */ + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_TREE(ctx->dlg, 5, 1, hdr); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL | RND_HATF_SCROLL); + ctx->wtree = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_TREE_SET_CB(ctx->dlg, selected_cb, prop_select_node_cb); + RND_DAD_TREE_SET_CB(ctx->dlg, ctx, ctx); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_STRING(ctx->dlg); + RND_DAD_HELP(ctx->dlg, "Filter text:\nlist properties with\nmatching name only"); + RND_DAD_CHANGE_CB(ctx->dlg, prop_filter_cb); + ctx->wfilter = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "add"); + RND_DAD_CHANGE_CB(ctx->dlg, prop_add_cb); + RND_DAD_HELP(ctx->dlg, "Create a new attribute\n(in the a/ subtree)"); + RND_DAD_BUTTON(ctx->dlg, "del"); + RND_DAD_CHANGE_CB(ctx->dlg, prop_del_cb); + RND_DAD_HELP(ctx->dlg, "Remove the selected attribute\n(from the a/ subtree)"); + RND_DAD_BUTTON(ctx->dlg, "rfr"); + RND_DAD_CHANGE_CB(ctx->dlg, prop_refresh_cb); + RND_DAD_HELP(ctx->dlg, "Refresh: rebuild the tree\nupdating all values from the sheet"); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + + /* right: preview and per type edit */ + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_PREVIEW(ctx->dlg, prop_prv_expose_cb, prop_prv_mouse_cb, NULL, NULL, &prvbb, 150, 150, ctx); + ctx->wprev = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "help"); + ctx->whelptxt = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_PREVIEW(ctx->dlg, prop_nil_expose_cb, NULL, NULL, NULL, &prvbb, 1, 150, ctx); /* placeholder */ + RND_DAD_END(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, ""); + ctx->wscope = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_HELP(ctx->dlg, "Scope: list of objects affected"); + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL | RND_HATF_SCROLL); + RND_DAD_TREE(ctx->dlg, 2, 0, hdr_val); + ctx->wvals = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_CHANGE_CB(ctx->dlg, prop_preset_cb); + RND_DAD_END(ctx->dlg); + RND_DAD_BEGIN_VBOX(ctx->dlg); + build_propval(ctx); + RND_DAD_END(ctx->dlg); + + RND_DAD_BEGIN_HBOX(ctx->dlg); + if (prop_scope_single_obj(&ctx->pe)) { + RND_DAD_BUTTON(ctx->dlg, "Attr. Dlg."); + RND_DAD_CHANGE_CB(ctx->dlg, prop_attrdlg_cb); + RND_DAD_HELP(ctx->dlg, "Invoke the attribute editor dialog box for this object"); + RND_DAD_BUTTON(ctx->dlg, "Quick edit"); + ctx->wquickattr = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_CHANGE_CB(ctx->dlg, prop_quickattr_cb); + RND_DAD_HELP(ctx->dlg, "Invoke the assisted/special attribute editor for the attribute"); + } + /* spring */ + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_END(ctx->dlg); + RND_DAD_BUTTON_CLOSES(ctx->dlg, clbtn); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + + RND_DAD_NEW("propedit", ctx->dlg, "Property editor", ctx, rnd_false, propdlgclose_cb); /* type=local */ + + prop_refresh(ctx); + gdl_append(&propdlgs, ctx, link); + + /* default all abs */ + hv.lng = 1; + for(n = 0; n < CSCH_PROPT_max; n++) + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wabs[n], &hv); +} + +extern int prop_scope_add(csch_propedit_t *pe, const char *cmd, int quiet); + +const char csch_acts_propedit[] = "propedit(object[:id]|sheet|selection)\n"; +const char csch_acth_propedit[] = ""; +fgw_error_t csch_act_propedit(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_design_t *hl = RND_ACT_DESIGN; + csch_sheet_t *sheet = (csch_sheet_t *)hl; + propdlg_t *ctx = calloc(sizeof(propdlg_t), 1); + int a, r; + + ctx->sheet = sheet; + csch_props_init(&ctx->pe, sheet, &sheet->direct); + + if (argc > 1) { + for(a = 1; a < argc; a++) { + const char *cmd; + RND_ACT_CONVARG(a, FGW_STR, propedit, cmd = argv[a].val.str); + r = prop_scope_add(&ctx->pe, cmd, 0); + if (r != 0) + return r; + } + } + else + ctx->pe.use_selection = 1; + + csch_dlg_propdlg(ctx); + return 0; +} + +static void propdlg_unit_change(rnd_conf_native_t *cfg, int arr_idx, void *user_data) +{ + propdlg_t *ctx; + gdl_iterator_t it; + + gdl_foreach(&propdlgs, &it, ctx) { + prop_sch2dlg(ctx); + } +} + +static void propedit_sheet_edit(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + propdlg_t *pd; + + for(pd = gdl_first(&propdlgs); pd != NULL; pd = gdl_next(&propdlgs, pd)) + if ((pd->pe.use_selection || (pd->pe.objs.lst.length != 0)) && !pd->lock) + prop_refresh(pd); +} + +static void propedit_sheet_preunload(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + csch_sheet_t *sheet = (csch_sheet_t *)hidlib; + propdlg_t *n, *next; + rnd_dad_retovr_t retovr = {0}; + + for(n = gdl_first(&propdlgs); n != NULL; n = next) { + next = gdl_next(&propdlgs, n); + if (n->sheet == sheet) + rnd_hid_dad_close(n->dlg_hid_ctx, &retovr, 0); + } +} + + +static rnd_conf_hid_id_t propdlg_conf_id; +static const char *propdlg_cookie = "propdlg"; +void csch_propdlg_init(void) +{ + static rnd_conf_hid_callbacks_t cbs; + rnd_conf_native_t *n = rnd_conf_get_field("editor/grid_unit"); + propdlg_conf_id = rnd_conf_hid_reg(propdlg_cookie, NULL); + + if (n != NULL) { + cbs.val_change_post = propdlg_unit_change; + rnd_conf_hid_set_cb(n, propdlg_conf_id, &cbs); + } + + rnd_event_bind(CSCH_EVENT_SHEET_EDITED, propedit_sheet_edit, NULL, csch_propedit_cookie); + rnd_event_bind(CSCH_EVENT_SELECTION_CHANGED, propedit_sheet_edit, NULL, csch_propedit_cookie); + rnd_event_bind(CSCH_EVENT_SHEET_PREUNLOAD, propedit_sheet_preunload, NULL, csch_propedit_cookie); +} + +void csch_propdlg_uninit(void) +{ + rnd_conf_hid_unreg(propdlg_cookie); + rnd_event_unbind_allcookie(csch_propedit_cookie); +} Index: tags/1.0.5/src/plugins/propedit/propdlg.h =================================================================== --- tags/1.0.5/src/plugins/propedit/propdlg.h (nonexistent) +++ tags/1.0.5/src/plugins/propedit/propdlg.h (revision 10414) @@ -0,0 +1,13 @@ +#ifndef PCB_PROPDLG_H +#define PCB_PROPDLG_H + +#include + +extern const char csch_acts_propedit[]; +extern const char csch_acth_propedit[]; +fgw_error_t csch_act_propedit(fgw_arg_t *res, int argc, fgw_arg_t *argv); + +void csch_propdlg_init(void); +void csch_propdlg_uninit(void); + +#endif Index: tags/1.0.5/src/plugins/propedit/propedit.c =================================================================== --- tags/1.0.5/src/plugins/propedit/propedit.c (nonexistent) +++ tags/1.0.5/src/plugins/propedit/propedit.c (revision 10414) @@ -0,0 +1,403 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - property editor + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "props.h" +#include "propsel.h" +#include "propdlg.h" + +const char csch_propedit_cookie[] = "propedit"; + +extern csch_chdr_t *csch_obj_clicked; + +int prop_scope_add_obj(csch_propedit_t *pe, const csch_chdr_t *obj) +{ + csch_oidpath_t *tmp; + + tmp = calloc(sizeof(csch_oidpath_t), 1); + csch_oidpath_from_obj(tmp, obj); + csch_oidpath_list_append(&pe->objs, tmp); + return 0; +} + +int prop_scope_add(csch_propedit_t *pe, const char *cmd, int quiet) +{ + csch_chdr_t *obj = NULL; + + if (strncmp(cmd, "parent", 6) == 0) { + if (csch_obj_clicked != NULL) + obj = &csch_obj_clicked->parent->hdr; + goto add_obj; + } + else if (strncmp(cmd, "object", 6) == 0) { + csch_oidpath_t idp = {0}, *tmp; + + if (cmd[6] == ':') { + if (csch_oidpath_parse(&idp, cmd+7) != 0) { + if (!quiet) + rnd_message(RND_MSG_ERROR, "Failed to convert object ID: '%s'\n", cmd+7); + return FGW_ERR_ARG_CONV; + } + tmp = malloc(sizeof(csch_oidpath_t)); + *tmp = idp; + csch_oidpath_list_append(&pe->objs, tmp); + } + else { + obj = csch_obj_clicked; + + add_obj:; + if (obj == NULL) { + if (!quiet) + rnd_message(RND_MSG_ERROR, "No object under the cursor\n"); + return FGW_ERR_ARG_CONV; + } + + tmp = calloc(sizeof(csch_oidpath_t), 1); + csch_oidpath_from_obj(tmp, obj); + csch_oidpath_list_append(&pe->objs, tmp); + } + } + else if (strcmp(cmd, "sheet") == 0) + pe->use_sheet = 1; + else if (strcmp(cmd, "selection") == 0) + pe->use_selection = 1; + else if (strcmp(cmd, "geo") == 0) + pe->geo = 1; + else { + if (!quiet) + rnd_message(RND_MSG_ERROR, "Invalid propedit scope: %s\n", cmd); + return FGW_ERR_ARG_CONV; + } + + return 0; +} + +/* pair of prop_scope_add() - uninits the scope */ +static void prop_scope_finish(csch_propedit_t *pe) +{ + csch_oidpath_t *idp; + + /* need to remove idpaths from the scope list, else it won't be possible + to add them again */ + while((idp = csch_oidpath_list_first(&pe->objs)) != NULL) { + csch_oidpath_list_remove(idp); + free(idp); + } +} + +csch_oidpath_t *prop_scope_single_obj(csch_propedit_t *pe) +{ + if (pe->use_selection || pe->use_sheet) + return NULL; + + if (csch_oidpath_list_length(&pe->objs) != 1) + return NULL; + + return csch_oidpath_list_first(&pe->objs); +} + +static const char csch_acts_propset[] = "propset([scope], name, value)"; +static const char csch_acth_propset[] = "Change the named property of scope or all selected objects to/by value. Scope is documented at PropEdit(). Existing attributes can be renamed to value by using a name rename/a/old_name, where old_name is the current name of the attribute."; +static fgw_error_t csch_act_propset(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_design_t *hl = RND_ACT_DESIGN; + csch_sheet_t *sheet = (csch_sheet_t *)hl; + const char *first, *name, *val; + csch_propedit_t ctx; + + csch_props_init(&ctx, sheet, &sheet->direct); + + + RND_ACT_CONVARG(1, FGW_STR, propset, first = argv[1].val.str); + if (strcmp(first, "objbin") == 0) { + fgw_arg_conv(&rnd_fgw, &argv[2], (FGW_PTR | FGW_STRUCT)); + if (!fgw_ptr_in_domain(&rnd_fgw, &argv[2], CSCH_PTR_DOMAIN_COBJ)) { + rnd_message(RND_MSG_ERROR, "propset: objbin arg is not a pointer to a concrete model object\n"); + return FGW_ERR_ARG_CONV; + } + prop_scope_add_obj(&ctx, argv[2].val.ptr_void); + RND_ACT_CONVARG(3, FGW_STR, propset, name = argv[3].val.str); + RND_ACT_CONVARG(4, FGW_STR, propset, val = argv[4].val.str); + } + else if (strcmp(first, "@") == 0) { + if (sheet->currobj == NULL) { + rnd_message(RND_MSG_ERROR, "propset: @ without sheet->currobj set\n"); + return FGW_ERR_ARG_CONV; + } + prop_scope_add_obj(&ctx, sheet->currobj); + RND_ACT_CONVARG(2, FGW_STR, propset, name = argv[2].val.str); + RND_ACT_CONVARG(3, FGW_STR, propset, val = argv[3].val.str); + } + else if (prop_scope_add(&ctx, first, 1) == 0) { + RND_ACT_CONVARG(2, FGW_STR, propset, name = argv[2].val.str); + RND_ACT_CONVARG(3, FGW_STR, propset, val = argv[3].val.str); + } + else { + name = first; + ctx.use_selection = 1; + RND_ACT_CONVARG(2, FGW_STR, propset, val = argv[2].val.str); + } + + RND_ACT_IRES(csch_propsel_set_str(&ctx, name, val)); + + prop_scope_finish(&ctx); + csch_props_uninit(&ctx); + return 0; +} + +static const char csch_acts_proptoggle[] = "proptoggle([scope], name, [create])"; +static const char csch_acth_proptoggle[] = "Toggle the named property of scope or all selected objects, assuming the property is boolean. Scope is documented at PropEdit(). If create is true, non-existing attributes are created as true."; +fgw_error_t csch_act_proptoggle(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_design_t *hl = RND_ACT_DESIGN; + csch_sheet_t *sheet = (csch_sheet_t *)hl; + const char *first, *name, *create = NULL; + csch_propedit_t ctx; + + csch_props_init(&ctx, sheet, &sheet->direct); + + RND_ACT_CONVARG(1, FGW_STR, proptoggle, first = argv[1].val.str); + if (prop_scope_add(&ctx, first, 1) == 0) { + RND_ACT_CONVARG(2, FGW_STR, proptoggle, name = argv[2].val.str); + RND_ACT_MAY_CONVARG(3, FGW_STR, proptoggle, create = argv[3].val.str); + } + else { + name = first; + RND_ACT_MAY_CONVARG(2, FGW_STR, proptoggle, create = argv[2].val.str); + ctx.use_selection = 1; + } + + RND_ACT_IRES(csch_propsel_toggle(&ctx, name, rnd_istrue(create))); + + prop_scope_finish(&ctx); + csch_props_uninit(&ctx); + return 0; +} + + +static const char csch_acts_propget[] = "propget([scope], name, [stattype])"; +static const char csch_acth_propget[] = "Return the named property of scope or all selected objects to/by value. Scope is documented at PropEdit()."; +fgw_error_t csch_act_propget(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_design_t *hl = RND_ACT_DESIGN; + csch_sheet_t *sheet = (csch_sheet_t *)hl; + const char *first, *name, *stty = "common"; + csch_props_t *p; + csch_propval_t *out, most_common, min, max, avg; + htprop_entry_t *e; + int r; + csch_propedit_t ctx; + minuid_str_t utmp; + + csch_props_init(&ctx, sheet, &sheet->direct); + + RND_ACT_CONVARG(1, FGW_STR, propget, first = argv[1].val.str); + if (strcmp(first, "objbin") == 0) { + fgw_arg_conv(&rnd_fgw, &argv[2], (FGW_PTR | FGW_STRUCT)); + if (!fgw_ptr_in_domain(&rnd_fgw, &argv[2], CSCH_PTR_DOMAIN_COBJ)) { + rnd_message(RND_MSG_ERROR, "propget: objbin arg is not a pointer to a concrete model object\n"); + return FGW_ERR_ARG_CONV; + } + prop_scope_add_obj(&ctx, argv[2].val.ptr_void); + RND_ACT_CONVARG(3, FGW_STR, propset, name = argv[3].val.str); + } + else if (prop_scope_add(&ctx, first, 1) == 0) { + RND_ACT_CONVARG(2, FGW_STR, propget, name = argv[2].val.str); + RND_ACT_MAY_CONVARG(3, FGW_STR, propget, stty = argv[3].val.str); + } + else { + name = first; + ctx.use_selection = 1; + RND_ACT_CONVARG(2, FGW_STR, propget, stty = argv[2].val.str); + } + + ctx.geo = 1; + csch_propsel_map_core(&ctx); + + p = htsp_get(&ctx.props, name); + if (p == NULL) + goto error; + + if (p->type == CSCH_PROPT_STRING) + r = csch_props_stat(&ctx, p, &most_common, NULL, NULL, NULL); + else + r = csch_props_stat(&ctx, p, &most_common, &min, &max, &avg); + + if (r != 0) + goto error; + + if (strcmp(stty, "common") == 0) out = &most_common; + else if (strcmp(stty, "min") == 0) out = &min; + else if (strcmp(stty, "max") == 0) out = &max; + else if (strcmp(stty, "avg") == 0) out = &avg; + else goto error; + + switch(p->type) { + case CSCH_PROPT_STRING: + if (out != &most_common) + goto error; + + /* get the first one for now */ + e = htprop_first(&p->values); + most_common = e->key; + res->type = FGW_STR | FGW_DYN; + res->val.str = rnd_strdup(out->string == NULL ? "" : out->string); + break; + case CSCH_PROPT_COMMS: res->type = FGW_STR | FGW_DYN; res->val.str = rnd_strdup(out->comms.str); break; + case CSCH_PROPT_COORD: res->type = FGW_LONG; res->val.nat_long = out->coord; break; + case CSCH_PROPT_ANGLE: res->type = FGW_DOUBLE; res->val.nat_double = out->angle; break; + case CSCH_PROPT_DOUBLE: res->type = FGW_DOUBLE; res->val.nat_double = out->d; break; + case CSCH_PROPT_BOOL: + case CSCH_PROPT_ENUM: + case CSCH_PROPT_INT: res->type = FGW_INT; res->val.nat_int = out->i; break; + case CSCH_PROPT_UUID: minuid_bin2str(utmp, out->u); res->type = FGW_STR | FGW_DYN; res->val.str = rnd_strdup(utmp); break; + + case CSCH_PROPT_ATTRARR: + case CSCH_PROPT_invalid: + case CSCH_PROPT_max: goto error; + } + prop_scope_finish(&ctx); + csch_props_uninit(&ctx); + return 0; + + error:; + prop_scope_finish(&ctx); + csch_props_uninit(&ctx); + return FGW_ERR_ARG_CONV; +} + +static const char csch_acts_propprint[] = "PropPrint([scope])"; +static const char csch_acth_propprint[] = "Print a property map of objects matching the scope. Scope is documented at PropEdit()."; +fgw_error_t csch_act_propprint(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_design_t *hl = RND_ACT_DESIGN; + csch_sheet_t *sheet = (csch_sheet_t *)hl; + const char *scope = NULL; + htsp_entry_t *e, *sorted; + csch_propedit_t ctx; + + csch_props_init(&ctx, sheet, &sheet->direct); + + RND_ACT_MAY_CONVARG(1, FGW_STR, propprint, scope = argv[1].val.str); + if (scope != NULL) { + if (prop_scope_add(&ctx, scope, 0) != 0) + return FGW_ERR_ARG_CONV; + } + else + ctx.use_selection = 1; + + csch_propsel_map_core(&ctx); + sorted = csch_props_sort(&ctx); + for(e = sorted; e->key != NULL; e++) { + csch_props_t *p = e->value; + csch_propval_t com, min, max, avg; + minuid_str_t utmp; + + printf("%s\n", e->key); + if (p->type == CSCH_PROPT_STRING) + csch_props_stat(&ctx, p, &com, NULL, NULL, NULL); + else + csch_props_stat(&ctx, p, &com, &min, &max, &avg); + switch(p->type) { + case CSCH_PROPT_STRING: printf(" common='%s'\n", com.string); break; + case CSCH_PROPT_COMMS: printf(" common='%s'\n", com.comms.str); break; + case CSCH_PROPT_COORD: + rnd_printf(" common='%$$rc'\n", com.coord); + rnd_printf(" min/avg/max=%$$rc/%$$rc/%$$rc\n", min.coord, avg.coord, max.coord); + break; + case CSCH_PROPT_ANGLE: + rnd_printf(" common='%f'\n", com.angle); + rnd_printf(" min/avg/max=%f/%f/%f\n", min.angle, avg.angle, max.angle); + break; + case CSCH_PROPT_DOUBLE: + rnd_printf(" common='%f'\n", com.d); + rnd_printf(" min/avg/max=%f/%f/%f\n", min.d, avg.d, max.d); + break; + case CSCH_PROPT_INT: + case CSCH_PROPT_BOOL: + case CSCH_PROPT_ENUM: + rnd_printf(" common='%d'\n", com.i); + rnd_printf(" min/avg/max=%d/%d/%d\n", min.i, avg.i, max.i); + break; + case CSCH_PROPT_UUID: + minuid_bin2str(utmp, com.u); + rnd_printf(" common=%s\n", utmp); + break; + case CSCH_PROPT_ATTRARR: + case CSCH_PROPT_invalid: + case CSCH_PROPT_max: + break; + } + } + free(sorted); + + prop_scope_finish(&ctx); + csch_props_uninit(&ctx); + RND_ACT_IRES(0); + return 0; +} + + +static rnd_action_t sch_propedit_action_list[] = { + {"propedit", csch_act_propedit, csch_acth_propedit, csch_acts_propedit}, + {"propprint", csch_act_propprint, csch_acth_propprint, csch_acts_propprint}, + {"propset", csch_act_propset, csch_acth_propset, csch_acts_propset}, + {"proptoggle", csch_act_proptoggle, csch_acth_proptoggle, csch_acts_proptoggle}, + {"propget", csch_act_propget, csch_acth_propget, csch_acts_propget} +}; + + +int pplg_check_ver_propedit(int ver_needed) { return 0; } + +void pplg_uninit_propedit(void) +{ + csch_propdlg_uninit(); + rnd_remove_actions_by_cookie(csch_propedit_cookie); +} + +int pplg_init_propedit(void) +{ + RND_API_CHK_VER; + + RND_REGISTER_ACTIONS(sch_propedit_action_list, csch_propedit_cookie); + csch_propdlg_init(); + return 0; +} + Index: tags/1.0.5/src/plugins/propedit/propedit.pup =================================================================== --- tags/1.0.5/src/plugins/propedit/propedit.pup (nonexistent) +++ tags/1.0.5/src/plugins/propedit/propedit.pup (revision 10414) @@ -0,0 +1,7 @@ +$class feature +$short object property editor +$long List and edit properties of a group of objects. +$state works +$package (core) +default buildin +autoload 1 Index: tags/1.0.5/src/plugins/propedit/props.c =================================================================== --- tags/1.0.5/src/plugins/propedit/props.c (nonexistent) +++ tags/1.0.5/src/plugins/propedit/props.c (revision 10414) @@ -0,0 +1,306 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - property editor plugin + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * (Adapted from propsel code in pcb-rnd by the same author) + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include +#include "props.h" +/*#include "propsel.h"*/ +#include +#include +#include +#include +#define HT(x) htprop_ ## x +#include +#undef HT + +/* Type names in text */ +static const char *type_names[] = { "invalid", "string", "coord", "angle", "double", "int" }; + +/* A hash function for each known type */ +static unsigned int prophash_coord(csch_propval_t key) { return longhash(key.coord); } +static unsigned int prophash_angle(csch_propval_t key) { return longhash(key.angle); } +static unsigned int prophash_double(csch_propval_t key) { return longhash(key.d); } +static unsigned int prophash_int(csch_propval_t key) { return longhash(key.i); } +static unsigned int prophash_bool(csch_propval_t key) { return longhash(key.i); } +static unsigned int prophash_comms(csch_propval_t key) { return key.comms.str == NULL ? 0 : strhash(key.comms.str); } +static unsigned int prophash_string(csch_propval_t key) { return key.string == NULL ? 0 : strhash(key.string); } +static unsigned int prophash_enum(csch_propval_t key) { return longhash(key.i); } +static unsigned int prophash_attrarr(csch_propval_t key){ return longhash(key.i); } +static unsigned int prophash_uuid(csch_propval_t key) { return murmurhash(key.u, sizeof(key.u)); } + + +typedef unsigned int (*prophash_ft)(csch_propval_t key); +static prophash_ft prophash[CSCH_PROPT_max] = { + NULL, prophash_string, prophash_coord, prophash_angle, prophash_double, prophash_int, prophash_bool, prophash_comms, prophash_enum, prophash_attrarr, prophash_uuid +}; + +/* A keyeq function for each known type */ +static int propkeyeq_coord(csch_propval_t a, csch_propval_t b) { return a.coord == b.coord; } +static int propkeyeq_angle(csch_propval_t a, csch_propval_t b) { return a.angle == b.angle; } +static int propkeyeq_double(csch_propval_t a, csch_propval_t b) { return a.d == b.d; } +static int propkeyeq_int(csch_propval_t a, csch_propval_t b) { return a.i == b.i; } +static int propkeyeq_bool(csch_propval_t a, csch_propval_t b) { return a.i == b.i; } +static int propkeyeq_comms(csch_propval_t a, csch_propval_t b) { return a.comms.str == b.comms.str; } +static int propkeyeq_string(csch_propval_t a, csch_propval_t b) +{ + if ((b.string == NULL) && (a.string == NULL)) + return 1; + if ((b.string == NULL) || (a.string == NULL)) + return 0; + return (strcmp(a.string, b.string) == 0); +} +static int propkeyeq_enum(csch_propval_t a, csch_propval_t b) { return a.i == b.i; } +static int propkeyeq_attrarr(csch_propval_t a, csch_propval_t b) { return a.i == b.i; } +static int propkeyeq_uuid(csch_propval_t a, csch_propval_t b) { return minuid_cmp(a.u, b.u) == 0; } + + +typedef int (*propkeyeq_ft)(csch_propval_t a, csch_propval_t b); +static propkeyeq_ft propkeyeq[CSCH_PROPT_max] = { + NULL, propkeyeq_string, propkeyeq_coord, propkeyeq_angle, propkeyeq_double, propkeyeq_int, propkeyeq_bool, propkeyeq_comms, propkeyeq_enum, propkeyeq_attrarr, propkeyeq_uuid +}; + + +/* Init & uninit */ +void csch_props_init(csch_propedit_t *ctx, csch_sheet_t *sheet, csch_cgrp_t *grp) +{ + memset(ctx, 0, sizeof(csch_propedit_t)); + htsp_init(&ctx->props, strhash, strkeyeq); + ctx->sheet = sheet; + ctx->grp = grp == NULL ? &sheet->direct : grp; +} + +void csch_props_reset(csch_propedit_t *ctx) +{ + htsp_entry_t *e; + for(e = htsp_first(&ctx->props); e != NULL; e = htsp_next(&ctx->props, e)) { + csch_props_t *p = e->value; + htprop_clear(&p->values); + } +} + + +void csch_props_clear(csch_propedit_t *ctx) +{ + htsp_entry_t *e; + for(e = htsp_first(&ctx->props); e != NULL; e = htsp_next(&ctx->props, e)) { + csch_props_t *p = e->value; + htprop_uninit(&p->values); + free(p); + free(e->key); + } + htsp_clear(&ctx->props); +} + + +void csch_props_uninit(csch_propedit_t *ctx) +{ + csch_props_clear(ctx); + TODO("clear the vectors") + memset(ctx, 0, sizeof(csch_propedit_t)); +} + +/* Retrieve values for a prop */ +csch_props_t *csch_props_get(csch_propedit_t *ctx, const char *propname) +{ + if (propname == NULL) + return NULL; + return htsp_get(&ctx->props, propname); +} + +/* Store a new value */ +csch_props_t *csch_props_add(csch_propedit_t *ctx, const char *propname, csch_prop_type_t type, csch_propval_t val) +{ + csch_props_t *p; + htprop_entry_t *e; + + if ((type <= CSCH_PROPT_invalid) || (type >= CSCH_PROPT_max)) + return NULL; + + /* look up or create the value list (p) associated with the property name */ + p = htsp_get(&ctx->props, propname); + if (p == NULL) { + p = malloc(sizeof(csch_props_t)); + p->type = type; + p->comms_type = CSCH_PROPCT_STRING; + p->enum_names = NULL; + htprop_init(&p->values, prophash[type], propkeyeq[type]); + htsp_set(&ctx->props, rnd_strdup(propname), p); + } + else { + if (type != p->type) + return NULL; + } + + /* Check if we already have this value */ + e = htprop_getentry(&p->values, val); + if (e == NULL) + htprop_set(&p->values, val, 1); + else + e->value++; + + return p; +} + + +const char *csch_props_type_name(csch_prop_type_t type) +{ + if (((int)type < 0) || (type >= CSCH_PROPT_max)) + return NULL; + + return type_names[type]; +} + +#define STAT(val, field, cnt) \ +do { \ + if (val.field < minp.field) minp = val; \ + if (val.field > maxp.field) maxp = val; \ + avgp.field += val.field * cnt; \ +} while(0) + +int csch_props_stat(csch_propedit_t *ctx, csch_props_t *p, csch_propval_t *most_common, csch_propval_t *min, csch_propval_t *max, csch_propval_t *avg) +{ + htprop_entry_t *e; + csch_propval_t bestp, minp, maxp, avgp; + unsigned long best = 0, num_vals = 0; + + if (most_common != NULL) { + most_common->string = NULL; + most_common->comms.str = NULL; + } + if (min != NULL) { + min->string = NULL; + min->comms.str = NULL; + } + if (max != NULL) { + max->string = NULL; + max->comms.str = NULL; + } + if (avg != NULL) { + avg->string = NULL; + avg->comms.str = NULL; + } + + if ((min != NULL) || (max != NULL) || (avg != NULL)) { + if (p->type == CSCH_PROPT_STRING) + return -1; + if (p->type == CSCH_PROPT_COMMS) + return -1; + if (p->type == CSCH_PROPT_UUID) + return -1; + if (p->type == CSCH_PROPT_ENUM) + return -1; + } + + /* set up internal avg, min, max */ + memset(&avgp, 0, sizeof(avgp)); + switch(p->type) { + case CSCH_PROPT_invalid: break; + case CSCH_PROPT_max: break; + case CSCH_PROPT_STRING: break; + case CSCH_PROPT_COORD: minp.coord = RND_COORD_MAX; maxp.coord = -minp.coord; break; + case CSCH_PROPT_ANGLE: minp.angle = 100000; maxp.angle = -minp.angle; break; + case CSCH_PROPT_DOUBLE: minp.d = 100000; maxp.d = -minp.d; break; + case CSCH_PROPT_INT: minp.i = INT_MAX; maxp.i = -minp.i; break; + case CSCH_PROPT_BOOL: minp.i = 1; maxp.i = 0; break; + case CSCH_PROPT_COMMS: break; + case CSCH_PROPT_UUID: break; + case CSCH_PROPT_ENUM: break; + case CSCH_PROPT_ATTRARR:break; + } + + /* walk through all known values */ + for (e = htprop_first(&p->values); e; e = htprop_next(&p->values, e)) { + if (e->value > best) { + best = e->value; + bestp = e->key; + } + num_vals += e->value; + switch(p->type) { + case CSCH_PROPT_invalid: break; + case CSCH_PROPT_max: break; + case CSCH_PROPT_STRING: break; + case CSCH_PROPT_COORD: STAT(e->key, coord, e->value); break; + case CSCH_PROPT_ANGLE: STAT(e->key, angle, e->value); break; + case CSCH_PROPT_DOUBLE: STAT(e->key, d, e->value); break; + case CSCH_PROPT_INT: STAT(e->key, i, e->value); break; + case CSCH_PROPT_BOOL: STAT(e->key, i, e->value); break; + case CSCH_PROPT_COMMS: break; + case CSCH_PROPT_UUID: break; + case CSCH_PROPT_ENUM: break; + case CSCH_PROPT_ATTRARR:break; + } + } + + /* generate the result */ + if (num_vals != 0) { + switch(p->type) { + case CSCH_PROPT_invalid: break; + case CSCH_PROPT_max: break; + case CSCH_PROPT_STRING: break; + case CSCH_PROPT_COORD: avgp.coord = avgp.coord/num_vals; break; + case CSCH_PROPT_ANGLE: avgp.angle = avgp.angle/num_vals; break; + case CSCH_PROPT_DOUBLE: avgp.angle = avgp.d/num_vals; break; + case CSCH_PROPT_INT: avgp.i = avgp.i/num_vals; break; + case CSCH_PROPT_BOOL: avgp.i = avgp.i * 100/num_vals; break; + case CSCH_PROPT_COMMS: break; + case CSCH_PROPT_UUID: break; + case CSCH_PROPT_ENUM: break; + case CSCH_PROPT_ATTRARR:break; + } + if (avg != NULL) *avg = avgp; + if (min != NULL) *min = minp; + if (max != NULL) *max = maxp; + if (most_common != NULL) *most_common = bestp; + } + return 0; +} + +int prop_cmp(const void *e1_, const void *e2_) +{ + const htsp_entry_t *e1 = e1_, *e2 = e2_; + if (e1->key[0] != e2->key[0]) /* special exception: list p/ first then a/ */ + return e1->key[0] < e2->key[0] ? 1 : -1; + return strcmp(e1->key, e2->key) > 0 ? 1 : -1; +} + +htsp_entry_t *csch_props_sort(csch_propedit_t *ctx) +{ + htsp_entry_t *e, *arr = malloc(sizeof(htsp_entry_t) * (ctx->props.used + 1)); + int n; + + for(e = htsp_first(&ctx->props), n = 0; e != NULL; e = htsp_next(&ctx->props, e), n++) + arr[n] = *e; + + qsort(arr, n, sizeof(htsp_entry_t), prop_cmp); + + arr[ctx->props.used].key = NULL; + return arr; +} + + +#undef STAT Index: tags/1.0.5/src/plugins/propedit/props.h =================================================================== --- tags/1.0.5/src/plugins/propedit/props.h (nonexistent) +++ tags/1.0.5/src/plugins/propedit/props.h (revision 10414) @@ -0,0 +1,149 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - property editor plugin + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * (Adapted from propsel code in pcb-rnd by the same author) + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/* This API builds and maintains a collection of values for each named property. + A value can be added any time. All values ever seen for a property is stored. + Duplicate values per property are stored only once, but number of occurence + per value (per property) is kept track on. Typically at the end of + a query, but generally ny time, the caller may query for: + - all known properties (it's a htsp) + - all known values of a property + - statistics of values of a property +*/ + +#include +#include +#include +#include +#include +#include + +typedef enum { + CSCH_PROPT_invalid, + CSCH_PROPT_STRING, + CSCH_PROPT_COORD, + CSCH_PROPT_ANGLE, + CSCH_PROPT_DOUBLE, + CSCH_PROPT_INT, + CSCH_PROPT_BOOL, + CSCH_PROPT_COMMS, + CSCH_PROPT_ENUM, + CSCH_PROPT_ATTRARR, + CSCH_PROPT_UUID, + CSCH_PROPT_max +} csch_prop_type_t; + +typedef enum { + CSCH_PROPCT_STRING = 0, /* default */ + CSCH_PROPCT_PEN +} csch_prop_comms_type_t; + +typedef union { + const char *string; + csch_coord_t coord; + rnd_angle_t angle; + int i; + double d; + csch_comm_str_t comms; + int attrarr; + minuid_bin_t u; +} csch_propval_t; + +typedef csch_propval_t htprop_key_t; +typedef unsigned long int htprop_value_t; +#define HT(x) htprop_ ## x +#include +#undef HT + +typedef struct { + csch_prop_type_t type; + csch_prop_comms_type_t comms_type; /* when type == CSCH_PROPT_COMMS: determine input method */ + const char **enum_names; + htprop_t values; + unsigned core:1; /* 1 if it is a core property */ +} csch_props_t; + +typedef struct { + htsp_t props; + + /* scope */ + csch_sheet_t *sheet; + csch_cgrp_t *grp; + htsp_t nets; + + /* target objects */ + csch_oidpath_list_t objs; + unsigned use_selection:1; /* all selected objects on the current pcb */ + unsigned use_sheet:1; /* run on the board too */ + unsigned geo:1; /* include fields related to geometry of objects */ +} csch_propedit_t; + +/* A property list (props) is a string->csch_props_t. Each entry is a named + property with a value that's a type and a value hash (vhash). vhash's + key is each value that the property ever took, and vhash's value is an + integer value of how many times the given property is taken */ +void csch_props_init(csch_propedit_t *ctx, csch_sheet_t *sheet, csch_cgrp_t *grp); +void csch_props_uninit(csch_propedit_t *ctx); + + +/* Reset stored values from the hash (ctx->props) */ +void csch_props_reset(csch_propedit_t *ctx); + +/* Free and remove all items from the hash (ctx->props) */ +void csch_props_clear(csch_propedit_t *ctx); + +/* Add a value of a named property; if the value is already known, its counter + is increased. If propname didn't exist, create it. Returns NULL on error. + Error conditions: + - invalid type + - mismatching type for the property (all values of a given property must be the same) +*/ +csch_props_t *csch_props_add(csch_propedit_t *ctx, const char *propname, csch_prop_type_t type, csch_propval_t val); + +/* Retrieve values for a prop - returns NULL if propname doesn't exist */ +csch_props_t *csch_props_get(csch_propedit_t *ctx, const char *propname); + + +/* Return the type name of a property type or NULL on error. */ +const char *csch_props_type_name(csch_prop_type_t type); + +/* Look up property p and calculate statistics for all values occured so far. + Any of most_common, min, max and avg can be NULL. Returns non-zero if propname + doesn't exist or stat values that can not be calculated for the given type + are not NULL. Invalid type/stat combinations: + type=string min, max, avg +*/ +int csch_props_stat(csch_propedit_t *ctx, csch_props_t *p, csch_propval_t *most_common, csch_propval_t *min, csch_propval_t *max, csch_propval_t *avg); + +/* Return a key=NULL terminated array of all entries from the hash, alphabetically sorted */ +htsp_entry_t *csch_props_sort(csch_propedit_t *ctx); + +/* If propedit context is for a single object, return that object, else + return NULL */ +csch_oidpath_t *prop_scope_single_obj(csch_propedit_t *pe); Index: tags/1.0.5/src/plugins/propedit/propsel.c =================================================================== --- tags/1.0.5/src/plugins/propedit/propsel.c (nonexistent) +++ tags/1.0.5/src/plugins/propedit/propsel.c (revision 10414) @@ -0,0 +1,914 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - property editor plugin + * Copyright (C) 2022, 2023 Tibor 'Igor2' Palinkas + * (Adapted from propsel code in pcb-rnd by the same author) + * + * (Supported by NLnet NGI0 PET Fund in 2022 and Entrust in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "props.h" +#include "propsel.h" + +/*********** map ***********/ +#define type2field_String string +#define type2field_csch_coord_t coord +#define type2field_g2d_angle_t angle +#define type2field_double d +#define type2field_int i +#define type2field_bool i +#define type2field_comms comms +#define type2field_pen comms +#define type2field_enum i +#define type2field_Attrarr attrarr +#define type2field_uuid u + + +#define type2TYPE_String CSCH_PROPT_STRING +#define type2TYPE_csch_coord_t CSCH_PROPT_COORD +#define type2TYPE_g2d_angle_t CSCH_PROPT_ANGLE +#define type2TYPE_double CSCH_PROPT_DOUBLE +#define type2TYPE_int CSCH_PROPT_INT +#define type2TYPE_bool CSCH_PROPT_BOOL +#define type2TYPE_comms CSCH_PROPT_COMMS +#define type2TYPE_enum CSCH_PROPT_ENUM +#define type2TYPE_pen CSCH_PROPT_COMMS +#define type2TYPE_Attrarr CSCH_PROPT_ATTRARR +#define type2TYPE_uuid CSCH_PROPT_UUID + + +#define map_add_prop_exec(ctx, name, type, val, exec) \ +do { \ + csch_propval_t v; \ + csch_props_t *prp; \ + const char *stype = #type; \ + v.type2field_ ## type = (val); \ + prp = csch_props_add(ctx, name, type2TYPE_ ## type, v); \ + if ((stype[0] == 'p') && (stype[1] == 'e') && (stype[2] == 'n')) \ + prp->comms_type = CSCH_PROPCT_PEN; \ + exec; \ +} while(0) + +#define map_add_prop_exec_memcpy(ctx, name, type, val, exec) \ +do { \ + csch_propval_t v; \ + csch_props_t *prp; \ + const char *stype = #type; \ + memcpy(v.type2field_ ## type, (val), sizeof(v.type2field_ ## type)); \ + prp = csch_props_add(ctx, name, type2TYPE_ ## type, v); \ + (void)stype; \ + (void)prp; \ + exec; \ +} while(0) + +#define map_add_prop(ctx, name, type, val) map_add_prop_exec(ctx, name, type, val, ;) +#define map_add_prop_memcpy(ctx, name, type, val) map_add_prop_exec_memcpy(ctx, name, type, val, ;) + +static void map_attr(void *ctx, htsp_t *attrs) +{ + int bl = 0; + char small[256]; + char *big = NULL; + htsp_entry_t *e; + + small[0] = 'a'; + small[1] = '/'; + + for(e = htsp_first(attrs); e != NULL; e = htsp_next(attrs, e)) { + int len = strlen(e->key); + char *nm; + const char *valstr; + csch_attrib_t *av = e->value; + + if (len >= sizeof(small)-3) { + if (len > bl) { + bl = len + 128; + if (big != NULL) + free(big); + big = malloc(bl); + big[0] = 'a'; + big[1] = '/'; + } + nm = big; + } + else + nm = small; + strcpy(nm+2, e->key); + + if (av->val != NULL) { + valstr = av->val; + map_add_prop(ctx, nm, String, valstr); + } + else + map_add_prop(ctx, nm, Attrarr, 0); + + } + if (big != NULL) + free(big); +} + +static void map_grp(csch_propedit_t *ctx, csch_cgrp_t *grp, int nogeo); + +static void map_sheet(csch_propedit_t *ctx, csch_sheet_t *sheet) +{ + map_add_prop(ctx, "p/sheet/loadname", String, sheet->hidlib.loadname); + map_add_prop(ctx, "p/sheet/filename", String, sheet->hidlib.fullpath); + map_add_prop(ctx, "p/sheet/loose_sym", bool, sheet->loose_sym); + map_attr(ctx, &sheet->direct.attr); + if (sheet->is_symbol) + map_grp(ctx, &sheet->direct, 1); +} + +/* Common properties as per {des3:81} and some extras */ +static void map_common_properites(csch_propedit_t *ctx, csch_chdr_t *obj) +{ + map_add_prop(ctx, "p/lock", bool, obj->lock); + map_add_prop(ctx, "p/floater", bool, obj->floater); + + /* extras */ + if (ctx->geo) { + map_add_prop(ctx, "p/bbox/x1", csch_coord_t, obj->bbox.x1); + map_add_prop(ctx, "p/bbox/y1", csch_coord_t, obj->bbox.y1); + map_add_prop(ctx, "p/bbox/x2", csch_coord_t, obj->bbox.x2); + map_add_prop(ctx, "p/bbox/y2", csch_coord_t, obj->bbox.y2); + map_add_prop(ctx, "p/bbox/cx", csch_coord_t, rnd_round((obj->bbox.x1 + obj->bbox.x2)/2.0)); + map_add_prop(ctx, "p/bbox/cy", csch_coord_t, rnd_round((obj->bbox.y1 + obj->bbox.y2)/2.0)); + } +} + +static void map_line(csch_propedit_t *ctx, csch_line_t *line) +{ + map_common_properites(ctx, &line->hdr); + map_add_prop(ctx, "p/stroke", pen, line->hdr.stroke_name); + if (ctx->geo) { + map_add_prop(ctx, "p/line/x1", csch_coord_t, line->spec.p1.x); + map_add_prop(ctx, "p/line/y1", csch_coord_t, line->spec.p1.y); + map_add_prop(ctx, "p/line/x2", csch_coord_t, line->spec.p2.x); + map_add_prop(ctx, "p/line/y2", csch_coord_t, line->spec.p2.y); + } +} + +static void map_arc(csch_propedit_t *ctx, csch_arc_t *arc) +{ + map_common_properites(ctx, &arc->hdr); + map_add_prop(ctx, "p/stroke", pen, arc->hdr.stroke_name); + map_add_prop(ctx, "p/arc/r", csch_coord_t, arc->spec.r); + map_add_prop(ctx, "p/arc/start", double, arc->spec.start * RND_RAD_TO_DEG); + map_add_prop(ctx, "p/arc/delta", double, arc->spec.delta * RND_RAD_TO_DEG); + if (ctx->geo) { + map_add_prop(ctx, "p/arc/cx", csch_coord_t, arc->spec.c.x); + map_add_prop(ctx, "p/arc/cy", csch_coord_t, arc->spec.c.y); + } +} + +static void map_bitmap(csch_propedit_t *ctx, csch_cbitmap_t *bitmap) +{ + map_common_properites(ctx, &bitmap->hdr); + TODO("bitmap: implement"); +} + +static void map_text(csch_propedit_t *ctx, csch_text_t *text) +{ + map_common_properites(ctx, &text->hdr); + map_add_prop(ctx, "p/stroke", pen, text->hdr.stroke_name); + map_add_prop(ctx, "p/text/rot", double, text->spec_rot); + map_add_prop(ctx, "p/text/mirx", bool, text->spec_mirx); + map_add_prop(ctx, "p/text/miry", bool, text->spec_miry); + map_add_prop_exec(ctx, "p/text/halign", enum, text->halign, prp->enum_names = csch_halign_names); + map_add_prop(ctx, "p/text/text", String, text->text); + map_add_prop(ctx, "p/text/dyntext", bool, text->dyntext); + map_add_prop(ctx, "p/text/has_bbox", bool, text->has_bbox); + if (ctx->geo) { + map_add_prop(ctx, "p/text/inst/rot", double, text->inst_rot); + map_add_prop(ctx, "p/text/inst/mirx", bool, text->inst_mirx); + map_add_prop(ctx, "p/text/inst/miry", bool, text->inst_miry); + map_add_prop(ctx, "p/text/x1", csch_coord_t, text->spec1.x); + map_add_prop(ctx, "p/text/y1", csch_coord_t, text->spec1.y); + map_add_prop(ctx, "p/text/x2", csch_coord_t, text->spec2.x); + map_add_prop(ctx, "p/text/y2", csch_coord_t, text->spec2.y); + } +} + +static void map_poly(csch_propedit_t *ctx, csch_cpoly_t *poly) +{ + map_common_properites(ctx, &poly->hdr); + map_add_prop(ctx, "p/stroke", pen, poly->hdr.stroke_name); + map_add_prop(ctx, "p/has_stroke", bool, poly->has_stroke); + map_add_prop(ctx, "p/fill", pen, poly->hdr.fill_name); + map_add_prop(ctx, "p/has_fill", bool, poly->has_fill); +} + +static void map_grp(csch_propedit_t *ctx, csch_cgrp_t *grp, int nogeo) +{ + map_attr(ctx, &grp->attr); + +TODO("recurse"); + + map_common_properites(ctx, &grp->hdr); + map_add_prop_memcpy(ctx, "p/grp/uuid", uuid, grp->uuid); + + if (grp->hdr.type == CSCH_CTYPE_GRP) + map_add_prop_memcpy(ctx, "p/grp/src_uuid", uuid, grp->data.grp.src_uuid); + + if (nogeo) + return; + + map_add_prop(ctx, "p/grp/rot", double, grp->spec_rot); + map_add_prop(ctx, "p/grp/mirx", bool, grp->mirx); + map_add_prop(ctx, "p/grp/miry", bool, grp->miry); + if (ctx->geo) { + map_add_prop(ctx, "p/grp/x", csch_coord_t, grp->x); + map_add_prop(ctx, "p/grp/y", csch_coord_t, grp->y); + } + +} + +static long csch_propsel_do(csch_sheet_t *sheet, csch_cgrp_t *grp, int data_in_grp, void *ctx, long (*cb)(void *ctx, csch_chdr_t *hdr, const void *udata), const void *udata) +{ + htip_entry_t *e; + long res = 0; + + for(e = htip_first(&grp->id2obj); e != NULL; e = htip_next(&grp->id2obj, e)) { + csch_chdr_t *h = e->value; + if (data_in_grp) { + TODO("rethink this: propset() should work on objects under group lock; example Erich's case on removing all pin numbers require to change them to floater so they can be removed; pcb-rnd also allows propset() to bypass group lock; pool node with the script: sch-rnd remove_pinnum") +#if 0 + if (floater_or_parent_group_atomic?(h)) + continue; /* grp lock: skip any selected object within a grp */ +#endif + } + + if (csch_obj_is_grp(h)) { + csch_cgrp_t *grp = (csch_cgrp_t *)h; + res += csch_propsel_do(sheet, grp, 1, ctx, cb, udata); /* recurse to groups */ + } + + if (h->selected) + res += cb(ctx, h, udata); + } + + return res; +} + +static long map_any(void *ctx_, csch_chdr_t *h, const void *udata) +{ + csch_propedit_t *ctx = ctx_; + if (h == NULL) + return 0; + switch(h->type) { + case CSCH_CTYPE_ARC: map_arc(ctx, (csch_arc_t *)h); break; + case CSCH_CTYPE_BITMAP: map_bitmap(ctx, (csch_cbitmap_t *)h); break; + case CSCH_CTYPE_LINE: map_line(ctx, (csch_line_t *)h); break; + case CSCH_CTYPE_POLY: map_poly(ctx, (csch_cpoly_t *)h); break; + case CSCH_CTYPE_TEXT: map_text(ctx, (csch_text_t *)h); break; + case CSCH_CTYPE_GRP_REF: + case CSCH_CTYPE_GRP: map_grp(ctx, (csch_cgrp_t *)h, 0); break; + default: return 0; + } + return 1; +} + +void csch_propsel_map_core(csch_propedit_t *ctx) +{ + csch_oidpath_t *idp; + + for(idp = csch_oidpath_list_first(&ctx->objs); idp != NULL; idp = csch_oidpath_list_next(idp)) + map_any(ctx, csch_oidpath_resolve(ctx->sheet, idp), NULL); + + if (ctx->use_selection) + csch_propsel_do(ctx->sheet, ctx->grp, 0, ctx, map_any, NULL); + + if (ctx->use_sheet) + map_sheet(ctx, ctx->sheet); +} + +/*******************/ + + +static csch_source_arg_t *propsel_src(void) +{ + return csch_attrib_src_c(NULL, 0, 0, "propsel user input"); +} + +static void toggle_attr(csch_propset_ctx_t *st, csch_cgrp_t *grp) +{ + const char *newval, *key = st->name+2; + const char *orig = csch_attrib_get_str(&grp->attr, key); + + if (orig == NULL) { + if (st->toggle_create) { + newval = "true"; + goto do_set; + } + /* else do not create non-existing attributes */ + return; + } + if (rnd_istrue(orig)) { + newval = "false"; + goto do_set; + } + else if (rnd_isfalse(orig)) { + newval = "true"; + goto do_set; + } + return; + + do_set:; + csch_attr_modify_str(st->sheet, grp, CSCH_ATP_USER_DEFAULT, key, newval, propsel_src(), 1); + st->set_cnt++; +} + +static void set_attr_obj(csch_propset_ctx_t *st, csch_chdr_t *hdr) +{ + const char *key = st->name+2; + const char *orig; + csch_attrib_t *orig_a; + csch_cgrp_t *grp = (csch_cgrp_t *)hdr; + + assert(csch_obj_is_grp(hdr)); + + if (st->toggle) { + toggle_attr(st, grp); + return; + } + + orig_a = csch_attrib_get(&grp->attr, key); + if ((orig_a == NULL) || orig_a->deleted) + orig = NULL; + else + orig = orig_a->val; + + if (st->arename) { + if ((orig_a == NULL) || (strcmp(key, st->s) == 0)) + return; + } + else { + if ((orig != NULL) && (strcmp(orig, st->s) == 0)) + return; + } + + + if (st->arename) + csch_attr_modify_rename(st->sheet, grp, orig_a, st->s, propsel_src(), 1); + else + csch_attr_modify_str(st->sheet, grp, CSCH_ATP_USER_DEFAULT, key, st->s, propsel_src(), 1); + st->set_cnt++; +} + +#define DONE { st->set_cnt++; uundo_restore_serial(&st->sheet->undo); return; } +#define DONE0 { st->set_cnt++; uundo_restore_serial(&st->sheet->undo); return 0; } +#define DONE1 { st->set_cnt++; uundo_restore_serial(&st->sheet->undo); return 1; } + +static void set_grp(csch_propset_ctx_t *st, csch_cgrp_t *grp); + +static void set_sheet(csch_propset_ctx_t *st, csch_sheet_t *sheet) +{ + if (st->is_attr) { + set_attr_obj(st, &sheet->direct.hdr); + return; + } + + + if (strncmp(st->name, "p/sheet/", 8) == 0) { + const char *pn = st->name + 8; + + if (strcmp(pn, "loose_sym") == 0) { + if (st->toggle) + st->sheet->loose_sym = !st->sheet->loose_sym; + else + st->sheet->loose_sym = st->c; + DONE; + } + + if (st->toggle) + return; /* can't toggle anything else */ + +TODO("sheet prop set"); +#if 0 + + if ((strcmp(pn, "loadname") == 0) && + (csch_board_change_name(rnd_strdup(st->s)))) DONE; + + if ((strcmp(pn, "filename") == 0)) { + free(pcb->hidlib.fullpath); + pcb->hidlib.fullpath = rnd_strdup(st->s); + DONE; + } +#endif + } + + if (sheet->is_symbol) + set_grp(st, &sheet->direct); +} + +/* Common object properties (as in {des3:81}) */ +static int set_common_properties_(csch_propset_ctx_t *st, csch_chdr_t *obj) +{ + int itmp = st->c; + + if (strcmp(st->name, "p/lock") == 0) { + csch_commprp_modify(st->sheet, obj, &itmp, 0, 1); + return 1; + } + if (strcmp(st->name, "p/floater") == 0) { + csch_commprp_modify(st->sheet, obj, 0, &itmp, 1); + return 1; + } + + return 0; +} + +#define set_common_properties(st, obj) \ +do { \ + if (set_common_properties_(st, obj)) { DONE; } \ +} while(0) + +static void set_line(csch_propset_ctx_t *st, csch_line_t *line) +{ + const char *pn = st->name + 7; + + if (st->toggle) + return; /* can't toggle anything else */ + + set_common_properties(st, &line->hdr); + + if (strcmp(st->name, "p/stroke") == 0) { + csch_chdr_pen_name_modify(st->sheet, &line->hdr, &st->comms, NULL, 1); + DONE; + } + + if (st->c_valid && (strcmp(pn, "x1") == 0)) { + csch_line_modify(st->sheet, line, &st->c, NULL, NULL, NULL, 1, !st->c_absolute, 1); + DONE; + } + + if (st->c_valid && (strcmp(pn, "y1") == 0)) { + csch_line_modify(st->sheet, line, NULL, &st->c, NULL, NULL, 1, !st->c_absolute, 1); + DONE; + } + + if (st->c_valid && (strcmp(pn, "x2") == 0)) { + csch_line_modify(st->sheet, line, NULL, NULL, &st->c, NULL, 1, !st->c_absolute, 1); + DONE; + } + + if (st->c_valid && (strcmp(pn, "y2") == 0)) { + csch_line_modify(st->sheet, line, NULL, NULL, NULL, &st->c, 1, !st->c_absolute, 1); + DONE; + } + +} + +static void set_arc(csch_propset_ctx_t *st, csch_arc_t *arc) +{ + const char *pn = st->name + 6; + + if (st->toggle) + return; /* can't toggle anything else */ + + set_common_properties(st, &arc->hdr); + + if (strcmp(st->name, "p/stroke") == 0) { + csch_chdr_pen_name_modify(st->sheet, &arc->hdr, &st->comms, NULL, 1); + DONE; + } + + if (st->c_valid && (strcmp(pn, "cx") == 0)) { + csch_arc_modify(st->sheet, arc, &st->c, NULL, NULL, NULL, NULL, 1, !st->c_absolute); + DONE; + } + + if (st->c_valid && (strcmp(pn, "cy") == 0)) { + csch_arc_modify(st->sheet, arc, NULL, &st->c, NULL, NULL, NULL, 1, !st->c_absolute); + DONE; + } + + if (st->c_valid && (strcmp(pn, "r") == 0)) { + csch_arc_modify(st->sheet, arc, NULL, NULL, &st->c, NULL, NULL, 1, !st->c_absolute); + DONE; + } + + + if (st->d_valid && (strcmp(pn, "start") == 0)) { + double rad = st->d / RND_RAD_TO_DEG; + csch_arc_modify(st->sheet, arc, NULL, NULL, NULL, &rad, NULL, 1, !st->d_absolute); + DONE; + } + + if (st->d_valid && (strcmp(pn, "delta") == 0)) { + double rad = st->d / RND_RAD_TO_DEG; + csch_arc_modify(st->sheet, arc, NULL, NULL, NULL, NULL, &rad, 1, !st->d_absolute); + DONE; + } + +} + +static void set_bitmap(csch_propset_ctx_t *st, csch_cbitmap_t *bitmap) +{ + TODO("bitmap: implement"); +} + + +static void set_text(csch_propset_ctx_t *st, csch_text_t *text) +{ + const char *pn = st->name + 7; + + if (st->toggle) + return; /* can't toggle anything else */ + + set_common_properties(st, &text->hdr); + + if (strcmp(st->name, "p/stroke") == 0) { + csch_chdr_pen_name_modify(st->sheet, &text->hdr, &st->comms, NULL, 1); + DONE; + } + + if (st->c_valid && (strcmp(pn, "x1") == 0)) { + csch_coord_t crd = st->c; + csch_text_modify(st->sheet, text, &crd, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1, !st->c_absolute); + DONE; + } + + if (st->c_valid && (strcmp(pn, "y1") == 0)) { + csch_coord_t crd = st->c; + csch_text_modify(st->sheet, text, NULL, &crd, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1, !st->c_absolute); + DONE; + } + + if (st->c_valid && (strcmp(pn, "x2") == 0)) { + csch_coord_t crd = st->c; + csch_text_modify(st->sheet, text, NULL, NULL, &crd, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1, !st->c_absolute); + DONE; + } + + if (st->c_valid && (strcmp(pn, "y2") == 0)) { + csch_coord_t crd = st->c; + csch_text_modify(st->sheet, text, NULL, NULL, NULL, &crd, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1, !st->c_absolute); + DONE; + } + + if (st->d_valid && (strcmp(pn, "rot") == 0)) { + csch_text_modify(st->sheet, text, NULL, NULL, NULL, NULL, &st->d, NULL, NULL, NULL, NULL, NULL, NULL, 1, !st->d_absolute); + DONE; + } + + if (st->c_valid && (strcmp(pn, "mirx") == 0)) { + int itmp = st->c; + csch_text_modify(st->sheet, text, NULL, NULL, NULL, NULL, NULL, &itmp, NULL, NULL, NULL, NULL, NULL, 1, !st->d_absolute); + DONE; + } + + if (st->c_valid && (strcmp(pn, "miry") == 0)) { + int itmp = st->c; + csch_text_modify(st->sheet, text, NULL, NULL, NULL, NULL, NULL, NULL, &itmp, NULL, NULL, NULL, NULL, 1, !st->d_absolute); + DONE; + } + + if (strcmp(pn, "halign") == 0) { + csch_halign_t tmp; + if (st->c_valid) + tmp = st->c; + else + tmp = csch_str2halign(st->s); + + if ((tmp < 0) || (tmp >= CSCH_HALIGN_invalid)) + return; + csch_text_modify(st->sheet, text, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &tmp, NULL, NULL, NULL, 1, 0); + DONE; + } + + if (strcmp(pn, "text") == 0) { + sch_rnd_op_text_edit(st->sheet, text, st->s); + DONE; + } + + if (st->c_valid && (strcmp(pn, "dyntext") == 0)) { + int tmp = st->c; + csch_text_modify(st->sheet, text, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &tmp, 1, 0); + DONE; + } + + if (st->c_valid && (strcmp(pn, "has_bbox") == 0)) { + int tmp = st->c; + csch_text_modify(st->sheet, text, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &tmp, NULL, 1, 0); + DONE; + } +} + + +static void set_poly(csch_propset_ctx_t *st, csch_cpoly_t *poly) +{ + set_common_properties(st, &poly->hdr); + + if (strcmp(st->name, "p/stroke") == 0) { + csch_chdr_pen_name_modify(st->sheet, &poly->hdr, &st->comms, NULL, 1); + DONE; + } + + if (strcmp(st->name, "p/fill") == 0) { + csch_chdr_pen_name_modify(st->sheet, &poly->hdr, NULL, &st->comms, 1); + DONE; + } + + if (strcmp(st->name, "p/has_stroke") == 0) { + if (st->toggle) { + int i = !poly->has_stroke; + csch_cpoly_modify(st->sheet, poly, &i, NULL, 1); + DONE; + } + else if (st->c_valid) { + int i = st->c; + csch_cpoly_modify(st->sheet, poly, &i, NULL, 1); + DONE; + } + } + + if (strcmp(st->name, "p/has_fill") == 0) { + if (st->toggle) { + int i = !poly->has_fill; + csch_cpoly_modify(st->sheet, poly, NULL, &i, 1); + DONE; + } + else if (st->c_valid ) { + int i = st->c; + csch_cpoly_modify(st->sheet, poly, NULL, &i, 1); + DONE; + } + } + +} + +static void set_grp(csch_propset_ctx_t *st, csch_cgrp_t *grp) +{ + const char *pn = st->name + 6; + + if ((st->name[0] != 'a') || (st->name[1] != '/')) { /* attributes are not recursive */ +TODO("set property recursively on all child using set_any()"); + } + + if (st->is_attr) { + set_attr_obj(st, &grp->hdr); + return; + } + + if (st->toggle) + return; /* can't toggle anything else */ + + set_common_properties(st, &grp->hdr); + + if (strcmp(pn, "uuid") == 0) { + csch_cgrp_modify_uuid(st->sheet, grp, &st->u, NULL, 1); + DONE; + } + + if ((grp->hdr.type == CSCH_CTYPE_GRP) && (strcmp(pn, "src_uuid") == 0)) { + csch_cgrp_modify_uuid(st->sheet, grp, NULL, &st->u, 1); + DONE; + } + + if (st->c_valid && (strcmp(pn, "x") == 0)) { + csch_cgrp_modify(st->sheet, grp, &st->c, NULL, NULL, NULL, NULL, 1, !st->c_absolute); + DONE; + } + + if (st->c_valid && (strcmp(pn, "y") == 0)) { + csch_cgrp_modify(st->sheet, grp, NULL, &st->c, NULL, NULL, NULL, 1, !st->c_absolute); + DONE; + } + + if (st->d_valid && (strcmp(pn, "rot") == 0)) { + csch_cgrp_modify(st->sheet, grp, NULL, NULL, &st->d, NULL, NULL, 1, !st->d_absolute); + DONE; + } + + if (st->c_valid && (strcmp(pn, "mirx") == 0)) { + int itmp = st->c; + csch_cgrp_modify(st->sheet, grp, NULL, NULL, NULL, &itmp, NULL, 1, !st->d_absolute); + DONE; + } + + if (st->c_valid && (strcmp(pn, "miry") == 0)) { + int itmp = st->c; + csch_cgrp_modify(st->sheet, grp, NULL, NULL, NULL, NULL, &itmp, 1, !st->d_absolute); + DONE; + } +} + +static long set_any(void *ctx_, csch_chdr_t *h, const void *udata) +{ + csch_propset_ctx_t *ctx = ctx_; + if (h == NULL) + return 0; + + if (csch_grp_ref_get_top(h->sheet, h) != NULL) { + rnd_message(RND_MSG_ERROR, "Can not change properties of a group_ref child\nbecause it would change the referenced group's children (probably in local lib)\n"); + return 0; + } + + switch(h->type) { + case CSCH_CTYPE_ARC: set_arc(ctx, (csch_arc_t *)h); break; + case CSCH_CTYPE_BITMAP: set_bitmap(ctx, (csch_cbitmap_t *)h); break; + case CSCH_CTYPE_LINE: set_line(ctx, (csch_line_t *)h); break; + case CSCH_CTYPE_POLY: set_poly(ctx, (csch_cpoly_t *)h); break; + case CSCH_CTYPE_TEXT: set_text(ctx, (csch_text_t *)h); break; + case CSCH_CTYPE_GRP_REF: + case CSCH_CTYPE_GRP: set_grp(ctx, (csch_cgrp_t *)h); break; + default: return 0; + } + return 1; +} + +int csch_propsel_set(csch_propedit_t *ctx, const char *prop, csch_propset_ctx_t *sctx) +{ + csch_oidpath_t *idp; + + sctx->sheet = ctx->sheet; + sctx->grp = ctx->grp; + sctx->is_attr = (prop[0] == 'a'); + sctx->name = prop; + + uundo_save_serial(&ctx->sheet->undo); + + for(idp = csch_oidpath_list_first(&ctx->objs); idp != NULL; idp = csch_oidpath_list_next(idp)) { + csch_chdr_t *obj = csch_oidpath_resolve(ctx->sheet, idp); + assert(obj != NULL); + set_any(sctx, obj, NULL); + } + + + if (ctx->use_selection) + csch_propsel_do(ctx->sheet, ctx->grp, 0, sctx, set_any, NULL); + + if (ctx->use_sheet) + set_sheet(sctx, ctx->sheet); + + csch_sheet_set_changed(ctx->sheet, 1); + uundo_inc_serial(&ctx->sheet->undo); + return sctx->set_cnt; +} + + +int csch_propsel_set_str(csch_propedit_t *ctx, const char *prop, const char *value) +{ + csch_propset_ctx_t sctx = {0}; + char *end; + const char *start; + + /* sanity checks for invalid props */ + if ((prop[0] == 'r') && (strncmp(prop, "rename/a/", 9)) == 0) { + sctx.arename = 1; + prop += 7; + } + + if ((prop[1] != '/') || ((prop[0] != 'a') && (prop[0] != 'p'))) { + rnd_message(RND_MSG_ERROR, "Invalid property path: '%s':\n must start with p/ for property or a/ for attribute\n", prop); + return 0; + } + + if (value == NULL) + value = ""; + sctx.s = value; + start = value; + while(isspace(*start)) start++; + if (*start == '#') { + sctx.d_absolute = 1; + start++; + } + else + sctx.d_absolute = ((*start != '-') && (*start != '+')); + sctx.toggle = 0; + sctx.c = rnd_get_value_ex(start, NULL, &sctx.c_absolute, NULL, NULL, &sctx.c_valid); + sctx.d = strtod(start, &end); + sctx.d_valid = (*end == '\0'); + sctx.set_cnt = 0; + + return csch_propsel_set(ctx, prop, &sctx); +} + +int csch_propsel_toggle(csch_propedit_t *ctx, const char *prop, rnd_bool create) +{ + csch_propset_ctx_t sctx; + + /* sanity checks for invalid props */ + if (prop[1] != '/') + return 0; + if ((prop[0] != 'a') && (prop[0] != 'p')) + return 0; + + memset(&sctx, 0, sizeof(sctx)); + + sctx.toggle = 1; + sctx.toggle_create = create; + sctx.set_cnt = 0; + + return csch_propsel_set(ctx, prop, &sctx); +} + +/*******************/ + +static long del_attr(csch_propedit_t *ctx, csch_chdr_t *obj, const char *key) +{ + if (!csch_obj_is_grp(obj)) + return 0; + + csch_attr_modify_del(ctx->sheet, (csch_cgrp_t *)obj, key, 1); + return 1; +} + +static long del_any(void *ctx, csch_chdr_t *h, const void *key) +{ + return del_attr(ctx, h, key); +} + +static long del_sheet(void *ctx, csch_sheet_t *sheet, const char *key) +{ + return del_attr(ctx, &sheet->direct.hdr, key); +} + +int csch_propsel_del(csch_propedit_t *ctx, const char *key) +{ + csch_oidpath_t *idp; + long del_cnt = 0; + + if ((key[0] != 'a') || (key[1] != '/')) /* do not attempt to remove anything but attributes */ + return 0; + + key += 2; + + for(idp = csch_oidpath_list_first(&ctx->objs); idp != NULL; idp = csch_oidpath_list_next(idp)) + del_cnt += del_any(ctx, csch_oidpath_resolve(ctx->sheet, idp), key); + + if (ctx->use_selection) + del_cnt += csch_propsel_do(ctx->sheet, ctx->grp, 0, ctx, del_any, key); + + if (ctx->use_sheet) + del_cnt += del_sheet(ctx, ctx->sheet, key); + + csch_sheet_set_changed(ctx->sheet, 1); + return del_cnt; +} + + +char *csch_propsel_printval(csch_props_t *p, const csch_propval_t *val) +{ + minuid_str_t utmp; + + switch(p->type) { + case CSCH_PROPT_STRING: return val->string == NULL ? rnd_strdup("") : rnd_strdup(val->string); + case CSCH_PROPT_COORD: return rnd_strdup_printf("%$rc", val->coord); + case CSCH_PROPT_ANGLE: return rnd_strdup_printf("%f", val->angle); + case CSCH_PROPT_DOUBLE: return rnd_strdup_printf("%f", val->d); + case CSCH_PROPT_INT: return rnd_strdup_printf("%d", val->i); + case CSCH_PROPT_ENUM: return rnd_strdup(p->enum_names[val->i]); + case CSCH_PROPT_BOOL: return rnd_strdup(val->i ? "true" : "false"); + case CSCH_PROPT_COMMS: return val->comms.str == NULL ? rnd_strdup("") : rnd_strdup(val->comms.str); + case CSCH_PROPT_UUID: minuid_bin2str(utmp, val->u); return rnd_strdup(utmp); + case CSCH_PROPT_ATTRARR:return rnd_strdup(""); + default: + return rnd_strdup(""); + } +} Index: tags/1.0.5/src/plugins/propedit/propsel.h =================================================================== --- tags/1.0.5/src/plugins/propedit/propsel.h (nonexistent) +++ tags/1.0.5/src/plugins/propedit/propsel.h (revision 10414) @@ -0,0 +1,60 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - property editor plugin + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * (Adapted from propsel code in pcb-rnd by the same author) + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/* This API builds a prop list by looking at all selected objects on a design. */ +void csch_propsel_map_core(csch_propedit_t *ctx); + +typedef struct set_ctx_s { + const char *s; /* only for string */ + csch_coord_t c; /* also int */ + double d; + csch_comm_str_t comms; + minuid_bin_t u; + rnd_bool c_absolute, d_absolute, c_valid, d_valid; + unsigned toggle:1; /* when 1, ignore value and attempt to toggle */ + unsigned toggle_create:1; /* when 1, create non-existing attribute on toggle, with value true */ + unsigned arename:1; /* when 1, attribute is renamed to s; must not be used for anything else but a/ */ + + /* private */ + unsigned is_attr:1; + csch_sheet_t *sheet; + csch_cgrp_t *grp; + const char *name; + int set_cnt; +} csch_propset_ctx_t; + + +int csch_propsel_set_str(csch_propedit_t *ctx, const char *prop, const char *value); +int csch_propsel_set(csch_propedit_t *ctx, const char *prop, csch_propset_ctx_t *sctx); +int csch_propsel_toggle(csch_propedit_t *ctx, const char *prop, rnd_bool create); +int csch_propsel_del(csch_propedit_t *ctx, const char *attr_name); + +/* Allocate new string and print the value using current unit */ +char *csch_propsel_printval(csch_props_t *p, const csch_propval_t *val); + Index: tags/1.0.5/src/plugins/query/Makefile =================================================================== --- tags/1.0.5/src/plugins/query/Makefile (nonexistent) +++ tags/1.0.5/src/plugins/query/Makefile (revision 10414) @@ -0,0 +1,6 @@ +all: + cd ../../sch-rnd && $(MAKE) mod_query + + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/1.0.5/src/plugins/query/Plug.tmpasm =================================================================== --- tags/1.0.5/src/plugins/query/Plug.tmpasm (nonexistent) +++ tags/1.0.5/src/plugins/query/Plug.tmpasm (revision 10414) @@ -0,0 +1,21 @@ +put /local/rnd/mod {query} +put /local/rnd/mod/OBJS [@ + $(PLUGDIR)/query/query.o + $(PLUGDIR)/query/query_access.o + $(PLUGDIR)/query/query_act.o + $(PLUGDIR)/query/query_exec.o + $(PLUGDIR)/query/query_l.o + $(PLUGDIR)/query/query_y.o + $(PLUGDIR)/query/fnc.o + $(PLUGDIR)/query/fields_sphash.o + $(PLUGDIR)/query/dlg_search.o +@] +put /local/rnd/mod/YACC {$(PLUGDIR)/query/query_y} +put /local/rnd/mod/LEX {$(PLUGDIR)/query/query_l} +put /local/rnd/mod/SPHASH {$(PLUGDIR)/query/fields.sphash} + +switch /local/module/query/controls + case {buildin} include /local/csch/tmpasm/buildin; end; + case {plugin} include /local/csch/tmpasm/plugin; end; + case {disable} include /local/csch/tmpasm/disable; end; +end Index: tags/1.0.5/src/plugins/query/dlg_search.c =================================================================== --- tags/1.0.5/src/plugins/query/dlg_search.c (nonexistent) +++ tags/1.0.5/src/plugins/query/dlg_search.c (revision 10414) @@ -0,0 +1,743 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - query + * Copyright (C) 2019, 2024 Tibor 'Igor2' Palinkas + * + * copied from: pcb-rnd, interactive printed circuit board design + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include "query.h" +#include + +#define MAX_ROW 8 +#define MAX_COL 4 + +static const char *search_acts[] = { "select", "unselect", "view", "count", NULL }; +static const char *search_scopes[] = { "sheet", "project", NULL }; + +#define NEW_EXPR_LAB "" + +/* for debugging: */ +/*#define NEW_EXPR_LAB rnd_strdup_printf("%d:%d", row, col)*/ + +#include "dlg_search_tab.h" + +typedef struct { + int valid; + const expr_wizard_t *expr; + const char *op; + char *right; +} search_expr_t; + +typedef struct{ + RND_DAD_DECL_NOINIT(dlg) + rnd_design_t *dsg; /* used when follow is set */ + int wexpr_str, wwizard, wact, wscope, wscope_label, wfollow; + int wrowbox[MAX_ROW]; + int wexpr[MAX_ROW][MAX_COL]; /* expression framed box */ + int wexpr_lab[MAX_ROW][MAX_COL]; /* the label within the expression box */ + int wexpr_del[MAX_ROW][MAX_COL], wexpr_edit[MAX_ROW][MAX_COL]; /* expression buttons */ + int wor[MAX_ROW][MAX_COL]; /* before the current col */ + int wand[MAX_ROW]; /* before the current row */ + int wnew_or[MAX_ROW], wnew_and; + int visible[MAX_ROW][MAX_COL]; + search_expr_t expr[MAX_ROW][MAX_COL]; + gdl_elem_t link; +} search_ctx_t; + +#define WIZ(ctx) (ctx->dlg[ctx->wwizard].val.lng) + +#include "dlg_search_edit.c" + +static gdl_list_t searches; + +static void free_expr(search_expr_t *e) +{ + free(e->right); + memset(e, 0, sizeof(search_expr_t)); +} + +static void search_close_cb(void *caller_data, rnd_hid_attr_ev_t ev) +{ + int r, c; + search_ctx_t *ctx = caller_data; + for(r = 0; r < MAX_ROW; r++) + for(c = 0; c < MAX_COL; c++) + free_expr(&ctx->expr[r][c]); + gdl_remove(&searches, ctx, link); + free(ctx); +} + +static void hspacer(search_ctx_t *ctx) +{ + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_END(ctx->dlg); +} + +static void vspacer(search_ctx_t *ctx) +{ + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_END(ctx->dlg); +} + +static void update_vis(search_ctx_t *ctx) +{ + int c, r, wen; + + wen = WIZ(ctx); + + for(r = 0; r < MAX_ROW; r++) { + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wrowbox[r],!ctx->visible[r][0]); + for(c = 0; c < MAX_COL; c++) { + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wexpr[r][c], !ctx->visible[r][c]); + if (c > 0) + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wor[r][c], !((ctx->visible[r][c-1] && ctx->visible[r][c]))); + rnd_gui->attr_dlg_widget_state(ctx->dlg_hid_ctx, ctx->wexpr_del[r][c], wen); + rnd_gui->attr_dlg_widget_state(ctx->dlg_hid_ctx, ctx->wexpr_edit[r][c], wen); + } + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wnew_or[r], !ctx->visible[r][0]); + if (r > 0) + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wand[r], !((ctx->visible[r-1][0] && ctx->visible[r][0]))); + rnd_gui->attr_dlg_widget_state(ctx->dlg_hid_ctx, ctx->wnew_or[r], wen); + } + rnd_gui->attr_dlg_widget_state(ctx->dlg_hid_ctx, ctx->wnew_and, wen); + rnd_gui->attr_dlg_widget_state(ctx->dlg_hid_ctx, ctx->wexpr_str, !wen); +} + +static rnd_design_t *get_design(search_ctx_t *ctx) +{ + + if (ctx->dlg[ctx->wfollow].val.lng) + return ctx->dsg; + return rnd_gui->get_dad_design(ctx->dlg_hid_ctx); +} + +static void update_scope(search_ctx_t *ctx) +{ + rnd_hid_attr_val_t hv; + rnd_design_t *ctx_hl = get_design(ctx); + + rnd_project_t *prj = ctx_hl->project; + char *freeme = NULL; + + if (ctx_hl != NULL) { + switch(ctx->dlg[ctx->wscope].val.lng) { + case 0: + if (ctx_hl->loadname != NULL) + hv.str = ctx_hl->loadname; + else + hv.str = ""; + break; + case 1: + if (prj->loadname != NULL) { + freeme = rnd_dirname(prj->loadname); + hv.str = rnd_basename(freeme); + } + else + hv.str = ""; + break; + default: + hv.str = ""; + break; + } + } + else + hv.str = ""; + + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wscope_label, &hv); + free(freeme); +} + +static void maybe_follow(search_ctx_t *ctx, rnd_design_t *dsg) +{ + if (!ctx->dlg[ctx->wfollow].val.lng) + return; + + ctx->dsg = dsg; + update_scope(ctx); +} + +/* look up row and col for a widget attr in a [row][col] widget idx array; returns 0 on success */ +static int rc_lookup(search_ctx_t *ctx, int w[MAX_ROW][MAX_COL], rnd_hid_attribute_t *attr, int *row, int *col) +{ + int r, c, idx = attr - ctx->dlg; + for(r = 0; r < MAX_ROW; r++) { + for(c = 0; c < MAX_COL; c++) { + if (w[r][c] == idx) { + *row = r; + *col = c; + return 0; + } + } + } + return -1; +} + +/* look up row for a widget attr in a [row] widget idx array; returns 0 on success */ +static int r_lookup(search_ctx_t *ctx, int w[MAX_ROW], rnd_hid_attribute_t *attr, int *row) +{ + int r, idx = attr - ctx->dlg; + for(r = 0; r < MAX_ROW; r++) { + if (w[r] == idx) { + *row = r; + return 0; + } + } + return -1; +} + +static void append_expr(gds_t *dst, search_expr_t *e, int sepchar) +{ + gds_append_str(dst, e->expr->left_var); + gds_append(dst, sepchar); + gds_append_str(dst, e->op); + gds_append(dst, sepchar); + gds_append_str(dst, e->right); +} + +static void redraw_expr(search_ctx_t *ctx, int row, int col) +{ + rnd_hid_attr_val_t hv; + gds_t buf; + search_expr_t *e = &(ctx->expr[row][col]); + + if (e->valid) { + gds_init(&buf); + append_expr(&buf, e, '\n'); + hv.str = buf.array; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wexpr_lab[row][col], &hv); + gds_uninit(&buf); + } + else { + hv.str = NEW_EXPR_LAB; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wexpr_lab[row][col], &hv); + } +} + +static void search_recompile(search_ctx_t *ctx) +{ + rnd_hid_attr_val_t hv; + gds_t buf; + int row, col; + + gds_init(&buf); + for(row = 0; row < MAX_ROW; row++) { + if (!ctx->visible[row][0] || !ctx->expr[row][0].valid) + continue; + if (row > 0) + gds_append_str(&buf, " && "); + gds_append(&buf, '('); + for(col = 0; col < MAX_COL; col++) { + if (!ctx->visible[row][col] || !ctx->expr[row][col].valid) + continue; + if (col > 0) + gds_append_str(&buf, " || "); + gds_append(&buf, '('); + append_expr(&buf, &(ctx->expr[row][col]), ' '); + gds_append(&buf, ')'); + } + gds_append(&buf, ')'); + } + hv.str = buf.array; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wexpr_str, &hv); + gds_uninit(&buf); +} + +static const char *qop_text[] = {"==", "!=", ">=", "<=", ">", "<", "~"}; +static const pcb_qry_nodetype_t qop[] = {PCBQ_OP_EQ, PCBQ_OP_NEQ, PCBQ_OP_GTEQ, PCBQ_OP_LTEQ, PCBQ_OP_GT, PCBQ_OP_LT, PCBQ_OP_MATCH}; + +static int search_decompile_op(gds_t *dst, pcb_qry_node_t *nd, rnd_bool want_coord) +{ + int res; + + switch(nd->type) { + case PCBQ_FIELD_OF: + for(nd = nd->data.children, res = 0; nd != NULL; nd = nd->next) + res |= search_decompile_op(dst, nd, want_coord); + return res; + case PCBQ_FIELD: + gds_append(dst, '.'); + gds_append_str(dst, nd->data.str); + return 0; + case PCBQ_VAR: + gds_append(dst, '@'); + return 0; + case PCBQ_DATA_COORD: + rnd_append_printf(dst, "%ld", nd->data.crd); + return 0; + case PCBQ_DATA_DOUBLE: + if (want_coord) + rnd_append_printf(dst, "%ld", (long)nd->data.dbl); + else + rnd_append_printf(dst, "%f", nd->data.dbl); + return 0; + case PCBQ_DATA_STRING: + gds_append(dst, '"'); + gds_append_str(dst, nd->data.str); + gds_append(dst, '"'); + return 0; + case PCBQ_DATA_REGEX: + case PCBQ_DATA_CONST: + gds_append_str(dst, nd->data.str); + return 0; + default: + break; + } + return -1; +} + +static int search_decompile_(search_ctx_t *ctx, pcb_qry_node_t *nd, int dry, int row, int col) +{ + int n, res; + const char *qopt = NULL, *right; + gds_t e; + const expr_wizard_t *w; + + + if (nd->type == PCBQ_EXPR_PROG) + return search_decompile_(ctx, nd->data.children, dry, row, col); + + if (nd->type == PCBQ_ITER_CTX) + return search_decompile_(ctx, nd->next, dry, row, col); + + if (nd->type == PCBQ_OP_AND) { + if ((nd->parent == NULL) || ((nd->parent->type != PCBQ_OP_AND) && (nd->parent->type != PCBQ_EXPR_PROG))) /* first level of ops must be AND */ + return -1; + if (search_decompile_(ctx, nd->data.children, dry, row, col) != 0) + return -1; + return search_decompile_(ctx, nd->data.children->next, dry, row+1, col); + } + + if (nd->type == PCBQ_OP_OR) { + if ((nd->parent == NULL) || ((nd->parent->type != PCBQ_OP_AND) && (nd->parent->type != PCBQ_OP_OR))) /* second level of ops must be OR */ + return -1; + if (search_decompile_(ctx, nd->data.children, dry, row, col) != 0) + return -1; + return search_decompile_(ctx, nd->data.children->next, dry, row, col+1); + } + + /* plain op */ + for(n = 0; n < sizeof(qop) / sizeof(qop[0]); n++) { + if (qop[n] == nd->type) { + qopt = qop_text[n]; + break; + } + } + + if (qopt == NULL) + return -1; /* unknown binary op */ + + gds_init(&e); + + res = search_decompile_op(&e, nd->data.children, 0); + + /* look up the left side to know how to fill in the expr editor dialog */ + for(w = expr_tab; w->left_desc != NULL; w++) + if ((w->left_var != NULL) && (strcmp(w->left_var, e.array) == 0)) + break; + if (w->left_desc == NULL) + w = NULL; + + gds_append(&e, '\n'); + gds_append_str(&e, qopt); + gds_append(&e, '\n'); + right = e.array + e.used; + res |= search_decompile_op(&e, nd->data.children->next, ((w != NULL) && (w->rtype == RIGHT_COORD))); + + if (res == 0) { + rnd_hid_attr_val_t hv; + + if (w != NULL) { + ctx->expr[row][col].expr = w; + ctx->expr[row][col].op = qopt; + ctx->expr[row][col].right = rnd_strdup(right); + ctx->expr[row][col].valid = 1; + + hv.str = e.array; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wexpr_lab[row][col], &hv); + ctx->visible[row][col] = 1; + } + else + res = -1; + } + + gds_uninit(&e); + + return res; +} + +static int search_decompile(search_ctx_t *ctx) +{ + const char *script = ctx->dlg[ctx->wexpr_str].val.str; + pcb_qry_node_t *root; + int row, col; + + if (script == NULL) return 0; + while(isspace(*script)) script++; + if (*script == '\0') return 0; + + root = pcb_query_compile(script); + if (root == NULL) { + rnd_message(RND_MSG_ERROR, "Syntax error compiling the script.\nPlease edit or remove the expression before enabling the GUI wizard.\n"); + return -1; + } + + if (search_decompile_(ctx, root, 1, 0, 0) != 0) { + rnd_message(RND_MSG_ERROR, "The script is too complex for the GUI\nPlease edit or remove the expression before enabling the GUI wizard.\n"); + return -1; + } + + for(row = 0; row < MAX_ROW; row++) { + for(col = 0; col < MAX_COL; col++) { + ctx->visible[row][col] = 0; + ctx->expr[row][col].valid = 0; + } + } + + search_decompile_(ctx, root, 0, 0, 0); + update_vis(ctx); + return 0; +} + +static void search_del_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + search_ctx_t *ctx = caller_data; + int row, col; + + if (rc_lookup(ctx, ctx->wexpr_del, attr, &row, &col) != 0) + return; + + free_expr(&(ctx->expr[row][col])); + for(;col < MAX_COL-1; col++) { + if (!ctx->visible[row][col+1]) { + ctx->visible[row][col] = 0; + memset(&ctx->expr[row][col], 0, sizeof(search_expr_t)); + break; + } + ctx->expr[row][col] = ctx->expr[row][col+1]; + redraw_expr(ctx, row, col); + } + update_vis(ctx); + search_recompile(ctx); +} + +static void search_edit_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + search_ctx_t *ctx = caller_data; + int row, col; + search_expr_t *e; + + if (rc_lookup(ctx, ctx->wexpr_edit, attr, &row, &col) != 0) + return; + + e = &(ctx->expr[row][col]); + if (srchedit_window(e) == 0) { + redraw_expr(ctx, row, col); + search_recompile(ctx); + } +} + +static void search_enable_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + search_ctx_t *ctx = caller_data; + if (WIZ(ctx)) { + if (search_decompile(ctx) != 0) {/* fills in the GUI from the expression, if possible */ + /* disable the wizard on failure */ + rnd_hid_attr_val_t hv; + hv.lng = 0; + rnd_gui->attr_dlg_set_value(hid_ctx, ctx->wwizard, &hv); + } + else + search_recompile(ctx); /* overwrite the edit box just in case the user had something custom in it */ + } + + update_vis(ctx); +} + +static void search_append_col_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + search_ctx_t *ctx = caller_data; + int row, col; + + if (r_lookup(ctx, ctx->wnew_or, attr, &row) != 0) + return; + + for(col = 0; col < MAX_COL; col++) { + if (!ctx->visible[row][col]) { + ctx->visible[row][col] = 1; + redraw_expr(ctx, row, col); + update_vis(ctx); + search_recompile(ctx); + return; + } + } + rnd_message(RND_MSG_ERROR, "Too many expressions in the row, can not add more\n"); +} + +static void search_append_row_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + search_ctx_t *ctx = caller_data; + int row; + + for(row = 0; row < MAX_ROW; row++) { + if (!ctx->visible[row][0]) { + ctx->visible[row][0] = 1; + redraw_expr(ctx, row, 0); + update_vis(ctx); + search_recompile(ctx); + return; + } + } + rnd_message(RND_MSG_ERROR, "Too many expression rows, can not add more\n"); +} + +static void search_apply_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + search_ctx_t *ctx = caller_data; + rnd_design_t *hidlib = get_design(ctx); + if (hidlib == NULL) { + rnd_message(RND_MSG_ERROR, "Can't search: invalid scope\n"); + return; + } + if (ctx->dlg[ctx->wexpr_str].val.str != NULL) { + const char *op = search_acts[ctx->dlg[ctx->wact].val.lng]; + const char *scp = search_scopes[ctx->dlg[ctx->wscope].val.lng]; + long res = rnd_actionva(hidlib, "query", op, ctx->dlg[ctx->wexpr_str].val.str, scp, NULL); + if (strcmp(op, "count") == 0) + rnd_message(RND_MSG_INFO, "Advanced search: %ld matched.\n", res); + } +} + +static void search_scope_chg_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + search_ctx_t *ctx = caller_data; + update_scope(ctx); +} + +static void search_follow_chg_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + search_ctx_t *ctx = caller_data; + maybe_follow(ctx, rnd_multi_get_current()); +} + + +static const char *icon_del[] = { +"5 5 2 1", +" c None", +"+ c #FF0000", +"+ +", +" + + ", +" + ", +" + + ", +"+ +", +}; + +static const char *icon_edit[] = { +"5 5 2 1", +" c None", +"+ c #000000", +"++++ ", +"+ ", +"+++ ", +"+ ", +"++++ ", +}; + +static void search_window_create(void) +{ + rnd_hid_dad_buttons_t clbtn[] = {{"Close", 0}, {NULL, 0}}; + search_ctx_t *ctx = calloc(sizeof(search_ctx_t), 1); + int row, col; + static const char *help_follow = "When ticked: the scope of dialog box follows sheet switches"; + + gdl_append(&searches, ctx, link); + + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_LABEL(ctx->dlg, "Query expression:"); + RND_DAD_STRING(ctx->dlg); + RND_DAD_WIDTH_CHR(ctx->dlg, 64); + ctx->wexpr_str = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Action on the results:"); + RND_DAD_ENUM(ctx->dlg, search_acts); + ctx->wact = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Scope:"); + RND_DAD_ENUM(ctx->dlg, search_scopes); + ctx->wscope = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_CHANGE_CB(ctx->dlg, search_scope_chg_cb); + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_TIGHT); + RND_DAD_LABEL(ctx->dlg, ""); + ctx->wscope_label = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_HELP(ctx->dlg, "Searches done from this dialog box will search in this scope (sheet or project)"); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_TIGHT); + RND_DAD_LABEL(ctx->dlg, "Follow:"); + RND_DAD_HELP(ctx->dlg, help_follow); + RND_DAD_BOOL(ctx->dlg); + ctx->wfollow = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_HELP(ctx->dlg, help_follow); + RND_DAD_DEFAULT_NUM(ctx->dlg, 0); + RND_DAD_CHANGE_CB(ctx->dlg, search_follow_chg_cb); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_FRAME | RND_HATF_EXPFILL | RND_HATF_SCROLL); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Enable the wizard:"); + RND_DAD_BOOL(ctx->dlg); + ctx->wwizard = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_DEFAULT_NUM(ctx->dlg, 1); + RND_DAD_CHANGE_CB(ctx->dlg, search_enable_cb); + RND_DAD_END(ctx->dlg); + for(row = 0; row < MAX_ROW; row++) { + if (row > 0) { + RND_DAD_BEGIN_HBOX(ctx->dlg); + ctx->wand[row] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL | RND_HATF_HIDE); + RND_DAD_LABEL(ctx->dlg, "AND"); + RND_DAD_END(ctx->dlg); + } + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, /*RND_HATF_EXPFILL | */RND_HATF_HIDE); + ctx->wrowbox[row] = RND_DAD_CURRENT(ctx->dlg); + for(col = 0; col < MAX_COL; col++) { + ctx->visible[row][col] = 0; + if (col > 0) { + RND_DAD_LABEL(ctx->dlg, " OR "); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_HIDE); + ctx->wor[row][col] = RND_DAD_CURRENT(ctx->dlg); + } + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_FRAME | RND_HATF_TIGHT | RND_HATF_HIDE); + ctx->wexpr[row][col] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, NEW_EXPR_LAB); + ctx->wexpr_lab[row][col] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_TIGHT); + RND_DAD_PICBUTTON(ctx->dlg, icon_del); + RND_DAD_HELP(ctx->dlg, "Remove expression"); + ctx->wexpr_del[row][col] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_CHANGE_CB(ctx->dlg, search_del_cb); + RND_DAD_PICBUTTON(ctx->dlg, icon_edit); + RND_DAD_HELP(ctx->dlg, "Edit expression"); + ctx->wexpr_edit[row][col] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_CHANGE_CB(ctx->dlg, search_edit_cb); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + } + hspacer(ctx); + RND_DAD_BUTTON(ctx->dlg, "append OR"); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_HIDE); + ctx->wnew_or[row] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_CHANGE_CB(ctx->dlg, search_append_col_cb); + RND_DAD_END(ctx->dlg); + } + vspacer(ctx); + RND_DAD_BUTTON(ctx->dlg, "append AND"); + ctx->wnew_and = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_CHANGE_CB(ctx->dlg, search_append_row_cb); + RND_DAD_END(ctx->dlg); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "Apply"); + RND_DAD_CHANGE_CB(ctx->dlg, search_apply_cb); + RND_DAD_HELP(ctx->dlg, "Execute the search expression\nusing the selected action"); + hspacer(ctx); + RND_DAD_BUTTON_CLOSES(ctx->dlg, clbtn); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + + RND_DAD_DEFSIZE(ctx->dlg, 300, 350); + RND_DAD_NEW("search", ctx->dlg, "sch-rnd search", ctx, rnd_false, search_close_cb); /* type=local */ + + ctx->dsg = rnd_gui->get_dad_design(ctx->dlg_hid_ctx); + ctx->visible[0][0] = 1; + update_vis(ctx); + update_scope(ctx); + search_recompile(ctx); +} + + +const char csch_acts_SearchDialog[] = "SearchDialog()\n"; +const char csch_acth_SearchDialog[] = "Open the log dialog."; +fgw_error_t csch_act_SearchDialog(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + search_window_create(); + RND_ACT_IRES(0); + return 0; +} + +static void search_close(search_ctx_t *ctx) +{ + rnd_dad_retovr_t retovr = {0}; + rnd_hid_dad_close(ctx->dlg_hid_ctx, &retovr, 0); +} + + +void sch_rnd_query_ev_preunload(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + search_ctx_t *ctx, *nextctx; + for(ctx = gdl_first(&searches); ctx != NULL; ctx = nextctx) { + rnd_design_t *ctx_hl = get_design(ctx); + nextctx = gdl_next(&searches, ctx); + if (ctx_hl == hidlib) + search_close(ctx); + } +} + +void sch_rnd_query_ev_sheet_chg(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + search_ctx_t *ctx; + rnd_design_t *dsg = argv[1].d.p; + for(ctx = gdl_first(&searches); ctx != NULL; ctx = gdl_next(&searches, ctx)) + maybe_follow(ctx, dsg); +} + + +void sch_rnd_search_close_all(void) +{ + search_ctx_t *ctx, *nextctx; + for(ctx = gdl_first(&searches); ctx != NULL; ctx = nextctx) { + nextctx = gdl_next(&searches, ctx); + search_close(ctx); + } +} Index: tags/1.0.5/src/plugins/query/dlg_search.h =================================================================== --- tags/1.0.5/src/plugins/query/dlg_search.h (nonexistent) +++ tags/1.0.5/src/plugins/query/dlg_search.h (revision 10414) @@ -0,0 +1,9 @@ +#include +extern const char csch_acts_SearchDialog[]; +extern const char csch_acth_SearchDialog[]; +fgw_error_t csch_act_SearchDialog(fgw_arg_t *res, int argc, fgw_arg_t *argv); + +void sch_rnd_search_close_all(void); +void sch_rnd_query_ev_preunload(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]); +void sch_rnd_query_ev_sheet_chg(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]); + Index: tags/1.0.5/src/plugins/query/dlg_search_edit.c =================================================================== --- tags/1.0.5/src/plugins/query/dlg_search_edit.c (nonexistent) +++ tags/1.0.5/src/plugins/query/dlg_search_edit.c (revision 10414) @@ -0,0 +1,382 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2019 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include + +#include +#include +#include +#include +#include +#include + +typedef struct{ + RND_DAD_DECL_NOINIT(dlg) + search_expr_t se; + int wleft, wop, wright[RIGHT_max]; + const expr_wizard_op_t *last_op; + right_type last_rtype; +} srchedit_ctx_t; + +static srchedit_ctx_t srchedit_ctx; + +/* Set the right side of the expression from the non-enum value of an widget attr */ +static void set_right(srchedit_ctx_t *ctx, rnd_hid_attribute_t *attr) +{ + free(ctx->se.right); + ctx->se.right = NULL; + + switch(ctx->se.expr->rtype) { + case RIGHT_STR: + ctx->se.right = rnd_strdup_printf("\"%s\"", attr->val.str); + break; + case RIGHT_INT: + ctx->se.right = rnd_strdup_printf("%d", attr->val.lng); + break; + case RIGHT_DOUBLE: + ctx->se.right = rnd_strdup_printf("%f", attr->val.dbl); + break; + case RIGHT_COORD: + ctx->se.right = rnd_strdup_printf("%$rr", attr->val.crd); + break; + case RIGHT_CONST: + case RIGHT_max: + break; + } +} + +static void srch_expr_set_ops(srchedit_ctx_t *ctx, const expr_wizard_op_t *op, int click) +{ + rnd_hid_tree_t *tree; + rnd_hid_attribute_t *attr; + rnd_hid_row_t *r, *cur = NULL; + char *cell[2], *cursor_path = NULL; + const char **o; + + if (op == ctx->last_op) + return; + + attr = &ctx->dlg[ctx->wop]; + tree = attr->wdata; + + /* remember cursor */ + if (click) { + r = rnd_dad_tree_get_selected(attr); + if (r != NULL) + cursor_path = rnd_strdup(r->cell[0]); + } + + /* remove existing items */ + rnd_dad_tree_clear(tree); + + /* add all items */ + cell[1] = NULL; + for(o = op->ops; *o != NULL; o++) { + cell[0] = rnd_strdup_printf(*o); + r = rnd_dad_tree_append(attr, NULL, cell); + r->user_data = (void *)(*o); /* will be casted back to const char * only */ + if ((!click) && (ctx->se.op == *o)) + cur = r; + } + + /* restore cursor */ + if (cursor_path != NULL) { + rnd_hid_attr_val_t hv; + hv.str = cursor_path; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wop, &hv); + free(cursor_path); + } + if (cur != NULL) + rnd_dad_tree_jumpto(attr, cur); + ctx->last_op = op; +} + +static void srch_expr_fill_in_right_const(srchedit_ctx_t *ctx, const search_expr_t *s) +{ + rnd_hid_tree_t *tree; + rnd_hid_attribute_t *attr; + char *cell[2]; + const char **o; + + attr = &ctx->dlg[ctx->wright[RIGHT_CONST]]; + tree = attr->wdata; + + /* remove existing items */ + rnd_dad_tree_clear(tree); + + /* add all items */ + cell[1] = NULL; + for(o = s->expr->right_const->ops; *o != NULL; o++) { + cell[0] = rnd_strdup_printf(*o); + rnd_dad_tree_append(attr, NULL, cell); + } + + /* set cursor to last known value */ + if ((s != NULL) && (s->right != NULL)) { + rnd_hid_attr_val_t hv; + hv.str = s->right; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wright[RIGHT_CONST], &hv); + } +} + +static void srch_expr_fill_in_right(srchedit_ctx_t *ctx, const search_expr_t *s) +{ + int n, empty = 0; + rnd_hid_attr_val_t hv; + + /* don't recalc if the same type; except for const, because there the same type means different set of values for each expr */ + if ((s->expr->rtype == ctx->last_rtype) && (s->expr->rtype != RIGHT_CONST)) + return; + + for(n = 0; n < RIGHT_max; n++) + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wright[n], 1); + + hv.str = ctx->se.right; + if (hv.str == NULL) { + hv.str = ""; + empty = 1; + } + + switch(s->expr->rtype) { + case RIGHT_STR: + if (*hv.str == '"') { /* strip double quotes */ + long len = strlen(hv.str); + char *tmp; + tmp = malloc(len); + memcpy(tmp, hv.str+1, len-2); + tmp[len-2] = '\0'; + hv.str = tmp; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wright[s->expr->rtype], &hv); + free(tmp); + } + else + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wright[s->expr->rtype], &hv); + break; + case RIGHT_INT: + hv.lng = strtol(hv.str, NULL, 10); + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wright[s->expr->rtype], &hv); + if (empty) + set_right(ctx, &ctx->dlg[ctx->wright[s->expr->rtype]]); + break; + case RIGHT_DOUBLE: + hv.dbl = strtod(hv.str, NULL); + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wright[s->expr->rtype], &hv); + if (empty) + set_right(ctx, &ctx->dlg[ctx->wright[s->expr->rtype]]); + break; + case RIGHT_COORD: + hv.crd = rnd_get_value_ex(hv.str, NULL, NULL, NULL, "cschem", NULL); + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wright[s->expr->rtype], &hv); + if (empty) + set_right(ctx, &ctx->dlg[ctx->wright[s->expr->rtype]]); + break; + case RIGHT_CONST: srch_expr_fill_in_right_const(ctx, s); break; + case RIGHT_max: break; + } + + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wright[s->expr->rtype], 0); + ctx->last_rtype = s->expr->rtype; +} + +static void srch_expr_left_cb(rnd_hid_attribute_t *attrib, void *hid_ctx, rnd_hid_row_t *row) +{ + rnd_hid_tree_t *tree = attrib->wdata; + srchedit_ctx_t *ctx = tree->user_ctx; + const expr_wizard_t *e; + + if (row == NULL) + return; + + e = row->user_data; + if (e->left_var == NULL) /* category */ + return; + + ctx->se.expr = e; + srch_expr_set_ops(ctx, e->op, 1); + srch_expr_fill_in_right(ctx, &ctx->se); +} + +static void srch_expr_op_cb(rnd_hid_attribute_t *attrib, void *hid_ctx, rnd_hid_row_t *row) +{ + rnd_hid_tree_t *tree = attrib->wdata; + srchedit_ctx_t *ctx = tree->user_ctx; + + if (row != NULL) + ctx->se.op = row->user_data; + else + ctx->se.op = NULL; +} + +/* the table on the left is static, needs to be filled in only once; + returns 1 if filled in op and right, else 0 */ +static int fill_in_left(srchedit_ctx_t *ctx) +{ + const expr_wizard_t *t; + rnd_hid_attribute_t *attr; + rnd_hid_row_t *r, *parent = NULL, *cur = NULL; + char *cell[2]; + + attr = &ctx->dlg[ctx->wleft]; + + cell[1] = NULL; + for(t = expr_tab; t->left_desc != NULL; t++) { + if (t->left_var == NULL) + parent = NULL; + cell[0] = rnd_strdup(t->left_desc); + if (parent != NULL) + r = rnd_dad_tree_append_under(attr, parent, cell); + else + r = rnd_dad_tree_append(attr, NULL, cell); + r->user_data = (void *)t; + if (t->left_var == NULL) + parent = r; + if (t == ctx->se.expr) + cur = r; + } + + if (cur != NULL) { + rnd_dad_tree_jumpto(attr, cur); + + /* clear all cache fields so a second window open won't inhibit refreshes */ + ctx->last_op = NULL; + ctx->last_rtype = RIGHT_max; + + srch_expr_set_ops(ctx, ctx->se.expr->op, 0); + srch_expr_fill_in_right(ctx, &ctx->se); + return 1; + } + return 0; +} + +static void srchexpr_right_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + srchedit_ctx_t *ctx = caller_data; + + set_right(ctx, attr); +} + +static void srch_expr_right_table_cb(rnd_hid_attribute_t *attrib, void *hid_ctx, rnd_hid_row_t *row) +{ + rnd_hid_tree_t *tree = attrib->wdata; + srchedit_ctx_t *ctx = tree->user_ctx; + + free(ctx->se.right); + ctx->se.right = NULL; + if (row != NULL) + ctx->se.right = rnd_strdup(row->cell[0]); +} + +static int srchedit_window(search_expr_t *expr) +{ + rnd_hid_dad_buttons_t clbtn[] = {{"Cancel", 1}, {"OK", 0}, {NULL, 0}}; + srchedit_ctx_t *ctx = &srchedit_ctx; + int res; + + ctx->se = *expr; + if (ctx->se.right != NULL) + ctx->se.right = rnd_strdup(ctx->se.right); + + /* clear all cache fields so a second window open won't inhibit refreshes */ + ctx->last_op = NULL; + ctx->last_rtype = RIGHT_max; + + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_TREE(ctx->dlg, 1, 1, NULL); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_SCROLL); + ctx->wleft = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_TREE_SET_CB(ctx->dlg, selected_cb, srch_expr_left_cb); + RND_DAD_TREE_SET_CB(ctx->dlg, ctx, ctx); + RND_DAD_END(ctx->dlg); + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_TREE(ctx->dlg, 1, 0, NULL); + ctx->wop = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_TREE_SET_CB(ctx->dlg, selected_cb, srch_expr_op_cb); + RND_DAD_TREE_SET_CB(ctx->dlg, ctx, ctx); + RND_DAD_END(ctx->dlg); + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + + RND_DAD_STRING(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_HIDE); + ctx->wright[RIGHT_STR] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_CHANGE_CB(ctx->dlg, srchexpr_right_cb); + + RND_DAD_INTEGER(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_HIDE); + ctx->wright[RIGHT_INT] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_MINMAX(ctx->dlg, -(1L<<30), (1L<<30)); + RND_DAD_CHANGE_CB(ctx->dlg, srchexpr_right_cb); + + RND_DAD_REAL(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_HIDE); + ctx->wright[RIGHT_DOUBLE] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_MINMAX(ctx->dlg, -(1L<<30), (1L<<30)); + RND_DAD_CHANGE_CB(ctx->dlg, srchexpr_right_cb); + + RND_DAD_CSCH_COORD(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_HIDE); + ctx->wright[RIGHT_COORD] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_CHANGE_CB(ctx->dlg, srchexpr_right_cb); + + RND_DAD_TREE(ctx->dlg, 1, 0, NULL); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_HIDE); + ctx->wright[RIGHT_CONST] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_TREE_SET_CB(ctx->dlg, selected_cb, srch_expr_right_table_cb); + RND_DAD_TREE_SET_CB(ctx->dlg, ctx, ctx); + + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_END(ctx->dlg); + RND_DAD_BUTTON_CLOSES(ctx->dlg, clbtn); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + + RND_DAD_DEFSIZE(ctx->dlg, 450, 450); + RND_DAD_NEW("search_expr", ctx->dlg, "sch-rnd search expression", ctx, rnd_true, NULL); /* type=local/modal */ + + if (fill_in_left(ctx) != 1) { + srch_expr_set_ops(ctx, op_tab, 1); /* just to get the initial tree widget width */ + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wright[RIGHT_CONST], 0); /* just to get something harmless display on the right side after open */ + } + + res = RND_DAD_RUN(ctx->dlg); + if (res == 0) { + free(expr->right); + *expr = ctx->se; + if (ctx->se.op != NULL) + expr->valid = 1; + } + else + free(ctx->se.right); + + RND_DAD_FREE(ctx->dlg); + return res; +} + + Index: tags/1.0.5/src/plugins/query/dlg_search_tab.h =================================================================== --- tags/1.0.5/src/plugins/query/dlg_search_tab.h (nonexistent) +++ tags/1.0.5/src/plugins/query/dlg_search_tab.h (revision 10414) @@ -0,0 +1,175 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - GUI + * Copyright (C) 2016,2020 Tibor 'Igor2' Palinkas (in pcb-rnd) + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * (copied from pcb-rnd by the author) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/* advanced search dialog - expressioin wizard tables; intended to be + included from the search dialog only */ + +typedef enum { + RIGHT_STR, + RIGHT_INT, + RIGHT_DOUBLE, + RIGHT_COORD, + RIGHT_CONST, + RIGHT_max +} right_type; + +typedef enum { + OPS_ANY, + OPS_EQ, + OPS_STR +} op_type_t; + +static const char *ops_any[] = {"==", "!=", ">=", "<=", ">", "<", NULL}; +static const char *ops_eq[] = {"==", "!=", NULL}; +static const char *ops_str[] = {"==", "!=", "~", NULL}; + +typedef struct expr_wizard_op_s expr_wizard_op_t; +struct expr_wizard_op_s { + const char **ops; +}; + +static expr_wizard_op_t op_tab[] = { + {ops_any}, + {ops_eq}, + {ops_str}, + {NULL} +}; + +typedef struct expr_wizard_s expr_wizard_t; +struct expr_wizard_s { + const char *left_var; + const char *left_desc; + const expr_wizard_op_t *op; + right_type rtype; + const expr_wizard_op_t *right_const; +}; + +static const char *right_const_objtype[] = { "LINE", "ARC", "POLY", "TEXT", "BITMAP", "CONN", "GRP", "GRP_REF", "PEN", NULL }; +static const char *right_const_yesno[] = {"YES", "NO", NULL}; +static const char *right_const_10[] = {"1", "0", NULL}; +static const char *right_const_halign[] = {"LEFT", "CENTER", "RIGHT", "WORD_JUST", "JUST", NULL}; +static const char *right_const_role[] = {"\"symbol\"", "\"wire-net\"", "\"terminal\"", NULL}; + +enum { + RC_OBJTYPE, + RC_YESNO, + RC_10, + RC_HALIGN, + RC_ROLE +}; + +static expr_wizard_op_t right_const_tab[] = { + {right_const_objtype}, + {right_const_yesno}, + {right_const_10}, + {right_const_halign}, + {right_const_role}, + {NULL} +}; + +static const expr_wizard_t expr_tab[] = { + {"@.a.name", "name (attribute)", &op_tab[OPS_STR], RIGHT_STR, NULL}, + {"@.a.value", "value (attribute)",&op_tab[OPS_STR], RIGHT_STR, NULL}, + {"@.a.role", "role (attribute)", &op_tab[OPS_EQ], RIGHT_CONST, &right_const_tab[RC_ROLE]}, + + {"@.ID", "object ID", &op_tab[OPS_ANY], RIGHT_INT, NULL}, + {"@.type", "object type", &op_tab[OPS_EQ], RIGHT_CONST, &right_const_tab[RC_OBJTYPE]}, + {"@.selected", "selected", &op_tab[OPS_EQ], RIGHT_CONST, &right_const_tab[RC_10]}, + {"@.locked", "explicitly locked",&op_tab[OPS_EQ], RIGHT_CONST, &right_const_tab[RC_10]}, + {"@.anylocked", "locked in any way",&op_tab[OPS_EQ], RIGHT_CONST, &right_const_tab[RC_10]}, + {"@.floater", "obj is floater", &op_tab[OPS_EQ], RIGHT_CONST, &right_const_tab[RC_10]}, + {"@.displayer", "display layer ID", &op_tab[OPS_EQ], RIGHT_INT, NULL}, + {"@.displayer_name", "display layer name",&op_tab[OPS_EQ], RIGHT_STR, NULL}, + + {NULL, "bounding box", NULL, 0, NULL}, + {"@.bbox.x1", "X1", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.bbox.y1", "Y1", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.bbox.x2", "X2", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.bbox.y2", "Y2", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.bbox.w", "width", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.bbox.h", "height", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + + {NULL, "stroke pen", NULL, 0, NULL}, + {"@.stroke.is_round", "shape is round", &op_tab[OPS_EQ], RIGHT_CONST, &right_const_tab[RC_10]}, + {"@.stroke.size", "tip size", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.stroke.dash", "dash pattern", &op_tab[OPS_EQ], RIGHT_INT, NULL}, + {"@.stroke.dash_period", "dash period", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.stroke.font_height", "font height", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.stroke.font_family", "font family", &op_tab[OPS_EQ], RIGHT_STR, NULL}, + {"@.stroke.font_style", "font style", &op_tab[OPS_EQ], RIGHT_STR, NULL}, + + + {NULL, "line", NULL, 0, NULL}, + {"@.x1", "X1", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.y1", "Y1", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.x2", "X2", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.y2", "Y2", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.lenght", "length", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.area", "area", &op_tab[OPS_ANY], RIGHT_DOUBLE, NULL}, + + {NULL, "arc", NULL, 0, NULL}, + {"@.x", "center X", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.y", "center Y", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.r", "radius", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.angle.start", "start angle", &op_tab[OPS_ANY], RIGHT_DOUBLE, NULL}, + {"@.angle.delta", "delta angle", &op_tab[OPS_ANY], RIGHT_DOUBLE, NULL}, + {"@.lenght", "length", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.area", "area", &op_tab[OPS_ANY], RIGHT_DOUBLE, NULL}, + + {NULL, "text", NULL, 0, NULL}, + {"@.x", "X", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.y", "Y", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.x2", "X2", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.y2", "Y2", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.string", "string (entered)", &op_tab[OPS_STR], RIGHT_STR, NULL}, + {"@.render", "string (rendered)",&op_tab[OPS_STR], RIGHT_STR, NULL}, + {"@.rotation", "rotation", &op_tab[OPS_ANY], RIGHT_DOUBLE, NULL}, + {"@.has_bbox", "bbox specified", &op_tab[OPS_EQ], RIGHT_CONST, &right_const_tab[RC_10]}, + {"@.dyntext", "dynamic text template",&op_tab[OPS_EQ], RIGHT_CONST, &right_const_tab[RC_10]}, + {"@.halign", "horizontal alignment",&op_tab[OPS_EQ], RIGHT_CONST, &right_const_tab[RC_HALIGN]}, + + {NULL, "polygon", NULL, 0, NULL}, + {"@.points", "points", &op_tab[OPS_ANY], RIGHT_INT, NULL}, + + {NULL, "grp", NULL, 0, NULL}, + {"@.x", "X", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.y", "Y", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.rotation", "rotation", &op_tab[OPS_ANY], RIGHT_DOUBLE, NULL}, + {"@.mirx", "X mirror", &op_tab[OPS_EQ], RIGHT_CONST, &right_const_tab[RC_10]}, + {"@.miry", "Y mirror", &op_tab[OPS_EQ], RIGHT_CONST, &right_const_tab[RC_10]}, + {"@.area", "area", &op_tab[OPS_ANY], RIGHT_DOUBLE, NULL}, + {"@.a.name", "name", &op_tab[OPS_STR], RIGHT_STR, NULL}, + {"@.a.value", "value", &op_tab[OPS_STR], RIGHT_STR, NULL}, + + {NULL, "bitmap", NULL, 0, NULL}, + {"@.x1", "x1", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.y1", "y1", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + + {NULL, NULL, NULL, 0, NULL} +}; + Index: tags/1.0.5/src/plugins/query/fields.sphash =================================================================== --- tags/1.0.5/src/plugins/query/fields.sphash (nonexistent) +++ tags/1.0.5/src/plugins/query/fields.sphash (revision 10414) @@ -0,0 +1,55 @@ +a +anylocked +p +x +y +r +cx +cy +x1 +y1 +x2 +y2 +type +angle +start +delta +rotation +rot +string +text +points +ID +bbox +width +height +area +length +length2 +render +mirx +miry +parent +selected +locked +stroke +fill +is_round +size +shape +color +dash +dash_period +font_height +font_family +font_style +displayer +displayer_name +conn +dyntext +has_bbox +halign +floater +uuid +src_uuid +level Index: tags/1.0.5/src/plugins/query/fnc.c =================================================================== --- tags/1.0.5/src/plugins/query/fnc.c (nonexistent) +++ tags/1.0.5/src/plugins/query/fnc.c (revision 10414) @@ -0,0 +1,153 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016,2020 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* Query language - basic functions */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "query_access.h" +#include "query_exec.h" + +#define PCB dontuse + +static int fnc_llen(pcb_qry_exec_t *ectx, int argc, pcb_qry_val_t *argv, pcb_qry_val_t *res) +{ + if (argc != 1) + return -1; + if (argv[0].type != PCBQ_VT_LST) + PCB_QRY_RET_INV(res); + PCB_QRY_RET_INT(res, vtp0_len(&argv[0].data.lst)); +} + +static int fnc_isvoid(pcb_qry_exec_t *ectx, int argc, pcb_qry_val_t *argv, pcb_qry_val_t *res) +{ + if (argc != 1) + return -1; + PCB_QRY_RET_INT(res, argv[0].type == PCBQ_VT_VOID); +} + +static int fnc_distance(pcb_qry_exec_t *ectx, int argc, pcb_qry_val_t *argv, pcb_qry_val_t *res) +{ + if ((argc == 4) && (argv[0].type == PCBQ_VT_COORD) && (argv[1].type == PCBQ_VT_COORD) && (argv[2].type == PCBQ_VT_COORD) && (argv[3].type == PCBQ_VT_COORD)) + PCB_QRY_RET_DBL(res, rnd_distance(argv[0].data.crd, argv[1].data.crd, argv[2].data.crd, argv[3].data.crd)); + PCB_QRY_RET_INV(res); +} + +static int fnc_abs(pcb_qry_exec_t *ectx, int argc, pcb_qry_val_t *argv, pcb_qry_val_t *res) +{ + if (argc == 1) { + switch(argv[0].type) { + case PCBQ_VT_COORD: PCB_QRY_RET_COORD(res, RND_ABS(argv[0].data.crd)); + case PCBQ_VT_LONG: PCB_QRY_RET_INT(res, RND_ABS(argv[0].data.lng)); + case PCBQ_VT_DOUBLE: PCB_QRY_RET_DBL(res, RND_ABS(argv[0].data.dbl)); + default: break; + } + } + PCB_QRY_RET_INV(res); +} + +static int fnc_double(pcb_qry_exec_t *ectx, int argc, pcb_qry_val_t *argv, pcb_qry_val_t *res) +{ + char *end; + double d; + if (argc == 1) { + switch(argv[0].type) { + case PCBQ_VT_COORD: PCB_QRY_RET_DBL(res, argv[0].data.crd); + case PCBQ_VT_LONG: PCB_QRY_RET_DBL(res, argv[0].data.lng); + case PCBQ_VT_DOUBLE: PCB_QRY_RET_DBL(res, argv[0].data.dbl); + case PCBQ_VT_STRING: + d = strtod(argv[0].data.str, &end); + if (*end == '\0') + PCB_QRY_RET_DBL(res, d); + default: break; + } + } + PCB_QRY_RET_INV(res); +} + +static int fnc_int(pcb_qry_exec_t *ectx, int argc, pcb_qry_val_t *argv, pcb_qry_val_t *res) +{ + char *end; + long d; + if (argc == 1) { + switch(argv[0].type) { + case PCBQ_VT_COORD: PCB_QRY_RET_INT(res, argv[0].data.crd); + case PCBQ_VT_LONG: PCB_QRY_RET_INT(res, argv[0].data.lng); + case PCBQ_VT_DOUBLE: PCB_QRY_RET_INT(res, argv[0].data.dbl); + case PCBQ_VT_STRING: + d = strtol(argv[0].data.str, &end, 10); + if (*end == '\0') + PCB_QRY_RET_INT(res, d); + default: break; + } + } + PCB_QRY_RET_INV(res); +} + +static int fnc_coord(pcb_qry_exec_t *ectx, int argc, pcb_qry_val_t *argv, pcb_qry_val_t *res) +{ + if (argc == 1) { + switch(argv[0].type) { + case PCBQ_VT_COORD: PCB_QRY_RET_COORD(res, argv[0].data.crd); + case PCBQ_VT_LONG: PCB_QRY_RET_COORD(res, argv[0].data.lng); + case PCBQ_VT_DOUBLE: PCB_QRY_RET_COORD(res, argv[0].data.dbl); + case PCBQ_VT_STRING: PCB_QRY_RET_COORD(res, (rnd_coord_t)rnd_get_value(argv[0].data.str, NULL, NULL, NULL)); + default: break; + } + } + PCB_QRY_RET_INV(res); +} + +#include "fnc_glue.c" +#include "fnc_list.c" + +void pcb_qry_basic_fnc_init(void) +{ + pcb_qry_fnc_reg("llen", fnc_llen); + pcb_qry_fnc_reg("abs", fnc_abs); + pcb_qry_fnc_reg("double", fnc_double); + pcb_qry_fnc_reg("int", fnc_int); + pcb_qry_fnc_reg("isvoid", fnc_isvoid); + pcb_qry_fnc_reg("coord", fnc_coord); + pcb_qry_fnc_reg("distance", fnc_distance); + pcb_qry_fnc_reg("mklist", fnc_mklist); + pcb_qry_fnc_reg("violation", fnc_violation); + pcb_qry_fnc_reg("action", fnc_action); + pcb_qry_fnc_reg("getconf", pcb_qry_fnc_getconf); + pcb_qry_fnc_reg("obj_by_idpath", fnc_obj_by_idpath); + pcb_qry_fnc_reg("text_invalid_chars", fnc_text_invalid_chars); +} Index: tags/1.0.5/src/plugins/query/fnc_glue.c =================================================================== --- tags/1.0.5/src/plugins/query/fnc_glue.c (nonexistent) +++ tags/1.0.5/src/plugins/query/fnc_glue.c (revision 10414) @@ -0,0 +1,238 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2020 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* Query language - glue functions to other infra */ + +#include + +static int fnc_action(pcb_qry_exec_t *ectx, int argc, pcb_qry_val_t *argv, pcb_qry_val_t *res) +{ + int n, retv = 0; + fgw_arg_t tmp, resa, arga[PCB_QRY_MAX_FUNC_ARGS], *arg; + + if (argv[0].type != PCBQ_VT_STRING) { + rnd_message(RND_MSG_ERROR, "query: action() first argument must be a string\n"); + return -1; + } + + /* convert query arguments to action arguments */ + for(n = 1; n < argc; n++) { + switch(argv[n].type) { + case PCBQ_VT_VOID: + arga[n].type = FGW_PTR; + arga[n].val.ptr_void = 0; + break; + case PCBQ_VT_LST: + { + long i; + csch_oidpath_list_t *list = calloc(sizeof(csch_oidpath_list_t), 1); + for(i = 0; i < argv[n].data.lst.used; i++) { + csch_oidpath_t *idp = calloc(sizeof(csch_oidpath_t), 1); + csch_oidpath_from_obj(idp, argv[n].data.lst.array[i]); + fgw_ptr_reg(&rnd_fgw, &tmp, RND_PTR_DOMAIN_IDPATH, FGW_PTR | FGW_STRUCT, idp); + csch_oidpath_list_append(list, fgw_idpath(&tmp)); + } + fgw_ptr_reg(&rnd_fgw, &(arga[n]), RND_PTR_DOMAIN_IDPATH_LIST, FGW_PTR | FGW_STRUCT, list); + } + break; + case PCBQ_VT_OBJ: + { + csch_oidpath_t *idp = calloc(sizeof(csch_oidpath_t), 1); + csch_oidpath_from_obj(idp, argv[n].data.obj); + fgw_ptr_reg(&rnd_fgw, &(arga[n]), RND_PTR_DOMAIN_IDPATH, FGW_PTR | FGW_STRUCT, idp); + } + break; + case PCBQ_VT_COORD: + arga[n].type = FGW_COORD; + fgw_coord(&arga[n]) = argv[n].data.crd; + break; + case PCBQ_VT_LONG: + arga[n].type = FGW_LONG; + arga[n].val.nat_long = argv[n].data.lng; + break; + case PCBQ_VT_DOUBLE: + arga[n].type = FGW_DOUBLE; + arga[n].val.nat_double = argv[n].data.dbl; + break; + case PCBQ_VT_STRING: + arga[n].type = FGW_STR; + arga[n].val.cstr = argv[n].data.str; + break; + } + } + + if (rnd_actionv_bin(&ectx->sheet->hidlib, argv[0].data.str, &resa, argc, arga) != 0) { + retv = -1; + goto fin; + } + + /* convert action result to query result */ + +# define FGW_TO_QRY_NUM(lst, val) res->source = NULL; res->type = PCBQ_VT_LONG; res->data.lng = val; goto fin; +# define FGW_TO_QRY_STR(lst, val) res->source = NULL; res->type = PCBQ_VT_STRING; res->data.str = rnd_strdup(val == NULL ? "" : val); goto fin; +# define FGW_TO_QRY_NIL(lst, val) res->source = NULL; res->type = PCBQ_VT_VOID; goto fin; + +/* has to free idpath and idpathlist return, noone else will have the chance */ +# define FGW_TO_QRY_PTR(lst, val) \ + if (val == NULL) { \ + res->source = NULL; \ + res->type = PCBQ_VT_VOID; \ + goto fin; \ + } \ + else if (fgw_ptr_in_domain(&rnd_fgw, val, RND_PTR_DOMAIN_IDPATH)) { \ + csch_oidpath_t *idp = val; \ + res->source = NULL; \ + res->type = PCBQ_VT_OBJ; \ + res->data.obj = csch_oidpath_resolve(ectx->sheet, idp); \ + csch_oidpath_list_remove(idp); \ + fgw_ptr_unreg(&rnd_fgw, &resa, RND_PTR_DOMAIN_IDPATH); \ + free(idp); \ + goto fin; \ + } \ + else if (fgw_ptr_in_domain(&rnd_fgw, val, RND_PTR_DOMAIN_IDPATH_LIST)) { \ + rnd_message(RND_MSG_ERROR, "query action(): can not convert object list yet\n"); \ + res->source = NULL; \ + res->type = PCBQ_VT_VOID; \ + goto fin; \ + } \ + else { \ + rnd_message(RND_MSG_ERROR, "query action(): can not convert unknown pointer\n"); \ + res->source = NULL; \ + res->type = PCBQ_VT_VOID; \ + goto fin; \ + } + + arg = &resa; + if (FGW_IS_TYPE_CUSTOM(resa.type)) + fgw_arg_conv(&rnd_fgw, &resa, FGW_AUTO); + + switch(FGW_BASE_TYPE(resa.type)) { + ARG_CONV_CASE_LONG(lst, FGW_TO_QRY_NUM); + ARG_CONV_CASE_LLONG(lst, FGW_TO_QRY_NUM); + ARG_CONV_CASE_DOUBLE(lst, FGW_TO_QRY_NUM); + ARG_CONV_CASE_LDOUBLE(lst, FGW_TO_QRY_NUM); + ARG_CONV_CASE_PTR(lst, FGW_TO_QRY_PTR); + ARG_CONV_CASE_STR(lst, FGW_TO_QRY_STR); + ARG_CONV_CASE_CLASS(lst, FGW_TO_QRY_NIL); + ARG_CONV_CASE_INVALID(lst, FGW_TO_QRY_NIL); + } + if (arg->type & FGW_PTR) { + FGW_TO_QRY_PTR(lst, arg->val.ptr_void); + } + else { + FGW_TO_QRY_NIL(lst, 0); + } + + fin:; + for(n = 1; n < argc; n++) { + switch(argv[n].type) { + case PCBQ_VT_LST: + { + csch_oidpath_list_t *list = arga[n].val.ptr_void; + csch_oidpath_list_clear(list); + free(list); + arga[n].val.ptr_void = NULL; + } + break; + default: break; + } + } + + fgw_arg_free(&rnd_fgw, &resa); + return retv; +} + +int pcb_qry_fnc_getconf(pcb_qry_exec_t *ectx, int argc, pcb_qry_val_t *argv, pcb_qry_val_t *res) +{ + rnd_conf_native_t *nat; + + if (argc != 1) + return -1; + if (argv[0].type != PCBQ_VT_STRING) + return -1; + + nat = rnd_conf_get_field(argv[0].data.str); + if (nat == NULL) + PCB_QRY_RET_INV(res); + + switch(nat->type) { + case RND_CFN_STRING: PCB_QRY_RET_STR(res, nat->val.string[0]); + case RND_CFN_BOOLEAN: PCB_QRY_RET_INT(res, nat->val.boolean[0]); + case RND_CFN_INTEGER: PCB_QRY_RET_INT(res, nat->val.integer[0]); + case RND_CFN_REAL: PCB_QRY_RET_DBL(res, nat->val.real[0]); + case RND_CFN_COORD: PCB_QRY_RET_COORD(res, nat->val.coord[0]); + + case RND_CFN_COLOR: PCB_QRY_RET_STR(res, nat->val.color[0].str); + + case RND_CFN_UNIT: + if (nat->val.unit[0] == NULL) + PCB_QRY_RET_INV(res); + else + PCB_QRY_RET_STR(res, nat->val.unit[0]->suffix); + break; + + case RND_CFN_LIST: + case RND_CFN_HLIST: + case RND_CFN_max: + PCB_QRY_RET_INV(res); + } + return 0; +} + +static int fnc_obj_by_idpath(pcb_qry_exec_t *ectx, int argc, pcb_qry_val_t *argv, pcb_qry_val_t *res) +{ + csch_sheet_t *sheet = ectx->sheet; + csch_oidpath_t path; + csch_chdr_t *obj; + + if ((argc != 1) || (argv[0].type != PCBQ_VT_STRING)) + return -1; + + if (csch_oidpath_parse(&path, argv[0].data.str) != 0) /* slash separated list of ids */ + PCB_QRY_RET_INV(res); + + obj = csch_oidpath_resolve(sheet, &path); + csch_oidpath_free(&path); + + if (obj == NULL) + PCB_QRY_RET_INV(res); + + PCB_QRY_RET_OBJ(res, obj); +} + +static int fnc_text_invalid_chars(pcb_qry_exec_t *ectx, int argc, pcb_qry_val_t *argv, pcb_qry_val_t *res) +{ + csch_chdr_t *obj; + + if ((argc != 1) || (argv[0].type != PCBQ_VT_OBJ)) + return -1; + + obj = argv[0].data.obj; + if (obj->type != CSCH_CTYPE_TEXT) + return -1; + + PCB_QRY_RET_INT(res, csch_text_invalid_chars(((csch_text_t *)obj))); +} Index: tags/1.0.5/src/plugins/query/fnc_list.c =================================================================== --- tags/1.0.5/src/plugins/query/fnc_list.c (nonexistent) +++ tags/1.0.5/src/plugins/query/fnc_list.c (revision 10414) @@ -0,0 +1,124 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2020 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* Query language - listing functions */ + +#define PCB dontuse + +static int fnc_mklist(pcb_qry_exec_t *ectx, int argc, pcb_qry_val_t *argv, pcb_qry_val_t *res) +{ + int n; + res->type = PCBQ_VT_LST; + vtp0_init(&res->data.lst); + for(n = 0; n < argc; n++) { + if (argv[n].type == PCBQ_VT_OBJ) + vtp0_append(&res->data.lst, argv[n].data.obj); + } + return 0; +} + +static int fnc_violation(pcb_qry_exec_t *ectx, int argc, pcb_qry_val_t *argv, pcb_qry_val_t *res) +{ + int n; + + if ((argc < 2) || (argc % 2 != 0)) + return -1; + + /* argument sanity checks */ + for(n = 0; n < argc; n+=2) { + pcb_qry_val_t *val = &argv[n+1]; + pcb_qry_drc_ctrl_t ctrl = pcb_qry_drc_ctrl_decode(argv[n].data.obj); + switch(ctrl) { + case PCB_QRY_DRC_GRP1: + case PCB_QRY_DRC_GRP2: + if (val->type != PCBQ_VT_OBJ) + return -1; + break; + case PCB_QRY_DRC_EXPECT: + case PCB_QRY_DRC_MEASURE: + break; /* accept as is */ + case PCB_QRY_DRC_TEXT: + break; /* accept anything */ + default: + return -1; + } + } + + res->type = PCBQ_VT_LST; + vtp0_init(&res->data.lst); + for(n = 0; n < argc; n+=2) { + pcb_qry_drc_ctrl_t ctrl = pcb_qry_drc_ctrl_decode(argv[n].data.obj); + pcb_qry_val_t *val = &argv[n+1]; + pcb_obj_qry_const_t *tmp; + + if (ctrl == PCB_QRY_DRC_TEXT) { + char *str = "", buff[128]; + switch(val->type) { + case PCBQ_VT_VOID: str = ""; break; + case PCBQ_VT_OBJ: str = ""; break; + case PCBQ_VT_LST: str = ""; break; + case PCBQ_VT_COORD: rnd_snprintf(buff, sizeof(buff), "%ld", argv[n+1].data.crd); str = buff; break; + case PCBQ_VT_LONG: rnd_snprintf(buff, sizeof(buff), "%ld", argv[n+1].data.lng); str = buff; break; + case PCBQ_VT_DOUBLE: rnd_snprintf(buff, sizeof(buff), "%f", argv[n+1].data.dbl); str = buff; break; + case PCBQ_VT_STRING: str = (char *)argv[n+1].data.str; break; + } + str = rnd_strdup(str == NULL ? "" : str); + vtp0_append(&res->data.lst, argv[n].data.obj); + vtp0_append(&res->data.lst, str); + vtp0_append(&ectx->autofree, str); + } + else if ((ctrl == PCB_QRY_DRC_EXPECT) || (ctrl == PCB_QRY_DRC_MEASURE)) { + tmp = malloc(sizeof(pcb_obj_qry_const_t)); + tmp->val = *val; + tmp->hdr.type = PCB_OBJ_QRY_CONST; + vtp0_append(&res->data.lst, argv[n].data.obj); + vtp0_append(&res->data.lst, tmp); + vtp0_append(&ectx->autofree, tmp); + } + else switch(val->type) { + case PCBQ_VT_OBJ: + vtp0_append(&res->data.lst, argv[n].data.obj); + vtp0_append(&res->data.lst, argv[n+1].data.obj); + break; + case PCBQ_VT_COORD: + case PCBQ_VT_LONG: + case PCBQ_VT_DOUBLE: + tmp = malloc(sizeof(pcb_obj_qry_const_t)); + memcpy(&tmp->val, val, sizeof(pcb_qry_val_t)); + vtp0_append(&res->data.lst, argv[n].data.obj); + vtp0_append(&res->data.lst, tmp); + vtp0_append(&ectx->autofree, tmp); + break; + case PCBQ_VT_VOID: + case PCBQ_VT_LST: + case PCBQ_VT_STRING: + /* can't be on a violation list at the moment */ + break; + } + } + return 0; +} + Index: tags/1.0.5/src/plugins/query/query.c =================================================================== --- tags/1.0.5/src/plugins/query/query.c (nonexistent) +++ tags/1.0.5/src/plugins/query/query.c (revision 10414) @@ -0,0 +1,466 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016,2019 Tibor 'Igor2' Palinkas + * Copyright (C) 2022 Tibor 'Igor2' Palinkas (slight modifications for sch-rnd) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* Query language - common code for the compiled tree and plugin administration */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "query.h" +#include "query_l.h" +#include "dlg_search.h" +#include + +#define PCB dontuse + +/******** tree helper ********/ + +csch_chdr_t pcb_qry_drc_ctrl[PCB_QRY_DRC_invalid]; + +typedef struct { + const char *name; + int has_children; +} pcb_qry_type_tab_t; + +const pcb_qry_type_tab_t type_tab[PCBQ_nodetype_max] = { + {"PCBQ_RULE", 1}, + {"PCBQ_RNAME", 0}, + {"PCBQ_EXPR_PROG", 1}, + {"PCBQ_EXPR", 1}, + {"PCBQ_ASSERT", 1}, + {"PCBQ_ITER_CTX", 0}, + {"PCBQ_OP_THUS", 1}, + {"PCBQ_OP_AND", 1}, + {"PCBQ_OP_OR", 1}, + {"PCBQ_OP_EQ", 1}, + {"PCBQ_OP_NEQ", 1}, + {"PCBQ_OP_GTEQ", 1}, + {"PCBQ_OP_LTEQ", 1}, + {"PCBQ_OP_GT", 1}, + {"PCBQ_OP_LT", 1}, + {"PCBQ_OP_ADD", 1}, + {"PCBQ_OP_SUB", 1}, + {"PCBQ_OP_MUL", 1}, + {"PCBQ_OP_DIV", 1}, + {"PCBQ_OP_MATCH", 1}, + {"PCBQ_OP_NOT", 1}, + {"PCBQ_FIELD", 0}, + {"PCBQ_FIELD_OF", 1}, + {"PCBQ_LISTVAR", 0}, + {"PCBQ_LET", 1}, + {"PCBQ_VAR", 0}, + {"PCBQ_FNAME", 0}, + {"PCBQ_FCALL", 1}, + {"PCBQ_FUNCTION", 1}, + {"PCBQ_RETURN", 1}, + {"PCBQ_ARG", 0}, + {"PCBQ_FLAG", 0}, + {"PCBQ_DATA_COORD", 0}, + {"PCBQ_DATA_DOUBLE", 0}, + {"PCBQ_DATA_STRING", 0}, + {"PCBQ_DATA_REGEX", 0}, + {"PCBQ_DATA_CONST", 0}, + {"PCBQ_DATA_OBJ", 0}, + {"PCBQ_DATA_INVALID", 0}, + {"PCBQ_DATA_LYTC", 0} +}; + +char *pcb_query_sprint_val(pcb_qry_val_t *val) +{ + switch(val->type) { + case PCBQ_VT_VOID: return rnd_strdup(""); + case PCBQ_VT_COORD: return rnd_strdup_printf("%ld", val->data.crd); + case PCBQ_VT_LONG: return rnd_strdup_printf("%ld", val->data.lng, val->data.lng); + case PCBQ_VT_DOUBLE: return rnd_strdup_printf("%f", val->data.dbl); + case PCBQ_VT_STRING: return rnd_strdup_printf("\"%s\"", val->data.str); + case PCBQ_VT_OBJ: return rnd_strdup_printf("", val->data.obj->oid); + case PCBQ_VT_LST: return rnd_strdup(""); + } + return rnd_strdup(""); +} + +const char *pcb_qry_nodetype_name(pcb_qry_nodetype_t ntype) +{ + int type = ntype; + if ((type < 0) || (type >= PCBQ_nodetype_max)) + return ""; + return type_tab[type].name; +} + +int pcb_qry_nodetype_has_children(pcb_qry_nodetype_t ntype) +{ + int type = ntype; + if ((type < 0) || (type >= PCBQ_nodetype_max)) + return 0; + return type_tab[type].has_children; +} + +pcb_qry_node_t *pcb_qry_n_alloc(pcb_qry_nodetype_t ntype) +{ + pcb_qry_node_t *nd = calloc(sizeof(pcb_qry_node_t), 1); + nd->type = ntype; + return nd; +} + +void pcb_qry_n_free(pcb_qry_node_t *nd) +{ + pcb_qry_node_t *ch, *chn; + + switch(nd->type) { + case PCBQ_RNAME: + case PCBQ_FIELD: + case PCBQ_LISTVAR: + case PCBQ_DATA_STRING: + case PCBQ_DATA_CONST: + case PCBQ_DATA_OBJ: + case PCBQ_FNAME: + free((char *)nd->data.str); + break; + + case PCBQ_DATA_REGEX: + free((char *)nd->data.str); + re_se_free(nd->precomp.regex); + break; + + case PCBQ_ITER_CTX: + pcb_qry_iter_free(nd->data.iter_ctx); + break; + + case PCBQ_FLAG: + case PCBQ_DATA_COORD: + case PCBQ_DATA_DOUBLE: + case PCBQ_DATA_INVALID: + case PCBQ_DATA_LYTC: + case PCBQ_VAR: + case PCBQ_ARG: + /* no allocated field */ + break; + + case PCBQ_LET: + case PCBQ_ASSERT: + case PCBQ_RETURN: + case PCBQ_FUNCTION: + if (nd->precomp.it_active != NULL) { + vti0_uninit(nd->precomp.it_active); + free(nd->precomp.it_active); + } + goto free_children; + + case PCBQ_OP_NOT: + case PCBQ_FIELD_OF: + case PCBQ_FCALL: + case PCBQ_OP_THUS: + case PCBQ_OP_AND: + case PCBQ_OP_OR: + case PCBQ_OP_EQ: + case PCBQ_OP_NEQ: + case PCBQ_OP_GTEQ: + case PCBQ_OP_LTEQ: + case PCBQ_OP_GT: + case PCBQ_OP_LT: + case PCBQ_OP_ADD: + case PCBQ_OP_SUB: + case PCBQ_OP_MUL: + case PCBQ_OP_DIV: + case PCBQ_OP_MATCH: + case PCBQ_RULE: + case PCBQ_EXPR_PROG: + case PCBQ_EXPR: + free_children:; + for(ch = nd->data.children; ch != NULL; ch = chn) { + chn = ch->next; + pcb_qry_n_free(ch); + } + break; + + case PCBQ_nodetype_max: break; + } + free(nd); +} + + +pcb_qry_node_t *pcb_qry_n_insert(pcb_qry_node_t *parent, pcb_qry_node_t *ch) +{ + ch->next = parent->data.children; + parent->data.children = ch; + ch->parent = parent; + return parent; +} + +pcb_qry_node_t *pcb_qry_n_append(pcb_qry_node_t *parent, pcb_qry_node_t *ch) +{ + pcb_qry_node_t *n; + + if (parent->data.children != NULL) { + for(n = parent->data.children; n->next != NULL; n = n->next) ; + n->next = ch; + } + else + parent->data.children = ch; + + /* set parent of all nodes */ + for(n = ch; n != NULL; n = n->next) + n->parent = parent; + + return parent; +} + + +static char ind[] = " "; +void pcb_qry_dump_tree_(const char *prefix, int level, pcb_qry_node_t *nd, pcb_query_iter_t *it_ctx) +{ + pcb_qry_node_t *n; + if (level < sizeof(ind)) ind[level] = '\0'; + printf("%s%s%s ", prefix, ind, pcb_qry_nodetype_name(nd->type)); + switch(nd->type) { + case PCBQ_DATA_INVALID:rnd_printf("%s%s invalid (literal)\n", prefix, ind); break; + case PCBQ_DATA_COORD: rnd_printf("%s%s %ld\n", prefix, ind, nd->data.crd); break; + case PCBQ_DATA_DOUBLE: rnd_printf("%s%s %f\n", prefix, ind, nd->data.dbl); break; + case PCBQ_DATA_CONST: rnd_printf("%s%s %s\n", prefix, ind, nd->data.str); break; + case PCBQ_DATA_OBJ: rnd_printf("%s%s %s\n", prefix, ind, nd->data.str); break; + case PCBQ_ITER_CTX: rnd_printf("%s%s vars=%d\n", prefix, ind, nd->data.iter_ctx->num_vars); break; + case PCBQ_VAR: + rnd_printf("%s%s ", prefix, ind); + if ((it_ctx != NULL) && (nd->data.crd < it_ctx->num_vars)) { + if (it_ctx->vects == NULL) + pcb_qry_iter_init(it_ctx); + printf("%s\n", it_ctx->vn[nd->data.crd]); + } + else + printf("\n", nd->data.crd); + break; + case PCBQ_FNAME: + if (nd->precomp.fnc.bui != NULL) { + const char *name = pcb_qry_fnc_name(nd->precomp.fnc.bui); + if (name == NULL) + rnd_printf("%s%s \n", prefix, ind); + else + rnd_printf("%s%s builtin %s()\n", prefix, ind, name); + } + else + rnd_printf("%s%s user %s()%s\n", prefix, ind, nd->data.str, (nd->precomp.fnc.uf == NULL ? " ERROR: not found" : "")); + break; + case PCBQ_RULE: + rnd_printf("%s%s%s\n", prefix, ind, nd->data.children->next->data.str); + n = nd->data.children->next->next; + if (n != NULL) { + for(; n != NULL; n = n->next) + pcb_qry_dump_tree_(prefix, level+1, n, it_ctx); + } + else + rnd_printf("%s%s\n", prefix, ind); + break; + case PCBQ_FIELD: + case PCBQ_LISTVAR: + case PCBQ_DATA_REGEX: + case PCBQ_DATA_STRING: rnd_printf("%s%s '%s'\n", prefix, ind, nd->data.str); break; + default: + printf("\n"); + if (level < sizeof(ind)) ind[level] = ' '; + for(n = nd->data.children; n != NULL; n = n->next) { + if (n->parent != nd) + printf("#parent# "); + pcb_qry_dump_tree_(prefix, level+1, n, it_ctx); + } + return; + } + if (level < sizeof(ind)) ind[level] = ' '; +} + +pcb_query_iter_t *pcb_qry_find_iter(pcb_qry_node_t *node) +{ + for(; node != NULL;node = node->parent) { + if ((node->type == PCBQ_EXPR_PROG) || (node->type == PCBQ_RULE) || (node->type == PCBQ_FUNCTION)) { + if (node->data.children->type == PCBQ_ITER_CTX) + return node->data.children->data.iter_ctx; + } + } + + return NULL; +} + +void pcb_qry_dump_tree(const char *prefix, pcb_qry_node_t *top) +{ + pcb_query_iter_t *iter_ctx = pcb_qry_find_iter(top); + + if (iter_ctx == NULL) + printf("\n"); + + for(; top != NULL; top = top->next) + pcb_qry_dump_tree_(prefix, 0, top, iter_ctx); +} + +/******** iter admin ********/ +pcb_query_iter_t *pcb_qry_iter_alloc(void) +{ + pcb_query_iter_t *it = calloc(1, sizeof(pcb_query_iter_t)); + htsi_init(&it->names, strhash, strkeyeq); + return it; +} + +void pcb_qry_iter_free_fields(pcb_query_iter_t *it) +{ + htsi_entry_t *e; + for(e = htsi_first(&it->names); e != NULL; e = htsi_next(&it->names, e)) + free(e->key); + htsi_uninit(&it->names); + free(it->vects); + free(it->idx); + free(it->lst); + free(it->vn); +} + +void pcb_qry_iter_free(pcb_query_iter_t *it) +{ + pcb_qry_iter_free_fields(it); + free(it); +} + + +int pcb_qry_iter_var(pcb_query_iter_t *it, const char *varname, int alloc) +{ + htsi_entry_t *e = htsi_getentry(&it->names, varname); + + if (e != NULL) + return e->value; + + if (!alloc) + return -1; + + htsi_set(&it->names, rnd_strdup(varname), it->num_vars); + return it->num_vars++; +} + +void pcb_qry_iter_init(pcb_query_iter_t *it) +{ + htsi_entry_t *e; + + if (it->vn != NULL) + return; + it->vects = calloc(sizeof(vtp0_t *), it->num_vars); + it->idx = calloc(sizeof(rnd_cardinal_t), it->num_vars); + it->lst = calloc(sizeof(pcb_qry_val_t), it->num_vars); + + it->vn = malloc(sizeof(char *) * it->num_vars); + for (e = htsi_first(&it->names); e; e = htsi_next(&it->names, e)) + it->vn[e->value] = e->key; + it->last_obj = NULL; +} + +/******** functions ********/ +static htsp_t *qfnc = NULL; + +static void pcb_qry_fnc_destroy(void) +{ + htsp_entry_t *e; + for(e = htsp_first(qfnc); e != NULL; e = htsp_next(qfnc, e)) + free(e->key); + htsp_free(qfnc); + qfnc = NULL; +} + +int pcb_qry_fnc_reg(const char *name, pcb_qry_fnc_t fnc) +{ + if (qfnc == NULL) + qfnc = htsp_alloc(strhash, strkeyeq); + if (htsp_get(qfnc, name) != NULL) + return -1; + + htsp_set(qfnc, rnd_strdup(name), rnd_cast_f2d((rnd_fptr_t)fnc)); + + return 0; +} + +pcb_qry_fnc_t pcb_qry_fnc_lookup(const char *name) +{ + if (qfnc == NULL) + return NULL; + + return (pcb_qry_fnc_t)rnd_cast_d2f(htsp_get(qfnc, name)); +} + +/* slow linear search: it's only for the dump */ +const char *pcb_qry_fnc_name(pcb_qry_fnc_t fnc) +{ + htsp_entry_t *e; + void *target = rnd_cast_f2d((rnd_fptr_t)fnc); + + if (qfnc == NULL) + return NULL; + + for(e = htsp_first(qfnc); e != NULL; e = htsp_next(qfnc, e)) + if (e->value == target) + return e->key; + return NULL; +} + +/******** parser helper ********/ +extern long pcb_qry_lex_lineno; +void qry_error(void *prog, const char *err) +{ + rnd_message(RND_MSG_ERROR, "query: %s (in line %ld)\n", err, pcb_qry_lex_lineno); +} + +int qry_wrap() +{ + return 1; +} + +/******** plugin helper ********/ +void query_action_reg(const char *cookie); + +static const char *query_cookie = "query plugin"; + +int pplg_check_ver_query(int ver_needed) { return 0; } + +void pplg_uninit_query(void) +{ + sch_rnd_search_close_all(); + rnd_remove_actions_by_cookie(query_cookie); + pcb_qry_fnc_destroy(); + qry_lex_destroy(); + rnd_event_unbind_allcookie(query_cookie); +} + +void pcb_qry_basic_fnc_init(void); + +int pplg_init_query(void) +{ + RND_API_CHK_VER; + pcb_qry_basic_fnc_init(); + query_action_reg(query_cookie); + rnd_event_bind(CSCH_EVENT_SHEET_PREUNLOAD, sch_rnd_query_ev_preunload, NULL, query_cookie); + rnd_event_bind(RND_EVENT_DESIGN_SET_CURRENT, sch_rnd_query_ev_sheet_chg, NULL, query_cookie); + return 0; +} Index: tags/1.0.5/src/plugins/query/query.h =================================================================== --- tags/1.0.5/src/plugins/query/query.h (nonexistent) +++ tags/1.0.5/src/plugins/query/query.h (revision 10414) @@ -0,0 +1,236 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#ifndef PCB_QUERY_H +#define PCB_QUERY_H + +#include +#include +#include +#include +#include "fields_sphash.h" + +#include + +typedef struct pcb_qry_val_s pcb_qry_val_t; +typedef struct pcb_query_iter_s pcb_query_iter_t; +typedef struct pcb_qry_exec_s pcb_qry_exec_t; + +typedef int (*pcb_qry_fnc_t)(pcb_qry_exec_t *ectx, int argc, pcb_qry_val_t *argv, pcb_qry_val_t *res); + +/* value of an expression */ +typedef enum pcb_qry_valtype_e { + PCBQ_VT_VOID, + PCBQ_VT_OBJ, + PCBQ_VT_LST, + PCBQ_VT_COORD, + PCBQ_VT_LONG, + PCBQ_VT_DOUBLE, + PCBQ_VT_STRING +} pcb_qry_valtype_t; + +typedef struct pcb_qry_node_s pcb_qry_node_t; + +struct pcb_qry_val_s { + pcb_qry_valtype_t type; + union { + csch_chdr_t *obj; + vtp0_t lst; + rnd_coord_t crd; + double dbl; + long lng; + const char *str; + } data; + void *source; /* TODO: for the cache */ +}; + +/* Script parsed into a tree */ +typedef enum { + PCBQ_RULE, + PCBQ_RNAME, + PCBQ_EXPR_PROG, + PCBQ_EXPR, + PCBQ_ASSERT, + PCBQ_ITER_CTX, + + PCBQ_OP_THUS, + PCBQ_OP_AND, + PCBQ_OP_OR, + PCBQ_OP_EQ, + PCBQ_OP_NEQ, + PCBQ_OP_GTEQ, + PCBQ_OP_LTEQ, + PCBQ_OP_GT, + PCBQ_OP_LT, + PCBQ_OP_ADD, + PCBQ_OP_SUB, + PCBQ_OP_MUL, + PCBQ_OP_DIV, + PCBQ_OP_MATCH, + + PCBQ_OP_NOT, + PCBQ_FIELD, + PCBQ_FIELD_OF, + PCBQ_LISTVAR, + PCBQ_LET, + PCBQ_VAR, + PCBQ_FNAME, + PCBQ_FCALL, + PCBQ_FUNCTION, + PCBQ_RETURN, + PCBQ_ARG, + + PCBQ_FLAG, /* leaf */ + + PCBQ_DATA_COORD, /* leaf */ + PCBQ_DATA_DOUBLE, /* leaf */ + PCBQ_DATA_STRING, /* leaf */ + PCBQ_DATA_REGEX, /* leaf */ + PCBQ_DATA_CONST, /* leaf */ + PCBQ_DATA_OBJ, /* leaf */ + PCBQ_DATA_INVALID, /* leaf */ + PCBQ_DATA_LYTC, /* leaf */ + + PCBQ_nodetype_max +} pcb_qry_nodetype_t; + +struct pcb_qry_node_s { + pcb_qry_nodetype_t type; + pcb_qry_node_t *next; /* sibling on this level of the tree (or NULL) */ + pcb_qry_node_t *parent; + union { /* field selection depends on ->type */ + rnd_coord_t crd; + double dbl; + const char *str; + pcb_query_iter_t *iter_ctx; + pcb_qry_node_t *children; /* first child (NULL for a leaf node) */ + } data; + union { /* field selection depends on ->type */ + query_fields_keys_t fld; /* field_sphash value from str */ + pcb_qry_val_t result; /* of pure functions and subtrees and constant values converted e.g. to coord */ + re_se_t *regex; + long cnst; /* named constant */ + long iconst; /* integer constant */ + csch_chdr_t *obj; + vti0_t *it_active; + struct { /* FCALL's FNAME*/ + pcb_qry_fnc_t bui; /* if not NULL, then data.str is NULL and this is a builtin call; if NULL, this is an user function call to node .uf */ + pcb_qry_node_t *uf; + } fnc; + } precomp; +}; + + +pcb_qry_node_t *pcb_qry_n_alloc(pcb_qry_nodetype_t ntype); +pcb_qry_node_t *pcb_qry_n_insert(pcb_qry_node_t *parent, pcb_qry_node_t *ch); +pcb_qry_node_t *pcb_qry_n_append(pcb_qry_node_t *parent, pcb_qry_node_t *ch); + +void pcb_qry_dump_tree(const char *prefix, pcb_qry_node_t *top); + +void pcb_qry_set_input(const char *script); + +struct pcb_query_iter_s { + htsi_t names; /* name->index hash */ + int num_vars, last_active; + + const char **vn; /* pointers to the hash names so they can be indexed */ + pcb_qry_val_t *lst; + vti0_t *it_active; /* points to a char array of which iterators are active */ + + /* iterator state for each variable - point into the corresponding lst[] */ + vtp0_t **vects; + rnd_cardinal_t *idx; + + csch_chdr_t *last_obj; /* last object retrieved by the expression */ +}; + +pcb_query_iter_t *pcb_qry_iter_alloc(void); +void pcb_qry_iter_free(pcb_query_iter_t *it); +void pcb_qry_iter_free_fields(pcb_query_iter_t *it); +int pcb_qry_iter_var(pcb_query_iter_t *it, const char *varname, int alloc); +void pcb_qry_iter_init(pcb_query_iter_t *it); + +void pcb_qry_n_free(pcb_qry_node_t *nd); + +pcb_query_iter_t *pcb_qry_find_iter(pcb_qry_node_t *node); + +char *pcb_query_sprint_val(pcb_qry_val_t *val); + +const char *pcb_qry_nodetype_name(pcb_qry_nodetype_t ntype); +int pcb_qry_nodetype_has_children(pcb_qry_nodetype_t ntype); + +/* functions */ +int pcb_qry_fnc_reg(const char *name, pcb_qry_fnc_t fnc); +pcb_qry_fnc_t pcb_qry_fnc_lookup(const char *name); +const char *pcb_qry_fnc_name(pcb_qry_fnc_t fnc); + +/* parser */ +void qry_error(void *prog, const char *err); + +/* external entry points for convenience */ + +/* Compile and execute a script, calling cb for each object. Returns the number + of evaluation errors or -1 if evaluation couldn't start */ +int pcb_qry_run_script(pcb_qry_exec_t *ec, csch_sheet_t *sheet, const char *script, const char *scope, void (*cb)(void *user_ctx, pcb_qry_val_t *res, csch_chdr_t *current), void *user_ctx); + +/* Compile a script; returns NULL on error, else the caller needs to call + pcb_qry_n_free() on the result to free it after use */ +pcb_qry_node_t *pcb_query_compile(const char *script); + +/* Extract a list of definitions used by the script (by compiling the script); + dst key is the definition name, val is the number of uses. Return value + is total number of definition usage. */ +int pcb_qry_extract_defs(htsi_t *dst, const char *script); + +/*** drc list-reports ***/ + +/* dynamic alloced fake objects that store constants */ + +#define PCB_OBJ_QRY_CONST 0x0100000 +typedef struct pcb_obj_qry_const_s { + csch_chdr_t hdr; + pcb_qry_val_t val; +} pcb_obj_qry_const_t; + +/* static alloced marker fake objects */ +typedef enum { + PCB_QRY_DRC_GRP1, + PCB_QRY_DRC_GRP2, + PCB_QRY_DRC_EXPECT, + PCB_QRY_DRC_MEASURE, + PCB_QRY_DRC_TEXT, + PCB_QRY_DRC_invalid +} pcb_qry_drc_ctrl_t; + +extern csch_chdr_t pcb_qry_drc_ctrl[PCB_QRY_DRC_invalid]; + +#define pcb_qry_drc_ctrl_decode(obj) \ +((((obj) >= &pcb_qry_drc_ctrl[0]) && ((obj) < &pcb_qry_drc_ctrl[PCB_QRY_DRC_invalid])) \ + ? ((obj) - &pcb_qry_drc_ctrl[0]) : PCB_QRY_DRC_invalid) + + + +#endif Index: tags/1.0.5/src/plugins/query/query.pup =================================================================== --- tags/1.0.5/src/plugins/query/query.pup (nonexistent) +++ tags/1.0.5/src/plugins/query/query.pup (revision 10414) @@ -0,0 +1,7 @@ +$class feature +$short query language +$long sch-rnd query language: execute expressions on objects and rules for the programmed drc. +$state works +$package (core) +default buildin +autoload 1 Index: tags/1.0.5/src/plugins/query/query_access.c =================================================================== --- tags/1.0.5/src/plugins/query/query_access.c (nonexistent) +++ tags/1.0.5/src/plugins/query/query_access.c (revision 10414) @@ -0,0 +1,628 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - query + * Copyright (C) 2016,2020 Tibor 'Igor2' Palinkas (in pcb-rnd) + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * (copied from pcb-rnd by the author) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/* Query language - access to / extract core data */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "query_access.h" +#include "query_exec.h" +#include "fields_sphash.h" + +#define APPEND(_lst_, _obj_) vtp0_append((vtp0_t *)_lst_, _obj_) + +static int list_grp(void *ctx, csch_cgrp_t *grp, int enter, csch_cmask_t mask) +{ + htip_entry_t *e; + + for(e = htip_first(&grp->id2obj); e != NULL; e = htip_next(&grp->id2obj, e)) { + csch_chdr_t *obj = e->value; + if (csch_ctype_in_cmask(obj->type, mask)) + APPEND(ctx, obj); + if (enter && (csch_obj_is_grp(obj))) + list_grp(ctx, (csch_cgrp_t *)obj, enter, mask); + } + + return 0; +} + +void pcb_qry_list_all_sheet(pcb_qry_val_t *lst, csch_sheet_t *sheet, csch_cmask_t mask) +{ + assert(lst->type == PCBQ_VT_LST); + list_grp(&lst->data.lst, &sheet->direct, 1, mask); +} + +void pcb_qry_list_all_sheet_indirect(pcb_qry_val_t *lst, csch_sheet_t *sheet, csch_cmask_t mask) +{ + assert(lst->type == PCBQ_VT_LST); + list_grp(&lst->data.lst, &sheet->indirect, 1, mask); +} + +void pcb_qry_list_all_grp(pcb_qry_val_t *lst, csch_cgrp_t *grp, csch_cmask_t mask) +{ + list_grp(&lst->data.lst, grp, 1, mask); +} + + +void pcb_qry_list_free(pcb_qry_val_t *lst_) +{ + vtp0_uninit(&lst_->data.lst); +} + +int pcb_qry_list_cmp(pcb_qry_val_t *lst1, pcb_qry_val_t *lst2) +{ + abort(); +} + +/***********************/ + +static int chdr_level(csch_chdr_t *obj) +{ + int l = 0; + csch_cgrp_t *grp; + + for(grp = obj->parent; grp != NULL; grp = grp->hdr.parent) l++; + + return l; +} + +/* set dst to point to the idxth field assuming field 0 is fld. Returns -1 + if there are not enough fields */ +#define fld_nth_req(dst, fld, idx) \ +do { \ + int __i__ = idx; \ + pcb_qry_node_t *__f__; \ + for(__f__ = (fld); __i__ > 0; __i__--, __f__ = __f__->next) { \ + if (__f__ == NULL) \ + return -1; \ + } \ + (dst) = __f__; \ +} while(0) + +#define fld_nth_opt(dst, fld, idx) \ +do { \ + int __i__ = idx; \ + pcb_qry_node_t *__f__; \ + for(__f__ = (fld); (__i__ > 0) && (__f__ != NULL); __i__--, __f__ = __f__->next) ; \ + (dst) = __f__; \ +} while(0) + +/* sets const char *s to point to the string data of the idxth field. Returns + -1 if tere are not enooung fields */ +#define fld2str_req(s, fld, idx) \ +do { \ + pcb_qry_node_t *_f_; \ + fld_nth_req(_f_, fld, idx); \ + if ((_f_ == NULL) || (_f_->type != PCBQ_FIELD)) \ + return -1; \ + (s) = _f_->data.str; \ +} while(0) + +/* Same, but doesn't return -1 on missing field but sets s to NULL */ +#define fld2str_opt(s, fld, idx) \ +do { \ + pcb_qry_node_t *_f_; \ + const char *__res__; \ + fld_nth_opt(_f_, fld, idx); \ + if (_f_ != NULL) { \ + if (_f_->type != PCBQ_FIELD) \ + return -1; \ + __res__ = _f_->data.str; \ + } \ + else \ + __res__ = NULL; \ + (s) = __res__; \ +} while(0) + +/* sets query_fields_keys_t h to point to the precomp field of the idxth field. + Returns -1 if tere are not enooung fields */ +#define fld2hash_req(h, fld, idx) \ +do { \ + pcb_qry_node_t *_f_; \ + fld_nth_req(_f_, fld, idx); \ + if ((_f_ == NULL) || (_f_->type != PCBQ_FIELD)) \ + return -1; \ + (h) = _f_->precomp.fld; \ +} while(0) + +/* Same, but doesn't return -1 on missing field but sets s to query_fields_SPHASH_INVALID */ +#define fld2hash_opt(h, fld, idx) \ +do { \ + pcb_qry_node_t *_f_; \ + query_fields_keys_t *__res__; \ + fld_nth_opt(_f_, fld, idx); \ + if (_f_ != NULL) { \ + if (_f_->type != PCBQ_FIELD) \ + return -1; \ + __res__ = _f_->precomp.fld; \ + } \ + else \ + __res__ = query_fields_SPHASH_INVALID; \ + (s) = __res__; \ +} while(0) + +#define COMMON_FIELDS(ec, obj, fh1, fld, res) \ +do { \ + if (fh1 == query_fields_ID) { \ + PCB_QRY_RET_INT(res, obj->oid); \ + } \ + \ + if (fh1 == query_fields_bbox) { \ + csch_rtree_box_t *bx = &(obj)->bbox; \ + query_fields_keys_t fh2; \ + \ + fld2hash_req(fh2, fld, 1); \ + switch(fh2) { \ + case query_fields_x1: PCB_QRY_RET_COORD(res, bx->x1); \ + case query_fields_y1: PCB_QRY_RET_COORD(res, bx->y1); \ + case query_fields_x2: PCB_QRY_RET_COORD(res, bx->x2); \ + case query_fields_y2: PCB_QRY_RET_COORD(res, bx->y2); \ + case query_fields_width: PCB_QRY_RET_COORD(res, bx->x2 - bx->x1); \ + case query_fields_height: PCB_QRY_RET_COORD(res, bx->y2 - bx->y1); \ + default:; \ + } \ + PCB_QRY_RET_INV(res); \ + } \ + \ + if (fh1 == query_fields_type) \ + PCB_QRY_RET_INT(res, obj->type); \ + \ + if (fh1 == query_fields_level) \ + PCB_QRY_RET_INT(res, chdr_level(obj)); \ + \ + if (fh1 == query_fields_selected) \ + PCB_QRY_RET_INT(res, csch_chdr_is_selected(obj)); \ + \ + if (fh1 == query_fields_locked) \ + PCB_QRY_RET_INT(res, obj->lock); \ + \ + if (fh1 == query_fields_anylocked) \ + PCB_QRY_RET_INT(res, csch_cobj_is_locked(obj)); \ + \ + if (fh1 == query_fields_floater) \ + PCB_QRY_RET_INT(res, obj->floater); \ + \ + if (fh1 == query_fields_parent) \ + return field_parent_obj(ec, obj, fld->next, res); \ + \ + if (fh1 == query_fields_displayer) \ + PCB_QRY_RET_INT(res, obj->dsply); \ + if (fh1 == query_fields_displayer_name) \ + PCB_QRY_RET_STR(res, csch_dsply_name(obj->dsply)); \ + \ + if (fh1 == query_fields_conn) \ + return field_obj_conn(ec, &obj->conn, res); \ +} while(0) + + +RND_INLINE double obj_thickness(csch_chdr_t *o) +{ + if (o->stroke == NULL) + return 1; + return o->stroke->size; +} + +RND_INLINE int field_obj_attr(pcb_qry_exec_t *ec, csch_cgrp_t *o, const char *key, pcb_qry_val_t *res) +{ + csch_attrib_t *a = csch_attrib_get(&o->attr, key); + long n; + + if (a == NULL) + PCB_QRY_RET_STR(res, NULL); + if (a->val != NULL) + PCB_QRY_RET_STR(res, a->val); + + res->type = PCBQ_VT_LST; + vtp0_init(&res->data.lst); + for(n = 0; n < a->arr.used; n++) { + pcb_qry_val_t *v = malloc(sizeof(pcb_qry_val_t)); + + v->type = PCBQ_VT_STRING; + v->data.str = a->arr.array[n]; + v->source = NULL; + vtp0_append(&ec->autofree, v); + vtp0_append(&res->data.lst, v); + } + return 0; +} + +RND_INLINE int field_obj_conn(pcb_qry_exec_t *ec, vtp0_t *conn_fld, pcb_qry_val_t *res) +{ + long n; + + res->type = PCBQ_VT_LST; + vtp0_init(&res->data.lst); + for(n = 0; n < conn_fld->used; n++) { + pcb_qry_val_t *v = malloc(sizeof(pcb_qry_val_t)); + + v->type = PCBQ_VT_OBJ; + v->data.obj = conn_fld->array[n]; + v->source = NULL; + vtp0_append(&ec->autofree, v); + vtp0_append(&res->data.lst, v); + } + + return 0; +} + +RND_INLINE int field_obj_pen(csch_chdr_t *o, csch_comm_str_t penname, csch_cpen_t *pen, pcb_qry_node_t *fld, pcb_qry_val_t *res) +{ + query_fields_keys_t fh1; + + if (fld == NULL) + PCB_QRY_RET_STR(res, penname.str); + + if (pen == NULL) + PCB_QRY_RET_INV(res); + + fld2hash_req(fh1, fld, 0); + switch(fh1) { + case query_fields_shape: + switch(pen->shape) { + case CSCH_PSHP_ROUND: PCB_QRY_RET_STR(res, "round"); + case CSCH_PSHP_SQUARE: PCB_QRY_RET_STR(res, "square"); + } + PCB_QRY_RET_INV(res); + case query_fields_is_round: PCB_QRY_RET_INT(res, pen->shape == CSCH_PSHP_ROUND); + case query_fields_size: PCB_QRY_RET_COORD(res, pen->size); + case query_fields_color: PCB_QRY_RET_STR(res, pen->color.str); + case query_fields_dash: PCB_QRY_RET_INT(res, pen->dash); + case query_fields_dash_period: PCB_QRY_RET_COORD(res, pen->dash_period); + case query_fields_font_height: PCB_QRY_RET_COORD(res, pen->font_height); + case query_fields_font_family: PCB_QRY_RET_STR(res, pen->font_family); + case query_fields_font_style: PCB_QRY_RET_STR(res, pen->font_style); + default: break; + } + + PCB_QRY_RET_INV(res); +} + + +static double pcb_line_len2(csch_line_t *l) +{ + double x = l->inst.c.p1.x - l->inst.c.p2.x; + double y = l->inst.c.p1.y - l->inst.c.p2.y; + return x*x + y*y; +} + +static int field_line(pcb_qry_exec_t *ec, csch_chdr_t *obj, pcb_qry_node_t *fld, pcb_qry_val_t *res) +{ + csch_line_t *l = (csch_line_t *)obj; + query_fields_keys_t fh1; + + fld2hash_req(fh1, fld, 0); + + switch(fh1) { + case query_fields_stroke: return field_obj_pen(obj, obj->stroke_name, obj->stroke, fld->next, res); + default: break; + } + + if (fld->next != NULL) + PCB_QRY_RET_INV(res); + + switch(fh1) { + case query_fields_x1: PCB_QRY_RET_COORD(res, l->inst.c.p1.x); + case query_fields_y1: PCB_QRY_RET_COORD(res, l->inst.c.p1.y); + case query_fields_x2: PCB_QRY_RET_COORD(res, l->inst.c.p2.x); + case query_fields_y2: PCB_QRY_RET_COORD(res, l->inst.c.p2.y); + case query_fields_length: + PCB_QRY_RET_DBL(res, ((rnd_coord_t)rnd_round(sqrt(pcb_line_len2(l))))); + break; + case query_fields_length2: + PCB_QRY_RET_DBL(res, pcb_line_len2(l)); + break; + case query_fields_area: + { + double th = obj_thickness(&l->hdr); + double len = rnd_round(sqrt(pcb_line_len2(l))); + PCB_QRY_RET_DBL(res, len * th + th*th/4*M_PI); + break; + } + default:; + } + + PCB_QRY_RET_INV(res); +} + +static double pcb_arc_len(csch_arc_t *a) +{ + double r = (a->inst.c.r + a->inst.c.r)/2; + return r * a->inst.c.delta; +} + +static int field_arc(pcb_qry_exec_t *ec, csch_chdr_t *obj, pcb_qry_node_t *fld, pcb_qry_val_t *res) +{ + csch_arc_t *a = (csch_arc_t *)obj; + query_fields_keys_t fh1, fh2; + + fld2hash_req(fh1, fld, 0); + + if (fh1 == query_fields_angle) { + fld2hash_req(fh2, fld, 1); + switch(fh2) { + case query_fields_start: PCB_QRY_RET_DBL(res, a->inst.c.start * RND_RAD_TO_DEG); + case query_fields_delta: PCB_QRY_RET_DBL(res, a->inst.c.delta * RND_RAD_TO_DEG); + default:; + } + PCB_QRY_RET_INV(res); + } + + switch(fh1) { + case query_fields_stroke: return field_obj_pen(obj, obj->stroke_name, obj->stroke, fld->next, res); + default: break; + } + + if (fld->next != NULL) + PCB_QRY_RET_INV(res); + + switch(fh1) { + case query_fields_cx: + case query_fields_x: PCB_QRY_RET_COORD(res, a->inst.c.c.x); + case query_fields_cy: + case query_fields_y: PCB_QRY_RET_COORD(res, a->inst.c.c.y); + case query_fields_r: PCB_QRY_RET_COORD(res, a->inst.c.r); + case query_fields_length: + PCB_QRY_RET_COORD(res, ((rnd_coord_t)rnd_round(pcb_arc_len(a)))); + break; + case query_fields_length2: + { + double l = pcb_arc_len(a); + PCB_QRY_RET_DBL(res, l*l); + } + break; + case query_fields_area: + { + double th = obj_thickness(&a->hdr); + double len = pcb_arc_len(a); + PCB_QRY_RET_DBL(res, len * th + th*th/4*M_PI); /* approx */ + } + break; + default:; + } + + PCB_QRY_RET_INV(res); +} + +static int field_bitmap(pcb_qry_exec_t *ec, csch_chdr_t *obj, pcb_qry_node_t *fld, pcb_qry_val_t *res) +{ +/* csch_cbitmap_t *b = (csch_cbitmap_t *)obj;*/ + query_fields_keys_t fh1; + + fld2hash_req(fh1, fld, 0); + + if (fld->next != NULL) + PCB_QRY_RET_INV(res); + +TODO("bitmap: field access"); + + switch(fh1) { + default:; + } + PCB_QRY_RET_INV(res); +} + +static int field_text(pcb_qry_exec_t *ec, csch_chdr_t *obj, pcb_qry_node_t *fld, pcb_qry_val_t *res) +{ + csch_text_t *t = (csch_text_t *)obj; + query_fields_keys_t fh1; + + fld2hash_req(fh1, fld, 0); + + if (fld->next != NULL) + PCB_QRY_RET_INV(res); + + switch(fh1) { + case query_fields_x1: + case query_fields_x: PCB_QRY_RET_COORD(res, t->inst1.x); + case query_fields_y1: + case query_fields_y: PCB_QRY_RET_COORD(res, t->inst1.y); + case query_fields_x2: PCB_QRY_RET_COORD(res, t->inst2.x); + case query_fields_y2: PCB_QRY_RET_COORD(res, t->inst2.y); + case query_fields_rotation: PCB_QRY_RET_DBL(res, t->inst_rot); + case query_fields_mirx: PCB_QRY_RET_INT(res, t->inst_mirx); + case query_fields_miry: PCB_QRY_RET_INT(res, t->inst_miry); + case query_fields_string: PCB_QRY_RET_STR(res, t->text); + case query_fields_text: PCB_QRY_RET_STR(res, t->text); + case query_fields_render: PCB_QRY_RET_STR(res, csch_text_get_rtext(t)); + case query_fields_dyntext: PCB_QRY_RET_INT(res, t->dyntext); + case query_fields_has_bbox: PCB_QRY_RET_INT(res, t->has_bbox); + case query_fields_halign: PCB_QRY_RET_INT(res, t->halign); + + case query_fields_area: + TODO("this is wrong for 45 degree rotated text, use isnt1 and isnt2 instead"); + PCB_QRY_RET_DBL(res, (double)(obj->bbox.y2 - obj->bbox.y1) * (double)(obj->bbox.x2 - obj->bbox.x1)); + default:; + } + + PCB_QRY_RET_INV(res); +} + +static int field_pen(pcb_qry_exec_t *ec, csch_chdr_t *obj, pcb_qry_node_t *fld, pcb_qry_val_t *res) +{ + csch_cpen_t *p = (csch_cpen_t *)obj; + + return field_obj_pen(obj, p->name, p, fld, res); +} + +static int field_conn(pcb_qry_exec_t *ec, csch_chdr_t *obj, pcb_qry_node_t *fld, pcb_qry_val_t *res) +{ + csch_conn_t *c = (csch_conn_t *)obj; + query_fields_keys_t fh1; + + fld2hash_req(fh1, fld, 0); + + if (fld->next != NULL) + PCB_QRY_RET_INV(res); + + switch(fh1) { + case query_fields_conn: return field_obj_conn(ec, &c->conn, res); + default: break; + } + + PCB_QRY_RET_INV(res); +} + +static int field_polygon(pcb_qry_exec_t *ec, csch_chdr_t *obj, pcb_qry_node_t *fld, pcb_qry_val_t *res) +{ + csch_cpoly_t *p = (csch_cpoly_t *)obj; + query_fields_keys_t fh1; + + fld2hash_req(fh1, fld, 0); + + switch(fh1) { + case query_fields_stroke: return field_obj_pen(obj, obj->stroke_name, obj->stroke, fld->next, res); + case query_fields_fill: return field_obj_pen(obj, obj->fill_name, obj->fill, fld->next, res); + default: break; + } + + if (fld->next != NULL) + PCB_QRY_RET_INV(res); + + switch(fh1) { + case query_fields_points: PCB_QRY_RET_INT(res, p->outline.used); + case query_fields_area: + TODO("calculate area"); + PCB_QRY_RET_DBL(res, 0); + default:; + } + + PCB_QRY_RET_INV(res); +} + +static int field_grp(pcb_qry_exec_t *ec, csch_chdr_t *obj, pcb_qry_node_t *fld, pcb_qry_val_t *res) +{ + csch_cgrp_t *g = (csch_cgrp_t *)obj; + query_fields_keys_t fh1; + + fld2hash_req(fh1, fld, 0); + if (fh1 == query_fields_a) { + const char *s2; + fld2str_req(s2, fld, 1); + return field_obj_attr(ec, g, s2, res); + } + + if (fld->next != NULL) + PCB_QRY_RET_INV(res); + + switch(fh1) { + case query_fields_x: PCB_QRY_RET_COORD(res, g->xform.x); + case query_fields_y: PCB_QRY_RET_COORD(res, g->xform.y); + case query_fields_rotation: PCB_QRY_RET_DBL(res, g->xform.rot); + case query_fields_mirx: PCB_QRY_RET_INT(res, g->xform.mirx); + case query_fields_miry: PCB_QRY_RET_INT(res, g->xform.miry); + case query_fields_area: PCB_QRY_RET_DBL(res, (double)(obj->bbox.y2 - obj->bbox.y1) * (double)(obj->bbox.x2 - obj->bbox.x1)); + case query_fields_uuid: PCB_QRY_RET_UID(res, g->uuid); + case query_fields_src_uuid: + if ((g->hdr.type == CSCH_CTYPE_GRP) && (!minuid_is_nil(g->data.grp.src_uuid))) + PCB_QRY_RET_UID(res, g->data.grp.src_uuid); + break; + default:; + } + PCB_QRY_RET_INV(res); +} + +static int field_parent_obj(pcb_qry_exec_t *ec, csch_chdr_t *obj, pcb_qry_node_t *fld, pcb_qry_val_t *res); + +static int field_grp_from_ptr(pcb_qry_exec_t *ec, csch_cgrp_t *grp, pcb_qry_node_t *fld, pcb_qry_val_t *res) +{ + csch_chdr_t *obj = (csch_chdr_t *)grp; + query_fields_keys_t fh1; + + fld2hash_req(fh1, fld, 0); + COMMON_FIELDS(ec, obj, fh1, fld, res); + + return field_grp(ec, obj, fld, res); +} + +static int field_parent_obj(pcb_qry_exec_t *ec, csch_chdr_t *obj, pcb_qry_node_t *fld, pcb_qry_val_t *res) +{ + const char *s1; + csch_cgrp_t *parent = obj->parent; + + /* if parent is not a group (or not available) evaluate to invalid */ + if (parent == NULL) + PCB_QRY_RET_INV(res); + + /* check subfield, if there's none, return the subcircuit object */ + fld2str_opt(s1, fld, 0); + if (s1 == NULL) { + res->source = NULL; + res->type = PCBQ_VT_OBJ; + res->data.obj = (csch_chdr_t *)parent; + return 0; + } + + /* return subfields of the parent group */ + return field_grp_from_ptr(ec, parent, fld, res); +} + +/***/ + +int pcb_qry_obj_field(pcb_qry_exec_t *ec, pcb_qry_val_t *objval, pcb_qry_node_t *fld, pcb_qry_val_t *res) +{ + csch_chdr_t *obj; + query_fields_keys_t fh1; + + if (objval->type != PCBQ_VT_OBJ) + return -1; + obj = objval->data.obj; + + res->source = NULL; + + fld2hash_req(fh1, fld, 0); + + COMMON_FIELDS(ec, obj, fh1, fld, res); + + switch(obj->type) { + case CSCH_CTYPE_LINE: return field_line(ec, obj, fld, res); + case CSCH_CTYPE_TEXT: return field_text(ec, obj, fld, res); + case CSCH_CTYPE_POLY: return field_polygon(ec, obj, fld, res); + case CSCH_CTYPE_ARC: return field_arc(ec, obj, fld, res); + case CSCH_CTYPE_BITMAP: return field_bitmap(ec, obj, fld, res); + case CSCH_CTYPE_GRP: return field_grp(ec, obj, fld, res); + case CSCH_CTYPE_GRP_REF: return field_grp(ec, obj, fld, res); + case CSCH_CTYPE_PEN: return field_pen(ec, obj, fld, res); + case CSCH_CTYPE_CONN: return field_conn(ec, obj, fld, res); + default:; + } + + return -1; +} + Index: tags/1.0.5/src/plugins/query/query_access.h =================================================================== --- tags/1.0.5/src/plugins/query/query_access.h (nonexistent) +++ tags/1.0.5/src/plugins/query/query_access.h (revision 10414) @@ -0,0 +1,47 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* Query language - access to / extract core data */ + +#ifndef PCB_QUERY_ACCESS_H +#define PCB_QUERY_ACCESS_H + +#include "query.h" + +/* Append objects with matching type to lst */ +void pcb_qry_list_all_sheet(pcb_qry_val_t *lst, csch_sheet_t *sheet, csch_cmask_t mask); +void pcb_qry_list_all_sheet_indirect(pcb_qry_val_t *lst, csch_sheet_t *sheet, csch_cmask_t mask); +void pcb_qry_list_all_grp(pcb_qry_val_t *lst, csch_cgrp_t *grp, csch_cmask_t mask); + + +int pcb_qry_list_cmp(pcb_qry_val_t *lst1, pcb_qry_val_t *lst2); + +void pcb_qry_list_free(pcb_qry_val_t *lst_); + +int pcb_qry_obj_field(pcb_qry_exec_t *ec, pcb_qry_val_t *obj, pcb_qry_node_t *fld, pcb_qry_val_t *res); + + +#endif Index: tags/1.0.5/src/plugins/query/query_act.c =================================================================== --- tags/1.0.5/src/plugins/query/query_act.c (nonexistent) +++ tags/1.0.5/src/plugins/query/query_act.c (revision 10414) @@ -0,0 +1,663 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016,2019,2020 Tibor 'Igor2' Palinkas + * Copyright (C) 2022, 2023 Tibor 'Igor2' Palinkas (slight modifications for sch-rnd) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* Query language - actions */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "query.h" +#include "query_y.h" +#include "query_exec.h" +#include "query_access.h" +#include +#include +#include "dlg_search.h" +#include +#include +#include + +static const char csch_acts_query[] = + "query(dump, expr) - dry run: compile and dump an expression\n" + "query(eval|evalidp, expr) - compile and evaluate an expression and print a list of results on stdout\n" + "query(count, expr) - compile and evaluate an expression and return the number of matched objects (-1 on error)\n" + "query(select|unselect|view, expr) - select or unselect or build a view of objects matching an expression\n" + "query(append, idplist, expr) - compile and run expr and append the idpath of resulting objects on idplist\n" + ; +static const char csch_acth_query[] = "Perform various queries on concrete model data."; + +typedef struct { + int trues, falses; + unsigned print_idpath:1; +} eval_stat_t; + +static void count_cb(void *user_ctx, pcb_qry_val_t *res, csch_chdr_t *current) +{ + eval_stat_t *st = (eval_stat_t *)user_ctx; + int t; + + t = pcb_qry_is_true(res); + if (t) + st->trues++; +} + +static void eval_cb(void *user_ctx, pcb_qry_val_t *res, csch_chdr_t *current) +{ + char *resv; + eval_stat_t *st = (eval_stat_t *)user_ctx; + int t; + + if (res->type == PCBQ_VT_VOID) { + printf(" \n"); + st->falses++; + return; + } + + if (st->print_idpath && (res->type == PCBQ_VT_OBJ)) { + char *idps = csch_chdr_to_oidpath_str(res->data.obj); + st->trues++; + printf(" \n", idps); + free(idps); + return; + } + + if ((res->type != PCBQ_VT_COORD) && (res->type != PCBQ_VT_LONG)) { + st->trues++; + resv = pcb_query_sprint_val(res); + printf(" %s\n", resv); + free(resv); + return; + } + + t = pcb_qry_is_true(res); + printf(" %s", t ? "true" : "false"); + if (t) { + resv = pcb_query_sprint_val(res); + printf(" (%s)\n", resv); + free(resv); + st->trues++; + } + else { + printf("\n"); + st->falses++; + } +} + +typedef struct { + csch_sheet_t *sheet; + rnd_cardinal_t cnt; + enum { FLAGOP_SELECT, FLAGOP_UNSELECT } act; +} flagop_t; + +static void flagop_cb(void *user_ctx, pcb_qry_val_t *res, csch_chdr_t *obj) +{ + flagop_t *sel = (flagop_t *)user_ctx; + if (!pcb_qry_is_true(res)) + return; + + { + switch(sel->act) { + case FLAGOP_SELECT: + if (!obj->selected) { + csch_cobj_select(sel->sheet, obj); + sel->cnt++; + } + break; + case FLAGOP_UNSELECT: + if (obj->selected) { + csch_cobj_unselect(sel->sheet, obj); + sel->cnt++; + } + break; + } + } +} + +static void append_cb(void *user_ctx, pcb_qry_val_t *res, csch_chdr_t *current) +{ + csch_oidpath_list_t *list = user_ctx; + csch_oidpath_t *idp; + + if (!pcb_qry_is_true(res)) + return; + + idp = calloc(sizeof(csch_oidpath_t), 1); + csch_oidpath_from_obj(idp, current); + csch_oidpath_list_append(list, idp); +} + +static void view_cb(void *user_ctx, pcb_qry_val_t *res, csch_chdr_t *current) +{ + vtp0_t *arr = user_ctx; + + if (!pcb_qry_is_true(res)) + return; + + vtp0_append(arr, current); +} + +pcb_qry_node_t *pcb_query_compile(const char *script) +{ + pcb_qry_node_t *prg = NULL; + + pcb_qry_set_input(script); + qry_parse(&prg); + return prg; +} + +int pcb_qry_run_script(pcb_qry_exec_t *ec, csch_sheet_t *sheet, const char *script, const char *scope, void (*cb)(void *user_ctx, pcb_qry_val_t *res, csch_chdr_t *current), void *user_ctx) +{ + pcb_qry_node_t *prg = NULL; + int res; + int project_scope = 0, bufno = -1; /* empty scope means board */ + + if (script == NULL) { + rnd_message(RND_MSG_ERROR, "Compilation error: no script specified.\n"); + return -1; + } + + pcb_qry_set_input(script); + qry_parse(&prg); + + if (prg == NULL) { + rnd_message(RND_MSG_ERROR, "Compilation error.\n"); + return -1; + } + + /* decode scope and set bufno */ + if ((scope != NULL) && (*scope != '\0')) { + if (strcmp(scope, "project") == 0) { + bufno = -1; + project_scope = 1; + } + else if (strcmp(scope, "sheet") == 0) bufno = -1; + else if (strcmp(scope, "sheet-indirect") == 0) bufno = -2; + else if (strncmp(scope, "buffer", 6) == 0) { + scope += 6; + if (*scope != '\0') { + char *end; + bufno = strtol(scope, &end, 10); + if (*end != '\0') { + rnd_message(RND_MSG_ERROR, "Invalid buffer number: '%s': not an integer\n", scope); + pcb_qry_n_free(prg); + return -1; + } + bufno--; + if ((bufno < 0) || (bufno >= SCH_RND_BUFFER_MAX)) { + rnd_message(RND_MSG_ERROR, "Invalid buffer number: '%d' out of range 1..%d\n", bufno+1, SCH_RND_BUFFER_MAX); + pcb_qry_n_free(prg); + return -1; + } + } + else + bufno = conf_core.editor.buffer_number; + } + else { + rnd_message(RND_MSG_ERROR, "Invalid scope: '%s': must be board or buffer or bufferN\n", scope); + pcb_qry_n_free(prg); + return -1; + } + } + + if (project_scope) { + long n; + rnd_project_t *prj = sheet->hidlib.project; + + for(n = 0; n < prj->designs.used; n++) { + int r = pcb_qry_run(ec, prj->designs.array[n], prg, bufno, cb, user_ctx); + if (r < 0) { + res = r; + break; + } + res += r; + } + } + else + res = pcb_qry_run(ec, sheet, prg, bufno, cb, user_ctx); + pcb_qry_n_free(prg); + return res; +} + +extern int pcb_qry_fnc_getconf(pcb_qry_exec_t *ectx, int argc, pcb_qry_val_t *argv, pcb_qry_val_t *res); +static void pcb_qry_extract_defs_(htsi_t *dst, pcb_qry_node_t *nd, int *total) +{ + if (nd->type == PCBQ_FCALL) { + pcb_qry_node_t *fname = nd->data.children; + if ((fname->type == PCBQ_FNAME) && (fname->precomp.fnc.bui == pcb_qry_fnc_getconf) && (fname->next->type == PCBQ_DATA_STRING)) { + const char *name = fname->next->data.str; + htsi_entry_t *e; + if (strncmp(name, "design/drc/", 11) == 0) { + name += 11; + e = htsi_getentry(dst, name); + if (e == NULL) { + htsi_set(dst, rnd_strdup(name), 0); + e = htsi_getentry(dst, name); + } + e->value++; + (*total)++; + } + } + } + + /* RULE needs special recursion */ + if (nd->type == PCBQ_RULE) { + for(nd = nd->data.children->next->next; nd != NULL; nd = nd->next) + pcb_qry_extract_defs_(dst, nd, total); + return; + } + + /* recurse */ + if (pcb_qry_nodetype_has_children(nd->type)) + for(nd = nd->data.children; nd != NULL; nd = nd->next) + pcb_qry_extract_defs_(dst, nd, total); +} + +int pcb_qry_extract_defs(htsi_t *dst, const char *script) +{ + pcb_qry_node_t *prg = NULL; + int total = 0; + + pcb_qry_set_input(script); + qry_parse(&prg); + if (prg == NULL) + return -1; + + pcb_qry_extract_defs_(dst, prg, &total); + + pcb_qry_n_free(prg); + return total; +} + + +static fgw_error_t csch_act_query(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_design_t *hidlib = RND_ACT_DESIGN; + csch_sheet_t *sheet = (csch_sheet_t *)hidlib; + const char *cmd, *arg = NULL, *scope = NULL; + flagop_t sel; + + sel.cnt = 0; + + RND_ACT_CONVARG(1, FGW_STR, query, cmd = argv[1].val.str); + RND_ACT_MAY_CONVARG(2, FGW_STR, query, arg = argv[2].val.str); + + if (strcmp(cmd, "version") == 0) { + RND_ACT_IRES(0100); /* 1.0 */ + return 0; + } + + if (strcmp(cmd, "dump") == 0) { + pcb_qry_node_t *prg = NULL; + + RND_ACT_MAY_CONVARG(2, FGW_STR, query, arg = argv[2].val.str); + printf("Script dump: '%s'\n", arg); + pcb_qry_set_input(arg); + qry_parse(&prg); + if (prg != NULL) { + pcb_qry_dump_tree(" ", prg); + pcb_qry_n_free(prg); + RND_ACT_IRES(0); + } + else + RND_ACT_IRES(1); + return 0; + } + + if ((strcmp(cmd, "eval") == 0) || (strcmp(cmd, "evalidp") == 0)) { + int errs; + eval_stat_t st; + + RND_ACT_MAY_CONVARG(2, FGW_STR, query, arg = argv[2].val.str); + RND_ACT_MAY_CONVARG(3, FGW_STR, query, scope = argv[3].val.str); + + memset(&st, 0, sizeof(st)); + st.print_idpath = (cmd[4] != '\0'); + printf("Script eval: '%s' scope='%s'\n", arg, scope == NULL ? "" : scope); + errs = pcb_qry_run_script(NULL, sheet, arg, scope, eval_cb, &st); + + if (errs < 0) + printf("Failed to run the query\n"); + else + printf("eval statistics: true=%d false=%d errors=%d\n", st.trues, st.falses, errs); + RND_ACT_IRES(0); + return 0; + } + + if ((strcmp(cmd, "count") == 0)) { + int errs; + eval_stat_t st; + + RND_ACT_MAY_CONVARG(2, FGW_STR, query, arg = argv[2].val.str); + RND_ACT_MAY_CONVARG(3, FGW_STR, query, scope = argv[3].val.str); + + memset(&st, 0, sizeof(st)); + st.print_idpath = (cmd[4] != '\0'); + errs = pcb_qry_run_script(NULL, sheet, arg, scope, count_cb, &st); + + if (errs == 0) + RND_ACT_IRES(st.trues); + else + RND_ACT_IRES(-1); + return 0; + } + + + if (strcmp(cmd, "select") == 0) { + sel.sheet = sheet; + sel.act = FLAGOP_SELECT; + + RND_ACT_MAY_CONVARG(2, FGW_STR, query, arg = argv[2].val.str); + RND_ACT_MAY_CONVARG(3, FGW_STR, query, scope = argv[3].val.str); + + if (pcb_qry_run_script(NULL, sheet, arg, scope, flagop_cb, &sel) < 0) + printf("Failed to run the query\n"); + if (sel.cnt > 0) { + csch_sheet_set_changed(sheet, rnd_true); + if (RND_HAVE_GUI_ATTR_DLG) + rnd_hid_redraw(hidlib); + } + RND_ACT_IRES(0); + return 0; + } + + if (strcmp(cmd, "unselect") == 0) { + sel.sheet = sheet; + sel.act = FLAGOP_UNSELECT; + + RND_ACT_MAY_CONVARG(2, FGW_STR, query, arg = argv[2].val.str); + RND_ACT_MAY_CONVARG(3, FGW_STR, query, scope = argv[3].val.str); + + if (pcb_qry_run_script(NULL, sheet, arg, scope, flagop_cb, &sel) < 0) + printf("Failed to run the query\n"); + if (sel.cnt > 0) { + csch_sheet_set_changed(sheet, rnd_true); + if (RND_HAVE_GUI_ATTR_DLG) + rnd_hid_redraw(hidlib); + } + RND_ACT_IRES(0); + return 0; + } + + if (strcmp(cmd, "append") == 0) { + csch_oidpath_list_t *list; + + RND_ACT_CONVARG(2, FGW_IDPATH_LIST, query, list = fgw_idpath_list(&argv[2])); + RND_ACT_MAY_CONVARG(3, FGW_STR, query, arg = argv[3].val.str); + RND_ACT_MAY_CONVARG(4, FGW_STR, query, scope = argv[4].val.str); + + if (!fgw_ptr_in_domain(&rnd_fgw, &argv[2], RND_PTR_DOMAIN_IDPATH_LIST)) + return FGW_ERR_PTR_DOMAIN; + + if (pcb_qry_run_script(NULL, sheet, arg, scope, append_cb, list) < 0) + RND_ACT_IRES(1); + else + RND_ACT_IRES(0); + return 0; + } + + if (strcmp(cmd, "view") == 0) { + fgw_arg_t args[4], ares; + vtp0_t arr = {0}; + RND_ACT_MAY_CONVARG(2, FGW_STR, query, arg = argv[2].val.str); + RND_ACT_MAY_CONVARG(3, FGW_STR, query, scope = argv[3].val.str); + if (pcb_qry_run_script(NULL, sheet, arg, scope, view_cb, &arr) >= 0) { + args[1].type = FGW_STR; args[1].val.str = "objarr"; + fgw_ptr_reg(&rnd_fgw, &args[2], CSCH_PTR_DOMAIN_COBJ_ARR, FGW_PTR | FGW_STRUCT, &arr); + rnd_actionv_bin(RND_ACT_DESIGN, "TreeDialog", &ares, 3, args); + fgw_ptr_unreg(&rnd_fgw, &args[2], CSCH_PTR_DOMAIN_COBJ_ARR); + vtp0_uninit(&arr); + RND_ACT_IRES(0); + } + else + RND_ACT_IRES(1); + + vtp0_uninit(&arr); + return 0; + } + + RND_ACT_FAIL(query); +} + +static const char *PTR_DOMAIN_PCFIELD = "ptr_domain_query_precompiled_field"; + +static pcb_qry_node_t *field_comp(const char *fields) +{ + char fname[64], *fno; + const char *s; + int len = 1, flen = 0, idx = 0, quote = 0; + pcb_qry_node_t *res; + + if (*fields == '.') fields++; + if (*fields == '\0') + return NULL; + + for(s = fields; *s != '\0'; s++) { + if (*s == '.') { + len++; + if (len > 16) + return NULL; /* too many fields chained */ + if (flen >= sizeof(fname)) + return NULL; /* field name segment too long */ + flen = 0; + } + else + flen++; + } + + res = calloc(sizeof(pcb_qry_node_t), len); + fno = fname; + for(s = fields;; s++) { + if ((quote == 0) && ((*s == '.') || (*s == '\0'))) { + *fno = '\0'; + if (idx > 0) + res[idx-1].next = &res[idx]; + res[idx].type = PCBQ_FIELD; + res[idx].precomp.fld = query_fields_sphash(fname); +/*rnd_trace("[%d/%d] '%s' -> %d\n", idx, len, fname, res[idx].precomp.fld);*/ + if (res[idx].precomp.fld < 0) /* if compilation failed, this will need to be evaluated run-time, save as string */ + res[idx].data.str = rnd_strdup(fname); + fno = fname; + if (*s == '\0') + break; + idx++; + if (s[1] == '\"') { + quote = s[1]; + s++; + } + } + else { + if (*s == quote) + quote = 0; + else + *fno++ = *s; + } + } + + return res; +} + +static void field_free(pcb_qry_node_t *fld) +{ + pcb_qry_node_t *f; + for(f = fld; f != NULL; f = f->next) + if (f->data.str != NULL) + free((char *)f->data.str); + free(fld); +} + + +static void val2fgw(fgw_arg_t *dst, pcb_qry_val_t *src) +{ + switch(src->type) { + case PCBQ_VT_COORD: + dst->type = FGW_COORD_; + fgw_coord(dst) = src->data.crd; + break; + case PCBQ_VT_LONG: + dst->type = FGW_LONG; + dst->val.nat_long = src->data.lng; + break; + case PCBQ_VT_DOUBLE: + dst->type = FGW_DOUBLE; + dst->val.nat_double = src->data.dbl; + break; + case PCBQ_VT_STRING: + if (src->data.str != NULL) { + dst->type = FGW_STR | FGW_DYN; + dst->val.str = rnd_strdup(src->data.str); + } + else { + dst->type = FGW_PTR; + dst->val.ptr_void = NULL; + } + break; + case PCBQ_VT_VOID: + case PCBQ_VT_OBJ: + case PCBQ_VT_LST: + default:; + break; + } +} + +static const char csch_acts_QueryObj[] = "QueryObj(idpath, [.fieldname|fieldID])"; +static const char csch_acth_QueryObj[] = "Return the value of a field of an object, addressed by the object's idpath and the field's name or precompiled ID. Returns NIL on error."; +static fgw_error_t csch_act_QueryObj(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_design_t *hidlib = RND_ACT_DESIGN; + csch_sheet_t *sheet = (csch_sheet_t *)hidlib; + csch_oidpath_t *idp; + pcb_qry_node_t *fld = NULL; + pcb_qry_val_t obj; + pcb_qry_val_t val; + int free_fld = 0; + + RND_ACT_CONVARG(1, FGW_IDPATH, QueryObj, idp = fgw_idpath(&argv[1])); + + if ((argv[2].type & FGW_STR) == FGW_STR) { + const char *field; + RND_ACT_CONVARG(2, FGW_STR, QueryObj, field = argv[2].val.str); + if (field == NULL) + goto err; + if (*field != '.') + goto id; + fld = field_comp(field); + free_fld = 1; + } + else if ((argv[2].type & FGW_PTR) == FGW_PTR) { + id:; + RND_ACT_CONVARG(2, FGW_PTR, QueryObj, fld = argv[2].val.ptr_void); + if (!fgw_ptr_in_domain(&rnd_fgw, &argv[2], PTR_DOMAIN_PCFIELD)) + return FGW_ERR_PTR_DOMAIN; + } + + if ((fld == NULL) || (!fgw_ptr_in_domain(&rnd_fgw, &argv[1], RND_PTR_DOMAIN_IDPATH))) { + if (free_fld) + field_free(fld); + return FGW_ERR_PTR_DOMAIN; + } + + obj.type = PCBQ_VT_OBJ; + obj.data.obj = csch_oidpath_resolve(sheet, idp); + if (obj.data.obj == NULL) + goto err; + + { + int ret; + pcb_qry_exec_t ec; + + pcb_qry_init(&ec, sheet, NULL, -1); + ret = pcb_qry_obj_field(NULL, &obj, fld, &val); + pcb_qry_uninit(&ec); + + if (ret != 0) + goto err; + } + + if (free_fld) + field_free(fld); + + val2fgw(res, &val); + return 0; + + err:; + if (free_fld) + field_free(fld); + res->type = FGW_PTR; + res->val.ptr_void = NULL; + return 0; +} + +static const char csch_acts_QueryCompileField[] = + "QueryCompileField(compile, fieldname)\n" + "QueryCompileField(free, fieldID)"; +static const char csch_acth_QueryCompileField[] = "With \"compile\": precompiles textual field name to field ID; with \"free\": frees the memory allocated for a previously precompiled fieldID."; +static fgw_error_t csch_act_QueryCompileField(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *cmd, *fname; + pcb_qry_node_t *fld; + + RND_ACT_CONVARG(1, FGW_STR, QueryCompileField, cmd = argv[1].val.str); + switch(*cmd) { + case 'c': /* compile */ + RND_ACT_CONVARG(2, FGW_STR, QueryCompileField, fname = argv[2].val.str); + fld = field_comp(fname); + fgw_ptr_reg(&rnd_fgw, res, PTR_DOMAIN_PCFIELD, FGW_PTR | FGW_STRUCT, fld); + return 0; + case 'f': /* free */ + if (!fgw_ptr_in_domain(&rnd_fgw, &argv[2], PTR_DOMAIN_PCFIELD)) + return FGW_ERR_PTR_DOMAIN; + RND_ACT_CONVARG(2, FGW_PTR, QueryCompileField, fld = argv[2].val.ptr_void); + fgw_ptr_unreg(&rnd_fgw, &argv[2], PTR_DOMAIN_PCFIELD); + field_free(fld); + return 0; + default: + return FGW_ERR_ARG_CONV; + } + return 0; +} + +/* in net_len.c */ +extern const char csch_acts_QueryCalcNetLen[]; +extern const char csch_acth_QueryCalcNetLen[]; +extern fgw_error_t csch_act_QueryCalcNetLen(fgw_arg_t *res, int argc, fgw_arg_t *argv); + +rnd_action_t query_action_list[] = { + {"query", csch_act_query, csch_acth_query, csch_acts_query}, + {"QueryObj", csch_act_QueryObj, csch_acth_QueryObj, csch_acts_QueryObj}, + {"QueryCompileField", csch_act_QueryCompileField, csch_acth_QueryCompileField, csch_acts_QueryCompileField}, + {"SearchDialog", csch_act_SearchDialog, csch_acth_SearchDialog, csch_acts_SearchDialog} +}; + +void query_action_reg(const char *cookie) +{ + RND_REGISTER_ACTIONS(query_action_list, cookie) +} Index: tags/1.0.5/src/plugins/query/query_exec.c =================================================================== --- tags/1.0.5/src/plugins/query/query_exec.c (nonexistent) +++ tags/1.0.5/src/plugins/query/query_exec.c (revision 10414) @@ -0,0 +1,884 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016,2019 Tibor 'Igor2' Palinkas + * Copyright (C) 2022 Tibor 'Igor2' Palinkas (slight modifications for sch-rnd) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* Query language - execution */ + +#include +#include + +#include + +#include + +#include "query.h" +#include "query_exec.h" +#include "query_access.h" +#include + +#include + +void pcb_qry_setup(pcb_qry_exec_t *ctx, csch_sheet_t *sheet, pcb_qry_node_t *root) +{ + ctx->sheet = sheet; + ctx->root = root; + ctx->iter = NULL; +} + +void pcb_qry_init(pcb_qry_exec_t *ctx, csch_sheet_t *sheet, pcb_qry_node_t *root, int bufno) +{ + memset(ctx, 0, sizeof(pcb_qry_exec_t)); + ctx->all.type = PCBQ_VT_LST; + if (bufno == -1) + pcb_qry_list_all_sheet(&ctx->all, sheet, CSCH_CMASK_ANY); + else if (bufno == -2) + pcb_qry_list_all_sheet_indirect(&ctx->all, sheet, CSCH_CMASK_ANY); + else + pcb_qry_list_all_sheet(&ctx->all, sch_rnd_buffer[bufno], CSCH_CMASK_ANY); + + pcb_qry_setup(ctx, sheet, root); +} + +void pcb_qry_autofree(pcb_qry_exec_t *ctx) +{ + long l; + + if (ctx->iter != NULL) { + for(l = 0; l < ctx->iter->num_vars; l++) { + if (ctx->iter->lst[l].data.lst.array != ctx->all.data.lst.array) /* some lists are just alias to ->all, do not free them */ + pcb_qry_list_free(&ctx->iter->lst[l]); + } + } + + for(l = 0; l < ctx->autofree.used; l++) + free(ctx->autofree.array[l]); + vtp0_uninit(&ctx->autofree); + + ctx->iter = NULL; /* no need to free the iterator: ctx->root free handled that as it was allocated in one of the nodes */ +} + +void pcb_qry_uninit(pcb_qry_exec_t *ctx) +{ + pcb_qry_autofree(ctx); + + pcb_qry_list_free(&ctx->all); + + vtp0_uninit(&ctx->tmplst); +} + +static void val_free_fields(pcb_qry_val_t *val) +{ + switch(val->type) { + case PCBQ_VT_LST: + pcb_qry_list_free(val); + break; + case PCBQ_VT_STRING: + TODO("decide if strings are strdup'd; action return may need to, ther est not; maybe introduce DSTR for dynamic string?"); + /* NOTE: attribute resolver depends on non-free here */ + break; + case PCBQ_VT_VOID: + case PCBQ_VT_OBJ: + case PCBQ_VT_COORD: + case PCBQ_VT_LONG: + case PCBQ_VT_DOUBLE: + break; + } +} + +void pcb_qry_val_free_fields(pcb_qry_val_t *val) +{ + val_free_fields(val); +} + +static int pcb_qry_run_(pcb_qry_exec_t *ec, pcb_qry_node_t *prg, pcb_qry_val_t *res, int it_reset, int eval_list, void (*cb)(void *user_ctx, pcb_qry_val_t *res, csch_chdr_t *current), void *user_ctx) +{ + pcb_qry_val_t restmp; + int errs = 0, keep_res = 1; + + if (it_reset && (pcb_qry_it_reset(ec, prg) != 0)) + return -1; + + if (res == NULL) { + res = &restmp; + keep_res = 0; + } + res->type = PCBQ_VT_VOID; + + do { + val_free_fields(res); + if ((pcb_qry_eval(ec, prg, res, cb, user_ctx) == 0) && (cb != NULL)) { + if ((eval_list) && (res->type == PCBQ_VT_LST)) { + long n; + + /* special case: result is a list, need to return each object so 'let' gets it */ + for(n = 0; n < res->data.lst.used; n++) + cb(user_ctx, res, res->data.lst.array[n]); + } + else if (ec->iter->last_obj != NULL) { + cb(user_ctx, res, ec->iter->last_obj); + } + } + else + errs++; + } while(pcb_qry_it_next(ec)); + if (!keep_res) + val_free_fields(res); + return errs; +} + + +typedef struct { + pcb_qry_exec_t *ctx; + vtp0_t *vt; +} let_ctx_t; + +static void let_cb(void *user_ctx, pcb_qry_val_t *res, csch_chdr_t *current) +{ + let_ctx_t *lctx = user_ctx; + + if (res->type == PCBQ_VT_OBJ) /* result overwrites last checked node */ + current = res->data.obj; + + if (pcb_qry_is_true(res)) + vtp0_append(lctx->vt, current); +} + +static void pcb_qry_let(pcb_qry_exec_t *ctx, pcb_qry_node_t *node) +{ + let_ctx_t lctx; + int vi = node->data.children->data.crd; + pcb_qry_node_t *expr = node->data.children->next; + + lctx.ctx = ctx; + pcb_qry_it_reset(ctx, node); + + /* set up the list */ + ctx->iter->lst[vi].type = PCBQ_VT_LST; + lctx.vt = &ctx->iter->lst[vi].data.lst; + + /* evaluate 'let' the expression, filling up the list */ + pcb_qry_it_reset_(lctx.ctx, 0); + ctx->iter->it_active = node->precomp.it_active; + pcb_qry_run_(lctx.ctx, expr, NULL, 0, 1,let_cb, &lctx); + ctx->iter->it_active = NULL; + + /* initialize the iterator */ + ctx->iter->vects[vi] = &ctx->iter->lst[vi].data.lst; + ctx->iter->idx[vi] = 0; +} + +/* Run one node; increment ret by the number of hits and return that, or -1 on error. + If res is not NULL the value of PCBQ_RETURN is loaded in it. + Call cb/user_ctx when assert is true. */ +static int pcb_qry_run_one(pcb_qry_exec_t *ec, pcb_qry_node_t *prg, int ret, pcb_qry_val_t *res, void (*cb)(void *user_ctx, pcb_qry_val_t *res, csch_chdr_t *current), void *user_ctx) +{ + int r; + pcb_qry_node_t *start; + int is_ret = 0; + + if (res != NULL) + res->type = PCBQ_VT_VOID; + + if (prg->type == PCBQ_FUNCTION) { + if (ec->trace) + rnd_message(RND_MSG_INFO, "query: entering user function %s\n", prg->data.children->next->data.str); + start = prg->data.children->next->next; + while(start->type == PCBQ_ARG) + start = start->next; + goto run_all; + } + else if (prg->type == PCBQ_RULE) { + pcb_qry_node_t *n; + start = prg->data.children->next->next; + + /* execute 'let' statements first */ + run_all:; + for(n = start; n != NULL; n = n->next) { + if (n->type == PCBQ_LET) + pcb_qry_let(ec, n); + if (n->type == PCBQ_RETURN) + break; + } + + for(n = start; n != NULL; n = n->next) { + if (ec->trace) + rnd_message(RND_MSG_INFO, "query: %p %s\n", n, pcb_qry_nodetype_name(n->type)); + switch(n->type) { + case PCBQ_LET: break; + case PCBQ_RETURN: + is_ret = 1; + case PCBQ_ASSERT: + ec->root = n; + if (ec->iter != NULL) + ec->iter->it_active = n->precomp.it_active; + r = pcb_qry_run_(ec, n->data.children, (is_ret ? res : NULL), 1, 0, (n->type == PCBQ_RETURN ? NULL : cb), user_ctx); + if (ec->iter != NULL) + ec->iter->it_active = NULL; + if (r < 0) + ret = r; + else if (ret >= 0) + ret += r; + ec->root = NULL; + break; + default:; + } + if (is_ret) + break; + } + } + else + return -1; + + return ret; +} + +static int pcb_qry_run_all(pcb_qry_exec_t *ec, pcb_qry_node_t *prg, int ret, void (*cb)(void *user_ctx, pcb_qry_val_t *res, csch_chdr_t *current), void *user_ctx) +{ + while(prg != NULL) { /* execute a list of rules */ + if (prg->type != PCBQ_FUNCTION) + ret = pcb_qry_run_one(ec, prg, ret, NULL, cb, user_ctx); + prg = prg->next; + } + return ret; +} + +int pcb_qry_run(pcb_qry_exec_t *ec, csch_sheet_t *sheet, pcb_qry_node_t *prg, int bufno, void (*cb)(void *user_ctx, pcb_qry_val_t *res, csch_chdr_t *current), void *user_ctx) +{ + int ret = 0, ec_uninit = 0; + pcb_qry_exec_t ec_local; + + if (ec == NULL) { + ec = &ec_local; + ec_uninit = 1; + pcb_qry_init(ec, sheet, prg, bufno); + } + else { + if (ec->sheet != sheet) + return -1; + pcb_qry_setup(ec, sheet, prg); + } + + if (prg->type == PCBQ_EXPR_PROG) + ret = pcb_qry_run_(ec, prg, NULL, 1, 0, cb, user_ctx); + else + ret = pcb_qry_run_all(ec, prg, ret, cb, user_ctx); + + if (ec_uninit) + pcb_qry_uninit(&ec_local); + else + pcb_qry_autofree(ec); + return ret; +} + +static int qry_exec_user_func(pcb_qry_exec_t *ectx, pcb_qry_node_t *fdef, int argc, pcb_qry_val_t *argv, pcb_qry_val_t *res, void (*cb)(void *user_ctx, pcb_qry_val_t *res, csch_chdr_t *current), void *user_ctx) +{ + pcb_qry_exec_t fctx; + int n, ret, alloced[PCB_QRY_MAX_FUNC_ARGS]; + pcb_qry_node_t *fname; + + if (argc > PCB_QRY_MAX_FUNC_ARGS) + return -1; + + if (fdef == NULL) { + rnd_message(RND_MSG_ERROR, "call to unknown/undefined function\n"); + return -1; + } + + fctx = *ectx; + + assert(fdef->type == PCBQ_FUNCTION); + fname = fdef->data.children; + assert(fname->type == PCBQ_ITER_CTX); + fctx.iter = fname->data.iter_ctx; + fname = fname->next; /* skip iter */ + + pcb_qry_iter_init(fctx.iter); + + /* accept only objects and lists as argument */ + for(n = 0; n < argc; n++) { + if ((argv[n].type != PCBQ_VT_OBJ) && (argv[n].type != PCBQ_VT_LST)) + return -1; + } + + for(n = 0; n < argc; n++) { + if (argv[n].type == PCBQ_VT_OBJ) { + fctx.iter->lst[n].type = PCBQ_VT_LST; + vtp0_init(&fctx.iter->lst[n].data.lst); + vtp0_append(&fctx.iter->lst[n].data.lst, argv[n].data.obj); + alloced[n] = 1; + } + else { + fctx.iter->lst[n] = argv[n]; + alloced[n] = 0; + } + fctx.iter->vects[n] = &fctx.iter->lst[n].data.lst; + fctx.iter->idx[n] = 0; + } + + /* reset lists from the previous calls */ + for(; n < fctx.iter->num_vars; n++) { + vtp0_t *v = fctx.iter->vects[n]; + if (v != NULL) + v->used = 0; + } + + ret = pcb_qry_run_one(&fctx, fdef, 0, res, cb, user_ctx); + + for(n = 0; n < argc; n++) { + if (alloced[n]) + vtp0_uninit(&fctx.iter->lst[n].data.lst); + } + + return ret; +} + +/* load unary operand to o1 */ +#define UNOP() \ +do { \ + if ((node->data.children == NULL) || (node->data.children->next != NULL)) \ + return -1; \ + if (pcb_qry_eval(ctx, node->data.children, &o1, cb, user_ctx) < 0) \ + return -1; \ +} while(0) + +/* load 1st binary operand to o1 */ +#define BINOPS1() \ +do { \ + if ((node->data.children == NULL) || (node->data.children->next == NULL) || (node->data.children->next->next != NULL)) \ + return -1; \ + if (pcb_qry_eval(ctx, node->data.children, &o1, cb, user_ctx) < 0) \ + return -1; \ +} while(0) + +/* load 2nd binary operand to o2 */ +#define BINOPS2() \ +do { \ + if (pcb_qry_eval(ctx, node->data.children->next, &o2, cb, user_ctx) < 0) \ + return -1; \ +} while(0) + +/* load binary operands to o1 and o2 */ +#define BINOPS() \ +do { \ + BINOPS1(); \ + BINOPS2(); \ +} while(0) + +static int promote(pcb_qry_val_t *a, pcb_qry_val_t *b) +{ + if ((a->type == PCBQ_VT_VOID) || (b->type == PCBQ_VT_VOID)) { + a->type = b->type = PCBQ_VT_VOID; + return 0; + } + if (a->type == b->type) + return 0; + switch(a->type) { + case PCBQ_VT_OBJ: return -1; + case PCBQ_VT_LST: return -1; + case PCBQ_VT_COORD: + if (b->type == PCBQ_VT_DOUBLE) PCB_QRY_RET_DBL(a, a->data.crd); + if (b->type == PCBQ_VT_LONG) PCB_QRY_RET_COORD(b, b->data.lng); + return -1; + case PCBQ_VT_LONG: + if (b->type == PCBQ_VT_DOUBLE) PCB_QRY_RET_DBL(a, a->data.lng); + if (b->type == PCBQ_VT_COORD) PCB_QRY_RET_COORD(a, a->data.lng); + return -1; + case PCBQ_VT_DOUBLE: + if (b->type == PCBQ_VT_COORD) PCB_QRY_RET_DBL(b, b->data.crd); + if (b->type == PCBQ_VT_LONG) PCB_QRY_RET_DBL(b, b->data.lng); + return -1; + case PCBQ_VT_STRING: + case PCBQ_VT_VOID: + return -1; + } + return -1; +} + +static const char *op2str(char *buff, int buff_size, pcb_qry_val_t *val) +{ + switch(val->type) { + case PCBQ_VT_COORD: + rnd_snprintf(buff, buff_size, "%ld", val->data.crd); + return buff; + case PCBQ_VT_LONG: + rnd_snprintf(buff, buff_size, "%ld", val->data.lng); + return buff; + case PCBQ_VT_DOUBLE: + rnd_snprintf(buff, buff_size, "%f", val->data.crd); + return buff; + case PCBQ_VT_STRING: + return val->data.str; + case PCBQ_VT_VOID: + case PCBQ_VT_OBJ: + case PCBQ_VT_LST: return NULL; + } + return NULL; +} + +int pcb_qry_is_true(pcb_qry_val_t *val) +{ + switch(val->type) { + case PCBQ_VT_VOID: return 0; + case PCBQ_VT_OBJ: return val->data.obj->type != CSCH_CTYPE_invalid; + case PCBQ_VT_LST: return vtp0_len(&val->data.lst) > 0; + case PCBQ_VT_COORD: return val->data.crd; + case PCBQ_VT_LONG: return val->data.lng; + case PCBQ_VT_DOUBLE: return val->data.dbl; + case PCBQ_VT_STRING: return (val->data.str != NULL) && (*val->data.str != '\0'); + } + return 0; +} + +static void setup_iter_list(pcb_qry_exec_t *ctx, int var_id, pcb_qry_val_t *listval) +{ + ctx->iter->lst[var_id] = *listval; + assert(listval->type == PCBQ_VT_LST); + + ctx->iter->vects[var_id] = &listval->data.lst; + ctx->iter->idx[var_id] = 0; +} + +static int pcb_qry_it_active(pcb_query_iter_t *iter, int i) +{ + if (iter->it_active == NULL) return 1; /* no activity map: all iterators are active */ + if (i >= iter->it_active->used) return 0; + return iter->it_active->array[i]; +} + +int pcb_qry_it_reset_(pcb_qry_exec_t *ctx, int persistent) +{ + int n; + + if (!persistent) + pcb_qry_iter_init(ctx->iter); + + for(n = 0; n < ctx->iter->num_vars; n++) { + if (strcmp(ctx->iter->vn[n], "@") == 0) { + setup_iter_list(ctx, n, &ctx->all); + ctx->iter->last_obj = NULL; + break; + } + } + + ctx->iter->last_active = -1; + for(n = 0; n < ctx->iter->num_vars; n++) + if ((ctx->iter->vects[n] != NULL) && pcb_qry_it_active(ctx->iter, n)) + ctx->iter->last_active = n; + + return 0; +} + +int pcb_qry_it_reset(pcb_qry_exec_t *ctx, pcb_qry_node_t *node) +{ + ctx->iter = pcb_qry_find_iter(node); + if (ctx->iter == NULL) + return -1; + + return pcb_qry_it_reset_(ctx, 0); +} + + +#define PROGRESS_CB(ctx, at, total, cancel) \ +do { \ + time_t now; \ + cancel = 0; \ + if (ctx->progress_cb == NULL) break; \ + now = time(NULL); \ + if (ctx->last_prog_cb == 0) \ + ctx->last_prog_cb = now; \ + else if (now > ctx->last_prog_cb) { \ + ctx->last_prog_cb = now; \ + cancel = ctx->progress_cb(ctx, at, total); \ + } \ +} while(0) + +int pcb_qry_it_next(pcb_qry_exec_t *ctx) +{ + int i; + for(i = 0; i < ctx->iter->num_vars; i++) { + if ((ctx->iter->vects[i] != NULL) && pcb_qry_it_active(ctx->iter, i)) { + long ilen = vtp0_len(ctx->iter->vects[i]); + long at = ++ctx->iter->idx[i]; + if (at < ilen) { + if (i == ctx->iter->last_active) { + int cancel; + PROGRESS_CB(ctx, at, ilen, cancel); + if (cancel) + return 0; + } + return 1; + } + } + ctx->iter->idx[i] = 0; + } + return 0; +} + + +/* load s1 and s2 from o1 and o2, convert empty string to NULL */ +#define load_strings_null() \ +do { \ + s1 = o1.data.str; \ + s2 = o2.data.str; \ + if ((s1 != NULL) && (*s1 == '\0')) s1 = NULL; \ + if ((s2 != NULL) && (*s2 == '\0')) s2 = NULL; \ +} while(0) + +static char *pcb_qry_empty = ""; + +/* load s1 and s2 from o1 and o2, convert NULL to empty string */ +#define load_strings_empty() \ +do { \ + s1 = o1.data.str; \ + s2 = o2.data.str; \ + if (s1 == NULL) s1 = pcb_qry_empty; \ + if (s2 == NULL) s2 = pcb_qry_empty; \ +} while(0) + +int pcb_qry_eval(pcb_qry_exec_t *ctx, pcb_qry_node_t *node, pcb_qry_val_t *res, void (*cb)(void *user_ctx, pcb_qry_val_t *res, csch_chdr_t *current), void *user_ctx) +{ + pcb_qry_val_t o1, o2; + csch_chdr_t **tmp; + const char *s1, *s2; + + switch(node->type) { + case PCBQ_EXPR: + return pcb_qry_eval(ctx, node->data.children, res, cb, user_ctx); + + case PCBQ_EXPR_PROG: { + pcb_qry_node_t *itn, *exprn; + itn = node->data.children; + if (itn == NULL) + return -1; + exprn = itn->next; + if (exprn == NULL) + return -1; + if (itn->type != PCBQ_ITER_CTX) + return -1; + if (ctx->iter != itn->data.iter_ctx) + return -1; + return pcb_qry_eval(ctx, exprn, res, cb, user_ctx); + } + + + case PCBQ_OP_AND: /* lazy */ + BINOPS1(); + if (!pcb_qry_is_true(&o1)) + PCB_QRY_RET_INT(res, 0); + BINOPS2(); + if (!pcb_qry_is_true(&o2)) + PCB_QRY_RET_INT(res, 0); + PCB_QRY_RET_INT(res, 1); + + case PCBQ_OP_THUS: /* lazy */ + BINOPS1(); + if (!pcb_qry_is_true(&o1)) + PCB_QRY_RET_INV(res); + BINOPS2(); + *res = o2; + return 0; + + case PCBQ_OP_OR: /* lazy */ + BINOPS1(); + if (pcb_qry_is_true(&o1)) + PCB_QRY_RET_INT(res, 1); + BINOPS2(); + if (pcb_qry_is_true(&o2)) + PCB_QRY_RET_INT(res, 1); + PCB_QRY_RET_INT(res, 0); + + case PCBQ_OP_EQ: + BINOPS(); + if (promote(&o1, &o2) != 0) + return -1; + switch(o1.type) { + case PCBQ_VT_VOID: PCB_QRY_RET_INV(res); + case PCBQ_VT_OBJ: PCB_QRY_RET_INT(res, ((o1.data.obj) == (o2.data.obj))); + case PCBQ_VT_LST: PCB_QRY_RET_INT(res, pcb_qry_list_cmp(&o1, &o2)); + case PCBQ_VT_COORD: PCB_QRY_RET_INT(res, o1.data.crd == o2.data.crd); + case PCBQ_VT_LONG: PCB_QRY_RET_INT(res, o1.data.lng == o2.data.lng); + case PCBQ_VT_DOUBLE: PCB_QRY_RET_INT(res, o1.data.dbl == o2.data.dbl); + case PCBQ_VT_STRING: + load_strings_null(); + if (s1 == s2) + PCB_QRY_RET_INT(res, 1); + if ((s1 == NULL) || (s2 == NULL)) + PCB_QRY_RET_INT(res, 0); + PCB_QRY_RET_INT(res, strcmp(s1, s2) == 0); + } + return -1; + + case PCBQ_OP_NEQ: + BINOPS(); + if (promote(&o1, &o2) != 0) + return -1; + switch(o1.type) { + case PCBQ_VT_VOID: PCB_QRY_RET_INV(res); + case PCBQ_VT_OBJ: PCB_QRY_RET_INT(res, ((o1.data.obj) != (o2.data.obj))); + case PCBQ_VT_LST: PCB_QRY_RET_INT(res, !pcb_qry_list_cmp(&o1, &o2)); + case PCBQ_VT_COORD: PCB_QRY_RET_INT(res, o1.data.crd != o2.data.crd); + case PCBQ_VT_LONG: PCB_QRY_RET_INT(res, o1.data.lng != o2.data.lng); + case PCBQ_VT_DOUBLE: PCB_QRY_RET_INT(res, o1.data.dbl != o2.data.dbl); + case PCBQ_VT_STRING: + load_strings_null(); + if (s1 == s2) + PCB_QRY_RET_INT(res, 0); + if ((s1 == NULL) || (s2 == NULL)) + PCB_QRY_RET_INT(res, 1); + PCB_QRY_RET_INT(res, strcmp(s1, s2) != 0); + } + return -1; + + case PCBQ_OP_GTEQ: + BINOPS(); + if (promote(&o1, &o2) != 0) + return -1; + switch(o1.type) { + case PCBQ_VT_VOID: PCB_QRY_RET_INV(res); + case PCBQ_VT_COORD: PCB_QRY_RET_INT(res, o1.data.crd >= o2.data.crd); + case PCBQ_VT_LONG: PCB_QRY_RET_INT(res, o1.data.lng >= o2.data.lng); + case PCBQ_VT_DOUBLE: PCB_QRY_RET_INT(res, o1.data.dbl >= o2.data.dbl); + case PCBQ_VT_STRING: + load_strings_empty(); + PCB_QRY_RET_INT(res, strcmp(s1, s2) >= 0); + default: return -1; + } + return -1; + + case PCBQ_OP_LTEQ: + BINOPS(); + if (promote(&o1, &o2) != 0) + return -1; + switch(o1.type) { + case PCBQ_VT_VOID: PCB_QRY_RET_INV(res); + case PCBQ_VT_COORD: PCB_QRY_RET_INT(res, o1.data.crd <= o2.data.crd); + case PCBQ_VT_LONG: PCB_QRY_RET_INT(res, o1.data.lng <= o2.data.lng); + case PCBQ_VT_DOUBLE: PCB_QRY_RET_INT(res, o1.data.dbl <= o2.data.dbl); + case PCBQ_VT_STRING: + load_strings_empty(); + PCB_QRY_RET_INT(res, strcmp(s1, s2) <= 0); + default: return -1; + } + return -1; + + case PCBQ_OP_GT: + BINOPS(); + if (promote(&o1, &o2) != 0) + return -1; + switch(o1.type) { + case PCBQ_VT_VOID: PCB_QRY_RET_INV(res); + case PCBQ_VT_COORD: PCB_QRY_RET_INT(res, o1.data.crd > o2.data.crd); + case PCBQ_VT_LONG: PCB_QRY_RET_INT(res, o1.data.lng > o2.data.lng); + case PCBQ_VT_DOUBLE: PCB_QRY_RET_INT(res, o1.data.dbl > o2.data.dbl); + case PCBQ_VT_STRING: + load_strings_empty(); + PCB_QRY_RET_INT(res, strcmp(s1, s2) > 0); + default: return -1; + } + return -1; + case PCBQ_OP_LT: + BINOPS(); + if (promote(&o1, &o2) != 0) + return -1; + switch(o1.type) { + case PCBQ_VT_VOID: PCB_QRY_RET_INV(res); + case PCBQ_VT_COORD: PCB_QRY_RET_INT(res, o1.data.crd < o2.data.crd); + case PCBQ_VT_LONG: PCB_QRY_RET_INT(res, o1.data.lng < o2.data.lng); + case PCBQ_VT_DOUBLE: PCB_QRY_RET_INT(res, o1.data.dbl < o2.data.dbl); + case PCBQ_VT_STRING: + load_strings_empty(); + PCB_QRY_RET_INT(res, strcmp(s1, s2) < 0); + default: return -1; + } + return -1; + + case PCBQ_OP_ADD: + BINOPS(); + if (promote(&o1, &o2) != 0) + return -1; + switch(o1.type) { + case PCBQ_VT_VOID: PCB_QRY_RET_INV(res); + case PCBQ_VT_COORD: PCB_QRY_RET_INT(res, o1.data.crd + o2.data.crd); + case PCBQ_VT_LONG: PCB_QRY_RET_INT(res, o1.data.lng + o2.data.lng); + case PCBQ_VT_DOUBLE: PCB_QRY_RET_DBL(res, o1.data.dbl + o2.data.dbl); + default: return -1; + } + return -1; + + case PCBQ_OP_SUB: + BINOPS(); + if (promote(&o1, &o2) != 0) + return -1; + switch(o1.type) { + case PCBQ_VT_VOID: PCB_QRY_RET_INV(res); + case PCBQ_VT_COORD: PCB_QRY_RET_INT(res, o1.data.crd - o2.data.crd); + case PCBQ_VT_LONG: PCB_QRY_RET_INT(res, o1.data.lng - o2.data.lng); + case PCBQ_VT_DOUBLE: PCB_QRY_RET_DBL(res, o1.data.dbl - o2.data.dbl); + default: return -1; + } + return -1; + + case PCBQ_OP_MUL: + BINOPS(); + if (promote(&o1, &o2) != 0) + return -1; + switch(o1.type) { + case PCBQ_VT_VOID: PCB_QRY_RET_INV(res); + case PCBQ_VT_COORD: PCB_QRY_RET_INT(res, o1.data.crd * o2.data.crd); + case PCBQ_VT_LONG: PCB_QRY_RET_INT(res, o1.data.lng * o2.data.lng); + case PCBQ_VT_DOUBLE: PCB_QRY_RET_DBL(res, o1.data.dbl * o2.data.dbl); + default: return -1; + } + return -1; + + case PCBQ_OP_DIV: + BINOPS(); + if (promote(&o1, &o2) != 0) + return -1; + switch(o1.type) { + case PCBQ_VT_VOID: PCB_QRY_RET_INV(res); + case PCBQ_VT_COORD: PCB_QRY_RET_INT(res, o1.data.crd / o2.data.crd); + case PCBQ_VT_LONG: PCB_QRY_RET_INT(res, o1.data.lng / o2.data.lng); + case PCBQ_VT_DOUBLE: PCB_QRY_RET_DBL(res, o1.data.dbl / o2.data.dbl); + default: return -1; + } + return -1; + + case PCBQ_OP_MATCH: + BINOPS1(); + { + pcb_qry_node_t *o2n =node->data.children->next; + char buff[128]; + const char *s; + if (o2n->type != PCBQ_DATA_REGEX) + return -1; + s = op2str(buff, sizeof(buff), &o1); + if (s != NULL) + PCB_QRY_RET_INT(res, re_se_exec(o2n->precomp.regex, s)); + } + PCB_QRY_RET_INV(res); + + case PCBQ_OP_NOT: + UNOP(); + PCB_QRY_RET_INT(res, !pcb_qry_is_true(&o1)); + + case PCBQ_FIELD_OF: + if ((node->data.children == NULL) || (node->data.children->next == NULL)) + return -1; + if (pcb_qry_eval(ctx, node->data.children, &o1, cb, user_ctx) < 0) + return -1; + return pcb_qry_obj_field(ctx, &o1, node->data.children->next, res); + + case PCBQ_LET: + /* no-op: present only in rules and are executed before any assert expression */ + return 0; + + case PCBQ_ASSERT: + /* no-op: present only in rules and are executed manually */ + return 0; + + case PCBQ_VAR: + assert((node->data.crd >= 0) && (node->data.crd < ctx->iter->num_vars)); + res->source = NULL; + res->type = PCBQ_VT_VOID; + if (ctx->iter->vects[node->data.crd] == NULL) + return -1; + tmp = (csch_chdr_t **)vtp0_get(ctx->iter->vects[node->data.crd], ctx->iter->idx[node->data.crd], 0); + if ((tmp == NULL) || (*tmp == NULL)) + return -1; + res->type = PCBQ_VT_OBJ; + res->data.obj = ctx->iter->last_obj = *tmp; + return 0; + + case PCBQ_LISTVAR: { + int vi = pcb_qry_iter_var(ctx->iter, node->data.str, 0); + if ((vi < 0) && (strcmp(node->data.str, "@") == 0)) { + res->source = NULL; + res->type = PCBQ_VT_LST; + res->data.lst = ctx->all.data.lst; + return 0; + } + if (vi >= 0) { + res->source = NULL; + res->type = PCBQ_VT_LST; + res->data.lst = ctx->iter->lst[vi].data.lst; + return 0; + } + } + return -1; + + case PCBQ_FNAME: + return -1; /* shall not eval such a node */ + + case PCBQ_FCALL: { + pcb_qry_val_t args[PCB_QRY_MAX_FUNC_ARGS]; + int n; + pcb_qry_node_t *farg, *fname = node->data.children; + if (fname == NULL) + return -1; + farg = fname->next; + if (fname->type != PCBQ_FNAME) + return -1; + memset(args, 0, sizeof(args)); + for(n = 0; (n < PCB_QRY_MAX_FUNC_ARGS) && (farg != NULL); n++, farg = farg->next) + if (pcb_qry_eval(ctx, farg, &args[n], cb, user_ctx) < 0) + return -1; + + if (farg != NULL) { + rnd_message(RND_MSG_ERROR, "too many function arguments\n"); + return -1; + } + if (fname->precomp.fnc.bui != NULL) + return fname->precomp.fnc.bui(ctx, n, args, res); + else + return qry_exec_user_func(ctx, fname->precomp.fnc.uf, n, args, res, cb, user_ctx); + } + + case PCBQ_DATA_COORD: PCB_QRY_RET_INT_SRC(res, node->data.crd, node); + case PCBQ_DATA_DOUBLE: PCB_QRY_RET_DBL_SRC(res, node->data.dbl, node); + case PCBQ_DATA_STRING: PCB_QRY_RET_STR_SRC(res, node->data.str, node); + case PCBQ_DATA_CONST: PCB_QRY_RET_INT_SRC(res, node->precomp.cnst, node); + case PCBQ_DATA_OBJ: PCB_QRY_RET_OBJ_SRC(res, node->precomp.obj, node); + case PCBQ_DATA_INVALID: PCB_QRY_RET_INV_SRC(res, node); + + /* not yet implemented: */ + case PCBQ_RULE: + + /* must not meet these while executing a node */ + case PCBQ_FLAG: + case PCBQ_DATA_REGEX: + case PCBQ_nodetype_max: + case PCBQ_FIELD: + case PCBQ_RNAME: + case PCBQ_DATA_LYTC: + case PCBQ_ITER_CTX: + case PCBQ_FUNCTION: + case PCBQ_RETURN: + case PCBQ_ARG: + return -1; + } + return -1; +} Index: tags/1.0.5/src/plugins/query/query_exec.h =================================================================== --- tags/1.0.5/src/plugins/query/query_exec.h (nonexistent) +++ tags/1.0.5/src/plugins/query/query_exec.h (revision 10414) @@ -0,0 +1,163 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016,2020 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* Query language - execution */ + +#ifndef PCB_QUERY_EXEC_H +#define PCB_QUERY_EXEC_H + +#include "query.h" +#include +#include +#include + +#define PCB_QRY_MAX_FUNC_ARGS 64 + +struct pcb_qry_exec_s { + csch_sheet_t *sheet; + pcb_qry_node_t *root; + pcb_qry_val_t all; /* a list of all objects */ + pcb_query_iter_t *iter; /* current iterator */ + vtp0_t autofree; + unsigned cfg_prefer_term:1; /* prefer ending in terminal */ + + int (*progress_cb)(pcb_qry_exec_t *ec, long at, long total); + void *progress_ctx; + + /* data/call cache */ + vtp0_t tmplst; /* may be reused in a function call to save on allocation; always clear it at the end of the fnc */ + time_t last_prog_cb; + + unsigned warned_missing_thickness:1; + unsigned trace:1; +}; + +/* if bufno is -1, scope is the board, else scope is the buffer addressed by bufno */ +void pcb_qry_init(pcb_qry_exec_t *ctx, csch_sheet_t *sheet, pcb_qry_node_t *root, int bufno); +void pcb_qry_uninit(pcb_qry_exec_t *ctx); + +/* parts of init/uninit for the case a single pcb_qry_exec_t is used for + multiple queries for sharing the cache */ +void pcb_qry_setup(pcb_qry_exec_t *ctx, csch_sheet_t *sheet, pcb_qry_node_t *root); +void pcb_qry_autofree(pcb_qry_exec_t *ctx); + +/* Execute an expression or a rule; if ec is NULL, use a temporary context and + free it before returning; else ec is the shared context for multiple queries + with persistent cache */ +int pcb_qry_run(pcb_qry_exec_t *ec, csch_sheet_t *sheet, pcb_qry_node_t *prg, int bufno, void (*cb)(void *user_ctx, pcb_qry_val_t *res, csch_chdr_t *current), void *user_ctx); + +int pcb_qry_is_true(pcb_qry_val_t *val); + +int pcb_qry_eval(pcb_qry_exec_t *ctx, pcb_qry_node_t *node, pcb_qry_val_t *res, void (*cb)(void *user_ctx, pcb_qry_val_t *res, csch_chdr_t *current), void *user_ctx); + +int pcb_qry_it_reset(pcb_qry_exec_t *ctx, pcb_qry_node_t *node); +int pcb_qry_it_reset_(pcb_qry_exec_t *ctx, int persistent); + +/* Returns 1 if context iterator is valid, 0 if the loop is over */ +int pcb_qry_it_next(pcb_qry_exec_t *ctx); + + +void pcb_qry_val_free_fields(pcb_qry_val_t *val); + +/* Helper macros: load value o and return 0 */ +#define PCB_QRY_RET_INT_SRC(o, value, node) \ +do { \ + o->source = node; \ + o->type = PCBQ_VT_LONG; \ + o->data.lng = value; \ + return 0; \ +} while(0) +#define PCB_QRY_RET_INT(o, value) PCB_QRY_RET_INT_SRC(o, value, NULL) + + +#define PCB_QRY_RET_OBJ_SRC(o, value, node) \ +do { \ + o->source = node; \ + o->type = PCBQ_VT_OBJ; \ + o->data.obj = value; \ + return 0; \ +} while(0) +#define PCB_QRY_RET_OBJ(o, value) PCB_QRY_RET_OBJ_SRC(o, value, NULL) + +#define PCB_QRY_RET_DBL_SRC(o, value, node) \ +do { \ + o->source = node; \ + o->type = PCBQ_VT_DOUBLE; \ + o->data.dbl = value; \ + return 0; \ +} while(0) +#define PCB_QRY_RET_DBL(o, value) PCB_QRY_RET_DBL_SRC(o, value, NULL) + +#define PCB_QRY_RET_COORD_SRC(o, value, node) \ +do { \ + o->source = node; \ + o->type = PCBQ_VT_COORD; \ + o->data.crd = value; \ + return 0; \ +} while(0) +#define PCB_QRY_RET_COORD(o, value) PCB_QRY_RET_COORD_SRC(o, value, NULL) + +#define PCB_QRY_RET_STR_SRC(o, value, node) \ +do { \ + o->source = node; \ + o->type = PCBQ_VT_STRING; \ + o->data.str = value; \ + return 0; \ +} while(0) +#define PCB_QRY_RET_STR(o, value) PCB_QRY_RET_STR_SRC(o, value, NULL) + +#define PCB_QRY_RET_UID(o, value) \ +do { \ + minuid_str_t __tmp__; \ + minuid_bin2str(__tmp__, value); \ + PCB_QRY_RET_STR(o, __tmp__); \ +} while(0) + +/* The case when the operation couldn't be carried out, sort of NaN */ +#define PCB_QRY_RET_INV_SRC(o, node) \ +do { \ + o->source = node; \ + o->type = PCBQ_VT_VOID; \ + return 0; \ +} while(0) +#define PCB_QRY_RET_INV(o) PCB_QRY_RET_INV_SRC(o, NULL) + +/* Convert src_arg to coordinate and cache the result if src_arg is tied + to a tree node */ +#define PCB_QRY_ARG_CONV_TO_COORD(dst_crd, src_arg, err_inst) \ +do { \ + rnd_bool succ; \ + if ((src_arg)->type == PCBQ_VT_COORD) { dst_crd = (src_arg)->data.crd; break; } \ + if ((src_arg)->type == PCBQ_VT_LONG) { dst_crd = (src_arg)->data.lng; break; } \ + if ((src_arg)->type == PCBQ_VT_DOUBLE) { dst_crd = rnd_round((src_arg)->data.dbl); break; } \ + if ((src_arg)->type == PCBQ_VT_STRING) { \ + dst_crd = rnd_get_value((src_arg)->data.str, NULL, NULL, &succ); \ + if (succ) break; \ + } \ + err_inst; \ +} while(0) + +#endif Index: tags/1.0.5/src/plugins/query/query_l.c =================================================================== --- tags/1.0.5/src/plugins/query/query_l.c (nonexistent) +++ tags/1.0.5/src/plugins/query/query_l.c (revision 10414) @@ -0,0 +1,2559 @@ +#line 2 "query_l.c" + +#line 4 "query_l.c" + +#define YY_INT_ALIGNED short int + +/* A lexical scanner generated by flex */ + +#define yy_create_buffer qry__create_buffer +#define yy_delete_buffer qry__delete_buffer +#define yy_scan_buffer qry__scan_buffer +#define yy_scan_string qry__scan_string +#define yy_scan_bytes qry__scan_bytes +#define yy_init_buffer qry__init_buffer +#define yy_flush_buffer qry__flush_buffer +#define yy_load_buffer_state qry__load_buffer_state +#define yy_switch_to_buffer qry__switch_to_buffer +#define yypush_buffer_state qry_push_buffer_state +#define yypop_buffer_state qry_pop_buffer_state +#define yyensure_buffer_stack qry_ensure_buffer_stack +#define yy_flex_debug qry__flex_debug +#define yyin qry_in +#define yyleng qry_leng +#define yylex qry_lex +#define yylineno qry_lineno +#define yyout qry_out +#define yyrestart qry_restart +#define yytext qry_text +#define yywrap qry_wrap +#define yyalloc qry_alloc +#define yyrealloc qry_realloc +#define yyfree qry_free + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 6 +#define YY_FLEX_SUBMINOR_VERSION 4 +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif + +#ifdef yy_create_buffer +#define qry__create_buffer_ALREADY_DEFINED +#else +#define yy_create_buffer qry__create_buffer +#endif + +#ifdef yy_delete_buffer +#define qry__delete_buffer_ALREADY_DEFINED +#else +#define yy_delete_buffer qry__delete_buffer +#endif + +#ifdef yy_scan_buffer +#define qry__scan_buffer_ALREADY_DEFINED +#else +#define yy_scan_buffer qry__scan_buffer +#endif + +#ifdef yy_scan_string +#define qry__scan_string_ALREADY_DEFINED +#else +#define yy_scan_string qry__scan_string +#endif + +#ifdef yy_scan_bytes +#define qry__scan_bytes_ALREADY_DEFINED +#else +#define yy_scan_bytes qry__scan_bytes +#endif + +#ifdef yy_init_buffer +#define qry__init_buffer_ALREADY_DEFINED +#else +#define yy_init_buffer qry__init_buffer +#endif + +#ifdef yy_flush_buffer +#define qry__flush_buffer_ALREADY_DEFINED +#else +#define yy_flush_buffer qry__flush_buffer +#endif + +#ifdef yy_load_buffer_state +#define qry__load_buffer_state_ALREADY_DEFINED +#else +#define yy_load_buffer_state qry__load_buffer_state +#endif + +#ifdef yy_switch_to_buffer +#define qry__switch_to_buffer_ALREADY_DEFINED +#else +#define yy_switch_to_buffer qry__switch_to_buffer +#endif + +#ifdef yypush_buffer_state +#define qry_push_buffer_state_ALREADY_DEFINED +#else +#define yypush_buffer_state qry_push_buffer_state +#endif + +#ifdef yypop_buffer_state +#define qry_pop_buffer_state_ALREADY_DEFINED +#else +#define yypop_buffer_state qry_pop_buffer_state +#endif + +#ifdef yyensure_buffer_stack +#define qry_ensure_buffer_stack_ALREADY_DEFINED +#else +#define yyensure_buffer_stack qry_ensure_buffer_stack +#endif + +#ifdef yylex +#define qry_lex_ALREADY_DEFINED +#else +#define yylex qry_lex +#endif + +#ifdef yyrestart +#define qry_restart_ALREADY_DEFINED +#else +#define yyrestart qry_restart +#endif + +#ifdef yylex_init +#define qry_lex_init_ALREADY_DEFINED +#else +#define yylex_init qry_lex_init +#endif + +#ifdef yylex_init_extra +#define qry_lex_init_extra_ALREADY_DEFINED +#else +#define yylex_init_extra qry_lex_init_extra +#endif + +#ifdef yylex_destroy +#define qry_lex_destroy_ALREADY_DEFINED +#else +#define yylex_destroy qry_lex_destroy +#endif + +#ifdef yyget_debug +#define qry_get_debug_ALREADY_DEFINED +#else +#define yyget_debug qry_get_debug +#endif + +#ifdef yyset_debug +#define qry_set_debug_ALREADY_DEFINED +#else +#define yyset_debug qry_set_debug +#endif + +#ifdef yyget_extra +#define qry_get_extra_ALREADY_DEFINED +#else +#define yyget_extra qry_get_extra +#endif + +#ifdef yyset_extra +#define qry_set_extra_ALREADY_DEFINED +#else +#define yyset_extra qry_set_extra +#endif + +#ifdef yyget_in +#define qry_get_in_ALREADY_DEFINED +#else +#define yyget_in qry_get_in +#endif + +#ifdef yyset_in +#define qry_set_in_ALREADY_DEFINED +#else +#define yyset_in qry_set_in +#endif + +#ifdef yyget_out +#define qry_get_out_ALREADY_DEFINED +#else +#define yyget_out qry_get_out +#endif + +#ifdef yyset_out +#define qry_set_out_ALREADY_DEFINED +#else +#define yyset_out qry_set_out +#endif + +#ifdef yyget_leng +#define qry_get_leng_ALREADY_DEFINED +#else +#define yyget_leng qry_get_leng +#endif + +#ifdef yyget_text +#define qry_get_text_ALREADY_DEFINED +#else +#define yyget_text qry_get_text +#endif + +#ifdef yyget_lineno +#define qry_get_lineno_ALREADY_DEFINED +#else +#define yyget_lineno qry_get_lineno +#endif + +#ifdef yyset_lineno +#define qry_set_lineno_ALREADY_DEFINED +#else +#define yyset_lineno qry_set_lineno +#endif + +#ifdef yywrap +#define qry_wrap_ALREADY_DEFINED +#else +#define yywrap qry_wrap +#endif + +#ifdef yyalloc +#define qry_alloc_ALREADY_DEFINED +#else +#define yyalloc qry_alloc +#endif + +#ifdef yyrealloc +#define qry_realloc_ALREADY_DEFINED +#else +#define yyrealloc qry_realloc +#endif + +#ifdef yyfree +#define qry_free_ALREADY_DEFINED +#else +#define yyfree qry_free +#endif + +#ifdef yytext +#define qry_text_ALREADY_DEFINED +#else +#define yytext qry_text +#endif + +#ifdef yyleng +#define qry_leng_ALREADY_DEFINED +#else +#define yyleng qry_leng +#endif + +#ifdef yyin +#define qry_in_ALREADY_DEFINED +#else +#define yyin qry_in +#endif + +#ifdef yyout +#define qry_out_ALREADY_DEFINED +#else +#define yyout qry_out +#endif + +#ifdef yy_flex_debug +#define qry__flex_debug_ALREADY_DEFINED +#else +#define yy_flex_debug qry__flex_debug +#endif + +#ifdef yylineno +#define qry_lineno_ALREADY_DEFINED +#else +#define yylineno qry_lineno +#endif + +/* First, we deal with platform-specific or compiler-specific issues. */ + +/* begin standard C headers. */ +#include +#include +#include +#include + +/* end standard C headers. */ + +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have . Non-C99 systems may or may not. */ + +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + +/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, + * if you want the limit (max/min) macros for int types. + */ +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 +#endif + +#include +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; + +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767-1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#ifndef SIZE_MAX +#define SIZE_MAX (~(size_t)0) +#endif + +#endif /* ! C99 */ + +#endif /* ! FLEXINT_H */ + +/* begin standard C++ headers. */ + +/* TODO: this is always defined, so inline it */ +#define yyconst const + +#if defined(__GNUC__) && __GNUC__ >= 3 +#define yynoreturn __attribute__((__noreturn__)) +#else +#define yynoreturn +#endif + +/* Returned upon end-of-file. */ +#define YY_NULL 0 + +/* Promotes a possibly negative, possibly signed char to an + * integer in range [0..255] for use as an array index. + */ +#define YY_SC_TO_UI(c) ((YY_CHAR) (c)) + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN (yy_start) = 1 + 2 * +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START (((yy_start) - 1) / 2) +#define YYSTATE YY_START +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE yyrestart( yyin ) +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#ifndef YY_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k. + * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. + * Ditto for the __ia64__ case accordingly. + */ +#define YY_BUF_SIZE 32768 +#else +#define YY_BUF_SIZE 16384 +#endif /* __ia64__ */ +#endif + +/* The state buf must be large enough to hold one state per character in the main buffer. + */ +#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + +extern int yyleng; + +extern FILE *yyin, *yyout; + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + + #define YY_LESS_LINENO(n) + #define YY_LINENO_REWIND_TO(ptr) + +/* Return all but the first "n" matched characters back to the input stream. */ +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + *yy_cp = (yy_hold_char); \ + YY_RESTORE_YY_MORE_OFFSET \ + (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ + } \ + while ( 0 ) +#define unput(c) yyunput( c, (yytext_ptr) ) + +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE +struct yy_buffer_state + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + int yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; + +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via yyrestart()), so that the user can continue scanning by + * just pointing yyin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + + }; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ + +/* Stack of input buffers. */ +static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ +static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ +static YY_BUFFER_STATE * yy_buffer_stack = NULL; /**< Stack as an array. */ + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + * + * Returns the top of the stack, or NULL. + */ +#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ + ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ + : NULL) +/* Same as previous macro, but useful when we know that the buffer stack is not + * NULL or when we need an lvalue. For internal use only. + */ +#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] + +/* yy_hold_char holds the character lost when yytext is formed. */ +static char yy_hold_char; +static int yy_n_chars; /* number of characters read into yy_ch_buf */ +int yyleng; + +/* Points to current character in buffer. */ +static char *yy_c_buf_p = NULL; +static int yy_init = 0; /* whether we need to initialize */ +static int yy_start = 0; /* start state number */ + +/* Flag which is used to allow yywrap()'s to do buffer switches + * instead of setting up a fresh yyin. A bit of a hack ... + */ +static int yy_did_buffer_switch_on_eof; + +void yyrestart ( FILE *input_file ); +void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer ); +YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size ); +void yy_delete_buffer ( YY_BUFFER_STATE b ); +void yy_flush_buffer ( YY_BUFFER_STATE b ); +void yypush_buffer_state ( YY_BUFFER_STATE new_buffer ); +void yypop_buffer_state ( void ); + +static void yyensure_buffer_stack ( void ); +static void yy_load_buffer_state ( void ); +static void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file ); +#define YY_FLUSH_BUFFER yy_flush_buffer( YY_CURRENT_BUFFER ) + +YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size ); +YY_BUFFER_STATE yy_scan_string ( const char *yy_str ); +YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len ); + +void *yyalloc ( yy_size_t ); +void *yyrealloc ( void *, yy_size_t ); +void yyfree ( void * ); + +#define yy_new_buffer yy_create_buffer +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! YY_CURRENT_BUFFER ){ \ + yyensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer( yyin, YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ + } +#define yy_set_bol(at_bol) \ + { \ + if ( ! YY_CURRENT_BUFFER ){\ + yyensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer( yyin, YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ + } +#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) + +/* Begin user sect3 */ +typedef flex_uint8_t YY_CHAR; + +FILE *yyin = NULL, *yyout = NULL; + +typedef int yy_state_type; + +extern int yylineno; +int yylineno = 1; + +extern char *yytext; +#ifdef yytext_ptr +#undef yytext_ptr +#endif +#define yytext_ptr yytext + +static yy_state_type yy_get_previous_state ( void ); +static yy_state_type yy_try_NUL_trans ( yy_state_type current_state ); +static int yy_get_next_buffer ( void ); +static void yynoreturn yy_fatal_error ( const char* msg ); + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up yytext. + */ +#define YY_DO_BEFORE_ACTION \ + (yytext_ptr) = yy_bp; \ + yyleng = (int) (yy_cp - yy_bp); \ + (yy_hold_char) = *yy_cp; \ + *yy_cp = '\0'; \ + (yy_c_buf_p) = yy_cp; +#define YY_NUM_RULES 65 +#define YY_END_OF_BUFFER 66 +/* This struct is not used in this scanner, + but its presence is necessary. */ +struct yy_trans_info + { + flex_int32_t yy_verify; + flex_int32_t yy_nxt; + }; +static const flex_int16_t yy_accept[246] = + { 0, + 63, 63, 66, 65, 64, 63, 61, 65, 61, 65, + 65, 61, 57, 61, 65, 61, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 65, 60, 60, 60, + 49, 60, 60, 60, 60, 65, 63, 54, 0, 1, + 52, 0, 2, 58, 59, 57, 56, 53, 55, 60, + 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 43, 60, 38, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, 62, 11, + 60, 60, 60, 60, 60, 60, 10, 60, 60, 60, + + 51, 59, 14, 60, 60, 25, 60, 60, 60, 60, + 32, 60, 20, 60, 60, 60, 60, 42, 22, 60, + 60, 60, 60, 60, 60, 60, 60, 39, 60, 60, + 60, 60, 3, 60, 60, 60, 60, 60, 60, 60, + 19, 60, 60, 60, 60, 60, 60, 60, 60, 60, + 35, 13, 15, 60, 60, 17, 36, 60, 24, 60, + 60, 60, 60, 60, 8, 60, 5, 50, 60, 60, + 60, 60, 60, 60, 60, 60, 40, 60, 60, 60, + 60, 31, 60, 60, 60, 60, 12, 60, 60, 60, + 60, 18, 33, 60, 60, 60, 60, 60, 60, 60, + + 60, 60, 26, 60, 60, 4, 60, 60, 7, 60, + 60, 60, 44, 45, 60, 48, 21, 27, 60, 16, + 60, 37, 60, 60, 9, 60, 60, 60, 60, 60, + 60, 60, 6, 60, 60, 46, 60, 41, 60, 34, + 23, 28, 47, 29, 0 + } ; + +static const YY_CHAR yy_ec[256] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 4, 5, 1, 6, 1, 7, 8, 6, + 6, 6, 6, 6, 6, 9, 6, 10, 11, 12, + 10, 10, 10, 10, 10, 10, 10, 1, 13, 14, + 15, 16, 1, 6, 17, 18, 19, 20, 21, 22, + 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 40, 41, 33, + 1, 42, 1, 1, 43, 1, 44, 33, 45, 46, + + 47, 48, 49, 50, 51, 33, 52, 53, 33, 54, + 55, 56, 33, 57, 58, 59, 60, 61, 33, 33, + 33, 33, 1, 62, 1, 6, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1 + } ; + +static const YY_CHAR yy_meta[63] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, + 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 1 + } ; + +static const flex_int16_t yy_base[249] = + { 0, + 0, 0, 284, 285, 285, 60, 268, 277, 285, 274, + 272, 54, 58, 264, 263, 262, 242, 54, 51, 53, + 245, 257, 239, 235, 241, 233, 0, 244, 237, 53, + 55, 44, 56, 242, 53, 245, 262, 72, 35, 210, + 0, 42, 254, 45, 212, 199, 91, 285, 255, 285, + 285, 251, 285, 86, 89, 97, 285, 285, 285, 0, + 239, 238, 220, 220, 224, 223, 233, 232, 230, 221, + 216, 229, 208, 210, 214, 0, 221, 0, 212, 213, + 223, 210, 198, 200, 201, 201, 200, 198, 285, 285, + 174, 187, 176, 168, 169, 169, 285, 167, 172, 164, + + 285, 100, 0, 196, 193, 0, 185, 190, 188, 92, + 0, 183, 174, 180, 190, 178, 192, 0, 0, 171, + 177, 192, 173, 187, 182, 185, 185, 0, 157, 154, + 157, 157, 0, 141, 139, 151, 139, 173, 178, 173, + 0, 159, 152, 157, 169, 168, 167, 153, 165, 150, + 0, 0, 161, 147, 151, 0, 0, 163, 0, 137, + 122, 169, 118, 123, 0, 118, 0, 0, 140, 141, + 138, 154, 138, 137, 151, 127, 0, 145, 131, 139, + 132, 0, 134, 133, 134, 100, 285, 107, 106, 102, + 124, 0, 0, 118, 132, 91, 117, 115, 128, 120, + + 130, 117, 103, 124, 107, 0, 88, 96, 0, 104, + 115, 120, 0, 0, 101, 0, 0, 0, 109, 0, + 113, 0, 100, 75, 0, 97, 95, 89, 90, 102, + 88, 84, 0, 99, 88, 0, 96, 0, 84, 0, + 0, 0, 0, 0, 285, 130, 132, 112 + } ; + +static const flex_int16_t yy_def[249] = + { 0, + 245, 1, 245, 245, 245, 245, 245, 246, 245, 245, + 247, 245, 245, 245, 245, 245, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 245, 248, 248, 248, + 248, 248, 248, 248, 248, 245, 245, 245, 246, 245, + 245, 247, 245, 245, 245, 245, 245, 245, 245, 248, + 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, 245, 245, + 248, 248, 248, 248, 248, 248, 245, 248, 248, 248, + + 245, 245, 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 245, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, + + 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 0, 245, 245, 245 + } ; + +static const flex_int16_t yy_nxt[348] = + { 0, + 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 13, 13, 6, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 27, 29, + 30, 31, 27, 27, 32, 33, 27, 34, 35, 27, + 36, 37, 27, 38, 27, 27, 27, 39, 27, 27, + 40, 41, 42, 27, 27, 43, 44, 27, 45, 27, + 27, 46, 47, 54, 54, 54, 55, 56, 56, 56, + 62, 65, 47, 67, 77, 79, 83, 86, 63, 81, + 90, 66, 78, 87, 82, 80, 68, 92, 95, 84, + 64, 98, 96, 47, 93, 54, 54, 54, 102, 102, + + 102, 213, 214, 47, 99, 55, 56, 56, 56, 102, + 102, 102, 143, 60, 144, 244, 243, 242, 241, 240, + 145, 239, 238, 237, 236, 235, 234, 146, 233, 91, + 49, 49, 52, 52, 232, 231, 230, 229, 228, 227, + 226, 225, 224, 223, 222, 221, 220, 219, 218, 217, + 216, 215, 212, 211, 210, 209, 208, 207, 206, 205, + 204, 203, 202, 201, 200, 199, 198, 197, 196, 195, + 194, 193, 192, 191, 190, 189, 188, 187, 186, 185, + 184, 183, 182, 181, 180, 179, 178, 177, 176, 175, + 174, 173, 172, 171, 170, 169, 168, 167, 166, 165, + + 164, 163, 162, 161, 160, 159, 158, 157, 156, 155, + 154, 153, 152, 151, 150, 149, 148, 147, 142, 141, + 140, 139, 138, 137, 136, 135, 134, 133, 132, 131, + 130, 129, 128, 127, 126, 125, 124, 123, 122, 121, + 120, 119, 118, 117, 116, 115, 114, 113, 112, 111, + 110, 109, 108, 107, 106, 105, 104, 103, 53, 50, + 101, 100, 97, 94, 89, 88, 85, 76, 75, 74, + 73, 72, 71, 70, 69, 61, 59, 58, 57, 53, + 51, 50, 48, 245, 3, 245, 245, 245, 245, 245, + 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, + + 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, + 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, + 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, + 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, + 245, 245, 245, 245, 245, 245, 245 + } ; + +static const flex_int16_t yy_chk[348] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 6, 12, 12, 12, 13, 13, 13, 13, + 18, 19, 6, 20, 30, 31, 33, 35, 18, 32, + 38, 19, 30, 35, 32, 31, 20, 39, 42, 33, + 18, 44, 42, 47, 39, 54, 54, 54, 55, 55, + + 55, 196, 196, 47, 44, 56, 56, 56, 56, 102, + 102, 102, 110, 248, 110, 239, 237, 235, 234, 232, + 110, 231, 230, 229, 228, 227, 226, 110, 224, 38, + 246, 246, 247, 247, 223, 221, 219, 215, 212, 211, + 210, 208, 207, 205, 204, 203, 202, 201, 200, 199, + 198, 197, 195, 194, 191, 190, 189, 188, 186, 185, + 184, 183, 181, 180, 179, 178, 176, 175, 174, 173, + 172, 171, 170, 169, 166, 164, 163, 162, 161, 160, + 158, 155, 154, 153, 150, 149, 148, 147, 146, 145, + 144, 143, 142, 140, 139, 138, 137, 136, 135, 134, + + 132, 131, 130, 129, 127, 126, 125, 124, 123, 122, + 121, 120, 117, 116, 115, 114, 113, 112, 109, 108, + 107, 105, 104, 100, 99, 98, 96, 95, 94, 93, + 92, 91, 88, 87, 86, 85, 84, 83, 82, 81, + 80, 79, 77, 75, 74, 73, 72, 71, 70, 69, + 68, 67, 66, 65, 64, 63, 62, 61, 52, 49, + 46, 45, 43, 40, 37, 36, 34, 29, 28, 26, + 25, 24, 23, 22, 21, 17, 16, 15, 14, 11, + 10, 8, 7, 3, 245, 245, 245, 245, 245, 245, + 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, + + 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, + 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, + 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, + 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, + 245, 245, 245, 245, 245, 245, 245 + } ; + +static yy_state_type yy_last_accepting_state; +static char *yy_last_accepting_cpos; + +extern int yy_flex_debug; +int yy_flex_debug = 0; + +/* The intent behind this definition is that it'll catch + * any uses of REJECT which flex missed. + */ +#define REJECT reject_used_but_not_detected +#define yymore() yymore_used_but_not_detected +#define YY_MORE_ADJ 0 +#define YY_RESTORE_YY_MORE_OFFSET +char *yytext; +#line 1 "query_l.l" +#line 2 "query_l.l" +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016,2019 Tibor 'Igor2' Palinkas + * Copyright (C) 2022 Tibor 'Igor2' Palinkas (slight modifications for sch-rnd) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +/* Query language - compiler: lexical analyzer */ + +#include +#include +#include "query.h" +#include "query_y.h" +#include +#include +#include + +static const char *pcb_qry_program, *pcb_qry_program_ptr; +static int qry_yy_input(char *buf, int buflen); +static pcb_qry_node_t *make_constant(char *str, long val); +static pcb_qry_node_t *make_const_obj(char *str, csch_chdr_t *obj); +#define YY_INPUT(buf, res, buflen) (res = qry_yy_input(buf, buflen)) + +static void qry_update_nl(const char *s); +long pcb_qry_lex_lineno; + +static rnd_unit_t lex_unit_k = {"k", 'c', 1.0/1000.0, 0, 0, 3, 0}; + +#line 904 "query_l.c" +#line 905 "query_l.c" + +#define INITIAL 0 + +#ifndef YY_NO_UNISTD_H +/* Special case for "unistd.h", since it is non-ANSI. We include it way + * down here because we want the user's section 1 to have been scanned first. + * The user has a chance to override it with an option. + */ +#include +#endif + +#ifndef YY_EXTRA_TYPE +#define YY_EXTRA_TYPE void * +#endif + +static int yy_init_globals ( void ); + +/* Accessor methods to globals. + These are made visible to non-reentrant scanners for convenience. */ + +int yylex_destroy ( void ); + +int yyget_debug ( void ); + +void yyset_debug ( int debug_flag ); + +YY_EXTRA_TYPE yyget_extra ( void ); + +void yyset_extra ( YY_EXTRA_TYPE user_defined ); + +FILE *yyget_in ( void ); + +void yyset_in ( FILE * _in_str ); + +FILE *yyget_out ( void ); + +void yyset_out ( FILE * _out_str ); + + int yyget_leng ( void ); + +char *yyget_text ( void ); + +int yyget_lineno ( void ); + +void yyset_lineno ( int _line_number ); + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int yywrap ( void ); +#else +extern int yywrap ( void ); +#endif +#endif + +#ifndef YY_NO_UNPUT + + static void yyunput ( int c, char *buf_ptr ); + +#endif + +#ifndef yytext_ptr +static void yy_flex_strncpy ( char *, const char *, int ); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen ( const char * ); +#endif + +#ifndef YY_NO_INPUT +#ifdef __cplusplus +static int yyinput ( void ); +#else +static int input ( void ); +#endif + +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k */ +#define YY_READ_BUF_SIZE 16384 +#else +#define YY_READ_BUF_SIZE 8192 +#endif /* __ia64__ */ +#endif + +/* Copy whatever the last rule matched to the standard output. */ +#ifndef ECHO +/* This used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite(). + */ +#define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0) +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ + if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ + { \ + int c = '*'; \ + int n; \ + for ( n = 0; n < max_size && \ + (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ + buf[n] = (char) c; \ + if ( c == '\n' ) \ + buf[n++] = (char) c; \ + if ( c == EOF && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + result = n; \ + } \ + else \ + { \ + errno=0; \ + while ( (result = (int) fread(buf, 1, (yy_size_t) max_size, yyin)) == 0 && ferror(yyin)) \ + { \ + if( errno != EINTR) \ + { \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + break; \ + } \ + errno=0; \ + clearerr(yyin); \ + } \ + }\ +\ + +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) +#endif + +/* end tables serialization structures and prototypes */ + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL_IS_OURS 1 + +extern int yylex (void); + +#define YY_DECL int yylex (void) +#endif /* !YY_DECL */ + +/* Code executed at the beginning of each rule, after yytext and yyleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK /*LINTED*/break; +#endif + +#define YY_RULE_SETUP \ + YY_USER_ACTION + +/** The main scanner function which does all the work. + */ +YY_DECL +{ + yy_state_type yy_current_state; + char *yy_cp, *yy_bp; + int yy_act; + + if ( !(yy_init) ) + { + (yy_init) = 1; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + if ( ! (yy_start) ) + (yy_start) = 1; /* first start state */ + + if ( ! yyin ) + yyin = stdin; + + if ( ! yyout ) + yyout = stdout; + + if ( ! YY_CURRENT_BUFFER ) { + yyensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer( yyin, YY_BUF_SIZE ); + } + + yy_load_buffer_state( ); + } + + { +#line 50 "query_l.l" + +#line 1124 "query_l.c" + + while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ + { + yy_cp = (yy_c_buf_p); + + /* Support of yytext. */ + *yy_cp = (yy_hold_char); + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + + yy_current_state = (yy_start); +yy_match: + do + { + YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 246 ) + yy_c = yy_meta[yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; + ++yy_cp; + } + while ( yy_base[yy_current_state] != 285 ); + +yy_find_action: + yy_act = yy_accept[yy_current_state]; + if ( yy_act == 0 ) + { /* have to back up */ + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + yy_act = yy_accept[yy_current_state]; + } + + YY_DO_BEFORE_ACTION; + +do_action: /* This label is used only to access EOF actions. */ + + switch ( yy_act ) + { /* beginning of action switch */ + case 0: /* must back up */ + /* undo the effects of YY_DO_BEFORE_ACTION */ + *yy_cp = (yy_hold_char); + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + goto yy_find_action; + +case 1: +/* rule 1 can match eol */ +YY_RULE_SETUP +#line 51 "query_l.l" +{ qry_lval.s = rnd_strdup(yytext+1); qry_lval.s[strlen(qry_lval.s)-1] = '\0'; return T_QSTR; /*"*/ } + YY_BREAK +case 2: +/* rule 2 can match eol */ +YY_RULE_SETUP +#line 52 "query_l.l" +{ qry_lval.s = rnd_strdup(yytext+1); qry_lval.s[strlen(qry_lval.s)-1] = '\0'; return T_QSTR; } + YY_BREAK +case 3: +YY_RULE_SETUP +#line 54 "query_l.l" +{ return T_LET; } + YY_BREAK +case 4: +YY_RULE_SETUP +#line 55 "query_l.l" +{ return T_ASSERT; } + YY_BREAK +case 5: +YY_RULE_SETUP +#line 56 "query_l.l" +{ return T_RULE; } + YY_BREAK +case 6: +YY_RULE_SETUP +#line 57 "query_l.l" +{ return T_FUNCTION; } + YY_BREAK +case 7: +YY_RULE_SETUP +#line 58 "query_l.l" +{ return T_RETURN; } + YY_BREAK +case 8: +YY_RULE_SETUP +#line 59 "query_l.l" +{ return T_LIST; } + YY_BREAK +case 9: +YY_RULE_SETUP +#line 60 "query_l.l" +{ return T_INVALID; } + YY_BREAK +case 10: +YY_RULE_SETUP +#line 61 "query_l.l" +{ return T_FLD_P; } + YY_BREAK +case 11: +YY_RULE_SETUP +#line 62 "query_l.l" +{ return T_FLD_A; } + YY_BREAK +case 12: +YY_RULE_SETUP +#line 63 "query_l.l" +{ return T_FLD_FLAG; } + YY_BREAK +case 13: +YY_RULE_SETUP +#line 65 "query_l.l" +{ qry_lval.n = make_constant(yytext, CSCH_CTYPE_LINE); return T_CONST; } + YY_BREAK +case 14: +YY_RULE_SETUP +#line 66 "query_l.l" +{ qry_lval.n = make_constant(yytext, CSCH_CTYPE_ARC); return T_CONST; } + YY_BREAK +case 15: +YY_RULE_SETUP +#line 67 "query_l.l" +{ qry_lval.n = make_constant(yytext, CSCH_CTYPE_POLY); return T_CONST; } + YY_BREAK +case 16: +YY_RULE_SETUP +#line 68 "query_l.l" +{ qry_lval.n = make_constant(yytext, CSCH_CTYPE_POLY); return T_CONST; } + YY_BREAK +case 17: +YY_RULE_SETUP +#line 69 "query_l.l" +{ qry_lval.n = make_constant(yytext, CSCH_CTYPE_TEXT); return T_CONST; } + YY_BREAK +case 18: +YY_RULE_SETUP +#line 70 "query_l.l" +{ qry_lval.n = make_constant(yytext, CSCH_CTYPE_BITMAP); return T_CONST; } + YY_BREAK +case 19: +YY_RULE_SETUP +#line 71 "query_l.l" +{ qry_lval.n = make_constant(yytext, CSCH_CTYPE_CONN); return T_CONST; } + YY_BREAK +case 20: +YY_RULE_SETUP +#line 72 "query_l.l" +{ qry_lval.n = make_constant(yytext, CSCH_CTYPE_GRP); return T_CONST; } + YY_BREAK +case 21: +YY_RULE_SETUP +#line 73 "query_l.l" +{ qry_lval.n = make_constant(yytext, CSCH_CTYPE_GRP_REF); return T_CONST; } + YY_BREAK +case 22: +YY_RULE_SETUP +#line 74 "query_l.l" +{ qry_lval.n = make_constant(yytext, CSCH_CTYPE_PEN); return T_CONST; } + YY_BREAK +case 23: +YY_RULE_SETUP +#line 76 "query_l.l" +{ qry_lval.n = make_constant(yytext, CSCH_DSPLY_BACKGROUND); return T_CONST; } + YY_BREAK +case 24: +YY_RULE_SETUP +#line 77 "query_l.l" +{ qry_lval.n = make_constant(yytext, CSCH_DSPLY_WIRE); return T_CONST; } + YY_BREAK +case 25: +YY_RULE_SETUP +#line 78 "query_l.l" +{ qry_lval.n = make_constant(yytext, CSCH_DSPLY_BUS); return T_CONST; } + YY_BREAK +case 26: +YY_RULE_SETUP +#line 79 "query_l.l" +{ qry_lval.n = make_constant(yytext, CSCH_DSPLY_SYMBOL); return T_CONST; } + YY_BREAK +case 27: +YY_RULE_SETUP +#line 80 "query_l.l" +{ qry_lval.n = make_constant(yytext, CSCH_DSPLY_HUBTERM); return T_CONST; } + YY_BREAK +case 28: +YY_RULE_SETUP +#line 81 "query_l.l" +{ qry_lval.n = make_constant(yytext, CSCH_DSPLY_DECORATION); return T_CONST; } + YY_BREAK +case 29: +YY_RULE_SETUP +#line 82 "query_l.l" +{ qry_lval.n = make_constant(yytext, CSCH_DSPLY_SYMBOL_GRP); return T_CONST; } + YY_BREAK +case 30: +YY_RULE_SETUP +#line 83 "query_l.l" +{ qry_lval.n = make_constant(yytext, CSCH_DSPLY_CONN); return T_CONST; } + YY_BREAK +case 31: +YY_RULE_SETUP +#line 85 "query_l.l" +{ qry_lval.n = make_constant(yytext, CSCH_HALIGN_START); return T_CONST; } + YY_BREAK +case 32: +YY_RULE_SETUP +#line 86 "query_l.l" +{ qry_lval.n = make_constant(yytext, CSCH_HALIGN_END); return T_CONST; } + YY_BREAK +case 33: +YY_RULE_SETUP +#line 87 "query_l.l" +{ qry_lval.n = make_constant(yytext, CSCH_HALIGN_CENTER); return T_CONST; } + YY_BREAK +case 34: +YY_RULE_SETUP +#line 88 "query_l.l" +{ qry_lval.n = make_constant(yytext, CSCH_HALIGN_WORD_JUST); return T_CONST; } + YY_BREAK +case 35: +YY_RULE_SETUP +#line 89 "query_l.l" +{ qry_lval.n = make_constant(yytext, CSCH_HALIGN_JUST); return T_CONST; } + YY_BREAK +case 36: +YY_RULE_SETUP +#line 92 "query_l.l" +{ qry_lval.n = make_constant(yytext, 1); return T_CONST; } + YY_BREAK +case 37: +YY_RULE_SETUP +#line 93 "query_l.l" +{ qry_lval.n = make_constant(yytext, 1); return T_CONST; } + YY_BREAK +case 38: +YY_RULE_SETUP +#line 94 "query_l.l" +{ qry_lval.n = make_constant(yytext, 1); return T_CONST; } + YY_BREAK +case 39: +YY_RULE_SETUP +#line 95 "query_l.l" +{ qry_lval.n = make_constant(yytext, 1); return T_CONST; } + YY_BREAK +case 40: +YY_RULE_SETUP +#line 97 "query_l.l" +{ qry_lval.n = make_constant(yytext, 0); return T_CONST; } + YY_BREAK +case 41: +YY_RULE_SETUP +#line 98 "query_l.l" +{ qry_lval.n = make_constant(yytext, 0); return T_CONST; } + YY_BREAK +case 42: +YY_RULE_SETUP +#line 99 "query_l.l" +{ qry_lval.n = make_constant(yytext, 0); return T_CONST; } + YY_BREAK +case 43: +YY_RULE_SETUP +#line 100 "query_l.l" +{ qry_lval.n = make_constant(yytext, 0); return T_CONST; } + YY_BREAK +case 44: +YY_RULE_SETUP +#line 102 "query_l.l" +{ qry_lval.n = make_const_obj(yytext, &pcb_qry_drc_ctrl[PCB_QRY_DRC_GRP1]); return T_CONST; } + YY_BREAK +case 45: +YY_RULE_SETUP +#line 103 "query_l.l" +{ qry_lval.n = make_const_obj(yytext, &pcb_qry_drc_ctrl[PCB_QRY_DRC_GRP2]); return T_CONST; } + YY_BREAK +case 46: +YY_RULE_SETUP +#line 104 "query_l.l" +{ qry_lval.n = make_const_obj(yytext, &pcb_qry_drc_ctrl[PCB_QRY_DRC_EXPECT]); return T_CONST; } + YY_BREAK +case 47: +YY_RULE_SETUP +#line 105 "query_l.l" +{ qry_lval.n = make_const_obj(yytext, &pcb_qry_drc_ctrl[PCB_QRY_DRC_MEASURE]); return T_CONST; } + YY_BREAK +case 48: +YY_RULE_SETUP +#line 106 "query_l.l" +{ qry_lval.n = make_const_obj(yytext, &pcb_qry_drc_ctrl[PCB_QRY_DRC_TEXT]); return T_CONST; } + YY_BREAK +case 49: +YY_RULE_SETUP +#line 108 "query_l.l" +{ qry_lval.u = &lex_unit_k; return T_UNIT; } + YY_BREAK +case 50: +YY_RULE_SETUP +#line 110 "query_l.l" +{ return T_THUS; } + YY_BREAK +case 51: +YY_RULE_SETUP +#line 111 "query_l.l" +{ return T_OR; } + YY_BREAK +case 52: +YY_RULE_SETUP +#line 112 "query_l.l" +{ return T_AND; } + YY_BREAK +case 53: +YY_RULE_SETUP +#line 113 "query_l.l" +{ return T_EQ; } + YY_BREAK +case 54: +YY_RULE_SETUP +#line 114 "query_l.l" +{ return T_NEQ; } + YY_BREAK +case 55: +YY_RULE_SETUP +#line 115 "query_l.l" +{ return T_GTEQ; } + YY_BREAK +case 56: +YY_RULE_SETUP +#line 116 "query_l.l" +{ return T_LTEQ; } + YY_BREAK +case 57: +YY_RULE_SETUP +#line 118 "query_l.l" +{ qry_lval.c = strtol(yytext, NULL, 10); return T_INT; } + YY_BREAK +case 58: +YY_RULE_SETUP +#line 119 "query_l.l" +{ qry_lval.d = strtod(yytext, NULL); return T_DBL; } + YY_BREAK +case 59: +YY_RULE_SETUP +#line 120 "query_l.l" +{ qry_lval.d = strtod(yytext, NULL); return T_DBL; } + YY_BREAK +case 60: +YY_RULE_SETUP +#line 121 "query_l.l" +{ qry_lval.s = rnd_strdup(yytext); return T_STR; } + YY_BREAK +case 61: +YY_RULE_SETUP +#line 123 "query_l.l" +{ return *yytext; } + YY_BREAK +case 62: +/* rule 62 can match eol */ +YY_RULE_SETUP +#line 125 "query_l.l" +{ continue; /* multiline rules */} + YY_BREAK +case 63: +/* rule 63 can match eol */ +YY_RULE_SETUP +#line 126 "query_l.l" +{ qry_update_nl(yytext); return T_NL; } + YY_BREAK +case 64: +YY_RULE_SETUP +#line 127 "query_l.l" +{ continue; } + YY_BREAK +case 65: +YY_RULE_SETUP +#line 129 "query_l.l" +ECHO; + YY_BREAK +#line 1510 "query_l.c" +case YY_STATE_EOF(INITIAL): + yyterminate(); + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = (yy_hold_char); + YY_RESTORE_YY_MORE_OFFSET + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed yyin at a new source and called + * yylex(). If so, then we have to assure + * consistency between YY_CURRENT_BUFFER and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state ); + + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++(yy_c_buf_p); + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { + yy_cp = (yy_c_buf_p); + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_END_OF_FILE: + { + (yy_did_buffer_switch_on_eof) = 0; + + if ( yywrap( ) ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * yytext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = + (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + (yy_c_buf_p) = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ + } /* end of user's declarations */ +} /* end of yylex */ + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ +static int yy_get_next_buffer (void) +{ + char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; + char *source = (yytext_ptr); + int number_to_move, i; + int ret_val; + + if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr) - 1); + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; + + else + { + int num_to_read = + YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ + + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; + + int yy_c_buf_p_offset = + (int) ((yy_c_buf_p) - b->yy_ch_buf); + + if ( b->yy_is_our_buffer ) + { + int new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; + + b->yy_ch_buf = (char *) + /* Include room in for 2 EOB chars. */ + yyrealloc( (void *) b->yy_ch_buf, + (yy_size_t) (b->yy_buf_size + 2) ); + } + else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = NULL; + + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); + + (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; + + num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - + number_to_move - 1; + + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), + (yy_n_chars), num_to_read ); + + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + if ( (yy_n_chars) == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + yyrestart( yyin ); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + if (((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { + /* Extend the array by 50%, plus the number we really need. */ + int new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc( + (void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, (yy_size_t) new_size ); + if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); + /* "- 2" to take care of EOB's */ + YY_CURRENT_BUFFER_LVALUE->yy_buf_size = (int) (new_size - 2); + } + + (yy_n_chars) += number_to_move; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; + + (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; + + return ret_val; +} + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + + static yy_state_type yy_get_previous_state (void) +{ + yy_state_type yy_current_state; + char *yy_cp; + + yy_current_state = (yy_start); + + for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) + { + YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 246 ) + yy_c = yy_meta[yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; + } + + return yy_current_state; +} + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ + static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) +{ + int yy_is_jam; + char *yy_cp = (yy_c_buf_p); + + YY_CHAR yy_c = 1; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 246 ) + yy_c = yy_meta[yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; + yy_is_jam = (yy_current_state == 245); + + return yy_is_jam ? 0 : yy_current_state; +} + +#ifndef YY_NO_UNPUT + + static void yyunput (int c, char * yy_bp ) +{ + char *yy_cp; + + yy_cp = (yy_c_buf_p); + + /* undo effects of setting up yytext */ + *yy_cp = (yy_hold_char); + + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) + { /* need to shift things up to make room */ + /* +2 for EOB chars. */ + int number_to_move = (yy_n_chars) + 2; + char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ + YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; + char *source = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; + + while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + *--dest = *--source; + + yy_cp += (int) (dest - source); + yy_bp += (int) (dest - source); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = + (yy_n_chars) = (int) YY_CURRENT_BUFFER_LVALUE->yy_buf_size; + + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) + YY_FATAL_ERROR( "flex scanner push-back overflow" ); + } + + *--yy_cp = (char) c; + + (yytext_ptr) = yy_bp; + (yy_hold_char) = *yy_cp; + (yy_c_buf_p) = yy_cp; +} + +#endif + +#ifndef YY_NO_INPUT +#ifdef __cplusplus + static int yyinput (void) +#else + static int input (void) +#endif + +{ + int c; + + *(yy_c_buf_p) = (yy_hold_char); + + if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + /* This was really a NUL. */ + *(yy_c_buf_p) = '\0'; + + else + { /* need more input */ + int offset = (int) ((yy_c_buf_p) - (yytext_ptr)); + ++(yy_c_buf_p); + + switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + yyrestart( yyin ); + + /*FALLTHROUGH*/ + + case EOB_ACT_END_OF_FILE: + { + if ( yywrap( ) ) + return 0; + + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(); +#else + return input(); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = (yytext_ptr) + offset; + break; + } + } + } + + c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ + *(yy_c_buf_p) = '\0'; /* preserve yytext */ + (yy_hold_char) = *++(yy_c_buf_p); + + return c; +} +#endif /* ifndef YY_NO_INPUT */ + +/** Immediately switch to a different input stream. + * @param input_file A readable stream. + * + * @note This function does not reset the start condition to @c INITIAL . + */ + void yyrestart (FILE * input_file ) +{ + + if ( ! YY_CURRENT_BUFFER ){ + yyensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer( yyin, YY_BUF_SIZE ); + } + + yy_init_buffer( YY_CURRENT_BUFFER, input_file ); + yy_load_buffer_state( ); +} + +/** Switch to a different input buffer. + * @param new_buffer The new input buffer. + * + */ + void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ) +{ + + /* TODO. We should be able to replace this entire function body + * with + * yypop_buffer_state(); + * yypush_buffer_state(new_buffer); + */ + yyensure_buffer_stack (); + if ( YY_CURRENT_BUFFER == new_buffer ) + return; + + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + YY_CURRENT_BUFFER_LVALUE = new_buffer; + yy_load_buffer_state( ); + + /* We don't actually know whether we did this switch during + * EOF (yywrap()) processing, but the only time this flag + * is looked at is after yywrap() is called, so it's safe + * to go ahead and always set it. + */ + (yy_did_buffer_switch_on_eof) = 1; +} + +static void yy_load_buffer_state (void) +{ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; + yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; + (yy_hold_char) = *(yy_c_buf_p); +} + +/** Allocate and initialize an input buffer state. + * @param file A readable stream. + * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. + * + * @return the allocated buffer state. + */ + YY_BUFFER_STATE yy_create_buffer (FILE * file, int size ) +{ + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) yyalloc( (yy_size_t) (b->yy_buf_size + 2) ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_is_our_buffer = 1; + + yy_init_buffer( b, file ); + + return b; +} + +/** Destroy the buffer. + * @param b a buffer created with yy_create_buffer() + * + */ + void yy_delete_buffer (YY_BUFFER_STATE b ) +{ + + if ( ! b ) + return; + + if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ + YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; + + if ( b->yy_is_our_buffer ) + yyfree( (void *) b->yy_ch_buf ); + + yyfree( (void *) b ); +} + +/* Initializes or reinitializes a buffer. + * This function is sometimes called more than once on the same buffer, + * such as during a yyrestart() or at EOF. + */ + static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file ) + +{ + int oerrno = errno; + + yy_flush_buffer( b ); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; + + /* If b is the current buffer, then yy_init_buffer was _probably_ + * called from yyrestart() or through yy_get_next_buffer. + * In that case, we don't want to reset the lineno or column. + */ + if (b != YY_CURRENT_BUFFER){ + b->yy_bs_lineno = 1; + b->yy_bs_column = 0; + } + + b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; + + errno = oerrno; +} + +/** Discard all buffered characters. On the next scan, YY_INPUT will be called. + * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. + * + */ + void yy_flush_buffer (YY_BUFFER_STATE b ) +{ + if ( ! b ) + return; + + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if ( b == YY_CURRENT_BUFFER ) + yy_load_buffer_state( ); +} + +/** Pushes the new state onto the stack. The new state becomes + * the current state. This function will allocate the stack + * if necessary. + * @param new_buffer The new state. + * + */ +void yypush_buffer_state (YY_BUFFER_STATE new_buffer ) +{ + if (new_buffer == NULL) + return; + + yyensure_buffer_stack(); + + /* This block is copied from yy_switch_to_buffer. */ + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + /* Only push if top exists. Otherwise, replace top. */ + if (YY_CURRENT_BUFFER) + (yy_buffer_stack_top)++; + YY_CURRENT_BUFFER_LVALUE = new_buffer; + + /* copied from yy_switch_to_buffer. */ + yy_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; +} + +/** Removes and deletes the top of the stack, if present. + * The next element becomes the new top. + * + */ +void yypop_buffer_state (void) +{ + if (!YY_CURRENT_BUFFER) + return; + + yy_delete_buffer(YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + if ((yy_buffer_stack_top) > 0) + --(yy_buffer_stack_top); + + if (YY_CURRENT_BUFFER) { + yy_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; + } +} + +/* Allocates the stack if it does not exist. + * Guarantees space for at least one push. + */ +static void yyensure_buffer_stack (void) +{ + yy_size_t num_to_alloc; + + if (!(yy_buffer_stack)) { + + /* First allocation is just for 2 elements, since we don't know if this + * scanner will even need a stack. We use 2 instead of 1 to avoid an + * immediate realloc on the next call. + */ + num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */ + (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc + (num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); + + memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); + + (yy_buffer_stack_max) = num_to_alloc; + (yy_buffer_stack_top) = 0; + return; + } + + if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ + + /* Increase the buffer to prepare for a possible push. */ + yy_size_t grow_size = 8 /* arbitrary grow size */; + + num_to_alloc = (yy_buffer_stack_max) + grow_size; + (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc + ((yy_buffer_stack), + num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); + + /* zero only the new slots.*/ + memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); + (yy_buffer_stack_max) = num_to_alloc; + } +} + +/** Setup the input buffer state to scan directly from a user-specified character buffer. + * @param base the character buffer + * @param size the size in bytes of the character buffer + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) +{ + YY_BUFFER_STATE b; + + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return NULL; + + b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); + + b->yy_buf_size = (int) (size - 2); /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = NULL; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; + + yy_switch_to_buffer( b ); + + return b; +} + +/** Setup the input buffer state to scan a string. The next call to yylex() will + * scan from a @e copy of @a str. + * @param yystr a NUL-terminated string to scan + * + * @return the newly allocated buffer state object. + * @note If you want to scan bytes that may contain NUL values, then use + * yy_scan_bytes() instead. + */ +YY_BUFFER_STATE yy_scan_string (const char * yystr ) +{ + + return yy_scan_bytes( yystr, (int) strlen(yystr) ); +} + +/** Setup the input buffer state to scan the given bytes. The next call to yylex() will + * scan from a @e copy of @a bytes. + * @param yybytes the byte buffer to scan + * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE yy_scan_bytes (const char * yybytes, int _yybytes_len ) +{ + YY_BUFFER_STATE b; + char *buf; + yy_size_t n; + int i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = (yy_size_t) (_yybytes_len + 2); + buf = (char *) yyalloc( n ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); + + for ( i = 0; i < _yybytes_len; ++i ) + buf[i] = yybytes[i]; + + buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; + + b = yy_scan_buffer( buf, n ); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); + + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; + + return b; +} + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +static void yynoreturn yy_fatal_error (const char* msg ) +{ + fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); +} + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + yytext[yyleng] = (yy_hold_char); \ + (yy_c_buf_p) = yytext + yyless_macro_arg; \ + (yy_hold_char) = *(yy_c_buf_p); \ + *(yy_c_buf_p) = '\0'; \ + yyleng = yyless_macro_arg; \ + } \ + while ( 0 ) + +/* Accessor methods (get/set functions) to struct members. */ + +/** Get the current line number. + * + */ +int yyget_lineno (void) +{ + + return yylineno; +} + +/** Get the input stream. + * + */ +FILE *yyget_in (void) +{ + return yyin; +} + +/** Get the output stream. + * + */ +FILE *yyget_out (void) +{ + return yyout; +} + +/** Get the length of the current token. + * + */ +int yyget_leng (void) +{ + return yyleng; +} + +/** Get the current token. + * + */ + +char *yyget_text (void) +{ + return yytext; +} + +/** Set the current line number. + * @param _line_number line number + * + */ +void yyset_lineno (int _line_number ) +{ + + yylineno = _line_number; +} + +/** Set the input stream. This does not discard the current + * input buffer. + * @param _in_str A readable stream. + * + * @see yy_switch_to_buffer + */ +void yyset_in (FILE * _in_str ) +{ + yyin = _in_str ; +} + +void yyset_out (FILE * _out_str ) +{ + yyout = _out_str ; +} + +int yyget_debug (void) +{ + return yy_flex_debug; +} + +void yyset_debug (int _bdebug ) +{ + yy_flex_debug = _bdebug ; +} + +static int yy_init_globals (void) +{ + /* Initialization is the same as for the non-reentrant scanner. + * This function is called from yylex_destroy(), so don't allocate here. + */ + + (yy_buffer_stack) = NULL; + (yy_buffer_stack_top) = 0; + (yy_buffer_stack_max) = 0; + (yy_c_buf_p) = NULL; + (yy_init) = 0; + (yy_start) = 0; + +/* Defined in main.c */ +#ifdef YY_STDINIT + yyin = stdin; + yyout = stdout; +#else + yyin = NULL; + yyout = NULL; +#endif + + /* For future reference: Set errno on error, since we are called by + * yylex_init() + */ + return 0; +} + +/* yylex_destroy is for both reentrant and non-reentrant scanners. */ +int yylex_destroy (void) +{ + + /* Pop the buffer stack, destroying each element. */ + while(YY_CURRENT_BUFFER){ + yy_delete_buffer( YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + yypop_buffer_state(); + } + + /* Destroy the stack itself. */ + yyfree((yy_buffer_stack) ); + (yy_buffer_stack) = NULL; + + /* Reset the globals. This is important in a non-reentrant scanner so the next time + * yylex() is called, initialization will occur. */ + yy_init_globals( ); + + return 0; +} + +/* + * Internal utility routines. + */ + +#ifndef yytext_ptr +static void yy_flex_strncpy (char* s1, const char * s2, int n ) +{ + + int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; +} +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (const char * s ) +{ + int n; + for ( n = 0; s[n]; ++n ) + ; + + return n; +} +#endif + +void *yyalloc (yy_size_t size ) +{ + return malloc(size); +} + +void *yyrealloc (void * ptr, yy_size_t size ) +{ + + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return realloc(ptr, size); +} + +void yyfree (void * ptr ) +{ + free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ +} + +#define YYTABLES_NAME "yytables" + +#line 129 "query_l.l" + + +static void qry_update_nl(const char *s) +{ + for(; *s != '\0'; s++) + if (*s == '\n') + pcb_qry_lex_lineno++; +} + +static int qry_yy_input(char *buf, int buflen) +{ + int len; + for(len = 0; (*pcb_qry_program_ptr != '\0') && (buflen > 0); len++,buflen--) { +/* printf("IN: '%c'\n", *pcb_qry_program_ptr);*/ + *buf = *pcb_qry_program_ptr; + buf++; + pcb_qry_program_ptr++; + } + return len; +} + +void pcb_qry_set_input(const char *script) +{ + while(isspace(*script)) script++; + pcb_qry_program = pcb_qry_program_ptr = script; + yy_flush_buffer(YY_CURRENT_BUFFER); + pcb_qry_lex_lineno = 1; +} + +static pcb_qry_node_t *make_constant(char *str, long val) +{ + pcb_qry_node_t *res = pcb_qry_n_alloc(PCBQ_DATA_CONST); + res->data.str = rnd_strdup(str); + res->precomp.cnst = val; + return res; +} + +static pcb_qry_node_t *make_const_obj(char *str, csch_chdr_t *o) +{ + pcb_qry_node_t *res = pcb_qry_n_alloc(PCBQ_DATA_OBJ); + res->data.str = rnd_strdup(str); + res->precomp.obj = o; + return res; +} + Index: tags/1.0.5/src/plugins/query/query_l.h =================================================================== --- tags/1.0.5/src/plugins/query/query_l.h (nonexistent) +++ tags/1.0.5/src/plugins/query/query_l.h (revision 10414) @@ -0,0 +1,708 @@ +#ifndef qry_HEADER_H +#define qry_HEADER_H 1 +#define qry_IN_HEADER 1 + +#line 6 "query_l.h" + +#line 8 "query_l.h" + +#define YY_INT_ALIGNED short int + +/* A lexical scanner generated by flex */ + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 6 +#define YY_FLEX_SUBMINOR_VERSION 4 +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif + +#ifdef yy_create_buffer +#define qry__create_buffer_ALREADY_DEFINED +#else +#define yy_create_buffer qry__create_buffer +#endif + +#ifdef yy_delete_buffer +#define qry__delete_buffer_ALREADY_DEFINED +#else +#define yy_delete_buffer qry__delete_buffer +#endif + +#ifdef yy_scan_buffer +#define qry__scan_buffer_ALREADY_DEFINED +#else +#define yy_scan_buffer qry__scan_buffer +#endif + +#ifdef yy_scan_string +#define qry__scan_string_ALREADY_DEFINED +#else +#define yy_scan_string qry__scan_string +#endif + +#ifdef yy_scan_bytes +#define qry__scan_bytes_ALREADY_DEFINED +#else +#define yy_scan_bytes qry__scan_bytes +#endif + +#ifdef yy_init_buffer +#define qry__init_buffer_ALREADY_DEFINED +#else +#define yy_init_buffer qry__init_buffer +#endif + +#ifdef yy_flush_buffer +#define qry__flush_buffer_ALREADY_DEFINED +#else +#define yy_flush_buffer qry__flush_buffer +#endif + +#ifdef yy_load_buffer_state +#define qry__load_buffer_state_ALREADY_DEFINED +#else +#define yy_load_buffer_state qry__load_buffer_state +#endif + +#ifdef yy_switch_to_buffer +#define qry__switch_to_buffer_ALREADY_DEFINED +#else +#define yy_switch_to_buffer qry__switch_to_buffer +#endif + +#ifdef yypush_buffer_state +#define qry_push_buffer_state_ALREADY_DEFINED +#else +#define yypush_buffer_state qry_push_buffer_state +#endif + +#ifdef yypop_buffer_state +#define qry_pop_buffer_state_ALREADY_DEFINED +#else +#define yypop_buffer_state qry_pop_buffer_state +#endif + +#ifdef yyensure_buffer_stack +#define qry_ensure_buffer_stack_ALREADY_DEFINED +#else +#define yyensure_buffer_stack qry_ensure_buffer_stack +#endif + +#ifdef yylex +#define qry_lex_ALREADY_DEFINED +#else +#define yylex qry_lex +#endif + +#ifdef yyrestart +#define qry_restart_ALREADY_DEFINED +#else +#define yyrestart qry_restart +#endif + +#ifdef yylex_init +#define qry_lex_init_ALREADY_DEFINED +#else +#define yylex_init qry_lex_init +#endif + +#ifdef yylex_init_extra +#define qry_lex_init_extra_ALREADY_DEFINED +#else +#define yylex_init_extra qry_lex_init_extra +#endif + +#ifdef yylex_destroy +#define qry_lex_destroy_ALREADY_DEFINED +#else +#define yylex_destroy qry_lex_destroy +#endif + +#ifdef yyget_debug +#define qry_get_debug_ALREADY_DEFINED +#else +#define yyget_debug qry_get_debug +#endif + +#ifdef yyset_debug +#define qry_set_debug_ALREADY_DEFINED +#else +#define yyset_debug qry_set_debug +#endif + +#ifdef yyget_extra +#define qry_get_extra_ALREADY_DEFINED +#else +#define yyget_extra qry_get_extra +#endif + +#ifdef yyset_extra +#define qry_set_extra_ALREADY_DEFINED +#else +#define yyset_extra qry_set_extra +#endif + +#ifdef yyget_in +#define qry_get_in_ALREADY_DEFINED +#else +#define yyget_in qry_get_in +#endif + +#ifdef yyset_in +#define qry_set_in_ALREADY_DEFINED +#else +#define yyset_in qry_set_in +#endif + +#ifdef yyget_out +#define qry_get_out_ALREADY_DEFINED +#else +#define yyget_out qry_get_out +#endif + +#ifdef yyset_out +#define qry_set_out_ALREADY_DEFINED +#else +#define yyset_out qry_set_out +#endif + +#ifdef yyget_leng +#define qry_get_leng_ALREADY_DEFINED +#else +#define yyget_leng qry_get_leng +#endif + +#ifdef yyget_text +#define qry_get_text_ALREADY_DEFINED +#else +#define yyget_text qry_get_text +#endif + +#ifdef yyget_lineno +#define qry_get_lineno_ALREADY_DEFINED +#else +#define yyget_lineno qry_get_lineno +#endif + +#ifdef yyset_lineno +#define qry_set_lineno_ALREADY_DEFINED +#else +#define yyset_lineno qry_set_lineno +#endif + +#ifdef yywrap +#define qry_wrap_ALREADY_DEFINED +#else +#define yywrap qry_wrap +#endif + +#ifdef yyalloc +#define qry_alloc_ALREADY_DEFINED +#else +#define yyalloc qry_alloc +#endif + +#ifdef yyrealloc +#define qry_realloc_ALREADY_DEFINED +#else +#define yyrealloc qry_realloc +#endif + +#ifdef yyfree +#define qry_free_ALREADY_DEFINED +#else +#define yyfree qry_free +#endif + +#ifdef yytext +#define qry_text_ALREADY_DEFINED +#else +#define yytext qry_text +#endif + +#ifdef yyleng +#define qry_leng_ALREADY_DEFINED +#else +#define yyleng qry_leng +#endif + +#ifdef yyin +#define qry_in_ALREADY_DEFINED +#else +#define yyin qry_in +#endif + +#ifdef yyout +#define qry_out_ALREADY_DEFINED +#else +#define yyout qry_out +#endif + +#ifdef yy_flex_debug +#define qry__flex_debug_ALREADY_DEFINED +#else +#define yy_flex_debug qry__flex_debug +#endif + +#ifdef yylineno +#define qry_lineno_ALREADY_DEFINED +#else +#define yylineno qry_lineno +#endif + +/* First, we deal with platform-specific or compiler-specific issues. */ + +/* begin standard C headers. */ +#include +#include +#include +#include + +/* end standard C headers. */ + +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have . Non-C99 systems may or may not. */ + +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + +/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, + * if you want the limit (max/min) macros for int types. + */ +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 +#endif + +#include +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; + +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767-1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#ifndef SIZE_MAX +#define SIZE_MAX (~(size_t)0) +#endif + +#endif /* ! C99 */ + +#endif /* ! FLEXINT_H */ + +/* begin standard C++ headers. */ + +/* TODO: this is always defined, so inline it */ +#define yyconst const + +#if defined(__GNUC__) && __GNUC__ >= 3 +#define yynoreturn __attribute__((__noreturn__)) +#else +#define yynoreturn +#endif + +/* Size of default input buffer. */ +#ifndef YY_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k. + * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. + * Ditto for the __ia64__ case accordingly. + */ +#define YY_BUF_SIZE 32768 +#else +#define YY_BUF_SIZE 16384 +#endif /* __ia64__ */ +#endif + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + +extern int yyleng; + +extern FILE *yyin, *yyout; + +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE +struct yy_buffer_state + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + int yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; + + }; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ + +void yyrestart ( FILE *input_file ); +void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer ); +YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size ); +void yy_delete_buffer ( YY_BUFFER_STATE b ); +void yy_flush_buffer ( YY_BUFFER_STATE b ); +void yypush_buffer_state ( YY_BUFFER_STATE new_buffer ); +void yypop_buffer_state ( void ); + +YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size ); +YY_BUFFER_STATE yy_scan_string ( const char *yy_str ); +YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len ); + +void *yyalloc ( yy_size_t ); +void *yyrealloc ( void *, yy_size_t ); +void yyfree ( void * ); + +/* Begin user sect3 */ + +extern int yylineno; + +extern char *yytext; +#ifdef yytext_ptr +#undef yytext_ptr +#endif +#define yytext_ptr yytext + +#ifdef YY_HEADER_EXPORT_START_CONDITIONS +#define INITIAL 0 + +#endif + +#ifndef YY_NO_UNISTD_H +/* Special case for "unistd.h", since it is non-ANSI. We include it way + * down here because we want the user's section 1 to have been scanned first. + * The user has a chance to override it with an option. + */ +#include +#endif + +#ifndef YY_EXTRA_TYPE +#define YY_EXTRA_TYPE void * +#endif + +/* Accessor methods to globals. + These are made visible to non-reentrant scanners for convenience. */ + +int yylex_destroy ( void ); + +int yyget_debug ( void ); + +void yyset_debug ( int debug_flag ); + +YY_EXTRA_TYPE yyget_extra ( void ); + +void yyset_extra ( YY_EXTRA_TYPE user_defined ); + +FILE *yyget_in ( void ); + +void yyset_in ( FILE * _in_str ); + +FILE *yyget_out ( void ); + +void yyset_out ( FILE * _out_str ); + + int yyget_leng ( void ); + +char *yyget_text ( void ); + +int yyget_lineno ( void ); + +void yyset_lineno ( int _line_number ); + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int yywrap ( void ); +#else +extern int yywrap ( void ); +#endif +#endif + +#ifndef yytext_ptr +static void yy_flex_strncpy ( char *, const char *, int ); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen ( const char * ); +#endif + +#ifndef YY_NO_INPUT + +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k */ +#define YY_READ_BUF_SIZE 16384 +#else +#define YY_READ_BUF_SIZE 8192 +#endif /* __ia64__ */ +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL_IS_OURS 1 + +extern int yylex (void); + +#define YY_DECL int yylex (void) +#endif /* !YY_DECL */ + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + +#undef YY_NEW_FILE +#undef YY_FLUSH_BUFFER +#undef yy_set_bol +#undef yy_new_buffer +#undef yy_set_interactive +#undef YY_DO_BEFORE_ACTION + +#ifdef YY_DECL_IS_OURS +#undef YY_DECL_IS_OURS +#undef YY_DECL +#endif + +#ifndef qry__create_buffer_ALREADY_DEFINED +#undef yy_create_buffer +#endif +#ifndef qry__delete_buffer_ALREADY_DEFINED +#undef yy_delete_buffer +#endif +#ifndef qry__scan_buffer_ALREADY_DEFINED +#undef yy_scan_buffer +#endif +#ifndef qry__scan_string_ALREADY_DEFINED +#undef yy_scan_string +#endif +#ifndef qry__scan_bytes_ALREADY_DEFINED +#undef yy_scan_bytes +#endif +#ifndef qry__init_buffer_ALREADY_DEFINED +#undef yy_init_buffer +#endif +#ifndef qry__flush_buffer_ALREADY_DEFINED +#undef yy_flush_buffer +#endif +#ifndef qry__load_buffer_state_ALREADY_DEFINED +#undef yy_load_buffer_state +#endif +#ifndef qry__switch_to_buffer_ALREADY_DEFINED +#undef yy_switch_to_buffer +#endif +#ifndef qry_push_buffer_state_ALREADY_DEFINED +#undef yypush_buffer_state +#endif +#ifndef qry_pop_buffer_state_ALREADY_DEFINED +#undef yypop_buffer_state +#endif +#ifndef qry_ensure_buffer_stack_ALREADY_DEFINED +#undef yyensure_buffer_stack +#endif +#ifndef qry_lex_ALREADY_DEFINED +#undef yylex +#endif +#ifndef qry_restart_ALREADY_DEFINED +#undef yyrestart +#endif +#ifndef qry_lex_init_ALREADY_DEFINED +#undef yylex_init +#endif +#ifndef qry_lex_init_extra_ALREADY_DEFINED +#undef yylex_init_extra +#endif +#ifndef qry_lex_destroy_ALREADY_DEFINED +#undef yylex_destroy +#endif +#ifndef qry_get_debug_ALREADY_DEFINED +#undef yyget_debug +#endif +#ifndef qry_set_debug_ALREADY_DEFINED +#undef yyset_debug +#endif +#ifndef qry_get_extra_ALREADY_DEFINED +#undef yyget_extra +#endif +#ifndef qry_set_extra_ALREADY_DEFINED +#undef yyset_extra +#endif +#ifndef qry_get_in_ALREADY_DEFINED +#undef yyget_in +#endif +#ifndef qry_set_in_ALREADY_DEFINED +#undef yyset_in +#endif +#ifndef qry_get_out_ALREADY_DEFINED +#undef yyget_out +#endif +#ifndef qry_set_out_ALREADY_DEFINED +#undef yyset_out +#endif +#ifndef qry_get_leng_ALREADY_DEFINED +#undef yyget_leng +#endif +#ifndef qry_get_text_ALREADY_DEFINED +#undef yyget_text +#endif +#ifndef qry_get_lineno_ALREADY_DEFINED +#undef yyget_lineno +#endif +#ifndef qry_set_lineno_ALREADY_DEFINED +#undef yyset_lineno +#endif +#ifndef qry_get_column_ALREADY_DEFINED +#undef yyget_column +#endif +#ifndef qry_set_column_ALREADY_DEFINED +#undef yyset_column +#endif +#ifndef qry_wrap_ALREADY_DEFINED +#undef yywrap +#endif +#ifndef qry_get_lval_ALREADY_DEFINED +#undef yyget_lval +#endif +#ifndef qry_set_lval_ALREADY_DEFINED +#undef yyset_lval +#endif +#ifndef qry_get_lloc_ALREADY_DEFINED +#undef yyget_lloc +#endif +#ifndef qry_set_lloc_ALREADY_DEFINED +#undef yyset_lloc +#endif +#ifndef qry_alloc_ALREADY_DEFINED +#undef yyalloc +#endif +#ifndef qry_realloc_ALREADY_DEFINED +#undef yyrealloc +#endif +#ifndef qry_free_ALREADY_DEFINED +#undef yyfree +#endif +#ifndef qry_text_ALREADY_DEFINED +#undef yytext +#endif +#ifndef qry_leng_ALREADY_DEFINED +#undef yyleng +#endif +#ifndef qry_in_ALREADY_DEFINED +#undef yyin +#endif +#ifndef qry_out_ALREADY_DEFINED +#undef yyout +#endif +#ifndef qry__flex_debug_ALREADY_DEFINED +#undef yy_flex_debug +#endif +#ifndef qry_lineno_ALREADY_DEFINED +#undef yylineno +#endif +#ifndef qry_tables_fload_ALREADY_DEFINED +#undef yytables_fload +#endif +#ifndef qry_tables_destroy_ALREADY_DEFINED +#undef yytables_destroy +#endif +#ifndef qry_TABLES_NAME_ALREADY_DEFINED +#undef yyTABLES_NAME +#endif + +#line 129 "query_l.l" + + +#line 707 "query_l.h" +#undef qry_IN_HEADER +#endif /* qry_HEADER_H */ Index: tags/1.0.5/src/plugins/query/query_l.l =================================================================== --- tags/1.0.5/src/plugins/query/query_l.l (nonexistent) +++ tags/1.0.5/src/plugins/query/query_l.l (revision 10414) @@ -0,0 +1,172 @@ +%{ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016,2019 Tibor 'Igor2' Palinkas + * Copyright (C) 2022 Tibor 'Igor2' Palinkas (slight modifications for sch-rnd) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +/* Query language - compiler: lexical analyzer */ + +#include +#include +#include "query.h" +#include "query_y.h" +#include +#include +#include + +static const char *pcb_qry_program, *pcb_qry_program_ptr; +static int qry_yy_input(char *buf, int buflen); +static pcb_qry_node_t *make_constant(char *str, long val); +static pcb_qry_node_t *make_const_obj(char *str, csch_chdr_t *obj); +#define YY_INPUT(buf, res, buflen) (res = qry_yy_input(buf, buflen)) + +static void qry_update_nl(const char *s); +long pcb_qry_lex_lineno; + +static rnd_unit_t lex_unit_k = {"k", 'c', 1.0/1000.0, 0, 0, 3, 0}; + +%} + +%option prefix="qry_" + +%% +["][^"]*["] { qry_lval.s = rnd_strdup(yytext+1); qry_lval.s[strlen(qry_lval.s)-1] = '\0'; return T_QSTR; /*"*/ } +['][^']*['] { qry_lval.s = rnd_strdup(yytext+1); qry_lval.s[strlen(qry_lval.s)-1] = '\0'; return T_QSTR; } + +let { return T_LET; } +assert { return T_ASSERT; } +rule { return T_RULE; } +function { return T_FUNCTION; } +return { return T_RETURN; } +list { return T_LIST; } +invalid { return T_INVALID; } +p[.] { return T_FLD_P; } +a[.] { return T_FLD_A; } +flag[.] { return T_FLD_FLAG; } + +"LINE" { qry_lval.n = make_constant(yytext, CSCH_CTYPE_LINE); return T_CONST; } +"ARC" { qry_lval.n = make_constant(yytext, CSCH_CTYPE_ARC); return T_CONST; } +"POLY" { qry_lval.n = make_constant(yytext, CSCH_CTYPE_POLY); return T_CONST; } +"POLYGON" { qry_lval.n = make_constant(yytext, CSCH_CTYPE_POLY); return T_CONST; } +"TEXT" { qry_lval.n = make_constant(yytext, CSCH_CTYPE_TEXT); return T_CONST; } +"BITMAP" { qry_lval.n = make_constant(yytext, CSCH_CTYPE_BITMAP); return T_CONST; } +"CONN" { qry_lval.n = make_constant(yytext, CSCH_CTYPE_CONN); return T_CONST; } +"GRP" { qry_lval.n = make_constant(yytext, CSCH_CTYPE_GRP); return T_CONST; } +"GRP_REF" { qry_lval.n = make_constant(yytext, CSCH_CTYPE_GRP_REF); return T_CONST; } +"PEN" { qry_lval.n = make_constant(yytext, CSCH_CTYPE_PEN); return T_CONST; } + +"BACKGROUND" { qry_lval.n = make_constant(yytext, CSCH_DSPLY_BACKGROUND); return T_CONST; } +"WIRE" { qry_lval.n = make_constant(yytext, CSCH_DSPLY_WIRE); return T_CONST; } +"BUS" { qry_lval.n = make_constant(yytext, CSCH_DSPLY_BUS); return T_CONST; } +"SYMBOL" { qry_lval.n = make_constant(yytext, CSCH_DSPLY_SYMBOL); return T_CONST; } +"HUBTERM" { qry_lval.n = make_constant(yytext, CSCH_DSPLY_HUBTERM); return T_CONST; } +"DECORATION" { qry_lval.n = make_constant(yytext, CSCH_DSPLY_DECORATION); return T_CONST; } +"SYMBOL_GRP" { qry_lval.n = make_constant(yytext, CSCH_DSPLY_SYMBOL_GRP); return T_CONST; } +"CONN" { qry_lval.n = make_constant(yytext, CSCH_DSPLY_CONN); return T_CONST; } + +"START" { qry_lval.n = make_constant(yytext, CSCH_HALIGN_START); return T_CONST; } +"END" { qry_lval.n = make_constant(yytext, CSCH_HALIGN_END); return T_CONST; } +"CENTER" { qry_lval.n = make_constant(yytext, CSCH_HALIGN_CENTER); return T_CONST; } +"WORD_JUST" { qry_lval.n = make_constant(yytext, CSCH_HALIGN_WORD_JUST); return T_CONST; } +"JUST" { qry_lval.n = make_constant(yytext, CSCH_HALIGN_JUST); return T_CONST; } + + +"TRUE" { qry_lval.n = make_constant(yytext, 1); return T_CONST; } +"VISIBLE" { qry_lval.n = make_constant(yytext, 1); return T_CONST; } +"ON" { qry_lval.n = make_constant(yytext, 1); return T_CONST; } +"YES" { qry_lval.n = make_constant(yytext, 1); return T_CONST; } + +"FALSE" { qry_lval.n = make_constant(yytext, 0); return T_CONST; } +"INVISIBLE" { qry_lval.n = make_constant(yytext, 0); return T_CONST; } +"OFF" { qry_lval.n = make_constant(yytext, 0); return T_CONST; } +"NO" { qry_lval.n = make_constant(yytext, 0); return T_CONST; } + +"DRCGRP1" { qry_lval.n = make_const_obj(yytext, &pcb_qry_drc_ctrl[PCB_QRY_DRC_GRP1]); return T_CONST; } +"DRCGRP2" { qry_lval.n = make_const_obj(yytext, &pcb_qry_drc_ctrl[PCB_QRY_DRC_GRP2]); return T_CONST; } +"DRCEXPECT" { qry_lval.n = make_const_obj(yytext, &pcb_qry_drc_ctrl[PCB_QRY_DRC_EXPECT]); return T_CONST; } +"DRCMEASURE" { qry_lval.n = make_const_obj(yytext, &pcb_qry_drc_ctrl[PCB_QRY_DRC_MEASURE]); return T_CONST; } +"DRCTEXT" { qry_lval.n = make_const_obj(yytext, &pcb_qry_drc_ctrl[PCB_QRY_DRC_TEXT]); return T_CONST; } + +k { qry_lval.u = &lex_unit_k; return T_UNIT; } + +thus { return T_THUS; } +[|][|] { return T_OR; } +[&][&] { return T_AND; } +[=][=] { return T_EQ; } +[!][=] { return T_NEQ; } +[>][=] { return T_GTEQ; } +[<][=] { return T_LTEQ; } + +[0-9]+ { qry_lval.c = strtol(yytext, NULL, 10); return T_INT; } +[.][0-9]+ { qry_lval.d = strtod(yytext, NULL); return T_DBL; } +[0-9]+[.][0-9]* { qry_lval.d = strtod(yytext, NULL); return T_DBL; } +[A-Za-z_][0-9A-Za-z_]* { qry_lval.s = rnd_strdup(yytext); return T_STR; } + +[$@().,<>!*+/~-] { return *yytext; } + +[\\][\r\n] { continue; /* multiline rules */} +[;\r\n]* { qry_update_nl(yytext); return T_NL; } +[ \t] { continue; } + +%% + +static void qry_update_nl(const char *s) +{ + for(; *s != '\0'; s++) + if (*s == '\n') + pcb_qry_lex_lineno++; +} + +static int qry_yy_input(char *buf, int buflen) +{ + int len; + for(len = 0; (*pcb_qry_program_ptr != '\0') && (buflen > 0); len++,buflen--) { +/* printf("IN: '%c'\n", *pcb_qry_program_ptr);*/ + *buf = *pcb_qry_program_ptr; + buf++; + pcb_qry_program_ptr++; + } + return len; +} + +void pcb_qry_set_input(const char *script) +{ + while(isspace(*script)) script++; + pcb_qry_program = pcb_qry_program_ptr = script; + yy_flush_buffer(YY_CURRENT_BUFFER); + pcb_qry_lex_lineno = 1; +} + +static pcb_qry_node_t *make_constant(char *str, long val) +{ + pcb_qry_node_t *res = pcb_qry_n_alloc(PCBQ_DATA_CONST); + res->data.str = rnd_strdup(str); + res->precomp.cnst = val; + return res; +} + +static pcb_qry_node_t *make_const_obj(char *str, csch_chdr_t *o) +{ + pcb_qry_node_t *res = pcb_qry_n_alloc(PCBQ_DATA_OBJ); + res->data.str = rnd_strdup(str); + res->precomp.obj = o; + return res; +} Index: tags/1.0.5/src/plugins/query/query_y.c =================================================================== --- tags/1.0.5/src/plugins/query/query_y.c (nonexistent) +++ tags/1.0.5/src/plugins/query/query_y.c (revision 10414) @@ -0,0 +1,2342 @@ +/* A Bison parser, made by GNU Bison 3.3.2. */ + +/* Bison implementation for Yacc-like parsers in C + + Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2019 Free Software Foundation, + Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* C LALR(1) parser skeleton written by Richard Stallman, by + simplifying the original so-called "semantic" parser. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Undocumented macros, especially those whose name start with YY_, + are private implementation details. Do not rely on them. */ + +/* Identify Bison output. */ +#define YYBISON 1 + +/* Bison version. */ +#define YYBISON_VERSION "3.3.2" + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 0 + +/* Push parsers. */ +#define YYPUSH 0 + +/* Pull parsers. */ +#define YYPULL 1 + + +/* Substitute the variable and function names. */ +#define yyparse qry_parse +#define yylex qry_lex +#define yyerror qry_error +#define yydebug qry_debug +#define yynerrs qry_nerrs + +#define yylval qry_lval +#define yychar qry_char + +/* First part of user prologue. */ +#line 1 "query_y.y" /* yacc.c:337 */ + +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/* Query language - compiler: grammar */ + +#include +#include +#include +#include +#include "query.h" +#include "query_l.h" +#include +#include +#include +#include "fields_sphash.h" + +#define UNIT_CONV(dst, negative, val, unit) \ +do { \ + dst = val; \ + if (negative) \ + dst = -dst; \ + if (unit != NULL) { \ + if (unit->family == RND_UNIT_IMPERIAL) \ + dst = RND_MIL_TO_COORD(dst); \ + else if (unit->family == RND_UNIT_METRIC) \ + dst = RND_MM_TO_COORD(dst); \ + dst /= unit->scale_factor; \ + } \ +} while(0) + +#define BINOP(dst, op1, operator, op2) \ +do { \ + assert(op2->next == NULL); \ + assert(op2->next == NULL); \ + dst = pcb_qry_n_alloc(operator); \ + pcb_qry_n_insert(dst, op2); \ + pcb_qry_n_insert(dst, op1); \ +} while(0) + +#define UNOP(dst, operator, op) \ +do { \ + assert(op->next == NULL); \ + dst = pcb_qry_n_alloc(operator); \ + pcb_qry_n_insert(dst, op); \ +} while(0) + +static pcb_query_iter_t *iter_ctx; +static vti0_t *iter_active_ctx; +static htsp_t *user_funcs; + +static char *attrib_prepend_free(char *orig, char *prep, char sep) +{ + int l1 = strlen(orig), l2 = strlen(prep); + char *res = malloc(l1+l2+2); + memcpy(res, prep, l2); + res[l2] = sep; + memcpy(res+l2+1, orig, l1+1); + free(orig); + free(prep); + return res; +} + +static pcb_qry_node_t *make_regex_free(char *str) +{ + pcb_qry_node_t *res = pcb_qry_n_alloc(PCBQ_DATA_REGEX); + res->data.str = str; + res->precomp.regex = re_se_comp(str); + if (res->precomp.regex == NULL) + yyerror(NULL, "Invalid regex\n"); + return res; +} + +static void link_user_funcs_(pcb_qry_node_t *root, int allow) +{ + pcb_qry_node_t *n, *f, *fname; + + for(n = root; n != NULL; n = n->next) { + if (pcb_qry_nodetype_has_children(n->type)) + link_user_funcs_(n->data.children, allow); + if (n->type == PCBQ_FCALL) { + fname = n->data.children; + if (fname->precomp.fnc.bui != NULL) /* builtin */ + continue; + + if (!allow) + rnd_message(RND_MSG_ERROR, "You shouldn't have user functions in query expressions, only in rules\n"); + + if (user_funcs != NULL) + f = htsp_get(user_funcs, fname->data.str); + else + f = NULL; + + fname->precomp.fnc.uf = f; + if (f == NULL) { + yyerror(NULL, "user function not defined:"); + yyerror(NULL, fname->data.str); + } + } + } + +} + +static void uninit_user_funcs() +{ + if (user_funcs != NULL) + htsp_free(user_funcs); + user_funcs = NULL; +} + +static void link_user_funcs(pcb_qry_node_t *root, int allow) +{ + link_user_funcs_(root, allow); + uninit_user_funcs(); +} + + + +#line 221 "query_y.c" /* yacc.c:337 */ +# ifndef YY_NULLPTR +# if defined __cplusplus +# if 201103L <= __cplusplus +# define YY_NULLPTR nullptr +# else +# define YY_NULLPTR 0 +# endif +# else +# define YY_NULLPTR ((void*)0) +# endif +# endif + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE 1 +#endif + +/* In a future release of Bison, this section will be replaced + by #include "query_y.h". */ +#ifndef YY_QRY_QUERY_Y_H_INCLUDED +# define YY_QRY_QUERY_Y_H_INCLUDED +/* Debug traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif +#if YYDEBUG +extern int qry_debug; +#endif + +/* Token type. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + enum yytokentype + { + T_LET = 258, + T_ASSERT = 259, + T_RULE = 260, + T_LIST = 261, + T_INVALID = 262, + T_FLD_P = 263, + T_FLD_A = 264, + T_FLD_FLAG = 265, + T_FUNCTION = 266, + T_RETURN = 267, + T_OR = 268, + T_AND = 269, + T_EQ = 270, + T_NEQ = 271, + T_GTEQ = 272, + T_LTEQ = 273, + T_NL = 274, + T_UNIT = 275, + T_STR = 276, + T_QSTR = 277, + T_INT = 278, + T_DBL = 279, + T_CONST = 280, + T_THUS = 281 + }; +#endif + +/* Value type. */ +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED + +union YYSTYPE +{ +#line 148 "query_y.y" /* yacc.c:352 */ + + char *s; + rnd_coord_t c; + double d; + const rnd_unit_t *u; + pcb_qry_node_t *n; + +#line 299 "query_y.c" /* yacc.c:352 */ +}; + +typedef union YYSTYPE YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define YYSTYPE_IS_DECLARED 1 +#endif + + +extern YYSTYPE qry_lval; + +int qry_parse (pcb_qry_node_t **prg_out); + +#endif /* !YY_QRY_QUERY_Y_H_INCLUDED */ + + + +#ifdef short +# undef short +#endif + +#ifdef YYTYPE_UINT8 +typedef YYTYPE_UINT8 yytype_uint8; +#else +typedef unsigned char yytype_uint8; +#endif + +#ifdef YYTYPE_INT8 +typedef YYTYPE_INT8 yytype_int8; +#else +typedef signed char yytype_int8; +#endif + +#ifdef YYTYPE_UINT16 +typedef YYTYPE_UINT16 yytype_uint16; +#else +typedef unsigned short yytype_uint16; +#endif + +#ifdef YYTYPE_INT16 +typedef YYTYPE_INT16 yytype_int16; +#else +typedef short yytype_int16; +#endif + +#ifndef YYSIZE_T +# ifdef __SIZE_TYPE__ +# define YYSIZE_T __SIZE_TYPE__ +# elif defined size_t +# define YYSIZE_T size_t +# elif ! defined YYSIZE_T +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# else +# define YYSIZE_T unsigned +# endif +#endif + +#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) + +#ifndef YY_ +# if defined YYENABLE_NLS && YYENABLE_NLS +# if ENABLE_NLS +# include /* INFRINGES ON USER NAME SPACE */ +# define YY_(Msgid) dgettext ("bison-runtime", Msgid) +# endif +# endif +# ifndef YY_ +# define YY_(Msgid) Msgid +# endif +#endif + +#ifndef YY_ATTRIBUTE +# if (defined __GNUC__ \ + && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \ + || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C +# define YY_ATTRIBUTE(Spec) __attribute__(Spec) +# else +# define YY_ATTRIBUTE(Spec) /* empty */ +# endif +#endif + +#ifndef YY_ATTRIBUTE_PURE +# define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__)) +#endif + +#ifndef YY_ATTRIBUTE_UNUSED +# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__)) +#endif + +/* Suppress unused-variable warnings by "using" E. */ +#if ! defined lint || defined __GNUC__ +# define YYUSE(E) ((void) (E)) +#else +# define YYUSE(E) /* empty */ +#endif + +#if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ +/* Suppress an incorrect diagnostic about yylval being uninitialized. */ +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ + _Pragma ("GCC diagnostic push") \ + _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\ + _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") +# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ + _Pragma ("GCC diagnostic pop") +#else +# define YY_INITIAL_VALUE(Value) Value +#endif +#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +# define YY_IGNORE_MAYBE_UNINITIALIZED_END +#endif +#ifndef YY_INITIAL_VALUE +# define YY_INITIAL_VALUE(Value) /* Nothing. */ +#endif + + +#if ! defined yyoverflow || YYERROR_VERBOSE + +/* The parser invokes alloca or malloc; define the necessary symbols. */ + +# ifdef YYSTACK_USE_ALLOCA +# if YYSTACK_USE_ALLOCA +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# elif defined __BUILTIN_VA_ARG_INCR +# include /* INFRINGES ON USER NAME SPACE */ +# elif defined _AIX +# define YYSTACK_ALLOC __alloca +# elif defined _MSC_VER +# include /* INFRINGES ON USER NAME SPACE */ +# define alloca _alloca +# else +# define YYSTACK_ALLOC alloca +# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS +# include /* INFRINGES ON USER NAME SPACE */ + /* Use EXIT_SUCCESS as a witness for stdlib.h. */ +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +# endif +# endif +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's 'empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) +# ifndef YYSTACK_ALLOC_MAXIMUM + /* The OS might guarantee only one guard page at the bottom of the stack, + and a page size can be as small as 4096 bytes. So we cannot safely + invoke alloca (N) if N exceeds 4096. Use a slightly smaller number + to allow for a few compiler-allocated temporary stack slots. */ +# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ +# endif +# else +# define YYSTACK_ALLOC YYMALLOC +# define YYSTACK_FREE YYFREE +# ifndef YYSTACK_ALLOC_MAXIMUM +# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM +# endif +# if (defined __cplusplus && ! defined EXIT_SUCCESS \ + && ! ((defined YYMALLOC || defined malloc) \ + && (defined YYFREE || defined free))) +# include /* INFRINGES ON USER NAME SPACE */ +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +# endif +# endif +# ifndef YYMALLOC +# define YYMALLOC malloc +# if ! defined malloc && ! defined EXIT_SUCCESS +void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# ifndef YYFREE +# define YYFREE free +# if ! defined free && ! defined EXIT_SUCCESS +void free (void *); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# endif +#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ + + +#if (! defined yyoverflow \ + && (! defined __cplusplus \ + || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + yytype_int16 yyss_alloc; + YYSTYPE yyvs_alloc; +}; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) + +# define YYCOPY_NEEDED 1 + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ + Stack = &yyptr->Stack_alloc; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (0) + +#endif + +#if defined YYCOPY_NEEDED && YYCOPY_NEEDED +/* Copy COUNT objects from SRC to DST. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if defined __GNUC__ && 1 < __GNUC__ +# define YYCOPY(Dst, Src, Count) \ + __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src))) +# else +# define YYCOPY(Dst, Src, Count) \ + do \ + { \ + YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (Dst)[yyi] = (Src)[yyi]; \ + } \ + while (0) +# endif +# endif +#endif /* !YYCOPY_NEEDED */ + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 4 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 252 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 41 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 34 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 83 +/* YYNSTATES -- Number of states. */ +#define YYNSTATES 139 + +#define YYUNDEFTOK 2 +#define YYMAXUTOK 281 + +/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM + as returned by yylex, with out-of-bounds checking. */ +#define YYTRANSLATE(YYX) \ + ((unsigned) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM + as returned by yylex. */ +static const yytype_uint8 yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 34, 2, 2, 39, 2, 2, 2, + 35, 36, 31, 29, 40, 30, 33, 32, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 27, 2, 28, 2, 38, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 37, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26 +}; + +#if YYDEBUG + /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ +static const yytype_uint16 yyrline[] = +{ + 0, 189, 189, 189, 190, 190, 195, 195, 208, 209, + 213, 221, 222, 234, 235, 236, 237, 241, 242, 243, + 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, + 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, + 264, 265, 277, 278, 279, 280, 284, 288, 289, 293, + 294, 295, 296, 297, 298, 302, 303, 304, 309, 308, + 328, 327, 342, 341, 355, 356, 357, 358, 363, 383, + 384, 388, 403, 404, 409, 416, 417, 421, 428, 429, + 434, 433, 455, 456 +}; +#endif + +#if YYDEBUG || YYERROR_VERBOSE || 1 +/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + "$end", "error", "$undefined", "T_LET", "T_ASSERT", "T_RULE", "T_LIST", + "T_INVALID", "T_FLD_P", "T_FLD_A", "T_FLD_FLAG", "T_FUNCTION", + "T_RETURN", "T_OR", "T_AND", "T_EQ", "T_NEQ", "T_GTEQ", "T_LTEQ", "T_NL", + "T_UNIT", "T_STR", "T_QSTR", "T_INT", "T_DBL", "T_CONST", "T_THUS", + "'<'", "'>'", "'+'", "'-'", "'*'", "'/'", "'.'", "'!'", "'('", "')'", + "'~'", "'@'", "'$'", "','", "$accept", "program", "$@1", "$@2", + "program_expr", "$@3", "program_rules", "rule", "rule_or_fdef", + "rule_item", "expr", "number", "string_literal", "maybe_unit", "fields", + "attribs", "let", "$@4", "assert", "$@5", "freturn", "$@6", "var", + "constant", "fcall", "fcallname", "fargs", "fdefarg", "fdefargs", + "fdefname", "fdef_", "fdef", "$@7", "words", YY_NULLPTR +}; +#endif + +# ifdef YYPRINT +/* YYTOKNUM[NUM] -- (External) token number corresponding to the + (internal) symbol number NUM (which must be that of a token). */ +static const yytype_uint16 yytoknum[] = +{ + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 60, 62, 43, + 45, 42, 47, 46, 33, 40, 41, 126, 64, 36, + 44 +}; +# endif + +#define YYPACT_NINF -98 + +#define yypact_value_is_default(Yystate) \ + (!!((Yystate) == (-98))) + +#define YYTABLE_NINF -72 + +#define yytable_value_is_error(Yytable_value) \ + 0 + + /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +static const yytype_int16 yypact[] = +{ + 28, 13, -1, -98, -98, -7, 20, -98, -1, 43, + -98, -98, 36, -7, -98, -98, -98, -98, 99, 30, + -98, 41, -98, 68, 68, -98, -17, 36, 36, -98, + 77, 117, -98, -98, -98, -98, -98, 78, -98, 79, + -98, -98, -98, -98, 80, 93, 96, -16, -98, -98, + -98, 68, 68, 89, 92, -98, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, 36, 3, + 51, -4, -13, -98, 95, 36, 36, 99, 99, 99, + 81, 91, -98, -98, -98, 166, 189, 206, 206, 215, + 215, 142, 215, 215, 52, 52, -8, -8, 3, 65, + 103, 114, -98, -98, -98, -98, 64, 102, -98, -98, + 100, 105, 36, 117, 117, -98, -98, -98, -98, -98, + -98, 106, -98, -98, 3, 115, 36, -98, 121, -98, + 117, 65, -98, 119, -98, -98, -98, 3, -98 +}; + + /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. + Performed when YYTABLE does not specify something else to do. Zero + means the default is an error. */ +static const yytype_uint8 yydefact[] = +{ + 4, 0, 8, 6, 1, 82, 0, 3, 8, 0, + 11, 5, 0, 82, 12, 77, 80, 9, 13, 0, + 20, 64, 46, 47, 47, 38, 0, 0, 0, 67, + 0, 7, 18, 19, 39, 40, 17, 0, 83, 0, + 58, 60, 62, 10, 0, 0, 0, 0, 48, 42, + 43, 47, 47, 21, 0, 68, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 81, 0, 0, 0, 13, 13, 13, + 0, 0, 44, 45, 22, 25, 24, 26, 27, 28, + 29, 23, 31, 30, 32, 33, 34, 35, 0, 0, + 49, 0, 41, 36, 37, 70, 72, 0, 74, 79, + 75, 0, 0, 61, 63, 15, 14, 16, 66, 65, + 53, 55, 57, 54, 0, 0, 0, 69, 0, 78, + 59, 0, 50, 51, 73, 76, 56, 0, 52 +}; + + /* YYPGOTO[NTERM-NUM]. */ +static const yytype_int16 yypgoto[] = +{ + -98, -98, -98, -98, -98, -98, 145, -98, -98, -10, + -12, -98, -98, -15, -97, 31, -98, -98, -98, -98, + -98, -98, -98, -98, -98, -98, 35, 37, -98, -98, + -98, -98, -98, 150 +}; + + /* YYDEFGOTO[NTERM-NUM]. */ +static const yytype_int8 yydefgoto[] = +{ + -1, 1, 2, 3, 11, 12, 7, 8, 9, 43, + 106, 32, 33, 49, 102, 123, 44, 74, 45, 75, + 46, 76, 34, 35, 36, 37, 107, 110, 111, 16, + 73, 10, 39, 14 +}; + + /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule whose + number is the opposite. If YYTABLE_NINF, syntax error. */ +static const yytype_int16 yytable[] = +{ + 31, 120, 19, 20, 5, 80, 51, 52, 108, 50, + 6, 98, 99, 4, 13, 53, 54, 21, 22, 23, + 24, 25, 81, 109, 100, 69, 26, 132, -2, 70, + 27, 28, 105, -2, 29, 30, 82, 83, 101, -2, + 138, 15, 19, 20, 85, 86, 87, 88, 89, 90, + 91, 92, 93, 94, 95, 96, 97, 21, 22, 23, + 24, 25, 18, 113, 114, 47, 26, 115, 116, 117, + 27, 28, 103, 104, 29, 30, -71, 56, 57, 58, + 59, 60, 61, 67, 68, 69, 121, 122, 48, 70, + 62, 63, 64, 65, 66, 67, 68, 69, 55, 77, + 130, 70, 40, 41, 126, 56, 57, 58, 59, 60, + 61, 42, 78, 71, 72, 79, 112, 118, 62, 63, + 64, 65, 66, 67, 68, 69, 70, 119, 84, 70, + 56, 57, 58, 59, 60, 61, 124, 125, 127, 131, + 128, 129, 108, 62, 63, 64, 65, 66, 67, 68, + 69, 133, 137, 17, 70, 56, 57, 58, 59, 60, + 61, 134, 136, 38, 0, 135, 0, 0, 0, 63, + 64, 65, 66, 67, 68, 69, 0, 0, 0, 70, + 57, 58, 59, 60, 61, 0, 0, 0, 0, 0, + 0, 0, 0, 63, 64, 65, 66, 67, 68, 69, + 0, 0, 0, 70, 58, 59, 60, 61, 0, 0, + 0, 0, 0, 0, 0, 0, 63, 64, 65, 66, + 67, 68, 69, 60, 61, 0, 70, 0, 0, 0, + 0, 0, 0, 63, 64, 65, 66, 67, 68, 69, + 0, 0, 0, 70, 65, 66, 67, 68, 69, 0, + 0, 0, 70 +}; + +static const yytype_int16 yycheck[] = +{ + 12, 98, 6, 7, 5, 21, 23, 24, 21, 24, + 11, 8, 9, 0, 21, 27, 28, 21, 22, 23, + 24, 25, 38, 36, 21, 33, 30, 124, 0, 37, + 34, 35, 36, 5, 38, 39, 51, 52, 35, 11, + 137, 21, 6, 7, 56, 57, 58, 59, 60, 61, + 62, 63, 64, 65, 66, 67, 68, 21, 22, 23, + 24, 25, 19, 75, 76, 35, 30, 77, 78, 79, + 34, 35, 21, 22, 38, 39, 35, 13, 14, 15, + 16, 17, 18, 31, 32, 33, 21, 22, 20, 37, + 26, 27, 28, 29, 30, 31, 32, 33, 21, 19, + 112, 37, 3, 4, 40, 13, 14, 15, 16, 17, + 18, 12, 19, 35, 35, 19, 21, 36, 26, 27, + 28, 29, 30, 31, 32, 33, 37, 36, 36, 37, + 13, 14, 15, 16, 17, 18, 33, 23, 36, 33, + 40, 36, 21, 26, 27, 28, 29, 30, 31, 32, + 33, 36, 33, 8, 37, 13, 14, 15, 16, 17, + 18, 126, 131, 13, -1, 128, -1, -1, -1, 27, + 28, 29, 30, 31, 32, 33, -1, -1, -1, 37, + 14, 15, 16, 17, 18, -1, -1, -1, -1, -1, + -1, -1, -1, 27, 28, 29, 30, 31, 32, 33, + -1, -1, -1, 37, 15, 16, 17, 18, -1, -1, + -1, -1, -1, -1, -1, -1, 27, 28, 29, 30, + 31, 32, 33, 17, 18, -1, 37, -1, -1, -1, + -1, -1, -1, 27, 28, 29, 30, 31, 32, 33, + -1, -1, -1, 37, 29, 30, 31, 32, 33, -1, + -1, -1, 37 +}; + + /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const yytype_uint8 yystos[] = +{ + 0, 42, 43, 44, 0, 5, 11, 47, 48, 49, + 72, 45, 46, 21, 74, 21, 70, 47, 19, 6, + 7, 21, 22, 23, 24, 25, 30, 34, 35, 38, + 39, 51, 52, 53, 63, 64, 65, 66, 74, 73, + 3, 4, 12, 50, 57, 59, 61, 35, 20, 54, + 54, 23, 24, 51, 51, 21, 13, 14, 15, 16, + 17, 18, 26, 27, 28, 29, 30, 31, 32, 33, + 37, 35, 35, 71, 58, 60, 62, 19, 19, 19, + 21, 38, 54, 54, 36, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 8, 9, + 21, 35, 55, 21, 22, 36, 51, 67, 21, 36, + 68, 69, 21, 51, 51, 50, 50, 50, 36, 36, + 55, 21, 22, 56, 33, 23, 40, 36, 40, 36, + 51, 33, 55, 36, 67, 68, 56, 33, 55 +}; + + /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const yytype_uint8 yyr1[] = +{ + 0, 41, 43, 42, 44, 42, 46, 45, 47, 47, + 48, 49, 49, 50, 50, 50, 50, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 52, 52, 52, 52, 53, 54, 54, 55, + 55, 55, 55, 55, 55, 56, 56, 56, 58, 57, + 60, 59, 62, 61, 63, 63, 63, 63, 64, 65, + 65, 66, 67, 67, 68, 69, 69, 70, 71, 71, + 73, 72, 74, 74 +}; + + /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ +static const yytype_uint8 yyr2[] = +{ + 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, + 3, 1, 2, 0, 3, 3, 3, 1, 1, 1, + 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, + 1, 3, 2, 2, 3, 3, 1, 0, 1, 1, + 3, 3, 5, 2, 2, 1, 3, 1, 0, 4, + 0, 3, 0, 3, 1, 4, 4, 1, 2, 4, + 3, 1, 1, 3, 1, 1, 3, 1, 3, 2, + 0, 4, 0, 2 +}; + + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab + + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ + do \ + if (yychar == YYEMPTY) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + YYPOPSTACK (yylen); \ + yystate = *yyssp; \ + goto yybackup; \ + } \ + else \ + { \ + yyerror (prg_out, YY_("syntax error: cannot back up")); \ + YYERROR; \ + } \ + while (0) + +/* Error token number */ +#define YYTERROR 1 +#define YYERRCODE 256 + + + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (0) + +/* This macro is provided for backward compatibility. */ +#ifndef YY_LOCATION_PRINT +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +#endif + + +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yy_symbol_print (stderr, \ + Type, Value, prg_out); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (0) + + +/*-----------------------------------. +| Print this symbol's value on YYO. | +`-----------------------------------*/ + +static void +yy_symbol_value_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep, pcb_qry_node_t **prg_out) +{ + FILE *yyoutput = yyo; + YYUSE (yyoutput); + YYUSE (prg_out); + if (!yyvaluep) + return; +# ifdef YYPRINT + if (yytype < YYNTOKENS) + YYPRINT (yyo, yytoknum[yytype], *yyvaluep); +# endif + YYUSE (yytype); +} + + +/*---------------------------. +| Print this symbol on YYO. | +`---------------------------*/ + +static void +yy_symbol_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep, pcb_qry_node_t **prg_out) +{ + YYFPRINTF (yyo, "%s %s (", + yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]); + + yy_symbol_value_print (yyo, yytype, yyvaluep, prg_out); + YYFPRINTF (yyo, ")"); +} + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (included). | +`------------------------------------------------------------------*/ + +static void +yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) +{ + YYFPRINTF (stderr, "Stack now"); + for (; yybottom <= yytop; yybottom++) + { + int yybot = *yybottom; + YYFPRINTF (stderr, " %d", yybot); + } + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (0) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +static void +yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule, pcb_qry_node_t **prg_out) +{ + unsigned long yylno = yyrline[yyrule]; + int yynrhs = yyr2[yyrule]; + int yyi; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", + yyrule - 1, yylno); + /* The symbols being reduced. */ + for (yyi = 0; yyi < yynrhs; yyi++) + { + YYFPRINTF (stderr, " $%d = ", yyi + 1); + yy_symbol_print (stderr, + yystos[yyssp[yyi + 1 - yynrhs]], + &yyvsp[(yyi + 1) - (yynrhs)] + , prg_out); + YYFPRINTF (stderr, "\n"); + } +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (yyssp, yyvsp, Rule, prg_out); \ +} while (0) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + +#if YYERROR_VERBOSE + +# ifndef yystrlen +# if defined __GLIBC__ && defined _STRING_H +# define yystrlen strlen +# else +/* Return the length of YYSTR. */ +static YYSIZE_T +yystrlen (const char *yystr) +{ + YYSIZE_T yylen; + for (yylen = 0; yystr[yylen]; yylen++) + continue; + return yylen; +} +# endif +# endif + +# ifndef yystpcpy +# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +static char * +yystpcpy (char *yydest, const char *yysrc) +{ + char *yyd = yydest; + const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +# endif + +# ifndef yytnamerr +/* Copy to YYRES the contents of YYSTR after stripping away unnecessary + quotes and backslashes, so that it's suitable for yyerror. The + heuristic is that double-quoting is unnecessary unless the string + contains an apostrophe, a comma, or backslash (other than + backslash-backslash). YYSTR is taken from yytname. If YYRES is + null, do not copy; instead, return the length of what the result + would have been. */ +static YYSIZE_T +yytnamerr (char *yyres, const char *yystr) +{ + if (*yystr == '"') + { + YYSIZE_T yyn = 0; + char const *yyp = yystr; + + for (;;) + switch (*++yyp) + { + case '\'': + case ',': + goto do_not_strip_quotes; + + case '\\': + if (*++yyp != '\\') + goto do_not_strip_quotes; + else + goto append; + + append: + default: + if (yyres) + yyres[yyn] = *yyp; + yyn++; + break; + + case '"': + if (yyres) + yyres[yyn] = '\0'; + return yyn; + } + do_not_strip_quotes: ; + } + + if (! yyres) + return yystrlen (yystr); + + return (YYSIZE_T) (yystpcpy (yyres, yystr) - yyres); +} +# endif + +/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message + about the unexpected token YYTOKEN for the state stack whose top is + YYSSP. + + Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is + not large enough to hold the message. In that case, also set + *YYMSG_ALLOC to the required number of bytes. Return 2 if the + required number of bytes is too large to store. */ +static int +yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, + yytype_int16 *yyssp, int yytoken) +{ + YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]); + YYSIZE_T yysize = yysize0; + enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; + /* Internationalized format string. */ + const char *yyformat = YY_NULLPTR; + /* Arguments of yyformat. */ + char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; + /* Number of reported tokens (one for the "unexpected", one per + "expected"). */ + int yycount = 0; + + /* There are many possibilities here to consider: + - If this state is a consistent state with a default action, then + the only way this function was invoked is if the default action + is an error action. In that case, don't check for expected + tokens because there are none. + - The only way there can be no lookahead present (in yychar) is if + this state is a consistent state with a default action. Thus, + detecting the absence of a lookahead is sufficient to determine + that there is no unexpected or expected token to report. In that + case, just report a simple "syntax error". + - Don't assume there isn't a lookahead just because this state is a + consistent state with a default action. There might have been a + previous inconsistent state, consistent state with a non-default + action, or user semantic action that manipulated yychar. + - Of course, the expected token list depends on states to have + correct lookahead information, and it depends on the parser not + to perform extra reductions after fetching a lookahead from the + scanner and before detecting a syntax error. Thus, state merging + (from LALR or IELR) and default reductions corrupt the expected + token list. However, the list is correct for canonical LR with + one exception: it will still contain any token that will not be + accepted due to an error action in a later state. + */ + if (yytoken != YYEMPTY) + { + int yyn = yypact[*yyssp]; + yyarg[yycount++] = yytname[yytoken]; + if (!yypact_value_is_default (yyn)) + { + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. In other words, skip the first -YYN actions for + this state because they are default actions. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST - yyn + 1; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; + int yyx; + + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR + && !yytable_value_is_error (yytable[yyx + yyn])) + { + if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) + { + yycount = 1; + yysize = yysize0; + break; + } + yyarg[yycount++] = yytname[yyx]; + { + YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]); + if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM) + yysize = yysize1; + else + return 2; + } + } + } + } + + switch (yycount) + { +# define YYCASE_(N, S) \ + case N: \ + yyformat = S; \ + break + default: /* Avoid compiler warnings. */ + YYCASE_(0, YY_("syntax error")); + YYCASE_(1, YY_("syntax error, unexpected %s")); + YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); + YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); + YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); + YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); +# undef YYCASE_ + } + + { + YYSIZE_T yysize1 = yysize + yystrlen (yyformat); + if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM) + yysize = yysize1; + else + return 2; + } + + if (*yymsg_alloc < yysize) + { + *yymsg_alloc = 2 * yysize; + if (! (yysize <= *yymsg_alloc + && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) + *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; + return 1; + } + + /* Avoid sprintf, as that infringes on the user's name space. + Don't have undefined behavior even if the translation + produced a string with the wrong number of "%s"s. */ + { + char *yyp = *yymsg; + int yyi = 0; + while ((*yyp = *yyformat) != '\0') + if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) + { + yyp += yytnamerr (yyp, yyarg[yyi++]); + yyformat += 2; + } + else + { + yyp++; + yyformat++; + } + } + return 0; +} +#endif /* YYERROR_VERBOSE */ + +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +static void +yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, pcb_qry_node_t **prg_out) +{ + YYUSE (yyvaluep); + YYUSE (prg_out); + if (!yymsg) + yymsg = "Deleting"; + YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + YYUSE (yytype); + YY_IGNORE_MAYBE_UNINITIALIZED_END +} + + + + +/* The lookahead symbol. */ +int yychar; + +/* The semantic value of the lookahead symbol. */ +YYSTYPE yylval; +/* Number of syntax errors so far. */ +int yynerrs; + + +/*----------. +| yyparse. | +`----------*/ + +int +yyparse (pcb_qry_node_t **prg_out) +{ + int yystate; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + + /* The stacks and their tools: + 'yyss': related to states. + 'yyvs': related to semantic values. + + Refer to the stacks through separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* The state stack. */ + yytype_int16 yyssa[YYINITDEPTH]; + yytype_int16 *yyss; + yytype_int16 *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs; + YYSTYPE *yyvsp; + + YYSIZE_T yystacksize; + + int yyn; + int yyresult; + /* Lookahead token as an internal (translated) token number. */ + int yytoken = 0; + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + +#if YYERROR_VERBOSE + /* Buffer for error messages, and its allocated size. */ + char yymsgbuf[128]; + char *yymsg = yymsgbuf; + YYSIZE_T yymsg_alloc = sizeof yymsgbuf; +#endif + +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) + + /* The number of symbols on the RHS of the reduced rule. + Keep to zero when no symbol should be popped. */ + int yylen = 0; + + yyssp = yyss = yyssa; + yyvsp = yyvs = yyvsa; + yystacksize = YYINITDEPTH; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + goto yysetstate; + + +/*------------------------------------------------------------. +| yynewstate -- push a new state, which is found in yystate. | +`------------------------------------------------------------*/ +yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. So pushing a state here evens the stacks. */ + yyssp++; + + +/*--------------------------------------------------------------------. +| yynewstate -- set current state (the top of the stack) to yystate. | +`--------------------------------------------------------------------*/ +yysetstate: + *yyssp = (yytype_int16) yystate; + + if (yyss + yystacksize - 1 <= yyssp) +#if !defined yyoverflow && !defined YYSTACK_RELOCATE + goto yyexhaustedlab; +#else + { + /* Get the current used size of the three stacks, in elements. */ + YYSIZE_T yysize = (YYSIZE_T) (yyssp - yyss + 1); + +# if defined yyoverflow + { + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + yytype_int16 *yyss1 = yyss; + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow (YY_("memory exhausted"), + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + &yystacksize); + yyss = yyss1; + yyvs = yyvs1; + } +# else /* defined YYSTACK_RELOCATE */ + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + goto yyexhaustedlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + yytype_int16 *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyexhaustedlab; + YYSTACK_RELOCATE (yyss_alloc, yyss); + YYSTACK_RELOCATE (yyvs_alloc, yyvs); +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + + YYDPRINTF ((stderr, "Stack size increased to %lu\n", + (unsigned long) yystacksize)); + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } +#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */ + + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + + if (yystate == YYFINAL) + YYACCEPT; + + goto yybackup; + + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + /* Do appropriate processing given the current state. Read a + lookahead token if we need one and don't already have one. */ + + /* First try to decide what to do without reference to lookahead token. */ + yyn = yypact[yystate]; + if (yypact_value_is_default (yyn)) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); + yychar = yylex (); + } + + if (yychar <= YYEOF) + { + yychar = yytoken = YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else + { + yytoken = YYTRANSLATE (yychar); + YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) + { + if (yytable_value_is_error (yyn)) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + /* Shift the lookahead token. */ + YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); + + /* Discard the shifted token. */ + yychar = YYEMPTY; + + yystate = yyn; + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + *++yyvsp = yylval; + YY_IGNORE_MAYBE_UNINITIALIZED_END + + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + '$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 2: +#line 189 "query_y.y" /* yacc.c:1652 */ + { uninit_user_funcs(); } +#line 1516 "query_y.c" /* yacc.c:1652 */ + break; + + case 3: +#line 189 "query_y.y" /* yacc.c:1652 */ + { *prg_out = (yyvsp[0].n); link_user_funcs((yyvsp[0].n), 1); } +#line 1522 "query_y.c" /* yacc.c:1652 */ + break; + + case 4: +#line 190 "query_y.y" /* yacc.c:1652 */ + { uninit_user_funcs(); } +#line 1528 "query_y.c" /* yacc.c:1652 */ + break; + + case 5: +#line 190 "query_y.y" /* yacc.c:1652 */ + { *prg_out = (yyvsp[0].n); link_user_funcs((yyvsp[0].n), 0); } +#line 1534 "query_y.c" /* yacc.c:1652 */ + break; + + case 6: +#line 195 "query_y.y" /* yacc.c:1652 */ + { iter_ctx = pcb_qry_iter_alloc(); } +#line 1540 "query_y.c" /* yacc.c:1652 */ + break; + + case 7: +#line 196 "query_y.y" /* yacc.c:1652 */ + { + (yyval.n) = pcb_qry_n_alloc(PCBQ_EXPR_PROG); + (yyval.n)->data.children = pcb_qry_n_alloc(PCBQ_ITER_CTX); + (yyval.n)->data.children->parent = (yyval.n); + (yyval.n)->data.children->data.iter_ctx = iter_ctx; + (yyval.n)->data.children->next = (yyvsp[0].n); + (yyvsp[0].n)->parent = (yyval.n); + } +#line 1553 "query_y.c" /* yacc.c:1652 */ + break; + + case 8: +#line 208 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = NULL; } +#line 1559 "query_y.c" /* yacc.c:1652 */ + break; + + case 9: +#line 209 "query_y.y" /* yacc.c:1652 */ + { if ((yyvsp[-1].n) != NULL) { (yyval.n) = (yyvsp[-1].n); (yyvsp[-1].n)->next = (yyvsp[0].n); } else { (yyval.n) = (yyvsp[0].n); } } +#line 1565 "query_y.c" /* yacc.c:1652 */ + break; + + case 10: +#line 213 "query_y.y" /* yacc.c:1652 */ + { + (yyval.n) = (yyvsp[-2].n); + if ((yyvsp[0].n) != NULL) + pcb_qry_n_append((yyval.n), (yyvsp[0].n)); + } +#line 1575 "query_y.c" /* yacc.c:1652 */ + break; + + case 11: +#line 221 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = (yyvsp[0].n); } +#line 1581 "query_y.c" /* yacc.c:1652 */ + break; + + case 12: +#line 222 "query_y.y" /* yacc.c:1652 */ + { + pcb_qry_node_t *nd; + iter_ctx = pcb_qry_iter_alloc(); + (yyval.n) = pcb_qry_n_alloc(PCBQ_RULE); + pcb_qry_n_insert((yyval.n), (yyvsp[0].n)); + nd = pcb_qry_n_alloc(PCBQ_ITER_CTX); + nd->data.iter_ctx = iter_ctx; + pcb_qry_n_insert((yyval.n), nd); + } +#line 1595 "query_y.c" /* yacc.c:1652 */ + break; + + case 13: +#line 234 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = NULL; } +#line 1601 "query_y.c" /* yacc.c:1652 */ + break; + + case 14: +#line 235 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = (yyvsp[-2].n); (yyvsp[-2].n)->next = (yyvsp[0].n); } +#line 1607 "query_y.c" /* yacc.c:1652 */ + break; + + case 15: +#line 236 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = (yyvsp[-2].n); (yyvsp[-2].n)->next = (yyvsp[0].n); } +#line 1613 "query_y.c" /* yacc.c:1652 */ + break; + + case 16: +#line 237 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = (yyvsp[-2].n); (yyvsp[-2].n)->next = (yyvsp[0].n); } +#line 1619 "query_y.c" /* yacc.c:1652 */ + break; + + case 17: +#line 241 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = (yyvsp[0].n); } +#line 1625 "query_y.c" /* yacc.c:1652 */ + break; + + case 18: +#line 242 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = (yyvsp[0].n); } +#line 1631 "query_y.c" /* yacc.c:1652 */ + break; + + case 19: +#line 243 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = (yyvsp[0].n); } +#line 1637 "query_y.c" /* yacc.c:1652 */ + break; + + case 20: +#line 244 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = pcb_qry_n_alloc(PCBQ_DATA_INVALID); } +#line 1643 "query_y.c" /* yacc.c:1652 */ + break; + + case 21: +#line 245 "query_y.y" /* yacc.c:1652 */ + { UNOP((yyval.n), PCBQ_OP_NOT, (yyvsp[0].n)); } +#line 1649 "query_y.c" /* yacc.c:1652 */ + break; + + case 22: +#line 246 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = (yyvsp[-1].n); } +#line 1655 "query_y.c" /* yacc.c:1652 */ + break; + + case 23: +#line 247 "query_y.y" /* yacc.c:1652 */ + { BINOP((yyval.n), (yyvsp[-2].n), PCBQ_OP_THUS, (yyvsp[0].n)); } +#line 1661 "query_y.c" /* yacc.c:1652 */ + break; + + case 24: +#line 248 "query_y.y" /* yacc.c:1652 */ + { BINOP((yyval.n), (yyvsp[-2].n), PCBQ_OP_AND, (yyvsp[0].n)); } +#line 1667 "query_y.c" /* yacc.c:1652 */ + break; + + case 25: +#line 249 "query_y.y" /* yacc.c:1652 */ + { BINOP((yyval.n), (yyvsp[-2].n), PCBQ_OP_OR, (yyvsp[0].n)); } +#line 1673 "query_y.c" /* yacc.c:1652 */ + break; + + case 26: +#line 250 "query_y.y" /* yacc.c:1652 */ + { BINOP((yyval.n), (yyvsp[-2].n), PCBQ_OP_EQ, (yyvsp[0].n)); } +#line 1679 "query_y.c" /* yacc.c:1652 */ + break; + + case 27: +#line 251 "query_y.y" /* yacc.c:1652 */ + { BINOP((yyval.n), (yyvsp[-2].n), PCBQ_OP_NEQ, (yyvsp[0].n)); } +#line 1685 "query_y.c" /* yacc.c:1652 */ + break; + + case 28: +#line 252 "query_y.y" /* yacc.c:1652 */ + { BINOP((yyval.n), (yyvsp[-2].n), PCBQ_OP_GTEQ, (yyvsp[0].n)); } +#line 1691 "query_y.c" /* yacc.c:1652 */ + break; + + case 29: +#line 253 "query_y.y" /* yacc.c:1652 */ + { BINOP((yyval.n), (yyvsp[-2].n), PCBQ_OP_LTEQ, (yyvsp[0].n)); } +#line 1697 "query_y.c" /* yacc.c:1652 */ + break; + + case 30: +#line 254 "query_y.y" /* yacc.c:1652 */ + { BINOP((yyval.n), (yyvsp[-2].n), PCBQ_OP_GT, (yyvsp[0].n)); } +#line 1703 "query_y.c" /* yacc.c:1652 */ + break; + + case 31: +#line 255 "query_y.y" /* yacc.c:1652 */ + { BINOP((yyval.n), (yyvsp[-2].n), PCBQ_OP_LT, (yyvsp[0].n)); } +#line 1709 "query_y.c" /* yacc.c:1652 */ + break; + + case 32: +#line 256 "query_y.y" /* yacc.c:1652 */ + { BINOP((yyval.n), (yyvsp[-2].n), PCBQ_OP_ADD, (yyvsp[0].n)); } +#line 1715 "query_y.c" /* yacc.c:1652 */ + break; + + case 33: +#line 257 "query_y.y" /* yacc.c:1652 */ + { BINOP((yyval.n), (yyvsp[-2].n), PCBQ_OP_SUB, (yyvsp[0].n)); } +#line 1721 "query_y.c" /* yacc.c:1652 */ + break; + + case 34: +#line 258 "query_y.y" /* yacc.c:1652 */ + { BINOP((yyval.n), (yyvsp[-2].n), PCBQ_OP_MUL, (yyvsp[0].n)); } +#line 1727 "query_y.c" /* yacc.c:1652 */ + break; + + case 35: +#line 259 "query_y.y" /* yacc.c:1652 */ + { BINOP((yyval.n), (yyvsp[-2].n), PCBQ_OP_DIV, (yyvsp[0].n)); } +#line 1733 "query_y.c" /* yacc.c:1652 */ + break; + + case 36: +#line 260 "query_y.y" /* yacc.c:1652 */ + { BINOP((yyval.n), (yyvsp[-2].n), PCBQ_OP_MATCH, make_regex_free((yyvsp[0].s))); } +#line 1739 "query_y.c" /* yacc.c:1652 */ + break; + + case 37: +#line 261 "query_y.y" /* yacc.c:1652 */ + { BINOP((yyval.n), (yyvsp[-2].n), PCBQ_OP_MATCH, make_regex_free((yyvsp[0].s))); } +#line 1745 "query_y.c" /* yacc.c:1652 */ + break; + + case 38: +#line 262 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = (yyvsp[0].n); } +#line 1751 "query_y.c" /* yacc.c:1652 */ + break; + + case 39: +#line 263 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = (yyvsp[0].n); } +#line 1757 "query_y.c" /* yacc.c:1652 */ + break; + + case 40: +#line 264 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = (yyvsp[0].n); } +#line 1763 "query_y.c" /* yacc.c:1652 */ + break; + + case 41: +#line 265 "query_y.y" /* yacc.c:1652 */ + { + pcb_qry_node_t *n; + (yyval.n) = pcb_qry_n_alloc(PCBQ_FIELD_OF); + (yyval.n)->data.children = (yyvsp[-2].n); + (yyvsp[-2].n)->next = (yyvsp[0].n); + (yyvsp[-2].n)->parent = (yyval.n); + for(n = (yyvsp[0].n); n != NULL; n = n->next) + n->parent = (yyval.n); + } +#line 1777 "query_y.c" /* yacc.c:1652 */ + break; + + case 42: +#line 277 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = pcb_qry_n_alloc(PCBQ_DATA_COORD); UNIT_CONV((yyval.n)->data.crd, 0, (yyvsp[-1].c), (yyvsp[0].u)); } +#line 1783 "query_y.c" /* yacc.c:1652 */ + break; + + case 43: +#line 278 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = pcb_qry_n_alloc(PCBQ_DATA_DOUBLE); UNIT_CONV((yyval.n)->data.dbl, 0, (yyvsp[-1].d), (yyvsp[0].u)); } +#line 1789 "query_y.c" /* yacc.c:1652 */ + break; + + case 44: +#line 279 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = pcb_qry_n_alloc(PCBQ_DATA_COORD); UNIT_CONV((yyval.n)->data.crd, 1, (yyvsp[-1].c), (yyvsp[0].u)); } +#line 1795 "query_y.c" /* yacc.c:1652 */ + break; + + case 45: +#line 280 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = pcb_qry_n_alloc(PCBQ_DATA_DOUBLE); UNIT_CONV((yyval.n)->data.dbl, 1, (yyvsp[-1].d), (yyvsp[0].u)); } +#line 1801 "query_y.c" /* yacc.c:1652 */ + break; + + case 46: +#line 284 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = pcb_qry_n_alloc(PCBQ_DATA_STRING); (yyval.n)->data.str = (yyvsp[0].s); } +#line 1807 "query_y.c" /* yacc.c:1652 */ + break; + + case 47: +#line 288 "query_y.y" /* yacc.c:1652 */ + { (yyval.u) = NULL; } +#line 1813 "query_y.c" /* yacc.c:1652 */ + break; + + case 48: +#line 289 "query_y.y" /* yacc.c:1652 */ + { (yyval.u) = (yyvsp[0].u); } +#line 1819 "query_y.c" /* yacc.c:1652 */ + break; + + case 49: +#line 293 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = pcb_qry_n_alloc(PCBQ_FIELD); (yyval.n)->data.str = (yyvsp[0].s); (yyval.n)->precomp.fld = query_fields_sphash((yyvsp[0].s)); } +#line 1825 "query_y.c" /* yacc.c:1652 */ + break; + + case 50: +#line 294 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = pcb_qry_n_alloc(PCBQ_FIELD); (yyval.n)->data.str = (yyvsp[-2].s); (yyval.n)->precomp.fld = query_fields_sphash((yyvsp[-2].s)); (yyval.n)->next = (yyvsp[0].n); } +#line 1831 "query_y.c" /* yacc.c:1652 */ + break; + + case 51: +#line 295 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = pcb_qry_n_alloc(PCBQ_DATA_CONST); (yyval.n)->precomp.iconst =(yyvsp[-1].c); } +#line 1837 "query_y.c" /* yacc.c:1652 */ + break; + + case 52: +#line 296 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = pcb_qry_n_alloc(PCBQ_DATA_CONST); (yyval.n)->precomp.iconst = (yyvsp[-3].c); (yyval.n)->next = (yyvsp[0].n); } +#line 1843 "query_y.c" /* yacc.c:1652 */ + break; + + case 53: +#line 297 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = (yyvsp[0].n); /* just ignore .p. */ } +#line 1849 "query_y.c" /* yacc.c:1652 */ + break; + + case 54: +#line 298 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = pcb_qry_n_alloc(PCBQ_FIELD); (yyval.n)->data.str = rnd_strdup("a"); (yyval.n)->precomp.fld = query_fields_sphash("a"); (yyval.n)->next = (yyvsp[0].n); } +#line 1855 "query_y.c" /* yacc.c:1652 */ + break; + + case 55: +#line 302 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = pcb_qry_n_alloc(PCBQ_FIELD); (yyval.n)->data.str = (yyvsp[0].s); } +#line 1861 "query_y.c" /* yacc.c:1652 */ + break; + + case 56: +#line 303 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = pcb_qry_n_alloc(PCBQ_FIELD); (yyval.n)->data.str = attrib_prepend_free((char *)(yyvsp[0].n)->data.str, (yyvsp[-2].s), '.'); } +#line 1867 "query_y.c" /* yacc.c:1652 */ + break; + + case 57: +#line 304 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = pcb_qry_n_alloc(PCBQ_FIELD); (yyval.n)->data.str = (yyvsp[0].s); } +#line 1873 "query_y.c" /* yacc.c:1652 */ + break; + + case 58: +#line 309 "query_y.y" /* yacc.c:1652 */ + { + iter_active_ctx = calloc(sizeof(vti0_t), 1); + } +#line 1881 "query_y.c" /* yacc.c:1652 */ + break; + + case 59: +#line 313 "query_y.y" /* yacc.c:1652 */ + { + pcb_qry_node_t *nd; + (yyval.n) = pcb_qry_n_alloc(PCBQ_LET); + (yyval.n)->precomp.it_active = iter_active_ctx; + iter_active_ctx = NULL; + pcb_qry_n_insert((yyval.n), (yyvsp[0].n)); + nd = pcb_qry_n_alloc(PCBQ_VAR); + nd->data.crd = pcb_qry_iter_var(iter_ctx, (yyvsp[-1].s), 1); + pcb_qry_n_insert((yyval.n), nd); + free((yyvsp[-1].s)); + } +#line 1897 "query_y.c" /* yacc.c:1652 */ + break; + + case 60: +#line 328 "query_y.y" /* yacc.c:1652 */ + { + iter_active_ctx = calloc(sizeof(vti0_t), 1); + } +#line 1905 "query_y.c" /* yacc.c:1652 */ + break; + + case 61: +#line 332 "query_y.y" /* yacc.c:1652 */ + { + (yyval.n) = pcb_qry_n_alloc(PCBQ_ASSERT); + (yyval.n)->precomp.it_active = iter_active_ctx; + iter_active_ctx = NULL; + pcb_qry_n_insert((yyval.n), (yyvsp[0].n)); + } +#line 1916 "query_y.c" /* yacc.c:1652 */ + break; + + case 62: +#line 342 "query_y.y" /* yacc.c:1652 */ + { + iter_active_ctx = calloc(sizeof(vti0_t), 1); + } +#line 1924 "query_y.c" /* yacc.c:1652 */ + break; + + case 63: +#line 346 "query_y.y" /* yacc.c:1652 */ + { + (yyval.n) = pcb_qry_n_alloc(PCBQ_RETURN); + (yyval.n)->precomp.it_active = iter_active_ctx; + iter_active_ctx = NULL; + pcb_qry_n_insert((yyval.n), (yyvsp[0].n)); + } +#line 1935 "query_y.c" /* yacc.c:1652 */ + break; + + case 64: +#line 355 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = pcb_qry_n_alloc(PCBQ_VAR); (yyval.n)->data.crd = pcb_qry_iter_var(iter_ctx, (yyvsp[0].s), 1); if (iter_active_ctx != NULL) vti0_set(iter_active_ctx, (yyval.n)->data.crd, 1); free((yyvsp[0].s)); } +#line 1941 "query_y.c" /* yacc.c:1652 */ + break; + + case 65: +#line 356 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = pcb_qry_n_alloc(PCBQ_LISTVAR); (yyval.n)->data.str = rnd_strdup("@"); /* delibertely not setting iter_active, list() protects against turning it into an iterator */ } +#line 1947 "query_y.c" /* yacc.c:1652 */ + break; + + case 66: +#line 357 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = pcb_qry_n_alloc(PCBQ_LISTVAR); (yyval.n)->data.str = (yyvsp[-1].s); /* delibertely not setting iter_active, list() protects against turning it into an iterator */ } +#line 1953 "query_y.c" /* yacc.c:1652 */ + break; + + case 67: +#line 358 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = pcb_qry_n_alloc(PCBQ_VAR); (yyval.n)->data.crd = pcb_qry_iter_var(iter_ctx, "@", 1); if (iter_active_ctx != NULL) vti0_set(iter_active_ctx, (yyval.n)->data.crd, 1); } +#line 1959 "query_y.c" /* yacc.c:1652 */ + break; + + case 68: +#line 364 "query_y.y" /* yacc.c:1652 */ + { + pcb_qry_node_t *fname, *nname; + + nname = pcb_qry_n_alloc(PCBQ_DATA_STRING); + nname->data.str = rnd_concat("design/drc/", (yyvsp[0].s), NULL); + free((yyvsp[0].s)); + + fname = pcb_qry_n_alloc(PCBQ_FNAME); + fname->data.str = NULL; + fname->precomp.fnc.bui = pcb_qry_fnc_lookup("getconf"); + + (yyval.n) = pcb_qry_n_alloc(PCBQ_FCALL); + fname->parent = nname->parent = (yyval.n); + (yyval.n)->data.children = fname; + (yyval.n)->data.children->next = nname; + } +#line 1980 "query_y.c" /* yacc.c:1652 */ + break; + + case 69: +#line 383 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = pcb_qry_n_alloc(PCBQ_FCALL); (yyval.n)->data.children = (yyvsp[-3].n); (yyval.n)->data.children->next = (yyvsp[-1].n); (yyvsp[-3].n)->parent = (yyvsp[-1].n)->parent = (yyval.n); } +#line 1986 "query_y.c" /* yacc.c:1652 */ + break; + + case 70: +#line 384 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = pcb_qry_n_alloc(PCBQ_FCALL); (yyval.n)->data.children = (yyvsp[-2].n); (yyvsp[-2].n)->parent = (yyval.n); } +#line 1992 "query_y.c" /* yacc.c:1652 */ + break; + + case 71: +#line 388 "query_y.y" /* yacc.c:1652 */ + { + (yyval.n) = pcb_qry_n_alloc(PCBQ_FNAME); + (yyval.n)->precomp.fnc.bui = pcb_qry_fnc_lookup((yyvsp[0].s)); + if ((yyval.n)->precomp.fnc.bui != NULL) { + /* builtin function */ + free((yyvsp[0].s)); + (yyval.n)->data.str = NULL; + } + else + (yyval.n)->data.str = (yyvsp[0].s); /* user function: save the name */ + } +#line 2008 "query_y.c" /* yacc.c:1652 */ + break; + + case 72: +#line 403 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = (yyvsp[0].n); } +#line 2014 "query_y.c" /* yacc.c:1652 */ + break; + + case 73: +#line 404 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = (yyvsp[-2].n); (yyval.n)->next = (yyvsp[0].n); } +#line 2020 "query_y.c" /* yacc.c:1652 */ + break; + + case 74: +#line 409 "query_y.y" /* yacc.c:1652 */ + { + (yyval.n) = pcb_qry_n_alloc(PCBQ_ARG); + (yyval.n)->data.crd = pcb_qry_iter_var(iter_ctx, (yyvsp[0].s), 1); + } +#line 2029 "query_y.c" /* yacc.c:1652 */ + break; + + case 75: +#line 416 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = (yyvsp[0].n); } +#line 2035 "query_y.c" /* yacc.c:1652 */ + break; + + case 76: +#line 417 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = (yyvsp[-2].n); (yyval.n)->next = (yyvsp[0].n); } +#line 2041 "query_y.c" /* yacc.c:1652 */ + break; + + case 77: +#line 421 "query_y.y" /* yacc.c:1652 */ + { + (yyval.n) = pcb_qry_n_alloc(PCBQ_FNAME); + (yyval.n)->data.str = (yyvsp[0].s); + } +#line 2050 "query_y.c" /* yacc.c:1652 */ + break; + + case 78: +#line 428 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = (yyvsp[-1].n); } +#line 2056 "query_y.c" /* yacc.c:1652 */ + break; + + case 79: +#line 429 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = NULL; } +#line 2062 "query_y.c" /* yacc.c:1652 */ + break; + + case 80: +#line 434 "query_y.y" /* yacc.c:1652 */ + { iter_ctx = pcb_qry_iter_alloc(); } +#line 2068 "query_y.c" /* yacc.c:1652 */ + break; + + case 81: +#line 435 "query_y.y" /* yacc.c:1652 */ + { + pcb_qry_node_t *nd; + + (yyval.n) = pcb_qry_n_alloc(PCBQ_FUNCTION); + + if ((yyvsp[0].n) != NULL) + pcb_qry_n_append((yyval.n), (yyvsp[0].n)); + + pcb_qry_n_insert((yyval.n), (yyvsp[-2].n)); + + nd = pcb_qry_n_alloc(PCBQ_ITER_CTX); + nd->data.iter_ctx = iter_ctx; + pcb_qry_n_insert((yyval.n), nd); + + if (user_funcs == NULL) + user_funcs = htsp_alloc(strhash, strkeyeq); + htsp_set(user_funcs, (char *)(yyvsp[-2].n)->data.str, (yyval.n)); + } +#line 2091 "query_y.c" /* yacc.c:1652 */ + break; + + case 82: +#line 455 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = pcb_qry_n_alloc(PCBQ_RNAME); (yyval.n)->data.str = (const char *)rnd_strdup(""); } +#line 2097 "query_y.c" /* yacc.c:1652 */ + break; + + case 83: +#line 456 "query_y.y" /* yacc.c:1652 */ + { + char *old = (char *)(yyvsp[0].n)->data.str, *sep = ((*old != '\0') ? " " : ""); + (yyvsp[0].n)->data.str = rnd_concat((yyvsp[-1].s), sep, old, NULL); + free(old); + free((yyvsp[-1].s)); + (yyval.n) = (yyvsp[0].n); + } +#line 2109 "query_y.c" /* yacc.c:1652 */ + break; + + +#line 2113 "query_y.c" /* yacc.c:1652 */ + default: break; + } + /* User semantic actions sometimes alter yychar, and that requires + that yytoken be updated with the new translation. We take the + approach of translating immediately before every use of yytoken. + One alternative is translating here after every semantic action, + but that translation would be missed if the semantic action invokes + YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or + if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an + incorrect destructor might then be invoked immediately. In the + case of YYERROR or YYBACKUP, subsequent parser actions might lead + to an incorrect destructor call or verbose syntax error message + before the lookahead is translated. */ + YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); + + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + + *++yyvsp = yyval; + + /* Now 'shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + { + const int yylhs = yyr1[yyn] - YYNTOKENS; + const int yyi = yypgoto[yylhs] + *yyssp; + yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp + ? yytable[yyi] + : yydefgoto[yylhs]); + } + + goto yynewstate; + + +/*--------------------------------------. +| yyerrlab -- here on detecting error. | +`--------------------------------------*/ +yyerrlab: + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); + + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { + ++yynerrs; +#if ! YYERROR_VERBOSE + yyerror (prg_out, YY_("syntax error")); +#else +# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ + yyssp, yytoken) + { + char const *yymsgp = YY_("syntax error"); + int yysyntax_error_status; + yysyntax_error_status = YYSYNTAX_ERROR; + if (yysyntax_error_status == 0) + yymsgp = yymsg; + else if (yysyntax_error_status == 1) + { + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); + yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc); + if (!yymsg) + { + yymsg = yymsgbuf; + yymsg_alloc = sizeof yymsgbuf; + yysyntax_error_status = 2; + } + else + { + yysyntax_error_status = YYSYNTAX_ERROR; + yymsgp = yymsg; + } + } + yyerror (prg_out, yymsgp); + if (yysyntax_error_status == 2) + goto yyexhaustedlab; + } +# undef YYSYNTAX_ERROR +#endif + } + + + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ + + if (yychar <= YYEOF) + { + /* Return failure if at end of input. */ + if (yychar == YYEOF) + YYABORT; + } + else + { + yydestruct ("Error: discarding", + yytoken, &yylval, prg_out); + yychar = YYEMPTY; + } + } + + /* Else will try to reuse lookahead token after shifting the error + token. */ + goto yyerrlab1; + + +/*---------------------------------------------------. +| yyerrorlab -- error raised explicitly by YYERROR. | +`---------------------------------------------------*/ +yyerrorlab: + /* Pacify compilers when the user code never invokes YYERROR and the + label yyerrorlab therefore never appears in user code. */ + if (0) + YYERROR; + + /* Do not reclaim the symbols of the rule whose action triggered + this YYERROR. */ + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + yystate = *yyssp; + goto yyerrlab1; + + +/*-------------------------------------------------------------. +| yyerrlab1 -- common code for both syntax error and YYERROR. | +`-------------------------------------------------------------*/ +yyerrlab1: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + for (;;) + { + yyn = yypact[yystate]; + if (!yypact_value_is_default (yyn)) + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + + yydestruct ("Error: popping", + yystos[yystate], yyvsp, prg_out); + YYPOPSTACK (1); + yystate = *yyssp; + YY_STACK_PRINT (yyss, yyssp); + } + + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + *++yyvsp = yylval; + YY_IGNORE_MAYBE_UNINITIALIZED_END + + + /* Shift the error token. */ + YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturn; + + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturn; + + +#if !defined yyoverflow || YYERROR_VERBOSE +/*-------------------------------------------------. +| yyexhaustedlab -- memory exhaustion comes here. | +`-------------------------------------------------*/ +yyexhaustedlab: + yyerror (prg_out, YY_("memory exhausted")); + yyresult = 2; + /* Fall through. */ +#endif + + +/*-----------------------------------------------------. +| yyreturn -- parsing is finished, return the result. | +`-----------------------------------------------------*/ +yyreturn: + if (yychar != YYEMPTY) + { + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = YYTRANSLATE (yychar); + yydestruct ("Cleanup: discarding lookahead", + yytoken, &yylval, prg_out); + } + /* Do not reclaim the symbols of the rule whose action triggered + this YYABORT or YYACCEPT. */ + YYPOPSTACK (yylen); + YY_STACK_PRINT (yyss, yyssp); + while (yyssp != yyss) + { + yydestruct ("Cleanup: popping", + yystos[*yyssp], yyvsp, prg_out); + YYPOPSTACK (1); + } +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif +#if YYERROR_VERBOSE + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); +#endif + return yyresult; +} Index: tags/1.0.5/src/plugins/query/query_y.h =================================================================== --- tags/1.0.5/src/plugins/query/query_y.h (nonexistent) +++ tags/1.0.5/src/plugins/query/query_y.h (revision 10414) @@ -0,0 +1,105 @@ +/* A Bison parser, made by GNU Bison 3.3.2. */ + +/* Bison interface for Yacc-like parsers in C + + Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2019 Free Software Foundation, + Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* Undocumented macros, especially those whose name start with YY_, + are private implementation details. Do not rely on them. */ + +#ifndef YY_QRY_QUERY_Y_H_INCLUDED +# define YY_QRY_QUERY_Y_H_INCLUDED +/* Debug traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif +#if YYDEBUG +extern int qry_debug; +#endif + +/* Token type. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + enum yytokentype + { + T_LET = 258, + T_ASSERT = 259, + T_RULE = 260, + T_LIST = 261, + T_INVALID = 262, + T_FLD_P = 263, + T_FLD_A = 264, + T_FLD_FLAG = 265, + T_FUNCTION = 266, + T_RETURN = 267, + T_OR = 268, + T_AND = 269, + T_EQ = 270, + T_NEQ = 271, + T_GTEQ = 272, + T_LTEQ = 273, + T_NL = 274, + T_UNIT = 275, + T_STR = 276, + T_QSTR = 277, + T_INT = 278, + T_DBL = 279, + T_CONST = 280, + T_THUS = 281 + }; +#endif + +/* Value type. */ +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED + +union YYSTYPE +{ +#line 148 "query_y.y" /* yacc.c:1921 */ + + char *s; + rnd_coord_t c; + double d; + const rnd_unit_t *u; + pcb_qry_node_t *n; + +#line 93 "query_y.h" /* yacc.c:1921 */ +}; + +typedef union YYSTYPE YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define YYSTYPE_IS_DECLARED 1 +#endif + + +extern YYSTYPE qry_lval; + +int qry_parse (pcb_qry_node_t **prg_out); + +#endif /* !YY_QRY_QUERY_Y_H_INCLUDED */ Index: tags/1.0.5/src/plugins/query/query_y.y =================================================================== --- tags/1.0.5/src/plugins/query/query_y.y (nonexistent) +++ tags/1.0.5/src/plugins/query/query_y.y (revision 10414) @@ -0,0 +1,463 @@ +%{ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/* Query language - compiler: grammar */ + +#include +#include +#include +#include +#include "query.h" +#include "query_l.h" +#include +#include +#include +#include "fields_sphash.h" + +#define UNIT_CONV(dst, negative, val, unit) \ +do { \ + dst = val; \ + if (negative) \ + dst = -dst; \ + if (unit != NULL) { \ + if (unit->family == RND_UNIT_IMPERIAL) \ + dst = RND_MIL_TO_COORD(dst); \ + else if (unit->family == RND_UNIT_METRIC) \ + dst = RND_MM_TO_COORD(dst); \ + dst /= unit->scale_factor; \ + } \ +} while(0) + +#define BINOP(dst, op1, operator, op2) \ +do { \ + assert(op2->next == NULL); \ + assert(op2->next == NULL); \ + dst = pcb_qry_n_alloc(operator); \ + pcb_qry_n_insert(dst, op2); \ + pcb_qry_n_insert(dst, op1); \ +} while(0) + +#define UNOP(dst, operator, op) \ +do { \ + assert(op->next == NULL); \ + dst = pcb_qry_n_alloc(operator); \ + pcb_qry_n_insert(dst, op); \ +} while(0) + +static pcb_query_iter_t *iter_ctx; +static vti0_t *iter_active_ctx; +static htsp_t *user_funcs; + +static char *attrib_prepend_free(char *orig, char *prep, char sep) +{ + int l1 = strlen(orig), l2 = strlen(prep); + char *res = malloc(l1+l2+2); + memcpy(res, prep, l2); + res[l2] = sep; + memcpy(res+l2+1, orig, l1+1); + free(orig); + free(prep); + return res; +} + +static pcb_qry_node_t *make_regex_free(char *str) +{ + pcb_qry_node_t *res = pcb_qry_n_alloc(PCBQ_DATA_REGEX); + res->data.str = str; + res->precomp.regex = re_se_comp(str); + if (res->precomp.regex == NULL) + yyerror(NULL, "Invalid regex\n"); + return res; +} + +static void link_user_funcs_(pcb_qry_node_t *root, int allow) +{ + pcb_qry_node_t *n, *f, *fname; + + for(n = root; n != NULL; n = n->next) { + if (pcb_qry_nodetype_has_children(n->type)) + link_user_funcs_(n->data.children, allow); + if (n->type == PCBQ_FCALL) { + fname = n->data.children; + if (fname->precomp.fnc.bui != NULL) /* builtin */ + continue; + + if (!allow) + rnd_message(RND_MSG_ERROR, "You shouldn't have user functions in query expressions, only in rules\n"); + + if (user_funcs != NULL) + f = htsp_get(user_funcs, fname->data.str); + else + f = NULL; + + fname->precomp.fnc.uf = f; + if (f == NULL) { + yyerror(NULL, "user function not defined:"); + yyerror(NULL, fname->data.str); + } + } + } + +} + +static void uninit_user_funcs() +{ + if (user_funcs != NULL) + htsp_free(user_funcs); + user_funcs = NULL; +} + +static void link_user_funcs(pcb_qry_node_t *root, int allow) +{ + link_user_funcs_(root, allow); + uninit_user_funcs(); +} + + +%} + +%name-prefix "qry_" +%error-verbose +%parse-param {pcb_qry_node_t **prg_out} + +%union { + char *s; + rnd_coord_t c; + double d; + const rnd_unit_t *u; + pcb_qry_node_t *n; +} + +%token T_LET T_ASSERT T_RULE T_LIST T_INVALID T_FLD_P T_FLD_A T_FLD_FLAG +%token T_FUNCTION T_RETURN +%token T_OR T_AND T_EQ T_NEQ T_GTEQ T_LTEQ +%token T_NL +%token T_UNIT +%token T_STR T_QSTR +%token T_INT +%token T_DBL +%token T_CONST + +/* the usual binary operators */ +%left T_THUS +%left T_OR +%left T_AND +%left T_EQ T_NEQ +%left '<' '>' T_GTEQ T_LTEQ +%left '+' '-' +%left '*' '/' +%left '.' + +/* Unary operators */ +%right '!' + +%left '(' + +%type number fields attribs let assert var constant fcallname fcall +%type fargs words freturn fdefarg fdefargs fdef_ fdef fdefname rule_or_fdef +%type string_literal expr rule_item program_expr program_rules rule +%type maybe_unit + +%% + +program: + { uninit_user_funcs(); } program_rules { *prg_out = $2; link_user_funcs($2, 1); } + | { uninit_user_funcs(); } program_expr { *prg_out = $2; link_user_funcs($2, 0); } + ; + +/* The program is a single expression - useful for search */ +program_expr: + { iter_ctx = pcb_qry_iter_alloc(); } + expr { + $$ = pcb_qry_n_alloc(PCBQ_EXPR_PROG); + $$->data.children = pcb_qry_n_alloc(PCBQ_ITER_CTX); + $$->data.children->parent = $$; + $$->data.children->data.iter_ctx = iter_ctx; + $$->data.children->next = $2; + $2->parent = $$; + } + ; + +/* The program is a collection of rules - useful for the DRC */ +program_rules: + /* empty */ { $$ = NULL; } + | rule program_rules { if ($1 != NULL) { $$ = $1; $1->next = $2; } else { $$ = $2; } } + ; + +rule: + rule_or_fdef T_NL rule_item { + $$ = $1; + if ($3 != NULL) + pcb_qry_n_append($$, $3); + } + ; + +rule_or_fdef: + fdef { $$ = $1; } + | T_RULE words { + pcb_qry_node_t *nd; + iter_ctx = pcb_qry_iter_alloc(); + $$ = pcb_qry_n_alloc(PCBQ_RULE); + pcb_qry_n_insert($$, $2); + nd = pcb_qry_n_alloc(PCBQ_ITER_CTX); + nd->data.iter_ctx = iter_ctx; + pcb_qry_n_insert($$, nd); + } + ; + +rule_item: + /* empty */ { $$ = NULL; } + | assert T_NL rule_item { $$ = $1; $1->next = $3; } + | let T_NL rule_item { $$ = $1; $1->next = $3; } + | freturn T_NL rule_item { $$ = $1; $1->next = $3; } + ; + +expr: + fcall { $$ = $1; } + | number { $$ = $1; } + | string_literal { $$ = $1; } + | T_INVALID { $$ = pcb_qry_n_alloc(PCBQ_DATA_INVALID); } + | '!' expr { UNOP($$, PCBQ_OP_NOT, $2); } + | '(' expr ')' { $$ = $2; } + | expr T_THUS expr { BINOP($$, $1, PCBQ_OP_THUS, $3); } + | expr T_AND expr { BINOP($$, $1, PCBQ_OP_AND, $3); } + | expr T_OR expr { BINOP($$, $1, PCBQ_OP_OR, $3); } + | expr T_EQ expr { BINOP($$, $1, PCBQ_OP_EQ, $3); } + | expr T_NEQ expr { BINOP($$, $1, PCBQ_OP_NEQ, $3); } + | expr T_GTEQ expr { BINOP($$, $1, PCBQ_OP_GTEQ, $3); } + | expr T_LTEQ expr { BINOP($$, $1, PCBQ_OP_LTEQ, $3); } + | expr '>' expr { BINOP($$, $1, PCBQ_OP_GT, $3); } + | expr '<' expr { BINOP($$, $1, PCBQ_OP_LT, $3); } + | expr '+' expr { BINOP($$, $1, PCBQ_OP_ADD, $3); } + | expr '-' expr { BINOP($$, $1, PCBQ_OP_SUB, $3); } + | expr '*' expr { BINOP($$, $1, PCBQ_OP_MUL, $3); } + | expr '/' expr { BINOP($$, $1, PCBQ_OP_DIV, $3); } + | expr '~' T_STR { BINOP($$, $1, PCBQ_OP_MATCH, make_regex_free($3)); } + | expr '~' T_QSTR { BINOP($$, $1, PCBQ_OP_MATCH, make_regex_free($3)); } + | T_CONST { $$ = $1; } + | var { $$ = $1; } + | constant { $$ = $1; } + | expr '.' fields { + pcb_qry_node_t *n; + $$ = pcb_qry_n_alloc(PCBQ_FIELD_OF); + $$->data.children = $1; + $1->next = $3; + $1->parent = $$; + for(n = $3; n != NULL; n = n->next) + n->parent = $$; + } + ; + +number: + T_INT maybe_unit { $$ = pcb_qry_n_alloc(PCBQ_DATA_COORD); UNIT_CONV($$->data.crd, 0, $1, $2); } + | T_DBL maybe_unit { $$ = pcb_qry_n_alloc(PCBQ_DATA_DOUBLE); UNIT_CONV($$->data.dbl, 0, $1, $2); } + | '-' T_INT maybe_unit { $$ = pcb_qry_n_alloc(PCBQ_DATA_COORD); UNIT_CONV($$->data.crd, 1, $2, $3); } + | '-' T_DBL maybe_unit { $$ = pcb_qry_n_alloc(PCBQ_DATA_DOUBLE); UNIT_CONV($$->data.dbl, 1, $2, $3); } + ; + +string_literal: + T_QSTR { $$ = pcb_qry_n_alloc(PCBQ_DATA_STRING); $$->data.str = $1; } + ; + +maybe_unit: + /* empty */ { $$ = NULL; } + | T_UNIT { $$ = $1; } + ; + +fields: + T_STR { $$ = pcb_qry_n_alloc(PCBQ_FIELD); $$->data.str = $1; $$->precomp.fld = query_fields_sphash($1); } + | T_STR '.' fields { $$ = pcb_qry_n_alloc(PCBQ_FIELD); $$->data.str = $1; $$->precomp.fld = query_fields_sphash($1); $$->next = $3; } + | '(' T_INT ')' { $$ = pcb_qry_n_alloc(PCBQ_DATA_CONST); $$->precomp.iconst =$2; } + | '(' T_INT ')' '.' fields { $$ = pcb_qry_n_alloc(PCBQ_DATA_CONST); $$->precomp.iconst = $2; $$->next = $5; } + | T_FLD_P fields { $$ = $2; /* just ignore .p. */ } + | T_FLD_A attribs { $$ = pcb_qry_n_alloc(PCBQ_FIELD); $$->data.str = rnd_strdup("a"); $$->precomp.fld = query_fields_sphash("a"); $$->next = $2; } + ; + +attribs: + T_STR { $$ = pcb_qry_n_alloc(PCBQ_FIELD); $$->data.str = $1; } + | T_STR '.' attribs { $$ = pcb_qry_n_alloc(PCBQ_FIELD); $$->data.str = attrib_prepend_free((char *)$3->data.str, $1, '.'); } + | T_QSTR { $$ = pcb_qry_n_alloc(PCBQ_FIELD); $$->data.str = $1; } + ; + +let: + T_LET + { + iter_active_ctx = calloc(sizeof(vti0_t), 1); + } + T_STR expr + { + pcb_qry_node_t *nd; + $$ = pcb_qry_n_alloc(PCBQ_LET); + $$->precomp.it_active = iter_active_ctx; + iter_active_ctx = NULL; + pcb_qry_n_insert($$, $4); + nd = pcb_qry_n_alloc(PCBQ_VAR); + nd->data.crd = pcb_qry_iter_var(iter_ctx, $3, 1); + pcb_qry_n_insert($$, nd); + free($3); + } + ; + +assert: + T_ASSERT + { + iter_active_ctx = calloc(sizeof(vti0_t), 1); + } + expr + { + $$ = pcb_qry_n_alloc(PCBQ_ASSERT); + $$->precomp.it_active = iter_active_ctx; + iter_active_ctx = NULL; + pcb_qry_n_insert($$, $3); + } + ; + +freturn: + T_RETURN + { + iter_active_ctx = calloc(sizeof(vti0_t), 1); + } + expr + { + $$ = pcb_qry_n_alloc(PCBQ_RETURN); + $$->precomp.it_active = iter_active_ctx; + iter_active_ctx = NULL; + pcb_qry_n_insert($$, $3); + } + ; + +var: + T_STR { $$ = pcb_qry_n_alloc(PCBQ_VAR); $$->data.crd = pcb_qry_iter_var(iter_ctx, $1, 1); if (iter_active_ctx != NULL) vti0_set(iter_active_ctx, $$->data.crd, 1); free($1); } + | T_LIST '(' '@' ')' { $$ = pcb_qry_n_alloc(PCBQ_LISTVAR); $$->data.str = rnd_strdup("@"); /* delibertely not setting iter_active, list() protects against turning it into an iterator */ } + | T_LIST '(' T_STR ')' { $$ = pcb_qry_n_alloc(PCBQ_LISTVAR); $$->data.str = $3; /* delibertely not setting iter_active, list() protects against turning it into an iterator */ } + | '@' { $$ = pcb_qry_n_alloc(PCBQ_VAR); $$->data.crd = pcb_qry_iter_var(iter_ctx, "@", 1); if (iter_active_ctx != NULL) vti0_set(iter_active_ctx, $$->data.crd, 1); } + ; + +/* $foo is shorthand for getconf("design/drc/foo") */ +constant: + '$' T_STR + { + pcb_qry_node_t *fname, *nname; + + nname = pcb_qry_n_alloc(PCBQ_DATA_STRING); + nname->data.str = rnd_concat("design/drc/", $2, NULL); + free($2); + + fname = pcb_qry_n_alloc(PCBQ_FNAME); + fname->data.str = NULL; + fname->precomp.fnc.bui = pcb_qry_fnc_lookup("getconf"); + + $$ = pcb_qry_n_alloc(PCBQ_FCALL); + fname->parent = nname->parent = $$; + $$->data.children = fname; + $$->data.children->next = nname; + } + ; + +fcall: + fcallname '(' fargs ')' { $$ = pcb_qry_n_alloc(PCBQ_FCALL); $$->data.children = $1; $$->data.children->next = $3; $1->parent = $3->parent = $$; } + | fcallname '(' ')' { $$ = pcb_qry_n_alloc(PCBQ_FCALL); $$->data.children = $1; $1->parent = $$; } + ; + +fcallname: + T_STR { + $$ = pcb_qry_n_alloc(PCBQ_FNAME); + $$->precomp.fnc.bui = pcb_qry_fnc_lookup($1); + if ($$->precomp.fnc.bui != NULL) { + /* builtin function */ + free($1); + $$->data.str = NULL; + } + else + $$->data.str = $1; /* user function: save the name */ + } + ; + + +fargs: + expr { $$ = $1; } + | expr ',' fargs { $$ = $1; $$->next = $3; } + ; + + +fdefarg: + T_STR { + $$ = pcb_qry_n_alloc(PCBQ_ARG); + $$->data.crd = pcb_qry_iter_var(iter_ctx, $1, 1); + } + ; + +fdefargs: + fdefarg { $$ = $1; } + | fdefarg ',' fdefarg { $$ = $1; $$->next = $3; } + ; + +fdefname: + T_STR { + $$ = pcb_qry_n_alloc(PCBQ_FNAME); + $$->data.str = $1; + } + ; + +fdef_: + '(' fdefargs ')' { $$ = $2; } + | '(' ')' { $$ = NULL; } + ; + +fdef: + T_FUNCTION fdefname + { iter_ctx = pcb_qry_iter_alloc(); } + fdef_ { + pcb_qry_node_t *nd; + + $$ = pcb_qry_n_alloc(PCBQ_FUNCTION); + + if ($4 != NULL) + pcb_qry_n_append($$, $4); + + pcb_qry_n_insert($$, $2); + + nd = pcb_qry_n_alloc(PCBQ_ITER_CTX); + nd->data.iter_ctx = iter_ctx; + pcb_qry_n_insert($$, nd); + + if (user_funcs == NULL) + user_funcs = htsp_alloc(strhash, strkeyeq); + htsp_set(user_funcs, (char *)$2->data.str, $$); + } + ; +words: + /* empty */ { $$ = pcb_qry_n_alloc(PCBQ_RNAME); $$->data.str = (const char *)rnd_strdup(""); } + | T_STR words { + char *old = (char *)$2->data.str, *sep = ((*old != '\0') ? " " : ""); + $2->data.str = rnd_concat($1, sep, old, NULL); + free(old); + free($1); + $$ = $2; + } + ; Index: tags/1.0.5/src/plugins/renumber/Makefile =================================================================== --- tags/1.0.5/src/plugins/renumber/Makefile (nonexistent) +++ tags/1.0.5/src/plugins/renumber/Makefile (revision 10414) @@ -0,0 +1,2 @@ +all: + cd ../../sch-rnd && make mod_renumber Index: tags/1.0.5/src/plugins/renumber/Plug.tmpasm =================================================================== --- tags/1.0.5/src/plugins/renumber/Plug.tmpasm (nonexistent) +++ tags/1.0.5/src/plugins/renumber/Plug.tmpasm (revision 10414) @@ -0,0 +1,14 @@ +put /local/rnd/mod {renumber} +put /local/rnd/mod/OBJS [@ + $(PLUGDIR)/renumber/renumber.o +@] + +put /local/rnd/mod/CONFFILE {renumber.conf} +put /local/rnd/mod/CONF {$(PLUGDIR)/renumber/renumber_conf.h} +put /local/rnd/mod/CONFVAR {renumber_conf_internal} + +switch /local/module/renumber/controls + case {buildin} include /local/csch/tmpasm/buildin; end; + case {plugin} include /local/csch/tmpasm/plugin; end; + case {disable} include /local/csch/tmpasm/disable; end; +end Index: tags/1.0.5/src/plugins/renumber/renumber.c =================================================================== --- tags/1.0.5/src/plugins/renumber/renumber.c (nonexistent) +++ tags/1.0.5/src/plugins/renumber/renumber.c (revision 10414) @@ -0,0 +1,174 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - renumber symbols + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "renumber_conf.h" +#include "conf_internal.c" + +static conf_renumber_t renumber_conf; + +static const char renumber_cookie[] = "renumber"; + +typedef struct renumber_s { + csch_sheet_t *sheet; + vtp0_t objs; /* all objects (eventually sorted array) */ + htsp_t name2sym; /* key: (const char *)name, val: (csch_cgrp_t *)sym */ + htsi_t next; /* next integer per prefix */ + int base; /* start numbering from */ + const char *sorta; + unsigned selected:1; /* renumber selected only */ + unsigned inprj:1; /* operate on the whole project */ +} renumber_t; + +#include "renumber_impl.c" +#include "renumber_dlg.c" + +const char csch_acts_Renumber[] = "Renumber(Selected|All|SelectedProject|AllProject, lr|rl|tb|bt, [base])\n"; +const char csch_acth_Renumber[] = "Rename (renumber) selected or all symbols on current sheet or on all sheets of the project. Second argument is the direction of numbering (e.g. rl means right-to-left). If base is specified, it is an integer and is the first number assigned. Non-numerical name prefix is preserved (R, C, etc.)"; +fgw_error_t csch_act_Renumber(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_design_t *hl = RND_ACT_DESIGN; + csch_sheet_t *sheet = (csch_sheet_t *)hl; + int cmd, rv = -1; + renumber_t rctx = {0}; + const char *sorta; + + rctx.base = 1; + + RND_ACT_CONVARG(1, FGW_KEYWORD, Renumber, cmd = fgw_keyword(&argv[1])); + RND_ACT_CONVARG(2, FGW_STR, Renumber, sorta = argv[2].val.str); + RND_ACT_MAY_CONVARG(3, FGW_INT, Renumber, rctx.base = argv[3].val.nat_int); + + htsp_init(&rctx.name2sym, strhash, strkeyeq); + htsi_init(&rctx.next, strhash, strkeyeq); + rctx.sheet = sheet; + rctx.sorta = sorta; + + switch(cmd) { + case F_Selected: + rctx.selected = 1; + break; + case F_SelectedProject: + rctx.selected = 1; + rctx.inprj = 1; + break; + case F_All: + break; + case F_AllProject: + rctx.inprj = 1; + break; + default: + rnd_message(RND_MSG_ERROR, "Renumber: invalid first argument\n"); + goto error; + } + + renumber_list_objs(&rctx); + if (rctx.objs.used == 0) { + rnd_message(RND_MSG_ERROR, "Renumber: no symbols %s to renumber\n", rctx.selected ? "selected" : "on sheet"); + goto error; + } + + rv = 0; + + if (renumber_sort(&rctx) != 0) { + rnd_message(RND_MSG_ERROR, "Renumber: invalid sorting algorithm '%s'\n", rctx.sorta); + goto error; + } + + renumber_objs(&rctx); + csch_sheet_set_changed(sheet, 1); + + error:; + htsp_uninit(&rctx.name2sym); + genht_uninit_deep(htsi, &rctx.next, { + free(htent->key); + }); + vtp0_uninit(&rctx.objs); + + RND_ACT_IRES(rv); + return 0; +} + +const char csch_acts_RenumberDialog[] = "RenumberDialog()\n"; +const char csch_acth_RenumberDialog[] = "Open the graphical frontend dialog box for the Renumber() action. The dialog box is single instance and non-modal."; +fgw_error_t csch_act_RenumberDialog(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + sch_rnd_dlg_renumdlg(); + return 0; +} + +static rnd_action_t renumber_action_list[] = { + {"Renumber", csch_act_Renumber, csch_acth_Renumber, csch_acts_Renumber}, + {"RenumberDialog", csch_act_RenumberDialog, csch_acth_RenumberDialog, csch_acts_RenumberDialog} +}; + +int pplg_check_ver_renumber(int ver_needed) { return 0; } + +void pplg_uninit_renumber(void) +{ + rnd_remove_actions_by_cookie(renumber_cookie); + rnd_conf_plug_unreg("plugins/renumber/", renumber_conf_internal, renumber_cookie); +} + +int pplg_init_renumber(void) +{ + RND_API_CHK_VER; + + RND_REGISTER_ACTIONS(renumber_action_list, renumber_cookie); + + rnd_conf_plug_reg(renumber_conf, renumber_conf_internal, renumber_cookie); +#define conf_reg(field,isarray,type_name,cpath,cname,desc,flags) \ + rnd_conf_reg_field(renumber_conf, field,isarray,type_name,cpath,cname,desc,flags); +#include "renumber_conf_fields.h" + + return 0; +} + Index: tags/1.0.5/src/plugins/renumber/renumber.conf =================================================================== --- tags/1.0.5/src/plugins/renumber/renumber.conf (nonexistent) +++ tags/1.0.5/src/plugins/renumber/renumber.conf (revision 10414) @@ -0,0 +1,9 @@ +li:pcb-rnd-conf-v1 { + ha:append { + ha:plugins { + ha:renumber { + todo = 1 + } + } + } +} Index: tags/1.0.5/src/plugins/renumber/renumber.pup =================================================================== --- tags/1.0.5/src/plugins/renumber/renumber.pup (nonexistent) +++ tags/1.0.5/src/plugins/renumber/renumber.pup (revision 10414) @@ -0,0 +1,7 @@ +$class feature +$short renumber symbols +$long Systematically change the name of selected symbols +$state works +$package (core) +default buildin +autoload 1 Index: tags/1.0.5/src/plugins/renumber/renumber_conf.h =================================================================== --- tags/1.0.5/src/plugins/renumber/renumber_conf.h (nonexistent) +++ tags/1.0.5/src/plugins/renumber/renumber_conf.h (revision 10414) @@ -0,0 +1,14 @@ +#ifndef SCH_RND_RENUMBER_CONF_H +#define SCH_RND_RENUMBER_CONF_H + +#include + +typedef struct { + const struct { + const struct { + RND_CFT_BOOLEAN todo; + } renumber; + } plugins; +} conf_renumber_t; + +#endif Index: tags/1.0.5/src/plugins/renumber/renumber_dlg.c =================================================================== --- tags/1.0.5/src/plugins/renumber/renumber_dlg.c (nonexistent) +++ tags/1.0.5/src/plugins/renumber/renumber_dlg.c (revision 10414) @@ -0,0 +1,120 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - renumber dialog + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include + +#include +#include +#include +#include +#include + +#include + +static const char *scope_names[] = {"all on sheet", "selected on sheet", "all in project", "selected in project", NULL}; +static const char *scopes[] = {"all", "selected", "allProject", "selectedProject", NULL}; +static const char *sorts[] = {"left->right (top->bottom within)", "right->left (top->bottom within)", "top->bottom (left->right within)", "bottom->top (left->right within)", NULL }; +static const char *sorts2[] = {"lr", "rl", "tb", "bt", NULL}; + +typedef struct{ + RND_DAD_DECL_NOINIT(dlg) + int wscope, wsort, wbase; + int active; /* already open - allow only one instance */ +} renumdlg_ctx_t; + +static renumdlg_ctx_t renumdlg_ctx; + +static void renumdlg_close_cb(void *caller_data, rnd_hid_attr_ev_t ev) +{ + renumdlg_ctx_t *ctx = caller_data; + RND_DAD_FREE(ctx->dlg); + memset(ctx, 0, sizeof(renumdlg_ctx_t)); /* reset all states to the initial - includes ctx->active = 0; */ +} + +static void renum_dlg_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr_btn) +{ + rnd_design_t *hl = rnd_multi_get_current(); + fgw_arg_t res, argv[5]; + + argv[1].type = FGW_STR; argv[1].val.cstr = scopes[renumdlg_ctx.dlg[renumdlg_ctx.wscope].val.lng]; + argv[2].type = FGW_STR; argv[2].val.cstr = sorts2[renumdlg_ctx.dlg[renumdlg_ctx.wsort].val.lng]; + argv[3].type = FGW_INT; argv[3].val.nat_int = renumdlg_ctx.dlg[renumdlg_ctx.wbase].val.lng; + rnd_actionv_bin(hl, "renumber", &res, 4, argv); + fgw_arg_free(&rnd_fgw, &res); +} + + +static void sch_rnd_dlg_renumdlg(void) +{ + rnd_hid_dad_buttons_t clbtn[] = {{"Close", 0}, {NULL, 0}}; + static const char *hscope = "Operate on which symbols"; + static const char *hsort = "Ascending order of numbers assigned"; + static const char *hbase = "First number assigned per prefix\ne.g. a value of 100 means resistors\nare numbered from R100"; + + if (renumdlg_ctx.active) + return; + + RND_DAD_BEGIN_VBOX(renumdlg_ctx.dlg); + RND_DAD_COMPFLAG(renumdlg_ctx.dlg, RND_HATF_EXPFILL); + RND_DAD_BEGIN_HBOX(renumdlg_ctx.dlg); + RND_DAD_LABEL(renumdlg_ctx.dlg, "Scope:"); + RND_DAD_HELP(renumdlg_ctx.dlg, hscope); + RND_DAD_ENUM(renumdlg_ctx.dlg, scope_names); + renumdlg_ctx.wscope = RND_DAD_CURRENT(renumdlg_ctx.dlg); + RND_DAD_HELP(renumdlg_ctx.dlg, hscope); + RND_DAD_END(renumdlg_ctx.dlg); + RND_DAD_BEGIN_HBOX(renumdlg_ctx.dlg); + RND_DAD_LABEL(renumdlg_ctx.dlg, "Sort:"); + RND_DAD_HELP(renumdlg_ctx.dlg, hsort); + RND_DAD_ENUM(renumdlg_ctx.dlg, sorts); + renumdlg_ctx.wsort = RND_DAD_CURRENT(renumdlg_ctx.dlg); + RND_DAD_HELP(renumdlg_ctx.dlg, hsort); + RND_DAD_END(renumdlg_ctx.dlg); + RND_DAD_BEGIN_HBOX(renumdlg_ctx.dlg); + RND_DAD_LABEL(renumdlg_ctx.dlg, "Base:"); + RND_DAD_HELP(renumdlg_ctx.dlg, hbase); + RND_DAD_INTEGER(renumdlg_ctx.dlg); + RND_DAD_DEFAULT_NUM(renumdlg_ctx.dlg, 1); + renumdlg_ctx.wbase = RND_DAD_CURRENT(renumdlg_ctx.dlg); + RND_DAD_HELP(renumdlg_ctx.dlg, hbase); + RND_DAD_END(renumdlg_ctx.dlg); + + RND_DAD_BEGIN_HBOX(renumdlg_ctx.dlg); + RND_DAD_BEGIN_HBOX(renumdlg_ctx.dlg); + RND_DAD_COMPFLAG(renumdlg_ctx.dlg, RND_HATF_EXPFILL); + RND_DAD_END(renumdlg_ctx.dlg); + RND_DAD_BUTTON(renumdlg_ctx.dlg, "Renumber!"); + RND_DAD_CHANGE_CB(renumdlg_ctx.dlg, renum_dlg_cb); + RND_DAD_BUTTON_CLOSES(renumdlg_ctx.dlg, clbtn); + RND_DAD_END(renumdlg_ctx.dlg); + RND_DAD_END(renumdlg_ctx.dlg); + + /* set up the context */ + renumdlg_ctx.active = 1; + + RND_DAD_NEW("renumdlg", renumdlg_ctx.dlg, "Renumber (rename) symbols", &renumdlg_ctx, rnd_false, renumdlg_close_cb); /* type=global */ +} + Index: tags/1.0.5/src/plugins/renumber/renumber_impl.c =================================================================== --- tags/1.0.5/src/plugins/renumber/renumber_impl.c (nonexistent) +++ tags/1.0.5/src/plugins/renumber/renumber_impl.c (revision 10414) @@ -0,0 +1,195 @@ +static const char *refdes(const csch_cgrp_t *g) +{ + return csch_attrib_get_str(&g->attr, "name"); +} + +static void renumber_list_objs_sheet(renumber_t *rctx, csch_sheet_t *sheet) +{ + htip_entry_t *e; + + for(e = htip_first(&sheet->direct.id2obj); e != NULL; e = htip_next(&sheet->direct.id2obj, e)) { + csch_cgrp_t *g = e->value; + const char *r; + + if (!csch_obj_is_grp(&g->hdr) || (g->role != CSCH_ROLE_SYMBOL)) + continue; + + r = refdes(g); + + /* unnamed symbols shouldn't be named by renumber - the user did not + want these symbols to be on the output */ + if (r == NULL) + continue; + + htsp_insert(&rctx->name2sym, (char *)r, g); + if (!rctx->selected || g->hdr.selected) { + vtp0_append(&rctx->objs, g); + g->hdr.mark = 1; /* objects we are going to change are marked */ + } + } +} + +static void renumber_list_objs(renumber_t *rctx) +{ + if (rctx->inprj) { + rnd_project_t *prj = rctx->sheet->hidlib.project; + long n; + for(n = 0; n < prj->designs.used; n++) + renumber_list_objs_sheet(rctx, prj->designs.array[n]); + } + else + renumber_list_objs_sheet(rctx, rctx->sheet); +} + + +static int cmp_tb(const void *v1, const void *v2); + +static int cmp_lr(const void *v1, const void *v2) +{ + const csch_cgrp_t **s1 = (const csch_cgrp_t **)v1, **s2 = (const csch_cgrp_t **)v2; + csch_coord_t x1 = (*s1)->hdr.bbox.x1 + (*s1)->hdr.bbox.x2, x2 = (*s2)->hdr.bbox.x1 + (*s2)->hdr.bbox.x2; + if ((*s1)->hdr.sheet->uid < (*s2)->hdr.sheet->uid) return -1; + if ((*s1)->hdr.sheet->uid > (*s2)->hdr.sheet->uid) return +1; + if (x1 == x2) return cmp_tb(v1, v2); + return (x1 > x2); +} + + +static int cmp_rl(const void *v1, const void *v2) +{ + const csch_cgrp_t **s1 = (const csch_cgrp_t **)v1, **s2 = (const csch_cgrp_t **)v2; + csch_coord_t x1 = (*s1)->hdr.bbox.x1 + (*s1)->hdr.bbox.x2, x2 = (*s2)->hdr.bbox.x1 + (*s2)->hdr.bbox.x2; + if ((*s1)->hdr.sheet->uid < (*s2)->hdr.sheet->uid) return -1; + if ((*s1)->hdr.sheet->uid > (*s2)->hdr.sheet->uid) return +1; + if (x1 == x2) return cmp_tb(v1, v2); + return (x1 < x2); +} + +static int cmp_tb(const void *v1, const void *v2) +{ + const csch_cgrp_t **s1 = (const csch_cgrp_t **)v1, **s2 = (const csch_cgrp_t **)v2; + csch_coord_t y1 = (*s1)->hdr.bbox.y1 + (*s1)->hdr.bbox.y2, y2 = (*s2)->hdr.bbox.y1 + (*s2)->hdr.bbox.y2; + if ((*s1)->hdr.sheet->uid < (*s2)->hdr.sheet->uid) return -1; + if ((*s1)->hdr.sheet->uid > (*s2)->hdr.sheet->uid) return +1; + if (y1 == y2) return cmp_lr(v1, v2); + return (y1 < y2); +} + +static int cmp_bt(const void *v1, const void *v2) +{ + const csch_cgrp_t **s1 = (const csch_cgrp_t **)v1, **s2 = (const csch_cgrp_t **)v2; + csch_coord_t y1 = (*s1)->hdr.bbox.y1 + (*s1)->hdr.bbox.y2, y2 = (*s2)->hdr.bbox.y1 + (*s2)->hdr.bbox.y2; + if ((*s1)->hdr.sheet->uid < (*s2)->hdr.sheet->uid) return -1; + if ((*s1)->hdr.sheet->uid > (*s2)->hdr.sheet->uid) return +1; + if (y1 == y2) return cmp_lr(v1, v2); + return (y1 > y2); +} + + +static int renumber_sort(renumber_t *rctx) +{ + int (*cmp)(const void *sym1, const void *sym2); + + if (strcmp(rctx->sorta, "lr") == 0) cmp = cmp_lr; + else if (strcmp(rctx->sorta, "rl") == 0) cmp = cmp_rl; + else if (strcmp(rctx->sorta, "tb") == 0) cmp = cmp_tb; + else if (strcmp(rctx->sorta, "bt") == 0) cmp = cmp_bt; + else + return -1; + + qsort(rctx->objs.array, rctx->objs.used, sizeof(csch_cgrp_t *), cmp); + return 0; +} + +/* renders next available refdes for prefix in prefix */ +static void set_next_num(renumber_t *rctx, char *prefix, char *flex) +{ + htsi_entry_t *e; + int n; + + + e = htsi_getentry(&rctx->next, prefix); + if (e == NULL) { + htsi_set(&rctx->next, rnd_strdup(prefix), rctx->base); + e = htsi_getentry(&rctx->next, prefix); + } + + for(n = 0; n < 32767; n++) { + csch_cgrp_t *user; + + sprintf(flex, "%d", e->value); + e->value++; + + user = htsp_get(&rctx->name2sym, prefix); + if ((user == NULL) || user->hdr.mark) /* unused or used by something we are going to rename anyway */ + return; /* accept this name */ + } + strcpy(flex, "??"); /* ran out of numbers... shouldn't happen */ +} + +static int renumber_sym(renumber_t *rctx, csch_cgrp_t *sym) +{ + csch_source_arg_t *src; + char *end, *r; + const char *orig = refdes(sym); + int len = strlen(orig); + + r = malloc(len + 16); /* enough room for appending %ld */ + memcpy(r, orig, len+1); + + end = r + len - 1; + while((end >= r) && ((*end == '?') || isdigit(*end))) end--; + + if (end < r) { + r[0] = 'U'; + r[1] = '\0'; + end = r+1; + } + else { + end++; + *end = '\0'; + } + + set_next_num(rctx, r, end); + src = csch_attrib_src_p("renumber", "Renumber()"); + + csch_attr_modify_str(sym->hdr.sheet, sym, CSCH_ATP_USER_DEFAULT, "name", r, src, 1); + free(r); + return 0; +} + +static int renumber_objs(renumber_t *rctx) +{ + long n; + rnd_project_t *prj = rctx->sheet->hidlib.project; + + if (rctx->inprj) { + for(n = 0; n < prj->designs.used; n++) { + csch_sheet_t *sheet = prj->designs.array[n]; + uundo_freeze_serial(&sheet->undo); + } + } + else + uundo_freeze_serial(&rctx->sheet->undo); + + for(n = 0; n < rctx->objs.used; n++) + renumber_sym(rctx, rctx->objs.array[n]); + + if (rctx->inprj) { + for(n = 0; n < prj->designs.used; n++) { + csch_sheet_t *sheet = prj->designs.array[n]; + uundo_unfreeze_serial(&sheet->undo); + uundo_inc_serial(&sheet->undo); + } + } + else { + uundo_unfreeze_serial(&rctx->sheet->undo); + uundo_inc_serial(&rctx->sheet->undo); + } + + for(n = 0; n < rctx->objs.used; n++) { + csch_cgrp_t *g = rctx->objs.array[n]; + g->hdr.mark = 0; + } + return 0; +} Index: tags/1.0.5/src/plugins/sch_dialogs/Makefile =================================================================== --- tags/1.0.5/src/plugins/sch_dialogs/Makefile (nonexistent) +++ tags/1.0.5/src/plugins/sch_dialogs/Makefile (revision 10414) @@ -0,0 +1,2 @@ +all: + cd ../../sch-rnd && make mod_sch_dialogs Index: tags/1.0.5/src/plugins/sch_dialogs/Plug.tmpasm =================================================================== --- tags/1.0.5/src/plugins/sch_dialogs/Plug.tmpasm (nonexistent) +++ tags/1.0.5/src/plugins/sch_dialogs/Plug.tmpasm (revision 10414) @@ -0,0 +1,29 @@ +put /local/rnd/mod {sch_dialogs} +put /local/rnd/mod/OBJS [@ + $(PLUGDIR)/sch_dialogs/sch_dialogs.o + $(PLUGDIR)/sch_dialogs/dlg_about.o + $(PLUGDIR)/sch_dialogs/dlg_undo.o + $(PLUGDIR)/sch_dialogs/dlg_pref_apptab.o + $(PLUGDIR)/sch_dialogs/dlg_pen.o + $(PLUGDIR)/sch_dialogs/dlg_text.o + $(PLUGDIR)/sch_dialogs/dlg_tree.o + $(PLUGDIR)/sch_dialogs/dlg_library.o + $(PLUGDIR)/sch_dialogs/dlg_attrib.o + $(PLUGDIR)/sch_dialogs/dlg_stance.o + $(PLUGDIR)/sch_dialogs/dlg_cond.o + $(PLUGDIR)/sch_dialogs/dlg_abstract.o + $(PLUGDIR)/sch_dialogs/dlg_view.o + $(PLUGDIR)/sch_dialogs/dlg_project.o + $(PLUGDIR)/sch_dialogs/quick_attr.o + $(PLUGDIR)/sch_dialogs/abst_attr.o +@] + +put /local/rnd/mod/CONFFILE {adialogs.conf} +put /local/rnd/mod/CONF {$(PLUGDIR)/sch_dialogs/adialogs_conf.h} +put /local/rnd/mod/CONFVAR {adialogs_conf_internal} + +switch /local/module/sch_dialogs/controls + case {buildin} include /local/csch/tmpasm/buildin; end; + case {plugin} include /local/csch/tmpasm/plugin; end; + case {disable} include /local/csch/tmpasm/disable; end; +end Index: tags/1.0.5/src/plugins/sch_dialogs/abst_attr.c =================================================================== --- tags/1.0.5/src/plugins/sch_dialogs/abst_attr.c (nonexistent) +++ tags/1.0.5/src/plugins/sch_dialogs/abst_attr.c (revision 10414) @@ -0,0 +1,325 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - GUI - abstract model + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "abst_attr.h" + +void aattr_dlg_ahist2dlg(abst_attrdlg_ctx_t *actx, csch_ahdr_t *aobj) +{ + rnd_hid_attribute_t *aattr = &(*actx->dlg)[actx->waattrs]; + rnd_hid_attribute_t *hattr = &(*actx->dlg)[actx->wahistory]; + rnd_hid_tree_t *htree = hattr->wdata; + rnd_hid_row_t *r, *bestr = NULL; + const char *aattr_name = NULL; + long best = 65537; + const char *export_name = NULL; + rnd_hid_attr_val_t hv; + + /* get abstract attr selected */ + r = rnd_dad_tree_get_selected(aattr); + if (r != NULL) + aattr_name = r->cell[0]; + + /* remove existing items */ + rnd_dad_tree_clear(htree); + + if (aattr_name != NULL) { + if (aobj != NULL) { + csch_attrib_t *a = csch_attrib_get(&aobj->attr, aattr_name); + long n, v; + char *cell[2]; + + export_name = a->export_name; /* side effect: display export name later */ + + cell[1] = NULL; + for(n = 0; n < a->source.used; n++) { + cell[0] = rnd_strdup(a->source.array[n]); + r = rnd_dad_tree_append(hattr, NULL, cell); + v = strtol(cell[0], NULL, 0); + if (v < best) { + best = v; + bestr = r; + } + } + } + } + + if (bestr != NULL) { + hv.str = bestr->path; + rnd_gui->attr_dlg_set_value(*actx->dlg_hid_ctx, actx->wahistory, &hv); + } + + /* side effect: display export name */ + hv.str = (export_name == NULL) ? "" : export_name; + rnd_gui->attr_dlg_set_value(*actx->dlg_hid_ctx, actx->wexport_name, &hv); +} + +static void aattr_dlg_sheet2dlg_abst_net(abst_attrdlg_ctx_t *actx, csch_anet_t *anet) +{ + rnd_hid_attribute_t *attr = &((*actx->dlg)[actx->wdetailtree]); + rnd_hid_tree_t *tree = attr->wdata; + char *cell[2]; + gds_t tmp = {0}; + long n; + + /* remove existing items */ + rnd_dad_tree_clear(tree); + + cell[1] = NULL; + for(n = 0; n < anet->conns.used; n++) { + csch_aport_t *p = anet->conns.array[n]; + + if (p->hdr.type == CSCH_ATYPE_PORT) { + csch_acomp_t *c = p->parent; + + if (c == NULL) { + const char *remark = NULL; + tmp.used = 0; + + if (p->referer != NULL) { /* hierarchic: this is a sheet port on a subsheet instance */ + gds_append(&tmp, '('); + gds_append_str(&tmp, p->referer->name); + gds_append(&tmp, '-'); + remark = ") subsheet port"; + } + else { + gds_append_str(&tmp, "?????"); + gds_append(&tmp, '-'); + } + gds_append_str(&tmp, p->name); + if (remark != NULL) + gds_append_str(&tmp, remark); + cell[0] = rnd_strdup(tmp.array); + } + else if (c->hdr.type == CSCH_ATYPE_COMP) { + tmp.used = 0; + if (c->hdr.omit) + gds_append(&tmp, '('); + gds_append_str(&tmp, c->name); + gds_append(&tmp, '-'); + gds_append_str(&tmp, p->name); + if (c->hdr.omit) + gds_append_str(&tmp, ") omitted"); + cell[0] = rnd_strdup(tmp.array); + } + else + cell[0] = rnd_strdup(p->name); + + rnd_dad_tree_append(attr, NULL, cell); + } + } + + gds_uninit(&tmp); +} + +void aattr_dlg_sheet2dlg_abstract(abst_attrdlg_ctx_t *actx, csch_ahdr_t *a) +{ + rnd_hid_attr_val_t hv; + rnd_hid_attribute_t *attr = &((*actx->dlg)[actx->waattrs]); + rnd_hid_tree_t *tree = attr->wdata; + rnd_hid_row_t *r; + char *cursor_path = NULL; + char name_tmp[256]; + + actx->last_ahdr = a; + + /* remember cursor */ + r = rnd_dad_tree_get_selected(attr); + if (r != NULL) + cursor_path = rnd_strdup(r->cell[0]); + + /* remove existing items */ + rnd_dad_tree_clear(tree); + + if (a != NULL) { + char *cell[3]; + vtp0_t tmp = {0}; + long n; + + /* add all items recursively */ + csch_attrib_sort(&tmp, &a->attr); + + for(n = 0; n < tmp.used; n++) { + csch_attrib_t *a = tmp.array[n]; + cell[0] = rnd_strdup(a->key); + if (a->val != NULL) + cell[1] = rnd_strdup(a->val); + else + cell[1] = rnd_strdup(""); + cell[2] = NULL; + r = rnd_dad_tree_append(attr, NULL, cell); + } + vtp0_uninit(&tmp); + hv.str = name_tmp; + switch(a->type) { + case CSCH_ATYPE_NET: rnd_snprintf(name_tmp, sizeof(name_tmp), "%s (net)", ((csch_anet_t *)a)->name); break; + case CSCH_ATYPE_PORT: rnd_snprintf(name_tmp, sizeof(name_tmp), "%s (port)", ((csch_aport_t *)a)->name); break; + case CSCH_ATYPE_COMP: rnd_snprintf(name_tmp, sizeof(name_tmp), "%s (component)", ((csch_acomp_t *)a)->name); break; + case CSCH_ATYPE_BUSNET: + case CSCH_ATYPE_BUSCHAN: + case CSCH_ATYPE_BUSPORT: + case CSCH_ATYPE_HUB: hv.str = "other"; break; /* these are not yet supported */ + case CSCH_ATYPE_INVALID: hv.str = ""; break; + } + } + else { + hv.str = ""; + } + rnd_gui->attr_dlg_set_value(*actx->dlg_hid_ctx, actx->waname, &hv); + + /* restore cursor */ + if (cursor_path != NULL) { + hv.str = cursor_path; + rnd_gui->attr_dlg_set_value(*actx->dlg_hid_ctx, actx->waattrs, &hv); + free(cursor_path); + aattr_dlg_ahist2dlg(actx, a); + } + + if (a == NULL) + goto hide_all; + + switch(a->type) { + case CSCH_ATYPE_NET: + hv.str = "Ports connected:"; + rnd_gui->attr_dlg_set_value(*actx->dlg_hid_ctx, actx->wdetaillab, &hv); + rnd_gui->attr_dlg_widget_hide(*actx->dlg_hid_ctx, actx->wdetaillab, 0); + rnd_gui->attr_dlg_widget_hide(*actx->dlg_hid_ctx, actx->wdetailtree, 0); + aattr_dlg_sheet2dlg_abst_net(actx, (csch_anet_t *)a); + break; + case CSCH_ATYPE_PORT: + { + gds_t tmp = {0}; + csch_aport_t *p = (csch_aport_t *)a; + + gds_append_str(&tmp, "Connected to:\n"); + if (p->conn.net != NULL) { + gds_append_str(&tmp, "net "); + gds_append_str(&tmp, p->conn.net->name); + } + else + gds_append_str(&tmp, ""); + + hv.str = tmp.array; + rnd_gui->attr_dlg_set_value(*actx->dlg_hid_ctx, actx->wdetaillab, &hv); + rnd_gui->attr_dlg_widget_hide(*actx->dlg_hid_ctx, actx->wdetaillab, 0); + gds_uninit(&tmp); + goto hide_all_but_lab; + } + default: + hide_all:; + rnd_gui->attr_dlg_widget_hide(*actx->dlg_hid_ctx, actx->wdetaillab, 1); + hide_all_but_lab:; + rnd_gui->attr_dlg_widget_hide(*actx->dlg_hid_ctx, actx->wdetailtree, 1); + break; + } +} + +void aattr_sources(abst_attrdlg_ctx_t *actx) +{ + if (actx->last_ahdr != NULL) { + fgw_arg_t args[4], ares; + rnd_design_t *hl; + csch_sheet_t *sheet = actx->prj->hdr.designs.array[0]; + + hl = &sheet->hidlib; + args[1].type = FGW_STR; args[1].val.str = "objarr"; + fgw_ptr_reg(&rnd_fgw, &args[2], CSCH_PTR_DOMAIN_COBJ_ARR, FGW_PTR | FGW_STRUCT, &actx->last_ahdr->srcs); + rnd_actionv_bin(hl, "TreeDialog", &ares, 3, args); + fgw_ptr_unreg(&rnd_fgw, &args[2], CSCH_PTR_DOMAIN_COBJ_ARR); + } +} + +void aattr_attr_src(abst_attrdlg_ctx_t *actx) +{ + csch_sheet_t *sheet = actx->prj->hdr.designs.array[0]; + rnd_design_t *hl= &sheet->hidlib; + fgw_arg_t args[4], ares; + rnd_hid_attribute_t *hattr = &(*actx->dlg)[actx->wahistory]; + rnd_hid_row_t *r = rnd_dad_tree_get_selected(hattr); + csch_chdr_t *cobj; + csch_ahdr_t *aobj; + char *attr; + const char *desc; + + if (r == NULL) + return; + rnd_trace("History button on: %s\n", r->cell[0]); + + if (csch_attrib_src_parse(sheet, r->cell[0], NULL, NULL, &cobj, &aobj, &attr, &desc) == 0) { + if (cobj != NULL) { + gds_t tmp = {0}; + csch_oidpath_t oidp = {0}; + + gds_append_str(&tmp, "object:"); + csch_oidpath_from_obj(&oidp, cobj); + csch_oidpath_to_str_append(&tmp, &oidp); + csch_oidpath_free(&oidp); + + args[1].type = FGW_STR | FGW_DYN; args[1].val.str = tmp.array; + args[2].type = FGW_STR; args[2].val.cstr = attr; + rnd_actionv_bin(hl, "AttributeDialog", &ares, 3, args); + fgw_arg_free(&rnd_fgw, &ares); + } + else if (aobj != NULL) { + args[1].type = FGW_LONG; args[1].val.nat_long = aobj->aid; + args[2].type = FGW_STR; args[2].val.cstr = attr; + rnd_actionv_bin(hl, "AbstractDialog", &ares, 3, args); + fgw_arg_free(&rnd_fgw, &ares); + } + } + free(attr); +} + +void aattr_dlg_select_attr(abst_attrdlg_ctx_t *actx, const char *attr_name) +{ + rnd_hid_attr_val_t hv; + hv.str = attr_name; + rnd_gui->attr_dlg_set_value(*actx->dlg_hid_ctx, actx->waattrs, &hv); + aattr_dlg_ahist2dlg(actx, actx->last_ahdr); +} + +void aattr_dlg_init(abst_attrdlg_ctx_t *actx) +{ + rnd_gui->attr_dlg_widget_hide(*actx->dlg_hid_ctx, actx->wdetailtree, 1); + rnd_gui->attr_dlg_widget_hide(*actx->dlg_hid_ctx, actx->wdetaillab, 1); +} + Index: tags/1.0.5/src/plugins/sch_dialogs/abst_attr.h =================================================================== --- tags/1.0.5/src/plugins/sch_dialogs/abst_attr.h (nonexistent) +++ tags/1.0.5/src/plugins/sch_dialogs/abst_attr.h (revision 10414) @@ -0,0 +1,132 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - GUI - abstract model + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include +#include + +typedef struct { + rnd_hid_attribute_t **dlg; + void **dlg_hid_ctx; + csch_project_t *prj; + csch_ahdr_t *last_ahdr; + int wright, waattrs, wahistory, waname; + int wdetaillab, wdetailtree, wexport_name; +} abst_attrdlg_ctx_t; + + +void aattr_dlg_ahist2dlg(abst_attrdlg_ctx_t *actx, csch_ahdr_t *aobj); +void aattr_dlg_sheet2dlg_abstract(abst_attrdlg_ctx_t *actx, csch_ahdr_t *a); + +/* Call this after the dialog is created */ +void aattr_dlg_init(abst_attrdlg_ctx_t *actx); + +/* Call this from aattr_sources_cb() */ +void aattr_sources(abst_attrdlg_ctx_t *actx); + +/* Call this from aattr_attr_src_cb() */ +void aattr_attr_src(abst_attrdlg_ctx_t *actx); + + +/* Create widgets for an abst_attrdlg_ctx_t in DAD context dlg */ +#define aattr_dlg_create(actx, dlg, prj, floater_cb) aattr_dlg_create_((actx), dlg, (prj), (floater_cb)) + +/* Select the row for attr_name */ +void aattr_dlg_select_attr(abst_attrdlg_ctx_t *actx, const char *attr_name); + + +/*** implementation ***/ + +#define aattr_dlg_create_(actx, Dlg, Prj, floater_cb) \ + do { \ + static const char *ahdr[] = {"key", "value", NULL}; \ +\ + actx->wright = RND_DAD_CURRENT(Dlg); \ + actx->dlg = &Dlg; \ + actx->dlg_hid_ctx = &Dlg ## _hid_ctx; \ + actx->prj = Prj; \ +\ + RND_DAD_BEGIN_HBOX(Dlg); \ + RND_DAD_LABEL(Dlg, "Abstract:"); \ +\ + RND_DAD_BEGIN_HBOX(ctx->dlg); \ + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); \ + RND_DAD_END(ctx->dlg); \ +\ + RND_DAD_LABEL(Dlg, ""); \ + actx->waname = RND_DAD_CURRENT(Dlg); \ + RND_DAD_END(Dlg); \ +\ + RND_DAD_TREE(Dlg, 2, 0, ahdr); \ + RND_DAD_COMPFLAG(Dlg, RND_HATF_EXPFILL | RND_HATF_SCROLL); \ + actx->waattrs = RND_DAD_CURRENT(Dlg); \ + RND_DAD_TREE_SET_CB(Dlg, selected_cb, aattr_select); \ + RND_DAD_TREE_SET_CB(Dlg, ctx, ctx); \ +\ + RND_DAD_BEGIN_HBOX(ctx->dlg); \ + RND_DAD_LABEL(Dlg, "Exported as:"); \ + RND_DAD_LABEL(Dlg, ""); \ + actx->wexport_name = RND_DAD_CURRENT(Dlg); \ + \ + RND_DAD_BEGIN_VBOX(ctx->dlg); \ + RND_DAD_COMPFLAG(Dlg, RND_HATF_EXPFILL); \ + RND_DAD_END(Dlg); \ + \ + if (floater_cb != NULL) { \ + RND_DAD_BUTTON(ctx->dlg, "Floater"); \ + RND_DAD_CHANGE_CB(ctx->dlg, floater_cb); \ + RND_DAD_HELP(ctx->dlg, "Create a floater text that prints the value of the attribute\nfrom the abstract model (compiled)"); \ + } \ + RND_DAD_END(Dlg); \ +\ + RND_DAD_LABEL(Dlg, "Attribute history:"); \ + RND_DAD_TREE(Dlg, 1, 0, NULL); \ + RND_DAD_COMPFLAG(Dlg, RND_HATF_EXPFILL | RND_HATF_SCROLL); \ + actx->wahistory = RND_DAD_CURRENT(Dlg); \ +\ + RND_DAD_BEGIN_HBOX(ctx->dlg); \ + RND_DAD_LABEL(Dlg, "Details:"); \ + actx->wdetaillab = RND_DAD_CURRENT(Dlg); \ + RND_DAD_BEGIN_HBOX(ctx->dlg); \ + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); \ + RND_DAD_END(ctx->dlg); \ + RND_DAD_BUTTON(Dlg, "history src"); \ + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_TIGHT); \ + RND_DAD_CHANGE_CB(ctx->dlg, aattr_attr_src_cb); \ + RND_DAD_HELP(Dlg, "Go to the source of the selected row of attribute history"); \ + RND_DAD_BUTTON(Dlg, "sources"); \ + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_TIGHT); \ + RND_DAD_CHANGE_CB(ctx->dlg, aattr_sources_cb); \ + RND_DAD_HELP(Dlg, "Present a list of concrete model objects\nthat contributed to this abstract object\nin the last compilation"); \ + RND_DAD_END(ctx->dlg); \ + RND_DAD_TREE(Dlg, 1, 0, NULL); \ + RND_DAD_COMPFLAG(Dlg, RND_HATF_EXPFILL | RND_HATF_SCROLL); \ + actx->wdetailtree = RND_DAD_CURRENT(Dlg); \ +\ + } while(0) + + Index: tags/1.0.5/src/plugins/sch_dialogs/adialogs.conf =================================================================== --- tags/1.0.5/src/plugins/sch_dialogs/adialogs.conf (nonexistent) +++ tags/1.0.5/src/plugins/sch_dialogs/adialogs.conf (revision 10414) @@ -0,0 +1,15 @@ +li:pcb-rnd-conf-v1 { + ha:append { + ha:plugins { + ha:dialogs { + ha:library { + preview_refresh_timeout = 500 + preview_vis_cpr = 1 + preview_vis_slk = 1 + preview_vis_mnp = 0 + preview_vis_doc = 0 + } + } + } + } +} Index: tags/1.0.5/src/plugins/sch_dialogs/adialogs_conf.h =================================================================== --- tags/1.0.5/src/plugins/sch_dialogs/adialogs_conf.h (nonexistent) +++ tags/1.0.5/src/plugins/sch_dialogs/adialogs_conf.h (revision 10414) @@ -0,0 +1,20 @@ +#ifndef SCH_RND_ADIALOGS_CONF_H +#define SCH_RND_ADIALOGS_CONF_H + +#include + +/* sch-rnd specific dialog config */ + +typedef struct { + const struct { + const struct { + const struct { + RND_CFT_INTEGER preview_refresh_timeout; /* how much time to wait (in milliseconds) after the last edit in filter before refreshing the preview, e.g. for parametric footprints */ + } library; + } dialogs; + } plugins; +} conf_adialogs_t; + +extern conf_adialogs_t adialogs_conf; + +#endif Index: tags/1.0.5/src/plugins/sch_dialogs/dlg_about.c =================================================================== --- tags/1.0.5/src/plugins/sch_dialogs/dlg_about.c (nonexistent) +++ tags/1.0.5/src/plugins/sch_dialogs/dlg_about.c (revision 10414) @@ -0,0 +1,120 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - GUI - about box + * Copyright (C) 2018 Tibor 'Igor2' Palinkas (in pcb-rnd) + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include + +#include +#include +#include +#include +#include + +#include + +#include "dlg_about.h" + +typedef struct{ + RND_DAD_DECL_NOINIT(dlg) + int active; /* already open - allow only one instance */ +} about_ctx_t; + +about_ctx_t about_ctx; + +static void about_close_cb(void *caller_data, rnd_hid_attr_ev_t ev) +{ + about_ctx_t *ctx = caller_data; + RND_DAD_FREE(ctx->dlg); + memset(ctx, 0, sizeof(about_ctx_t)); /* reset all states to the initial - includes ctx->active = 0; */ +} + + +static void sch_rnd_dlg_about(void) +{ + const char *tabs[] = { "About sch-rnd", "Options", "Paths", "License", NULL }; + rnd_hid_dad_buttons_t clbtn[] = {{"Close", 0}, {NULL, 0}}; + htsp_entry_t *e; + gds_t s; + + if (about_ctx.active) + return; + + RND_DAD_BEGIN_VBOX(about_ctx.dlg); + RND_DAD_COMPFLAG(about_ctx.dlg, RND_HATF_EXPFILL); + RND_DAD_BEGIN_TABBED(about_ctx.dlg, tabs); + RND_DAD_COMPFLAG(about_ctx.dlg, RND_HATF_EXPFILL); + RND_DAD_BEGIN_VBOX(about_ctx.dlg); + RND_DAD_LABEL(about_ctx.dlg, sch_rnd_get_info_program()); + RND_DAD_LABEL(about_ctx.dlg, sch_rnd_get_info_copyright()); + RND_DAD_LABEL(about_ctx.dlg, sch_rnd_get_info_websites(NULL)); + RND_DAD_END(about_ctx.dlg); + + RND_DAD_BEGIN_VBOX(about_ctx.dlg); + RND_DAD_COMPFLAG(about_ctx.dlg, /*RND_HATF_SCROLL |*/ /*RND_HATF_FRAME |*/ RND_HATF_EXPFILL); + RND_DAD_LABEL(about_ctx.dlg, sch_rnd_get_info_compile_options()); + RND_DAD_COMPFLAG(about_ctx.dlg, RND_HATF_EXPFILL); + RND_DAD_END(about_ctx.dlg); + + + RND_DAD_BEGIN_VBOX(about_ctx.dlg); + RND_DAD_COMPFLAG(about_ctx.dlg, RND_HATF_SCROLL); + gds_init(&s); + for (e = htsp_first(&rnd_file_loaded); e; e = htsp_next(&rnd_file_loaded, e)) { + htsp_entry_t *e2; + rnd_file_loaded_t *cat = e->value; + RND_DAD_LABEL(about_ctx.dlg, cat->name); + gds_truncate(&s, 0); + for (e2 = htsp_first(&cat->data.category.children); e2; e2 = htsp_next(&cat->data.category.children, e2)) { + rnd_file_loaded_t *file = e2->value; + rnd_append_printf(&s, " %s\t%s\t%s\n", file->name, file->data.file.path, file->data.file.desc); + } + RND_DAD_LABEL(about_ctx.dlg, s.array); + } + gds_uninit(&s); + RND_DAD_END(about_ctx.dlg); + + RND_DAD_BEGIN_VBOX(about_ctx.dlg); + RND_DAD_LABEL(about_ctx.dlg, sch_rnd_get_info_license()); + RND_DAD_END(about_ctx.dlg); + + RND_DAD_END(about_ctx.dlg); + RND_DAD_BUTTON_CLOSES(about_ctx.dlg, clbtn); + RND_DAD_END(about_ctx.dlg); + + /* set up the context */ + about_ctx.active = 1; + + RND_DAD_NEW("about", about_ctx.dlg, "About sch-rnd", &about_ctx, rnd_false, about_close_cb); /* type=global */ +} + +const char csch_acts_About[] = "About()\n"; +const char csch_acth_About[] = "Present the about box"; +fgw_error_t csch_act_About(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + sch_rnd_dlg_about(); + RND_ACT_IRES(0); + return 0; +} Index: tags/1.0.5/src/plugins/sch_dialogs/dlg_about.h =================================================================== --- tags/1.0.5/src/plugins/sch_dialogs/dlg_about.h (nonexistent) +++ tags/1.0.5/src/plugins/sch_dialogs/dlg_about.h (revision 10414) @@ -0,0 +1,3 @@ +extern const char csch_acts_About[]; +extern const char csch_acth_About[]; +fgw_error_t csch_act_About(fgw_arg_t *res, int argc, fgw_arg_t *argv); Index: tags/1.0.5/src/plugins/sch_dialogs/dlg_abstract.c =================================================================== --- tags/1.0.5/src/plugins/sch_dialogs/dlg_abstract.c (nonexistent) +++ tags/1.0.5/src/plugins/sch_dialogs/dlg_abstract.c (revision 10414) @@ -0,0 +1,462 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - GUI - abstract model + * Copyright (C) 2022,2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022 and Entrust in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/* abstract tree dialog */ + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "abst_attr.h" + +typedef struct abst_dlg_ctx_s { + RND_DAD_DECL_NOINIT(dlg) + + abst_attrdlg_ctx_t right; + csch_project_t *prj; + gds_t tmp; + + int wtree, wfilt, wnoanon, wnoomit; + + htip_t aid2row; +} abst_dlg_ctx_t; + +static htpp_t prj2dlg; + +static void abst_dlg_close_cb(void *caller_data, rnd_hid_attr_ev_t ev) +{ + abst_dlg_ctx_t *ctx = caller_data; + gds_uninit(&ctx->tmp); + htpp_pop(&prj2dlg, ctx->prj); + htip_uninit(&ctx->aid2row); + free(ctx); +} + +static rnd_hid_row_t *put_in_tree(abst_dlg_ctx_t *ctx, rnd_hid_attribute_t *attr, csch_ahdr_t *a); + +static char *get_aname_mkdir(abst_dlg_ctx_t *ctx, rnd_hid_attribute_t *attr, csch_ahdr_t *a, rnd_hid_row_t **parent) +{ + rnd_hid_tree_t *tree = attr->wdata; + + switch(a->type) { + case CSCH_ATYPE_NET: + { + static char tmp[] = "net"; + *parent = rnd_dad_tree_mkdirp(tree, tmp, NULL); + return rnd_strdup(((csch_anet_t *)a)->name); + } + case CSCH_ATYPE_COMP: + { + static char tmp[] = "comp"; + *parent = rnd_dad_tree_mkdirp(tree, tmp, NULL); + return rnd_strdup(((csch_acomp_t *)a)->name); + } + case CSCH_ATYPE_PORT: + { + static char tmp[] = "port"; + csch_aport_t *p = (csch_aport_t *)a; + csch_acomp_t *c = p->parent; + if ((c != NULL) && (c->hdr.type == CSCH_ATYPE_COMP)) { + ctx->tmp.used = 0; + gds_append_str(&ctx->tmp, "comp/"); + gds_append_str(&ctx->tmp, c->name); + *parent = htsp_get(&tree->paths, ctx->tmp.array); + if (*parent == NULL) + *parent = put_in_tree(ctx, attr, &c->hdr); + return rnd_strdup(p->name); + } + *parent = rnd_dad_tree_mkdirp(tree, tmp, NULL); + if (p->referer != NULL) { + gds_t tmp = {0}; + gds_append_str(&tmp, p->referer->name); + gds_append(&tmp, '-'); + gds_append_str(&tmp, p->name); + return tmp.array; /* ownership passed */ + } + return rnd_strdup(p->name); + } + + case CSCH_ATYPE_BUSNET: + case CSCH_ATYPE_BUSCHAN: + case CSCH_ATYPE_BUSPORT: + case CSCH_ATYPE_HUB: + case CSCH_ATYPE_INVALID: + break; + } + + { + static char tmp[] = "unknwon"; + *parent = rnd_dad_tree_mkdirp(tree, tmp, NULL); + } + return rnd_strdup_printf("%ld", a->aid); +} + +static const char *get_aname_dry(const csch_ahdr_t *a, int *type_score) +{ + switch(a->type) { + case CSCH_ATYPE_NET: *type_score = 1; return ((csch_anet_t *)a)->name; + case CSCH_ATYPE_COMP: *type_score = 2; return ((csch_acomp_t *)a)->name; + case CSCH_ATYPE_PORT: *type_score = 3; return ((csch_aport_t *)a)->name; + case CSCH_ATYPE_BUSNET: + case CSCH_ATYPE_BUSCHAN: + case CSCH_ATYPE_BUSPORT: + case CSCH_ATYPE_HUB: + case CSCH_ATYPE_INVALID: + break; + } + + *type_score = 1024; + return "unknown"; +} + + +static rnd_hid_row_t *put_in_tree(abst_dlg_ctx_t *ctx, rnd_hid_attribute_t *attr, csch_ahdr_t *a) +{ + char *cell[3]; + rnd_hid_row_t *parent, *r; + + cell[0] = get_aname_mkdir(ctx, attr, a, &parent); + cell[1] = NULL; + cell[2] = NULL; + + if (a->omit) + cell[1] = rnd_strdup("omitted"); + + r = rnd_dad_tree_append_under(attr, parent, cell); + r->user_data = a; + + htip_set(&ctx->aid2row, a->aid, r); + + return r; +} + +static int cmp_aobj(const void *v1, const void *v2) +{ + csch_ahdr_t * const *a1 = v1; + csch_ahdr_t * const *a2 = v2; + const char *n1, *n2; + int res, ts1, ts2; + + n1 = get_aname_dry(*a1, &ts1); + n2 = get_aname_dry(*a2, &ts2); + + if (ts1 < ts2) return -1; + if (ts1 > ts2) return +1; + + res = strcmp(n1, n2); + if (res == 0) return 1; + return res; +} + +static void abst_prj2dlg(abst_dlg_ctx_t *ctx) +{ + rnd_hid_attribute_t *attr = &ctx->dlg[ctx->wtree]; + rnd_hid_tree_t *tree = attr->wdata; + rnd_hid_row_t *r; + char *cursor_path = NULL; + htip_entry_t *e; + + htip_clear(&ctx->aid2row); + + /* remember cursor */ + r = rnd_dad_tree_get_selected(attr); + if (r != NULL) + cursor_path = rnd_strdup(r->path); + + /* remove existing items */ + rnd_dad_tree_clear(tree); + + /* add all non-ghost items recursively */ + if (ctx->prj->abst != NULL) { + vtp0_t sorting = {0}; + long n; + + /* collect all non-ghost abstract objects in a temp array */ + vtp0_enlarge(&sorting, htip_length(&ctx->prj->abst->aid2obj)); + sorting.used = 0; + for(e = htip_first(&ctx->prj->abst->aid2obj); e != NULL; e = htip_next(&ctx->prj->abst->aid2obj, e)) { + csch_ahdr_t *a = e->value; + if (a->ghost == NULL) + vtp0_append(&sorting, a); + } + + /* sort the temp array and add the result in the tree */ + qsort(sorting.array, sorting.used, sizeof(csch_ahdr_t *), cmp_aobj); + for(n = 0; n < sorting.used; n++) + put_in_tree(ctx, attr, sorting.array[n]); + vtp0_uninit(&sorting); + + /* restore cursor */ + if (cursor_path != NULL) { + rnd_hid_attr_val_t hv; + hv.str = cursor_path; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wtree, &hv); + free(cursor_path); + } + } +} + +static csch_ahdr_t *get_dlg_obj(abst_dlg_ctx_t *ctx) +{ + rnd_hid_attribute_t *attr = &ctx->dlg[ctx->wtree]; + rnd_hid_row_t *r = rnd_dad_tree_get_selected(attr); + + return r == NULL ? NULL : r->user_data; +} + +static void abst_select_node_cb(rnd_hid_attribute_t *attrib, void *hid_ctx, rnd_hid_row_t *row) +{ + rnd_hid_tree_t *tree = attrib->wdata; + abst_dlg_ctx_t *ctx = tree->user_ctx; + csch_ahdr_t *a = get_dlg_obj(ctx); + aattr_dlg_sheet2dlg_abstract(&ctx->right, a); +} + +static void aattr_select(rnd_hid_attribute_t *attrib, void *hid_ctx, rnd_hid_row_t *row) +{ + rnd_hid_tree_t *tree = attrib->wdata; + abst_dlg_ctx_t *ctx = tree->user_ctx; + csch_ahdr_t *a = get_dlg_obj(ctx); + + aattr_dlg_ahist2dlg(&ctx->right, a); /* update history */ +} + +static void aattr_sources_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + abst_dlg_ctx_t *ctx = caller_data; + aattr_sources(&ctx->right); +} + +static void aattr_attr_src_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + abst_dlg_ctx_t *ctx = caller_data; + aattr_attr_src(&ctx->right); +} + +static void aattr_tree_unhide(rnd_hid_tree_t *tree, gdl_list_t *rowlist, int level, re_sei_t *preg, int noanon, int noomit) +{ + rnd_hid_row_t *r, *pr; + + for(r = gdl_first(rowlist); r != NULL; r = gdl_next(rowlist, r)) { + int show = 1, recurse = 1, rmatch = 0; + csch_ahdr_t *a = r->user_data; + + if ((preg != NULL) && (level > 0)) rmatch = re_sei_exec(preg, r->cell[0]); + + if ((level == 1) && noanon && (strncmp(r->cell[0], "anon_", 5) == 0)) show = recurse = 0; + if (noomit && (a != NULL) && a->omit) show = recurse = 0; + if (show && (preg != NULL) && !rmatch) { show = 0; } + + if (show) { + rnd_dad_tree_hide_all(tree, &r->children, 0); /* if this is a node with children, show all children */ + for(pr = r; pr != NULL; pr = rnd_dad_tree_parent_row(tree, pr)) /* also show all parents so it is visible */ + pr->hide = 0; + if (rmatch) + recurse = 0; /* always show children of a matched node */ + } + else + r->hide = 1; + + if (recurse) + aattr_tree_unhide(tree, &r->children, level+1, preg, noanon, noomit); + } +} + +static void aattr_filter_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr_inp) +{ + abst_dlg_ctx_t *ctx = caller_data; + rnd_hid_attribute_t *attr = &ctx->dlg[ctx->wtree]; + rnd_hid_tree_t *tree = attr->wdata; + rnd_hid_attribute_t *attr_filt = &ctx->dlg[ctx->wfilt]; + const char *text = attr_filt->val.str; + rnd_hid_attribute_t *attr_noanon = &ctx->dlg[ctx->wnoanon]; + rnd_hid_attribute_t *attr_noomit = &ctx->dlg[ctx->wnoomit]; + int noanon = attr_noanon->val.lng, noomit = attr_noomit->val.lng; + int have_filter_text; + re_sei_t *regex = NULL; + + have_filter_text = ((text != NULL) && (*text != '\0')); + + /* hide everything */ + if (have_filter_text) { + /* need to unhide for expand to work */ + rnd_dad_tree_hide_all(tree, &tree->rows, 0); + rnd_dad_tree_update_hide(attr); + rnd_dad_tree_expcoll(attr, NULL, 1, 1); + } + rnd_dad_tree_hide_all(tree, &tree->rows, 1); + + if (have_filter_text) + regex = re_sei_comp(text); + + /* unhide hits and all their parents */ + aattr_tree_unhide(tree, &tree->rows, 0, regex, noanon, noomit); + rnd_dad_tree_update_hide(attr); + + if (regex != NULL) + re_sei_free(regex); +} + + +void sch_rnd_abst_dlg(csch_project_t *prj, long aid, const char *attr_name) +{ + abst_dlg_ctx_t *ctx; + rnd_hid_dad_buttons_t clbtn[] = {{"Close", 0}, {NULL, 0}}; + const char *hdr[] = {"name", "remarks", NULL}; + static const char *tooltip_noanon = "hide anon nets and components"; + static const char *tooltip_noomit = "hide objects that are omitted from the output\n(see also: the omit attribute)"; + + ctx = htpp_get(&prj2dlg, prj); + if (ctx != NULL) { + TODO("raise?"); + goto jump; + } + + ctx = calloc(sizeof(abst_dlg_ctx_t), 1); + ctx->prj = prj; + htpp_set(&prj2dlg, prj, ctx); + htip_init(&ctx->aid2row, longhash, longkeyeq); + + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_BEGIN_HPANE(ctx->dlg, "left-right"); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_BEGIN_VBOX(ctx->dlg); /* left */ + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_TREE(ctx->dlg, 2, 1, hdr); /* top left: tree */ + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL | RND_HATF_SCROLL); + RND_DAD_TREE_SET_CB(ctx->dlg, selected_cb, abst_select_node_cb); + RND_DAD_TREE_SET_CB(ctx->dlg, ctx, ctx); + ctx->wtree = RND_DAD_CURRENT(ctx->dlg); + + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_STRING(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL | RND_HATF_INIT_FOCUS); + RND_DAD_HELP(ctx->dlg, "filter: display only abstract objects matching this regex\ncase insensitive\n(if empty: display all)"); + RND_DAD_CHANGE_CB(ctx->dlg, aattr_filter_cb); + ctx->wfilt = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, " | no-anon:"); + RND_DAD_HELP(ctx->dlg, tooltip_noanon); + RND_DAD_BOOL(ctx->dlg); + RND_DAD_CHANGE_CB(ctx->dlg, aattr_filter_cb); + ctx->wnoanon = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_HELP(ctx->dlg, tooltip_noanon); + RND_DAD_LABEL(ctx->dlg, " | no-omit:"); + RND_DAD_HELP(ctx->dlg, tooltip_noomit); + RND_DAD_BOOL(ctx->dlg); + RND_DAD_CHANGE_CB(ctx->dlg, aattr_filter_cb); + ctx->wnoomit = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_HELP(ctx->dlg, tooltip_noomit); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + + RND_DAD_BEGIN_VBOX(ctx->dlg); /* right */ + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + aattr_dlg_create(&ctx->right, ctx->dlg, prj, NULL); + RND_DAD_BUTTON_CLOSES(ctx->dlg, clbtn); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + + RND_DAD_END(ctx->dlg); + + RND_DAD_DEFSIZE(ctx->dlg, 300, 400); + RND_DAD_NEW("AbstDialog", ctx->dlg, "Abstract model", ctx, 0, abst_dlg_close_cb); /* type=local */ + + aattr_dlg_init(&ctx->right); + abst_prj2dlg(ctx); + + jump:; + if (aid >= 0) { + rnd_hid_row_t *r = htip_get(&ctx->aid2row, aid); + if (r != NULL) { + rnd_hid_attr_val_t hv; + hv.str = r->path; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wtree, &hv); + aattr_dlg_sheet2dlg_abstract(&ctx->right, r->user_data); + if (attr_name != NULL) + aattr_dlg_select_attr(&ctx->right, attr_name); + } + } +} + +const char csch_acts_AbstractDialog[] = "AbstractDialog([abst_id [,attr_name]])"; +const char csch_acth_AbstractDialog[] = "Bring up the current project's abstract model dialog. If abstract object id, abst_id is specified, left-side cursor is set at that object initially. If attr_name is specified, right-side cursor is set on that attribute.\n"; +fgw_error_t csch_act_AbstractDialog(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_design_t *hidlib = RND_ACT_DESIGN; + csch_sheet_t *sheet = (csch_sheet_t *)hidlib; + long aid = -1; + const char *attr_name; + + RND_ACT_MAY_CONVARG(1, FGW_LONG, AbstractDialog, aid = argv[1].val.nat_long); + RND_ACT_MAY_CONVARG(2, FGW_STR, AbstractDialog, attr_name = argv[2].val.str); + + sch_rnd_abst_dlg((csch_project_t *)sheet->hidlib.project, aid, attr_name); + return 0; +} + +void csch_dlg_abst_compiled(csch_project_t *prj) +{ + abst_dlg_ctx_t *ctx = htpp_get(&prj2dlg, prj); + if (ctx != NULL) + abst_prj2dlg(ctx); +} + + +void csch_dlg_abst_init(void) +{ + htpp_init(&prj2dlg, ptrhash, ptrkeyeq); +} + +void csch_dlg_abst_uninit(void) +{ + rnd_dad_retovr_t retovr = {0}; + htpp_entry_t *e; + + for(e = htpp_first(&prj2dlg); e != NULL; e = htpp_next(&prj2dlg, e)) { + abst_dlg_ctx_t *ctx = e->value; + rnd_hid_dad_close(ctx->dlg_hid_ctx, &retovr, 0); + } + + htpp_uninit(&prj2dlg); +} Index: tags/1.0.5/src/plugins/sch_dialogs/dlg_abstract.h =================================================================== --- tags/1.0.5/src/plugins/sch_dialogs/dlg_abstract.h (nonexistent) +++ tags/1.0.5/src/plugins/sch_dialogs/dlg_abstract.h (revision 10414) @@ -0,0 +1,7 @@ +extern const char csch_acts_AbstractDialog[]; +extern const char csch_acth_AbstractDialog[]; +fgw_error_t csch_act_AbstractDialog(fgw_arg_t *res, int argc, fgw_arg_t *argv); + +void csch_dlg_abst_init(void); +void csch_dlg_abst_uninit(void); +void csch_dlg_abst_compiled(csch_project_t *prj); Index: tags/1.0.5/src/plugins/sch_dialogs/dlg_attrib.c =================================================================== --- tags/1.0.5/src/plugins/sch_dialogs/dlg_attrib.c (nonexistent) +++ tags/1.0.5/src/plugins/sch_dialogs/dlg_attrib.c (revision 10414) @@ -0,0 +1,1172 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - GUI - attribute dialog + * Copyright (C) 2020,2022,2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "abst_attr.h" +#include "quick_attr.h" +#include "dlg_attrib.h" + +typedef struct { + RND_DAD_DECL_NOINIT(dlg) + abst_attrdlg_ctx_t right; + + csch_sheet_t *sheet; + csch_cgrp_t *obj; + csch_coord_t *ch_xy; /* crosshair x;y coord at the moment of invocation or NULL if not available */ + csch_coord_t ch_xy_[2]; /* backing store for ch_xy */ + char *name; + const char *last_attr_key; + int modal; + + int wattrs, wstr_sect, warr_sect, wkey, wprio, wprio2, wval_str, wval_tree; + int wconv_arr, wconv_str; + int wvaledit, wassist, wfloater; + + int refresh_lock; /* when non-zero ignore obj attr change events */ + + gdl_elem_t link; +} attrdlg_ctx_t; + +static gdl_list_t attrdlgs; + +typedef struct { + const char *key; + enum { AT_ENUM, AT_STR, AT_ARR } type; + const char **vals; /* for AT_ENUM */ +} known_attr_t; + +static const char *role_vals[] = {"symbol", "wire-net", "terminal", NULL}; +static const known_attr_t known_attrs[] = { + {"name", AT_STR, NULL}, + {"purpose", AT_STR, NULL}, + {"role", AT_ENUM, role_vals}, + {NULL, AT_STR, NULL} +}; + +static char *known_attr_render_cell(const csch_attrib_t *a) +{ + const known_attr_t *k; + const char **v; + + for(k = known_attrs; k->key != NULL; k++) { + if (strcmp(a->key, k->key) == 0) { + if (a->val != NULL) { + switch(k->type) { + case AT_ENUM: + for(v = k->vals; *v != NULL; v++) { + if (strcmp(*v, a->val) == 0) + return rnd_strdup("*"); + } + return rnd_strdup("?"); /* unknown value */ + break; + case AT_ARR: + return rnd_strdup("!"); /* attrib is str, we expected an arr */ + case AT_STR: + return rnd_strdup("*"); + } + } + else { + switch(k->type) { + case AT_ENUM: + case AT_STR: + return rnd_strdup("!"); /* attrib is arr, we expected a string */ + case AT_ARR: + return rnd_strdup("*"); + } + } + } + } + return rnd_strdup(" "); +} + +static void attrdlg_close_cb(void *caller_data, rnd_hid_attr_ev_t ev) +{ + attrdlg_ctx_t *ctx = caller_data; + gdl_remove(&attrdlgs, ctx, link); + RND_DAD_FREE(ctx->dlg); + free(ctx->name); + if (!ctx->modal) + free(ctx); +} + +/* load attribute array strings in arr value tree qidget */ +static void attr2dlg_arr(attrdlg_ctx_t *ctx, csch_attrib_t *a) +{ + rnd_hid_attribute_t *attr; + rnd_hid_tree_t *tree; + rnd_hid_row_t *r; + char *cursor_path = NULL; + char *cell[2]; + long n; + + attr = &ctx->dlg[ctx->wval_tree]; + tree = attr->wdata; + + /* remember cursor */ + r = rnd_dad_tree_get_selected(attr); + if (r != NULL) + cursor_path = rnd_strdup(r->cell[0]); + + /* remove existing items */ + rnd_dad_tree_clear(tree); + + /* add all items recursively */ + cell[1] = NULL; + for(n = 0; n < a->arr.used; n++) { + cell[0] = rnd_strdup(a->arr.array[n]); + r = rnd_dad_tree_append(attr, NULL, cell); + r->user_data2.lng = n; + } + + /* restore cursor */ + if (cursor_path != NULL) { + rnd_hid_attr_val_t hv; + hv.str = cursor_path; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wval_tree, &hv); + free(cursor_path); + } +} + +static void attr2dlg_(attrdlg_ctx_t *ctx, int new_key) +{ + int is_arr = 0, is_str = 0, assistable = 0, refd = 0; + rnd_hid_attribute_t *attr = &ctx->dlg[ctx->wattrs]; +/* rnd_hid_tree_t *tree = attr->wdata;*/ + rnd_hid_row_t *r = rnd_dad_tree_get_selected(attr); + csch_attrib_t *a = NULL; + rnd_hid_attr_val_t hv; + + if (r != NULL) { + if ((r->cell[0][0] == ' ') && (ctx->obj->hdr.type == CSCH_CTYPE_GRP_REF) && (ctx->obj->data.ref.grp != NULL)) { + /* allow selecting group ref's referencede group attributes; these will + just be recreated as attributes of the group ref on edit */ + a = csch_attrib_get(&ctx->obj->data.ref.grp->attr, r->cell[0]+1); + refd = 1; + } + else + a = csch_attrib_get(&ctx->obj->attr, r->cell[0]); + } + + if (a != NULL) { + char tmp[128]; + + is_str = (a->val != NULL); + is_arr = (a->val == NULL); + + hv.str = a->key; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wkey, &hv); + + hv.lng = a->prio; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wprio, &hv); + + sprintf(tmp, "%d", a->prio); + hv.str = tmp; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wprio2, &hv); + + if (is_str) { + hv.str = a->val; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wval_str, &hv); + } + else + attr2dlg_arr(ctx, a); + + assistable = sch_rnd_attr_quick_editable(ctx->sheet, &ctx->obj->hdr, a->key); + } + + if (!new_key) + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wstr_sect, !is_str); + + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->warr_sect, !is_arr); + rnd_gui->attr_dlg_widget_state(ctx->dlg_hid_ctx, ctx->wassist, assistable); + + rnd_gui->attr_dlg_widget_state(ctx->dlg_hid_ctx, ctx->wconv_arr, !refd); + rnd_gui->attr_dlg_widget_state(ctx->dlg_hid_ctx, ctx->wconv_str, !refd); + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wprio, refd); + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wprio2, !refd); + +} + +static void attr2dlg(attrdlg_ctx_t *ctx) +{ + attr2dlg_(ctx, 0); +} + +static void sheet2dlg_concrete_attrs(attrdlg_ctx_t *ctx, csch_attribs_t *attribs, const char *banner) +{ + rnd_hid_attribute_t *attr = &ctx->dlg[ctx->wattrs]; + char *cell[4]; + long n; + vtp0_t tmp = {0}; + + csch_attrib_sort(&tmp, attribs); + + if ((tmp.used > 0) && (banner != NULL)) { + cell[1] = NULL; + cell[0] = rnd_strdup(""); + rnd_dad_tree_append(attr, NULL, cell); + cell[0] = rnd_strdup(banner); + rnd_dad_tree_append(attr, NULL, cell); + } + + for(n = 0; n < tmp.used; n++) { + csch_attrib_t *a = tmp.array[n]; + if (banner != NULL) + cell[0] = rnd_strdup_printf(" %s", a->key); + else + cell[0] = rnd_strdup(a->key); + cell[1] = known_attr_render_cell(a); + if (a->val != NULL) + cell[2] = rnd_strdup(a->val); + else + cell[2] = rnd_strdup(""); + cell[3] = NULL; + rnd_dad_tree_append(attr, NULL, cell); + } + + + vtp0_uninit(&tmp); +} + +static void sheet2dlg_concrete(attrdlg_ctx_t *ctx, const char *new_cursor_path, int new_key) +{ + rnd_hid_attr_val_t hv; + rnd_hid_attribute_t *attr = &ctx->dlg[ctx->wattrs]; + rnd_hid_tree_t *tree = attr->wdata; + rnd_hid_row_t *r; + char *cursor_path = NULL; + + /* remember cursor */ + if (new_cursor_path == NULL) { + r = rnd_dad_tree_get_selected(attr); + if (r != NULL) + cursor_path = rnd_strdup(r->cell[0]); + } + + /* remove existing items */ + rnd_dad_tree_clear(tree); + + /* add all items recursively; first immediate attributes of the object */ + sheet2dlg_concrete_attrs(ctx, &ctx->obj->attr, NULL); + + /* in case of group ref, also display, read-only, all attributes of the + referenced group */ + if (ctx->obj->hdr.type == CSCH_CTYPE_GRP_REF) { + if (ctx->obj->data.ref.grp == NULL) + csch_cgrp_ref_text2ptr(ctx->obj->hdr.sheet, ctx->obj); + if (ctx->obj->data.ref.grp != NULL) + sheet2dlg_concrete_attrs(ctx, &ctx->obj->data.ref.grp->attr, "**Referenced grp**"); + } + + + /* restore cursor */ + if (new_cursor_path != NULL) { + hv.str = new_cursor_path; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wattrs, &hv); + } + else if (cursor_path != NULL) { + hv.str = cursor_path; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wattrs, &hv); + free(cursor_path); + } + + attr2dlg_(ctx, new_key); +} + +static void sheet2dlg_cursor(attrdlg_ctx_t *ctx, const char *new_cursor_path, int new_key) +{ + int hier_idx = 0; TODO("<- hierarchic: need a widget for this"); + + sheet2dlg_concrete(ctx, new_cursor_path, new_key); + aattr_dlg_sheet2dlg_abstract(&ctx->right, csch_cgrp_get_abstract(ctx->sheet, (csch_cgrp_t *)ctx->obj, hier_idx)); +} + +static void sheet2dlg(attrdlg_ctx_t *ctx) +{ + sheet2dlg_cursor(ctx, NULL, 0); +} + + +static void attr_select(rnd_hid_attribute_t *attrib, void *hid_ctx, rnd_hid_row_t *row) +{ + rnd_hid_tree_t *tree = attrib->wdata; + attrdlg_ctx_t *ctx = tree->user_ctx; + rnd_hid_row_t *r = rnd_dad_tree_get_selected(attrib); + + ctx->last_attr_key = NULL; + if (r != NULL) { + csch_attrib_t *a = htsp_get(&ctx->obj->attr, r->cell[0]); + if (a != NULL) + ctx->last_attr_key = a->key; + } + + + attr2dlg(ctx); +} + +RND_INLINE csch_attrib_t *tree_get_current_attr(attrdlg_ctx_t *ctx) +{ + rnd_hid_attribute_t *attr = &ctx->dlg[ctx->wattrs]; + rnd_hid_row_t *r = rnd_dad_tree_get_selected(attr); + + if (r == NULL) + return NULL; + + return csch_attrib_get(&ctx->obj->attr, r->cell[0]); +} + +static csch_source_arg_t *attrdlg_src(void) +{ + return csch_attrib_src_c(NULL, 0, 0, "attr_dlg user input"); +} + +static void attr_val_set_meta_and_str(attrdlg_ctx_t *ctx, csch_attrib_t *a, int set_str) +{ + int prio, chg = 0; + const char *key; + const char *val; + + if (a == NULL) + return; /* shouldn't happen: no attribute selected */ + + prio = ctx->dlg[ctx->wprio].val.lng; + key = ctx->dlg[ctx->wkey].val.str; + val = ctx->dlg[ctx->wval_str].val.str; + + if ((key == NULL) || (*key == '\0')) + return; /* do not allow empty key */ + + if (strcmp(key, a->key) != 0) { + /* key change: rename attrib */ + ctx->refresh_lock++; + csch_attr_modify_rename(ctx->sheet, ctx->obj, a, key, attrdlg_src(), 1); + ctx->refresh_lock--; + sheet2dlg_cursor(ctx, key, 0); + return; + } + + if (prio != a->prio) + chg = 1; + + if ((set_str) && (strcmp(val, a->val) != 0)) + chg = 1; + + if (!chg) + return; + + ctx->refresh_lock++; + if (set_str) + csch_attr_modify_str(ctx->sheet, ctx->obj, prio, key, val, attrdlg_src(), 1); + else + csch_attr_modify_prio(ctx->sheet, ctx->obj, a, prio, attrdlg_src(), 1); + ctx->refresh_lock--; + sheet2dlg(ctx); +} + +static void attr_val_set_meta_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + attrdlg_ctx_t *ctx = caller_data; + csch_attrib_t *a = tree_get_current_attr(ctx); + attr_val_set_meta_and_str(ctx, a, 0); +} + +static void attr_strval_set_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + attrdlg_ctx_t *ctx = caller_data; + csch_attrib_t *a = tree_get_current_attr(ctx); + + if (a == NULL) { /* special case: new target key */ + int prio; + const char *key, *val; + + prio = ctx->dlg[ctx->wprio].val.lng; + key = ctx->dlg[ctx->wkey].val.str; + val = ctx->dlg[ctx->wval_str].val.str; + + ctx->refresh_lock++; + csch_attr_modify_str(ctx->sheet, ctx->obj, prio, key, val, attrdlg_src(), 1); + ctx->refresh_lock--; + sheet2dlg_cursor(ctx, key, 0); + } + else + attr_val_set_meta_and_str(ctx, a, 1); +} + +/*** Multiline string edit dialog ***/ +typedef struct { + RND_DAD_DECL_NOINIT(dlg) + int wtxt; + char *new_val; +} mledit_t; + +static void mledit_close_cb(void *caller_data, rnd_hid_attr_ev_t ev) +{ + mledit_t *ctx = caller_data; + rnd_hid_attribute_t *atxt = &ctx->dlg[ctx->wtxt]; + rnd_hid_text_t *txt = atxt->wdata; + + /* remember the string accepted */ + ctx->new_val = txt->hid_get_text(atxt, ctx->dlg_hid_ctx); +} + +static void attr_strval_mledit_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + mledit_t ctx = {0}; + attrdlg_ctx_t *pctx = caller_data; + const char *val = pctx->dlg[pctx->wval_str].val.str; + + rnd_hid_attr_val_t hv; + rnd_hid_dad_buttons_t clbtn[] = {{"Cancel", 0}, {"OK", 1}, {NULL, 0}}; + + + RND_DAD_BEGIN_VBOX(ctx.dlg); + RND_DAD_COMPFLAG(ctx.dlg, RND_HATF_EXPFILL); + RND_DAD_TEXT(ctx.dlg, NULL); + RND_DAD_COMPFLAG(ctx.dlg, RND_HATF_EXPFILL); + ctx.wtxt = RND_DAD_CURRENT(ctx.dlg); + RND_DAD_BUTTON_CLOSES(ctx.dlg, clbtn); + RND_DAD_END(ctx.dlg); + + RND_DAD_DEFSIZE(ctx.dlg, 400, 200); + RND_DAD_NEW("AttributeMultiline", ctx.dlg, "Atribute dialog: multiline text edit", &ctx, 1, mledit_close_cb); + + hv.str = (val == NULL ? "" : val); + rnd_gui->attr_dlg_set_value(ctx.dlg_hid_ctx, ctx.wtxt, &hv); + + if (RND_DAD_RUN(ctx.dlg) == 1) { + hv.str = ctx.new_val; + rnd_gui->attr_dlg_set_value(pctx->dlg_hid_ctx, pctx->wval_str, &hv); + attr_strval_set_cb(hid_ctx, caller_data, attr); /* get the str value set */ + } + + free(ctx.new_val); + RND_DAD_FREE(ctx.dlg); +} + + +/*** array ***/ +static csch_attrib_t *tree_get_current_attr_arr(attrdlg_ctx_t *ctx, long *idx, const char **key) +{ + rnd_hid_attribute_t *aattr = &ctx->dlg[ctx->wattrs]; + rnd_hid_row_t *r = rnd_dad_tree_get_selected(aattr); + rnd_hid_attribute_t *tattr = &ctx->dlg[ctx->wval_tree]; + rnd_hid_row_t *ri = rnd_dad_tree_get_selected(tattr); + + *key = ctx->dlg[ctx->wkey].val.str; + + if ((r == NULL) || (ri == NULL)) + return NULL; /* no row selected */ + + *idx = ri->user_data2.lng; + return csch_attrib_get(&ctx->obj->attr, r->cell[0]); +} + +static void attr_arrval_set(attrdlg_ctx_t *ctx, csch_attrib_t *a, const char *key, long idx, int ins_before) +{ + char *newval; + + newval = rnd_hid_prompt_for(&ctx->sheet->hidlib, "Edit attribute array entry:", (ins_before ? NULL : a->arr.array[idx]), "Attribute array value edit"); + if (newval == NULL) /* cancel - not yet implemented */ + return; + + ctx->refresh_lock++; + if (ins_before) + csch_attr_arr_modify_ins_before(ctx->sheet, ctx->obj, key, idx, newval, 1); + else + csch_attr_arr_modify_str(ctx->sheet, ctx->obj, key, idx, newval, 1); + ctx->refresh_lock--; + + attr2dlg(ctx); + + free(newval); +} + +static void attr_arrval_set_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + attrdlg_ctx_t *ctx = caller_data; + csch_attrib_t *a; + const char *key; + long idx; + + a = tree_get_current_attr_arr(ctx, &idx, &key); + if (a == NULL) + return; /* not found */ + + attr_arrval_set(ctx, a, key, idx, 0); +} + +static void attr_arrval_ins_before_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + attrdlg_ctx_t *ctx = caller_data; + csch_attrib_t *a; + const char *key; + long idx; + + a = tree_get_current_attr_arr(ctx, &idx, &key); + if (a == NULL) + idx = 0; /* happens when nothing is selected - insert at the front */ + + attr_arrval_set(ctx, a, key, idx, 1); +} + +static void attr_arrval_ins_after_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + attrdlg_ctx_t *ctx = caller_data; + csch_attrib_t *a; + const char *key; + long idx; + + a = tree_get_current_attr_arr(ctx, &idx, &key); + if (a == NULL) { + /* happens when nothing is selected - insert at the end */ + rnd_hid_attribute_t *aattr = &ctx->dlg[ctx->wattrs]; + rnd_hid_row_t *r = rnd_dad_tree_get_selected(aattr); + a = csch_attrib_get(&ctx->obj->attr, r->cell[0]); + idx = a->arr.used-1; + } + + attr_arrval_set(ctx, a, key, idx+1, 1); +} + +static void attr_arrval_del_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + attrdlg_ctx_t *ctx = caller_data; + csch_attrib_t *a; + const char *key; + long idx; + + a = tree_get_current_attr_arr(ctx, &idx, &key); + if (a == NULL) + return; /* not found */ + + ctx->refresh_lock++; + csch_attr_arr_modify_del(ctx->sheet, ctx->obj, key, idx, 1); + ctx->refresh_lock--; + sheet2dlg(ctx); +} + + +static void attr_arrval_move(attrdlg_ctx_t *ctx, long delta) +{ + csch_attrib_t *a; + const char *key; + long idx; + + a = tree_get_current_attr_arr(ctx, &idx, &key); + if (a == NULL) + return; /* not found */ + + ctx->refresh_lock++; + csch_attr_arr_modify_move(ctx->sheet, ctx->obj, key, idx, delta, 1); + ctx->refresh_lock--; + + attr2dlg(ctx); +} + +static void attr_arrval_move_up_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + attr_arrval_move(caller_data, -1); +} + +static void attr_arrval_move_down_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + attr_arrval_move(caller_data, +1); +} + +static void attr_conv_to(attrdlg_ctx_t *ctx, int toarr) +{ + rnd_hid_attribute_t *attr = &ctx->dlg[ctx->wattrs]; + rnd_hid_row_t *r = rnd_dad_tree_get_selected(attr); + + if (r == NULL) + return; + + + ctx->refresh_lock++; + if (toarr) + csch_attr_modify_conv_to_arr(ctx->sheet, ctx->obj, r->cell[0], 1); + else + csch_attr_modify_conv_to_str(ctx->sheet, ctx->obj, r->cell[0], 1); + ctx->refresh_lock--; + + sheet2dlg(ctx); +} + +static void attr_conv_to_arr_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + attr_conv_to(caller_data, 1); +} + +static void attr_conv_to_str_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + attr_conv_to(caller_data, 0); +} + +static void attr_new_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + attrdlg_ctx_t *ctx = caller_data; + char *key, *val; + + + key = rnd_hid_prompt_for(&ctx->sheet->hidlib, "Key for the new attribute", NULL, "Create new attribute"); + if ((key == NULL) || (*key == '\0')) + return; + + val = rnd_hid_prompt_for(&ctx->sheet->hidlib, "Value for the new attribute", NULL, "Create new attribute: value"); + if (val == NULL) + return; + + + if (!htsp_has(&ctx->obj->attr, key) || (*val != '\0')) { + ctx->refresh_lock++; + csch_attr_modify_str(ctx->sheet, ctx->obj, CSCH_ATP_USER_DEFAULT, key, val, attrdlg_src(), 1); + ctx->refresh_lock--; + } + + sheet2dlg_cursor(ctx, key, 0); + free(key); +} + +static void attr_floater_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + attrdlg_ctx_t *ctx = caller_data; + rnd_hid_attribute_t *tattr = &ctx->dlg[ctx->wattrs]; + rnd_hid_row_t *r = rnd_dad_tree_get_selected(tattr); + csch_cgrp_t *grp = (csch_cgrp_t *)ctx->obj; + const char *penname; + + if (r == NULL) { + rnd_message(RND_MSG_ERROR, "Select an attribute first!\n"); + return; + } + + penname = (grp->role == CSCH_ROLE_WIRE_NET ? "wire" : "sym-secondary"); + csch_auto_attr_place(ctx->sheet, grp, r->cell[0], penname, NULL, ctx->ch_xy); +} + +static void attr_afloater_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + attrdlg_ctx_t *ctx = caller_data; + rnd_hid_attribute_t *tattr = &ctx->dlg[ctx->right.waattrs]; + rnd_hid_row_t *r = rnd_dad_tree_get_selected(tattr); + csch_cgrp_t *grp = (csch_cgrp_t *)ctx->obj; + const char *penname; + char *templ; + + penname = (grp->role == CSCH_ROLE_WIRE_NET ? "wire" : "sym-secondary"); + + templ = rnd_strdup_printf("%%../a.%s%%", r->cell[0]); /* use the abstract attribute */ + csch_auto_attr_place(ctx->sheet, grp, r->cell[0], penname, templ, ctx->ch_xy); + free(templ); +} + + + +static void attr_del_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + attrdlg_ctx_t *ctx = caller_data; + rnd_hid_attribute_t *tattr = &ctx->dlg[ctx->wattrs]; + rnd_hid_row_t *r = rnd_dad_tree_get_selected(tattr); + + if (r == NULL) + return; + + ctx->refresh_lock++; + csch_attr_modify_del(ctx->sheet, ctx->obj, r->cell[0], 1); + ctx->refresh_lock--; + sheet2dlg(ctx); +} + +static void attr_assist_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + attrdlg_ctx_t *ctx = caller_data; + rnd_hid_attribute_t *tattr = &ctx->dlg[ctx->wattrs]; + rnd_hid_row_t *r = rnd_dad_tree_get_selected(tattr); + int res; + + if (r == NULL) + return; + + ctx->refresh_lock++; + res = sch_rnd_attr_quick_edit(ctx->sheet, &ctx->obj->hdr, r->cell[0]); + ctx->refresh_lock--; + if (res > 0) + sheet2dlg(ctx); +} + + +static void aattr_select(rnd_hid_attribute_t *attrib, void *hid_ctx, rnd_hid_row_t *row) +{ + rnd_hid_tree_t *tree = attrib->wdata; + attrdlg_ctx_t *ctx = tree->user_ctx; + + int hier_idx = 0; TODO("hierarchic: <- need a widget for this") + + aattr_dlg_ahist2dlg(&ctx->right, csch_cgrp_get_abstract(ctx->sheet, (csch_cgrp_t *)ctx->obj, hier_idx)); /* update history */ +} + + +static void spring(attrdlg_ctx_t *ctx) +{ + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_END(ctx->dlg); +} + +static attrdlg_ctx_t *attr_dlg_find(csch_sheet_t *sheet, csch_cgrp_t *obj) +{ + attrdlg_ctx_t *n; + for(n = gdl_first(&attrdlgs); n != NULL; n = gdl_next(&attrdlgs, n)) { + if ((n->sheet == sheet) && (n->obj == obj)) + return n; + } + return NULL; +} + +static void aattr_sources_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + attrdlg_ctx_t *ctx = caller_data; + aattr_sources(&ctx->right); +} + +static void aattr_attr_src_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + attrdlg_ctx_t *ctx = caller_data; + aattr_attr_src(&ctx->right); +} + +/* If pick is true, return the attrib key picked by the user (or NULL) */ +static const char *attr_dlg(csch_sheet_t *sheet, csch_cgrp_t *obj, const char *target_key, int pick, int has_coords) +{ + attrdlg_ctx_t *ctx; + rnd_hid_dad_buttons_t clbtn[] = {{"Close", 0}, {NULL, 0}}; + rnd_hid_dad_buttons_t clbtn_pick[] = {{"Cancel", -1}, {"Use selected", 1}, {NULL, 0}}; + const char *hdr[] = {"key", " ", "value", NULL}; + const char *oname, *orole, *req; + int modal = pick, new_key = 0; + + if (!modal) { + ctx = attr_dlg_find(sheet, obj); + if (ctx != NULL) { + TODO("raise?"); + return NULL; + } + } + + oname = csch_attrib_get_str(&obj->attr, "name"); + orole = csch_attrib_get_str(&obj->attr, "role"); + req = (pick ? "Pick an attribute in" : "Attributes of"); + + ctx = calloc(sizeof(attrdlg_ctx_t), 1); + ctx->sheet = sheet; + ctx->obj = obj; + ctx->modal = modal; + ctx->name = rnd_strdup_printf("%s %s %s", req, (orole == NULL ? "" : orole), (oname == NULL ? "" : oname)); + gdl_append(&attrdlgs, ctx, link); + + if (has_coords) { + ctx->ch_xy_[0] = P2C(sch_rnd_crosshair_x); + ctx->ch_xy_[1] = P2C(sch_rnd_crosshair_y); + ctx->ch_xy = ctx->ch_xy_; + } + + + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_BEGIN_HPANE(ctx->dlg, "left-right"); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + + RND_DAD_BEGIN_VBOX(ctx->dlg); /* left */ + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_LABEL(ctx->dlg, "Concrete:"); + RND_DAD_BEGIN_VPANE(ctx->dlg, "left_top-bottom"); + + RND_DAD_TREE(ctx->dlg, 3, 0, hdr); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL | RND_HATF_SCROLL); + ctx->wattrs = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_TREE_SET_CB(ctx->dlg, selected_cb, attr_select); + RND_DAD_TREE_SET_CB(ctx->dlg, ctx, ctx); + + RND_DAD_BEGIN_VBOX(ctx->dlg); /* bottom left: value edit */ + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + ctx->wvaledit = RND_DAD_CURRENT(ctx->dlg); + + RND_DAD_BEGIN_HBOX(ctx->dlg); /* new/del */ + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_FRAME); + RND_DAD_BUTTON(ctx->dlg, "Assisted edit"); + ctx->wassist = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_CHANGE_CB(ctx->dlg, attr_assist_cb); + RND_DAD_HELP(ctx->dlg, "Invoke attribute-specitic quick edit if available"); + spring(ctx); + RND_DAD_BUTTON(ctx->dlg, "Floater"); + ctx->wfloater = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_CHANGE_CB(ctx->dlg, attr_floater_cb); + RND_DAD_HELP(ctx->dlg, "Create a floater text that prints the value of the attribute\nfrom the concrete model (value before compilation)"); + spring(ctx); + RND_DAD_BUTTON(ctx->dlg, "New"); + RND_DAD_CHANGE_CB(ctx->dlg, attr_new_cb); + RND_DAD_BUTTON(ctx->dlg, "Del"); + RND_DAD_CHANGE_CB(ctx->dlg, attr_del_cb); + RND_DAD_END(ctx->dlg); + + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Key:"); + RND_DAD_STRING(ctx->dlg); + RND_DAD_WIDTH_CHR(ctx->dlg, 32); + RND_DAD_ENTER_CB(ctx->dlg, attr_val_set_meta_cb); + ctx->wkey = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_END(ctx->dlg); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Priority:"); + RND_DAD_INTEGER(ctx->dlg); + RND_DAD_WIDTH_CHR(ctx->dlg, 5); + RND_DAD_ENTER_CB(ctx->dlg, attr_val_set_meta_cb); + ctx->wprio = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, ""); + ctx->wprio2 = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_END(ctx->dlg); + + /* string value */ + RND_DAD_BEGIN_VBOX(ctx->dlg); + ctx->wstr_sect = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Val:"); + RND_DAD_STRING(ctx->dlg); + if (!pick && (target_key != NULL)) + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_INIT_FOCUS); + RND_DAD_WIDTH_CHR(ctx->dlg, 32); + RND_DAD_ENTER_CB(ctx->dlg, attr_strval_set_cb); + ctx->wval_str = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_END(ctx->dlg); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "Convert to array"); + RND_DAD_CHANGE_CB(ctx->dlg, attr_conv_to_arr_cb); + ctx->wconv_arr = RND_DAD_CURRENT(ctx->dlg); + spring(ctx); + RND_DAD_BUTTON(ctx->dlg, "Edit multiline"); + RND_DAD_CHANGE_CB(ctx->dlg, attr_strval_mledit_cb); + RND_DAD_BUTTON(ctx->dlg, "Set"); + RND_DAD_CHANGE_CB(ctx->dlg, attr_strval_set_cb); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + + /* array value */ + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + ctx->warr_sect = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Val:"); + RND_DAD_BUTTON(ctx->dlg, "Convert to string"); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_TIGHT); + RND_DAD_CHANGE_CB(ctx->dlg, attr_conv_to_str_cb); + ctx->wconv_str = RND_DAD_CURRENT(ctx->dlg); + spring(ctx); + RND_DAD_BUTTON(ctx->dlg, "Set prio/key"); + RND_DAD_CHANGE_CB(ctx->dlg, attr_val_set_meta_cb); + RND_DAD_END(ctx->dlg); + RND_DAD_TREE(ctx->dlg, 1, 0, NULL); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL | RND_HATF_SCROLL); + ctx->wval_tree = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_BEGIN_HBOX(ctx->dlg); /* array buttons 1 */ + RND_DAD_BUTTON(ctx->dlg, "Edit..."); + RND_DAD_CHANGE_CB(ctx->dlg, attr_arrval_set_cb); + RND_DAD_BUTTON(ctx->dlg, "Move up"); + RND_DAD_CHANGE_CB(ctx->dlg, attr_arrval_move_up_cb); + RND_DAD_BUTTON(ctx->dlg, "Move down"); + RND_DAD_CHANGE_CB(ctx->dlg, attr_arrval_move_down_cb); + RND_DAD_END(ctx->dlg); + RND_DAD_BEGIN_HBOX(ctx->dlg); /* array buttons 2 */ + RND_DAD_BUTTON(ctx->dlg, "Delete"); + RND_DAD_CHANGE_CB(ctx->dlg, attr_arrval_del_cb); + RND_DAD_BUTTON(ctx->dlg, "Ins before"); + RND_DAD_CHANGE_CB(ctx->dlg, attr_arrval_ins_before_cb); + RND_DAD_BUTTON(ctx->dlg, "Ins after"); + RND_DAD_CHANGE_CB(ctx->dlg, attr_arrval_ins_after_cb); + RND_DAD_END(ctx->dlg); + + RND_DAD_END(ctx->dlg); /* bottom left */ + RND_DAD_END(ctx->dlg); /* left vpane */ + RND_DAD_END(ctx->dlg); /* left side */ + + RND_DAD_END(ctx->dlg); + + RND_DAD_BEGIN_VBOX(ctx->dlg); /* top right */ + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + aattr_dlg_create(&ctx->right, ctx->dlg, (csch_project_t *)sheet->hidlib.project, attr_afloater_cb); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + + RND_DAD_BUTTON_CLOSES(ctx->dlg, pick ? clbtn_pick : clbtn); + RND_DAD_END(ctx->dlg); + + RND_DAD_DEFSIZE(ctx->dlg, 400, 300); + RND_DAD_NEW("AttributeDialog", ctx->dlg, ctx->name, ctx, modal, attrdlg_close_cb); /* type=local */ + + aattr_dlg_init(&ctx->right); + + if (pick) { + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wvaledit, 1); + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->right.wright, 1); + } + + /* grp refs shouldn't allow floaters to be created: no new object in a ref */ + if (obj->hdr.type != CSCH_CTYPE_GRP) + rnd_gui->attr_dlg_widget_state(ctx->dlg_hid_ctx, ctx->wfloater, 0); + + if (!pick && (target_key != NULL)) + new_key = !htsp_has(&obj->attr, target_key); + + sheet2dlg_cursor(ctx, target_key, new_key); + if (!pick && (target_key != NULL)) { + if (new_key) { /* fill in key and prio */ + rnd_hid_attr_val_t hv; + + hv.str = target_key; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wkey, &hv); + + hv.lng = CSCH_ATP_USER_DEFAULT; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wprio, &hv); + } + else + RND_DAD_STRING_SELECT_REGION(ctx->dlg_hid_ctx, ctx->wval_str, 0, 1<<30); + } + + if (modal) { + const char *ret = NULL; + + if (RND_DAD_RUN(ctx->dlg) == 1) { + if (ctx->last_attr_key != NULL) + ret = ctx->last_attr_key; + } + + free(ctx); + return ret; + } + return NULL; +} + + +extern csch_chdr_t *csch_obj_clicked; + +RND_INLINE csch_chdr_t *resolve_obj_(csch_sheet_t *sheet, const char *actname, const char *cmd, int *has_coords) +{ + *has_coords = 0; + + if (strcmp(cmd, "last-click") == 0) { + *has_coords = 1; + return csch_obj_clicked; + } + else if (strcmp(cmd, "parent") == 0) { + if (csch_obj_clicked != NULL) { + *has_coords = 1; + return &csch_obj_clicked->parent->hdr; + } + } + else if (strcmp(cmd, "sheet") == 0) { + return &sheet->direct.hdr; + } + else if (strncmp(cmd, "object", 6) == 0) { + if (cmd[6] == ':') { + csch_chdr_t *obj; + csch_oidpath_t idp = {0}; + + if (csch_oidpath_parse(&idp, cmd+7) != 0) { + rnd_message(RND_MSG_ERROR, "%s: Failed to convert object ID: '%s'\n", actname, cmd+7); + return NULL; + } + obj = csch_oidpath_resolve(sheet, &idp); + csch_oidpath_free(&idp); + return obj; + } + else { + rnd_coord_t x, y; + + rnd_hid_get_coords("Attribute edit/pick dialog: select object", &x, &y, 0); + *has_coords = 1; + return sch_rnd_search_first_gui_inspect(sheet, sch_rnd_crosshair_x, sch_rnd_crosshair_y); + } + } + else { + rnd_message(RND_MSG_ERROR, "%s: invalid first arg\n", actname); + return NULL; + } + + rnd_message(RND_MSG_ERROR, "%s: no such object\n", actname); + return NULL; +} + +csch_chdr_t *sch_dialog_resolve_obj(csch_sheet_t *sheet, const char *actname, const char *cmd, int *has_coords) +{ + csch_chdr_t *obj = resolve_obj_(sheet, actname, cmd, has_coords); + + /* if found a floater or wire, fall back to parent silently but do not end up editing sheet attrs that way */ + if ((obj != NULL) && (!csch_obj_is_grp(obj))) { + obj = &obj->parent->hdr; + if (obj == &sheet->direct.hdr) { + rnd_message(RND_MSG_ERROR, "%s: object is not a group.\n(Only groups have attributes)\n", actname); + return NULL; + } + } + + if (!csch_obj_is_grp(obj)) { + rnd_message(RND_MSG_ERROR, "%s: object is not a group.\n(Only groups have attributes)\n", actname); + return NULL; + } + return obj; +} + + +const char csch_acts_AttributeDialog[] = "AttributeDialog([last-click|parent|sheet|object[:idpath]], [target_key])"; +const char csch_acth_AttributeDialog[] = "Bring up the Attribute Editor Dialog for an object.\n"; +fgw_error_t csch_act_AttributeDialog(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_design_t *hidlib = RND_ACT_DESIGN; + csch_sheet_t *sheet = (csch_sheet_t *)hidlib; + const char *cmd = "object", *target_key = NULL; + csch_chdr_t *obj = NULL; + int has_coords; + + RND_ACT_MAY_CONVARG(1, FGW_STR, AttributeDialog, cmd = argv[1].val.str); + RND_ACT_MAY_CONVARG(2, FGW_STR, AttributeDialog, target_key = argv[2].val.str); + + obj = sch_dialog_resolve_obj(sheet, "AttributeDialog", cmd, &has_coords); + if (obj == NULL) { + RND_ACT_IRES(-1); + return 0; + } + + if (!csch_obj_is_grp(obj)) { + rnd_message(RND_MSG_ERROR, "AttributeDialog(): object is not a group\n"); + RND_ACT_IRES(-1); + return 0; + } + + attr_dlg(sheet, (csch_cgrp_t *)obj, target_key, 0, has_coords); + + RND_ACT_IRES(0); + return 0; +} + +const char csch_acts_AttributePick[] = "AttributePick([last-click|parent|object[:idpath]], [target_key])"; +const char csch_acth_AttributePick[] = "Bring up the Attribute Pick Dialog and ask the user to pick an attribute of an object.\n"; +fgw_error_t csch_act_AttributePick(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_design_t *hidlib = RND_ACT_DESIGN; + csch_sheet_t *sheet = (csch_sheet_t *)hidlib; + const char *cmd = "object", *target_key = NULL; + csch_chdr_t *obj = NULL; + const char *key; + int has_coords; + + RND_ACT_MAY_CONVARG(1, FGW_STR, AttributePick, cmd = argv[1].val.str); + + obj = sch_dialog_resolve_obj(sheet, "AttributePick", cmd, &has_coords); + if ((obj == NULL) || (!csch_obj_is_grp(obj))) { + res->type = FGW_PTR; + res->val.ptr_void = NULL; + return 0; + } + + key = attr_dlg(sheet, (csch_cgrp_t *)obj, target_key, 1, has_coords); + + res->type = FGW_STR; + res->val.cstr = key; + return 0; +} + + +void csch_dlg_attr_preunload(csch_sheet_t *sheet) +{ + attrdlg_ctx_t *n, *next; + rnd_dad_retovr_t retovr = {0}; + + for(n = gdl_first(&attrdlgs); n != NULL; n = next) { + next = gdl_next(&attrdlgs, n); + if (n->sheet == sheet) + rnd_hid_dad_close(n->dlg_hid_ctx, &retovr, 0); + } +} + + +void csch_dlg_attr_edit(csch_sheet_t *sheet) +{ + attrdlg_ctx_t *n, *next; + rnd_dad_retovr_t retovr = {0}; + + for(n = gdl_first(&attrdlgs); n != NULL; n = next) { + next = gdl_next(&attrdlgs, n); + if (n->sheet == sheet) { + if (csch_obj_is_deleted(&n->obj->hdr)) + rnd_hid_dad_close(n->dlg_hid_ctx, &retovr, 0); + } + } +} + +void csch_dlg_attr_compiled(csch_project_t *prj) +{ + attrdlg_ctx_t *n, *next; + + for(n = gdl_first(&attrdlgs); n != NULL; n = next) { + next = gdl_next(&attrdlgs, n); + if ((csch_project_t *)n->sheet->hidlib.project == prj) + sheet2dlg(n); + } +} + + +void csch_dlg_attr_obj_attr_edit(csch_sheet_t *sheet, csch_cgrp_t *obj) +{ + attrdlg_ctx_t *n; + + for(n = gdl_first(&attrdlgs); n != NULL; n = gdl_next(&attrdlgs, n)) + if (!n->refresh_lock && (n->sheet == sheet) && (n->obj == obj)) + sheet2dlg(n); +} + Index: tags/1.0.5/src/plugins/sch_dialogs/dlg_attrib.h =================================================================== --- tags/1.0.5/src/plugins/sch_dialogs/dlg_attrib.h (nonexistent) +++ tags/1.0.5/src/plugins/sch_dialogs/dlg_attrib.h (revision 10414) @@ -0,0 +1,18 @@ +#include + +extern const char csch_acts_AttributeDialog[]; +extern const char csch_acth_AttributeDialog[]; +extern fgw_error_t csch_act_AttributeDialog(fgw_arg_t *res, int argc, fgw_arg_t *argv); + +extern const char csch_acts_AttributePick[]; +extern const char csch_acth_AttributePick[]; +extern fgw_error_t csch_act_AttributePick(fgw_arg_t *res, int argc, fgw_arg_t *argv); + +void csch_dlg_attr_preunload(csch_sheet_t *sheet); +void csch_dlg_attr_edit(csch_sheet_t *sheet); +void csch_dlg_attr_obj_attr_edit(csch_sheet_t *sheet, csch_cgrp_t *obj); +void csch_dlg_attr_compiled(csch_project_t *prj); + + +csch_chdr_t *sch_dialog_resolve_obj(csch_sheet_t *sheet, const char *actname, const char *cmd, int *has_coords); + Index: tags/1.0.5/src/plugins/sch_dialogs/dlg_cond.c =================================================================== --- tags/1.0.5/src/plugins/sch_dialogs/dlg_cond.c (nonexistent) +++ tags/1.0.5/src/plugins/sch_dialogs/dlg_cond.c (revision 10414) @@ -0,0 +1,357 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - GUI - conditionals + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/* stance configuration dialog */ + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "quick_attr_util.h" + +/*** Conditional ***/ + +typedef enum { CDLG_DNP, CDLG_OMIT } cond_dlg_type_t; + +typedef struct cond_dlg_ctx_s { + RND_DAD_DECL_NOINIT(dlg) + + csch_sheet_t *sheet; + csch_oidpath_t idp; + const char *attr_name; + cond_dlg_type_t type; + + int wcond, wscript; + + void *obj; /* for the hash */ +} cond_dlg_ctx_t; + +static htpp_t obj2dlg; + +static void cond_apply(cond_dlg_ctx_t *ctx) +{ + vts0_t lst = {0}; + rnd_hid_attribute_t *atxt = &ctx->dlg[ctx->wscript]; + rnd_hid_text_t *txt = atxt->wdata; + char *tmp = txt->hid_get_text(atxt, ctx->dlg_hid_ctx), *s, *next; + csch_source_arg_t *src = csch_attrib_src_c(NULL, 0, 0, "ConditionalDialog input"); + csch_cgrp_t *obj = (csch_cgrp_t *)csch_oidpath_resolve(ctx->sheet, &ctx->idp); + + if (obj == NULL) { + rnd_message(RND_MSG_ERROR, "ConditionalDialog: can't apply: object does not exist\n"); + rnd_gui->attr_dlg_widget_state(ctx->dlg_hid_ctx, ctx->wcond, 0); + rnd_gui->attr_dlg_widget_state(ctx->dlg_hid_ctx, ctx->wscript, 0); + return; + } + + vts0_append(&lst, (char *)ctx->dlg[ctx->wcond].val.str); + for(s = tmp; (s != NULL) && (*s != '\0'); s = next) { + next = strpbrk(s, "\r\n"); + if (next != NULL) { + *next = '\0'; + next++; + } + vts0_append(&lst, s); + } + + csch_attrib_set_arr(&obj->attr, CSCH_ATP_USER_DEFAULT, ctx->attr_name, &lst, src, NULL); + csch_sheet_set_changed(obj->hdr.sheet, 1); + free(tmp); + vts0_uninit(&lst); +} + + +static void cond_dlg_close_cb(void *caller_data, rnd_hid_attr_ev_t ev) +{ + cond_dlg_ctx_t *ctx = caller_data; + + if (ctx->dlg_ret_override->value == 1) + cond_apply(ctx); + + csch_oidpath_free(&ctx->idp); + + htpp_pop(&obj2dlg, ctx->obj); + free(ctx); +} + +static void cond_obj2dlg(cond_dlg_ctx_t *ctx) +{ + csch_attrib_t *fa; + rnd_hid_attr_val_t hv; + gds_t tmp = {0}; + csch_cgrp_t *obj = (csch_cgrp_t *)csch_oidpath_resolve(ctx->sheet, &ctx->idp); + + if (obj == NULL) { + rnd_message(RND_MSG_ERROR, "ConditionalDialog: can't apply: object does not exist\n"); + rnd_gui->attr_dlg_widget_state(ctx->dlg_hid_ctx, ctx->wcond, 0); + rnd_gui->attr_dlg_widget_state(ctx->dlg_hid_ctx, ctx->wscript, 0); + return; + } + + fa = csch_attrib_get(&obj->attr, ctx->attr_name); + + if ((fa == NULL) || (fa->arr.used < 1)) + hv.str = "stance.model != \"standard\""; + else + hv.str = fa->arr.array[0]; + + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wcond, &hv); + + if ((fa == NULL) || (fa->arr.used < 2)) { + switch(ctx->type) { + case CDLG_DNP: gds_append_str(&tmp, "scalar,dnp\nsub,^.*$,yes,dnp\n"); break; + case CDLG_OMIT: gds_append_str(&tmp, "scalar,omit\nsub,^.*$,yes,omit\n"); break; + } + } + else { + long n; + for(n = 1; n < fa->arr.used; n++) { + gds_append_str(&tmp, fa->arr.array[n]); + gds_append(&tmp, '\n'); + } + } + + hv.str = tmp.array; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wscript, &hv); + gds_uninit(&tmp); +} + +static void cond_apply_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + cond_apply(caller_data); +} + +int sch_rnd_conditional_dlg(csch_cgrp_t *obj, cond_dlg_type_t type) +{ + cond_dlg_ctx_t *ctx; + rnd_hid_dad_buttons_t clbtn[] = {{"Cancel", 0}, {"Apply & close", 1}, {NULL, 0}}; + const char *attr_name; + csch_sheet_t *sheet = obj->hdr.sheet; + + while((obj != NULL) && !csch_obj_is_grp(&obj->hdr)) obj = obj->hdr.parent; + + if ((obj == NULL) || (obj == &sheet->direct)) { + rnd_message(RND_MSG_ERROR, "sch_rnd_conditional_dlg(): object is not in a group\n"); + return -1; + } + + if ((obj->role != CSCH_ROLE_SYMBOL) && (obj->role != CSCH_ROLE_WIRE_NET)) { + rnd_message(RND_MSG_ERROR, "sch_rnd_conditional_dlg(): group shall be a symbol or a wirenet\n"); + return -1; + } + + switch(type) { + case CDLG_DNP: attr_name = "forge-if/dnp"; break; + case CDLG_OMIT: attr_name = "forge-if/omit"; break; + default: return -1; + } + + ctx = htpp_get(&obj2dlg, obj); + if (ctx != NULL) { + TODO("raise?"); + return 0; + } + + ctx = calloc(sizeof(cond_dlg_ctx_t), 1); + ctx->obj = obj; + ctx->sheet = sheet; + ctx->attr_name = attr_name; + ctx->type = type; + + htpp_set(&obj2dlg, obj, ctx); + csch_oidpath_from_obj(&ctx->idp, &obj->hdr); + + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Attribute: "); + RND_DAD_LABEL(ctx->dlg, ctx->attr_name); + RND_DAD_END(ctx->dlg); + + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Cond.:"); + RND_DAD_STRING(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + ctx->wcond = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_END(ctx->dlg); + + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_LABEL(ctx->dlg, "Script:"); + RND_DAD_TEXT(ctx->dlg, ""); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL | RND_HATF_SCROLL); + ctx->wscript = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_END(ctx->dlg); + + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "Apply"); + RND_DAD_CHANGE_CB(ctx->dlg, cond_apply_cb); + + RND_DAD_BEGIN_VBOX(ctx->dlg); /* spring */ + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_END(ctx->dlg); + + RND_DAD_BUTTON_CLOSES(ctx->dlg, clbtn); + RND_DAD_END(ctx->dlg); + + RND_DAD_END(ctx->dlg); + + RND_DAD_DEFSIZE(ctx->dlg, 300, 400); + RND_DAD_NEW("ConditionalDialog", ctx->dlg, "Conditional forge quick edit", ctx, 0, cond_dlg_close_cb); /* type=local */ + + cond_obj2dlg(ctx); + return 0; +} + +void csch_dlg_cond_preunload(csch_sheet_t *sheet) +{ + htpp_entry_t *e; + rnd_dad_retovr_t retovr = {0}; + + for(e = htpp_first(&obj2dlg); e != NULL; e = htpp_next(&obj2dlg, e)) { + cond_dlg_ctx_t *ctx = e->value; + if (ctx->sheet == sheet) + rnd_hid_dad_close(ctx->dlg_hid_ctx, &retovr, 0); + } +} + +const char csch_acts_ConditionalDialog[] = "ConditionalDialog(object, dnp|omit)"; +const char csch_acth_ConditionalDialog[] = "Open the conditional helper dialog for an object.\n"; +fgw_error_t csch_act_ConditionalDialog(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_design_t *hidlib = RND_ACT_DESIGN; + csch_sheet_t *sheet = (csch_sheet_t *)hidlib; + const char *stype; + csch_chdr_t *obj; + int cmd; + cond_dlg_type_t type; + + CSCH_ACT_CONVARG_OBJ(1, ConditionalDialog, cmd, obj); + RND_ACT_MAY_CONVARG(2, FGW_STR, ConditionalDialog, stype = argv[2].val.cstr); + + if (rnd_strcasecmp(stype, "dnp") == 0) type = CDLG_DNP; + else if (rnd_strcasecmp(stype, "omit") == 0) type = CDLG_OMIT; + else { + rnd_message(RND_MSG_ERROR, "ConditionalDialog(): invalid second argument (type)\n"); + return FGW_ERR_ARG_CONV; + } + + switch(cmd) { + case F_Object: + { + csch_coord_t x, y; + + if (obj == NULL) { + if (sch_rnd_get_coords("Click on a symbol for editing conditionals", &x, &y, 0) != 0) + break; + obj = sch_rnd_search_obj_at(sheet, x, y, sch_rnd_slop); + if (obj == NULL) { + rnd_message(RND_MSG_ERROR, "ConditionalDialog(): no symbol under cursor\n"); + break; + } + } + } + break; + default: + rnd_message(RND_MSG_ERROR, "ConditionalDialog(): invalid first argument\n"); + return FGW_ERR_ARG_CONV; + } + + return sch_rnd_conditional_dlg((csch_cgrp_t *)obj, type); +} + +const char csch_acts_quick_attr_forge__if__dnp[] = "quick_attr_forge__if__dnp(objptr)"; +const char csch_acth_quick_attr_forge__if__dnp[] = "Quick Attribute Edit for the standard forge-if/dnp attribute"; +const char csch_acts_quick_attr_forge__if__omit[] = "quick_attr_forge__if__dnp(objptr)"; +const char csch_acth_quick_attr_forge__if__omit[] = "Quick Attribute Edit for the standard forge-if/omit attribute"; +fgw_error_t csch_act_quick_attr_forge__if__dnp_omit(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *fname = argv[0].val.argv0.func->name; + csch_cgrp_t *grp; + + if (strlen(fname) < 22) { + rnd_message(RND_MSG_ERROR, "csch_act_quick_attr_forge__if__dnp_omit(): called with invalid name '%s' (1)\n", fname); + return FGW_ERR_ARG_CONV; + } + + QUICK_ATTR_GET_GRP(grp, "csch_act_quick_attr_forge__if__dnp_omit"); + + switch(fname[22]) { + case 'd': sch_rnd_conditional_dlg(grp, CDLG_DNP); break; + case 'o': sch_rnd_conditional_dlg(grp, CDLG_OMIT); break; + default: + rnd_message(RND_MSG_ERROR, "csch_act_quick_attr_forge__if__dnp_omit(): called with invalid name '%s' (2)\n", fname); + return FGW_ERR_ARG_CONV; + } + + return 0; +} + + + +/*** Common ***/ + +void csch_dlg_cond_init(void) +{ + htpp_init(&obj2dlg, ptrhash, ptrkeyeq); +} + +void csch_dlg_cond_uninit(void) +{ + rnd_dad_retovr_t retovr = {0}; + htpp_entry_t *e; + + for(e = htpp_first(&obj2dlg); e != NULL; e = htpp_next(&obj2dlg, e)) { + cond_dlg_ctx_t *ctx = e->value; + rnd_hid_dad_close(ctx->dlg_hid_ctx, &retovr, 0); + } + htpp_uninit(&obj2dlg); +} Index: tags/1.0.5/src/plugins/sch_dialogs/dlg_cond.h =================================================================== --- tags/1.0.5/src/plugins/sch_dialogs/dlg_cond.h (nonexistent) +++ tags/1.0.5/src/plugins/sch_dialogs/dlg_cond.h (revision 10414) @@ -0,0 +1,13 @@ +void csch_dlg_cond_init(void); +void csch_dlg_cond_uninit(void); + + +extern const char csch_acts_ConditionalDialog[]; +extern const char csch_acth_ConditionalDialog[]; +fgw_error_t csch_act_ConditionalDialog(fgw_arg_t *res, int argc, fgw_arg_t *argv); + +extern const char csch_acts_quick_attr_forge__if__dnp[]; +extern const char csch_acth_quick_attr_forge__if__dnp[]; +extern const char csch_acts_quick_attr_forge__if__omit[]; +extern const char csch_acth_quick_attr_forge__if__omit[]; +fgw_error_t csch_act_quick_attr_forge__if__dnp_omit(fgw_arg_t *res, int argc, fgw_arg_t *argv); Index: tags/1.0.5/src/plugins/sch_dialogs/dlg_infobar.c =================================================================== --- tags/1.0.5/src/plugins/sch_dialogs/dlg_infobar.c (nonexistent) +++ tags/1.0.5/src/plugins/sch_dialogs/dlg_infobar.c (revision 10414) @@ -0,0 +1,124 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - GUI + * Copyright (C) 2018,2022 Tibor 'Igor2' Palinkas + * Copied from pcb-rnd by the original author + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* Common dialogs: simple, modal dialogs and info bars. + Even the core will run some of these, through a dispatcher (e.g. + action). */ + +#include +#include +#include +#include + +#include + +#include + +static void ifb_file_chg_reload_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + rnd_design_t *dsg = rnd_gui->get_dad_design(hid_ctx); + csch_revert_sheet((csch_sheet_t *)dsg, sch_rnd_sheet_new4revert); + rnd_actionva(dsg, "InfoBarFileChanged", "close", NULL); +} + +static void ifb_file_chg_close_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + rnd_design_t *dsg = rnd_gui->get_dad_design(hid_ctx); + rnd_actionva(dsg, "InfoBarFileChanged", "close", NULL); +} + +const char csch_acts_InfoBarFileChanged[] = "InfoBarFileChanged(open|close)\n"; +const char csch_acth_InfoBarFileChanged[] = "Present the \"file changed\" warning info bar with buttons to reload or cancel"; +fgw_error_t csch_act_InfoBarFileChanged(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + static rnd_hid_dad_subdialog_t sub; + static int active = 0, wlab[2]; + rnd_design_t *dsg = RND_ACT_DESIGN; + csch_sheet_t *sheet = (csch_sheet_t *)dsg; + rnd_hid_attr_val_t hv; + const char *cmd; + + if (!RND_HAVE_GUI_ATTR_DLG) { + RND_ACT_IRES(0); + return 0; + } + + RND_ACT_CONVARG(1, FGW_STR, InfoBarFileChanged, cmd = argv[1].val.str); + + if (strcmp(cmd, "open") == 0) { + if (!active) { + RND_DAD_BEGIN_HBOX(sub.dlg); + RND_DAD_COMPFLAG(sub.dlg, RND_HATF_EXPFILL | RND_HATF_FRAME); + RND_DAD_BEGIN_VBOX(sub.dlg); + RND_DAD_PICTURE(sub.dlg, rnd_dlg_xpm_by_name("warning")); + RND_DAD_END(sub.dlg); + RND_DAD_BEGIN_VBOX(sub.dlg); + RND_DAD_COMPFLAG(sub.dlg, RND_HATF_EXPFILL); + RND_DAD_BEGIN_HBOX(sub.dlg); RND_DAD_COMPFLAG(sub.dlg, RND_HATF_EXPFILL); RND_DAD_END(sub.dlg); + RND_DAD_LABEL(sub.dlg, "line0"); + wlab[0] = RND_DAD_CURRENT(sub.dlg); + RND_DAD_LABEL(sub.dlg, "line1"); + wlab[1] = RND_DAD_CURRENT(sub.dlg); + RND_DAD_BEGIN_HBOX(sub.dlg); RND_DAD_COMPFLAG(sub.dlg, RND_HATF_EXPFILL); RND_DAD_END(sub.dlg); + RND_DAD_END(sub.dlg); + RND_DAD_BEGIN_VBOX(sub.dlg); + RND_DAD_BUTTON(sub.dlg, "Reload"); + RND_DAD_HELP(sub.dlg, "Load the new verison of the file from disk,\ndiscarding any in-memory change on the board"); + RND_DAD_CHANGE_CB(sub.dlg, ifb_file_chg_reload_cb); + RND_DAD_BEGIN_HBOX(sub.dlg); RND_DAD_COMPFLAG(sub.dlg, RND_HATF_EXPFILL); RND_DAD_END(sub.dlg); + RND_DAD_BUTTON(sub.dlg, "Cancel"); + RND_DAD_HELP(sub.dlg, "Hide this info bar until the file changes again on disk"); + RND_DAD_CHANGE_CB(sub.dlg, ifb_file_chg_close_cb); + RND_DAD_END(sub.dlg); + RND_DAD_END(sub.dlg); + if (rnd_hid_dock_enter(&sub, RND_HID_DOCK_TOP_INFOBAR, "file_changed") != 0) { + RND_ACT_IRES(1); + return 0; + } + active = 1; + } + + /* update labels */ + hv.str = rnd_strdup_printf("The file %s has changed on disk", dsg->fullpath); + rnd_gui->attr_dlg_set_value(sub.dlg_hid_ctx, wlab[0], &hv); + free((char *)hv.str); + + hv.str = (sheet->changed ? "Do you want to drop your changes and reload the file?" : "Do you want to reload the file?"); + rnd_gui->attr_dlg_set_value(sub.dlg_hid_ctx, wlab[1], &hv); + } + else if (strcmp(cmd, "close") == 0) { + if (active) { + rnd_hid_dock_leave(&sub); + active = 0; + } + } + else + RND_ACT_FAIL(InfoBarFileChanged); + + RND_ACT_IRES(0); + return 0; +} Index: tags/1.0.5/src/plugins/sch_dialogs/dlg_library.c =================================================================== --- tags/1.0.5/src/plugins/sch_dialogs/dlg_library.c (nonexistent) +++ tags/1.0.5/src/plugins/sch_dialogs/dlg_library.c (revision 10414) @@ -0,0 +1,1138 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - GUI - library dialog + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * (icons copied from pcb-rnd by the author) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/* symbol library dialog */ + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "adialogs_conf.h" + +#define MAX_PARAMS 128 + +typedef struct library_dlg_ctx_s library_ctx_t; +typedef csch_lib_t library_ent_t; + +#include "../../../src_3rd/rnd_inclib/dialogs/dlg_library_param.h" + +typedef struct library_dlg_ctx_s { + RND_DAD_DECL_NOINIT(dlg) + csch_sheet_t *sheet; + csch_lib_master_t *master; + char *title; + int wtree, wfilt, wpreview, wpend, wnopend, wprev_text, wedit; + int wlocframe, wloc_del, wloc_refresh, wloc_edit, wloc_list; + + rnd_hidval_t timer; + unsigned timer_active:1; + unsigned active:1; + unsigned last_clicked:1; + + library_param_ctx_t param; /* for the parametric */ + + int modal; + char *last_path; + csch_sheet_t prsh; /* temp sheet for preview */ +} library_dlg_ctx_t; + +static htip_t sheetlib2dlg; + + +/* XPM */ +static const char *xpm_edit_param[] = { +"16 16 4 1", +"@ c #000000", +"* c #7A8584", +"+ c #6EA5D7", +" c None", +" ", +" @ @ ", +" @ ++++++++ @ ", +" @ + + @ ", +" @ + @@@@ + @ ", +" @ + + @ ", +"@ + @@ + @", +"@ + + @", +"@ + @ @ @+ @", +"@ + + @", +" @ + @@ + @ ", +" @ + @@@@ + @ ", +" @ + + @ ", +" @ ++++++++ @ ", +" @ @ ", +" " +}; + + +/* XPM */ +static const char *xpm_refresh[] = { +"16 16 4 1", +"@ c #000000", +"* c #7A8584", +"+ c #6EA5D7", +" c None", +" @ ", +" @@@@@@@ ", +" @@@ @@ ", +" @@@@ @ ", +" @ ", +" @ ", +" @ ", +" @ @ ", +" @ @ ", +" @ ", +" @ ", +" @ ", +" @ @@@@ ", +" @@ @@@ ", +" @@@@@@@ ", +" @ ", +}; + +/* XPM */ +static const char *xpm_loc_count[] = { +"16 16 4 1", +"@ c #000000", +"* c #7A8584", +"+ c #6EA5D7", +" c None", + +" ", +" @@@@ @@@@ ", +" @++@ @++@ ", +"@@@@++@@@@++@@@@", +"@++++++++++++++@", +"@++++++++++++++@", +"@@@@++@@@@++@@@@", +" @++@ @++@ ", +" @++@ @++@ ", +"@@@@++@@@@++@@@@", +"@++++++++++++++@", +"@++++++++++++++@", +"@@@@++@@@@++@@@@", +" @++@ @++@ ", +" @@@@ @@@@ ", +" " +}; + +/* XPM */ +static const char *xpm_loc_del[] = { +"16 16 4 1", +"@ c #000000", +"* c #7A8584", +"+ c #6EA5D7", +" c None", + +" ", +" ", +" ", +" @@ @@ ", +" @+@ @+@ ", +" @+@ @+@ ", +" @+@@+@ ", +" @++@ ", +" @++@ ", +" @+@@+@ ", +" @+@ @+@ ", +" @+@ @+@ ", +" @@ @@ ", +" ", +" ", +" " +}; + + +/* XPM */ +static const char *xpm_loc_refresh[] = { +"16 16 4 1", +"@ c #000000", +"* c #7A8584", +"+ c #6EA5D7", +" c None", +" @ ", +" @@@@@@@ ", +" @@@ @@ ", +" @@@@ @ ", +" @ ", +" @@@@@ @ ", +" @ @ ", +" @ @@@ @ ", +" @ @@@ @ ", +" @ @ ", +" @ @@@@@ ", +" @ ", +" @ @@@@ ", +" @@ @@@ ", +" @@@@@@@ ", +" @ ", +}; + +/* XPM */ +static const char *xpm_loc_edit[] = { +"16 16 4 1", +"@ c #000000", +"* c #7A8584", +"+ c #6EA5D7", +" c None", +" ", +" ", +" ++++++++++++ ", +" + + ", +" + @@@ @ @@ + ", +" + + ", +" + @@ @@ @ + ", +" + + ", +" + @ @ @@@ @+ ", +" + + ", +" + @@ @@ + ", +" + @@@@@ @@ + ", +" + + ", +" ++++++++++++ ", +" ", +" " +}; + +/***/ + +static void library_filter_reapply(void *hid_ctx, library_dlg_ctx_t *ctx); + +static long sheetlib_id(const csch_sheet_t *sheet, const csch_lib_master_t *master) +{ + if (master->uid > 255) + rnd_message(RND_MSG_ERROR, "Internal error: library type ID %d too large\nPlease report this bug.\n*** SAVE AND EXIT ASAP ***\n"); + if (sheet != NULL) return (sheet->uid << 8) + master->uid; + return -master->uid; +} + +static library_dlg_ctx_t *sheetlib_lookup(const csch_sheet_t *sheet, const csch_lib_master_t *master) +{ + return htip_get(&sheetlib2dlg, sheetlib_id(sheet, master)); +} + +static void sheetlib_set(const csch_sheet_t *sheet, const csch_lib_master_t *master, library_dlg_ctx_t *ctx) +{ + htip_set(&sheetlib2dlg, sheetlib_id(sheet, master), ctx); +} + +static void sheetlib_del(const csch_sheet_t *sheet, const csch_lib_master_t *master) +{ + htip_pop(&sheetlib2dlg, sheetlib_id(sheet, master)); +} + + +static csch_cgrp_t *first_grp(const csch_cgrp_t *src) +{ + htip_entry_t *e; + for(e = htip_first(&src->id2obj); e != NULL; e = htip_next(&src->id2obj, e)) { + csch_cgrp_t *obj = e->value; + if (csch_obj_is_grp(&obj->hdr)) + return obj; + } + return NULL; +} + +static void library_update_preview_sym(library_dlg_ctx_t *ctx, csch_lib_t *l, const char *parametric) +{ + rnd_box_t bbox; + rnd_hid_attr_val_t hv; + gds_t tmp = {0}; + char *param = NULL; + + sch_rnd_buffer_clear(&ctx->prsh); + if (parametric != NULL) { + char *name, *end; + + gds_append_str(&tmp, parametric); + name = tmp.array; + param = strchr(name, '('); + if (param == NULL) { + rnd_message(RND_MSG_ERROR, "library_update_preview(): internal error: parametric without parameters '%s'\n", parametric); + goto error; + } + + *param = '\0'; + param++; + end = strrchr(param, ')'); + if (end != NULL) + *end = '\0'; + + if (ctx->sheet != NULL) + l = csch_lib_search(ctx->sheet->libs.array[ctx->master->uid], name, CSCH_SLIB_PARAMETRIC); + else + l = csch_lib_search_master(ctx->master, name, CSCH_SLIB_PARAMETRIC); + + if (l == NULL) { + rnd_message(RND_MSG_ERROR, "library_update_preview(): parametric '%s' not found in the library\n", name); + goto error; + } + tmp.used = 0; + } + if (l != NULL) { + csch_cgrp_t *sym; + const csch_rtree_box_t *shb; + csch_coord_t wm, hm; + csch_lib_load(ctx->sheet, &ctx->prsh, l, param); + sym = first_grp(&ctx->prsh.direct); + + shb = csch_sheet_bbox(&ctx->prsh); + wm = (shb->x2 - shb->x1) / 4; + hm = (shb->y2 - shb->y1) / 4; + + bbox.X1 = C2P(shb->x1 - wm); + bbox.Y1 = C2P(shb->y1 - hm); + bbox.X2 = C2P(shb->x2 + wm); + bbox.Y2 = C2P(shb->y2 + hm); + + rnd_dad_preview_zoomto(&ctx->dlg[ctx->wpreview], &bbox); + + sch_rnd_buffer_clear(SCH_RND_PASTEBUFFER); + if (sym != NULL) { + csch_cobj_dup(SCH_RND_PASTEBUFFER, &SCH_RND_PASTEBUFFER->direct, &sym->hdr, 0, 0); + rnd_tool_select_by_name(&ctx->sheet->hidlib, "buffer"); + } + } + + if (l != NULL) { + hv.str = "TODO: fill in tags"; + } + else + hv.str = ""; + + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wprev_text, &hv); + + error:; + gds_uninit(&tmp); +} + +static void library_update_preview(library_dlg_ctx_t *ctx, csch_lib_t *l, const char *parametric) +{ + if ((l != NULL) && (l->backend != NULL)) { + if (l->backend->preview_text != NULL) { + rnd_hid_attr_val_t hv; + char *tmp = l->backend->preview_text(ctx->sheet, l, parametric); + hv.str = tmp == NULL ? "" : tmp; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wprev_text, &hv); + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wpreview, 1); + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wprev_text, 0); + free(tmp); + return; + } + } + + /* fallback: assume a simple symbol */ + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wpreview, 0); + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wprev_text, 0); + library_update_preview_sym(ctx, l, parametric); +} + + +static void create_lib_tree_model_recurse(rnd_hid_attribute_t *attr, csch_lib_t *subtree, rnd_hid_row_t *parent_row) +{ + const char *name; + char *cell[2]; + rnd_hid_row_t *row; + + name = subtree->name; + if (*name == '?') + name++; + + cell[0] = rnd_strdup(name); + cell[1] = NULL; + row = rnd_dad_tree_append_under(attr, parent_row, cell); + row->user_data = subtree; + + if (subtree->type == CSCH_SLIB_DIR) { + long n; + for(n = 0; n < subtree->children.used; n++) + create_lib_tree_model_recurse(attr, subtree->children.array[n], row); + } +} + +static void library_sheet2dlg(library_dlg_ctx_t *ctx) +{ + rnd_hid_attribute_t *attr; + rnd_hid_tree_t *tree; + rnd_hid_row_t *r; + char *cursor_path = NULL; + + attr = &ctx->dlg[ctx->wtree]; + tree = attr->wdata; + + /* remember cursor */ + r = rnd_dad_tree_get_selected(attr); + if (r != NULL) + cursor_path = rnd_strdup(r->path); + + /* remove existing items */ + rnd_dad_tree_clear(tree); + + /* add all items recursively */ + if (ctx->sheet == NULL) { + htsp_entry_t *e; + for(e = htsp_first(&ctx->master->roots); e != NULL; e = htsp_next(&ctx->master->roots, e)) + create_lib_tree_model_recurse(attr, e->value, NULL); + } + else { + long n; + csch_lib_root_t *libroot; + + /* local lib */ + libroot = ctx->sheet->local_libs.array[ctx->master->uid]; + if (libroot != NULL) + create_lib_tree_model_recurse(attr, libroot->roots.array[0], NULL); + + /* external libs */ + libroot = NULL; + if (ctx->master->uid < ctx->sheet->libs.used) + libroot = ctx->sheet->libs.array[ctx->master->uid]; + + if (libroot != NULL) + for(n = 0; n < libroot->roots.used; n++) + create_lib_tree_model_recurse(attr, libroot->roots.array[n], NULL); + } + + /* restore cursor */ + if (cursor_path != NULL) { + rnd_hid_attr_val_t hv; + hv.str = cursor_path; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wtree, &hv); + free(cursor_path); + } +} + +static void library_tree_unhide(rnd_hid_tree_t *tree, gdl_list_t *rowlist, re_sei_t *preg, vtp0_t *taglist) +{ + rnd_hid_row_t *r, *pr; + + for(r = gdl_first(rowlist); r != NULL; r = gdl_next(rowlist, r)) { + if ((preg == NULL) || (re_sei_exec(preg, r->cell[0]))) { + rnd_dad_tree_hide_all(tree, &r->children, 0); /* if this is a node with children, show all children */ + for(pr = r; pr != NULL; pr = rnd_dad_tree_parent_row(tree, pr)) /* also show all parents so it is visible */ + pr->hide = 0; + } + library_tree_unhide(tree, &r->children, preg, taglist); + } +} + + + + +static rnd_bool library_mouse(rnd_hid_attribute_t *attrib, rnd_hid_preview_t *prv, rnd_hid_mouse_ev_t kind, rnd_coord_t x, rnd_coord_t y) +{ + return rnd_false; +} + +static void library_expose_grp(rnd_hid_attribute_t *attrib, rnd_hid_preview_t *prv, rnd_hid_gc_t gc, rnd_hid_expose_ctx_t *e) +{ + library_dlg_ctx_t *ctx = prv->user_ctx; + rnd_xform_t xform = {0}; + + xform.fallback_pen = &ctx->sheet->direct; + sch_rnd_draw_sheet(&ctx->prsh, gc, e, &xform); +} + +static void library_expose(rnd_hid_attribute_t *attrib, rnd_hid_preview_t *prv, rnd_hid_gc_t gc, rnd_hid_expose_ctx_t *e) +{ + TODO("do this only if master has "); + library_expose_grp(attrib, prv, gc, e); +} + + +static void timed_update_preview_(library_dlg_ctx_t *ctx, const char *otext) +{ + if (otext != NULL) { + TODO("load sym from path otext to buffer"); + library_update_preview(ctx, NULL, otext); + rnd_gui->invalidate_all(rnd_gui); + } + else + sch_rnd_buffer_clear(SCH_RND_PASTEBUFFER); + ctx->timer_active = 0; + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wpend, 1); + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wnopend, 0); +} + +static void timed_update_preview_cb(rnd_hidval_t user_data) +{ + library_dlg_ctx_t *ctx = user_data.ptr; + const char *otext = ctx->dlg[ctx->wfilt].val.str; + timed_update_preview_(ctx, otext); +} + +static void timed_update_preview(library_dlg_ctx_t *ctx, int active) +{ + if (ctx->timer_active) { + rnd_gui->stop_timer(rnd_gui, ctx->timer); + ctx->timer_active = 0; + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wpend, 1); + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wnopend, 0); + } + + if (active) { + rnd_hidval_t user_data; + user_data.ptr = ctx; + ctx->timer = rnd_gui->add_timer(rnd_gui, timed_update_preview_cb, adialogs_conf.plugins.dialogs.library.preview_refresh_timeout, user_data); + ctx->timer_active = 1; + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wpend, 0); + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wnopend, 1); + } +} + +static void update_edit_button(library_dlg_ctx_t *ctx) +{ + const char *otext = ctx->dlg[ctx->wfilt].val.str; + int param_entered = 0, param_selected = 0; + rnd_hid_row_t *row = rnd_dad_tree_get_selected(&(ctx->dlg[ctx->wtree])); + + if (row != NULL) { + csch_lib_t *l = row->user_data; + param_selected = (l != NULL) && (l->type == CSCH_SLIB_PARAMETRIC); + } + + param_entered = !ctx->param.pactive && (otext != NULL) && (strchr(otext, '(') != NULL); + + rnd_gui->attr_dlg_widget_state(ctx->dlg_hid_ctx, ctx->wedit, param_selected || ((row == NULL) && param_entered)); +} + +static void library_set_filter(library_ctx_t *ctx, const char *text) +{ + rnd_hid_attr_val_t hv; + + hv.str = text; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wfilt, &hv); +} + +static const char *library_get_ent_name(library_ent_t *e) { return e->name; } +static const char *library_ent_path(library_ent_t *e) { return e->realpath; } + +#include "../../../src_3rd/rnd_inclib/dialogs/dlg_library_param.c" + +static void library_dlg_close_cb(void *caller_data, rnd_hid_attr_ev_t ev) +{ + library_dlg_ctx_t *ctx = caller_data; + + library_param_dialog_close(&ctx->param); + + csch_sheet_uninit(&ctx->prsh); + sheetlib_del(ctx->sheet, ctx->master); + free(ctx->title); + ctx->title = NULL; + if (!ctx->modal) + free(ctx); +} + +static void library_select(rnd_hid_attribute_t *attrib, void *hid_ctx, rnd_hid_row_t *row) +{ + rnd_hid_attr_val_t hv; + rnd_hid_tree_t *tree = attrib->wdata; + library_dlg_ctx_t *ctx = tree->user_ctx; + int close_param = 1, is_local = 0; + static csch_lib_t *last = NULL; + const csch_lib_backend_t *be = NULL; + + ctx->last_clicked = 1; + + timed_update_preview(ctx, 0); + + library_update_preview(ctx, NULL, NULL); + if (row != NULL) { + csch_lib_t *l = row->user_data, *lpar; + + if (l->backend != NULL) { + lpar = l->parent; + is_local = (lpar != NULL) && (strcmp(lpar->name, "") == 0); + be = l->backend; + } + + ctx->last_path = row->path; + if (l != NULL) { + if ((l->type == CSCH_SLIB_PARAMETRIC)) { + if (last != l) { /* first click */ + library_select_show_param_example(ctx, l); + update_edit_button(ctx); + } + else { /* second click */ + ctx->param.lib_ctx = ctx; + library_param_dialog(&ctx->param, l, ctx->dlg[ctx->wfilt].val.str); + close_param = 0; + } + } + else if ((l->type == CSCH_SLIB_STATIC)) { + library_update_preview(ctx, l, NULL); + update_edit_button(ctx); + rnd_gui->invalidate_all(rnd_gui); + } + } + last = l; + } + + if (close_param) { + ctx->param.lib_ctx = ctx; + library_param_dialog(&ctx->param, NULL, NULL); + } + + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wlocframe, !is_local); + + if (be != NULL) { + if ((be->loc_refresh_from_ext == NULL) && (be->loc_list == NULL) && (be->loc_del == NULL)) + is_local = 0; + + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wloc_list, (be->loc_list == NULL)); + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wloc_del, (be->loc_del == NULL)); + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wloc_refresh, (be->loc_refresh_from_ext == NULL)); + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wloc_edit, (be->loc_edit == NULL)); + } + + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wlocframe, !is_local); + + hv.str = NULL; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wpreview, &hv); +} + +static void library_refresh_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr_inp) +{ + library_dlg_ctx_t *ctx = caller_data; + rnd_hid_attribute_t *attr = &ctx->dlg[ctx->wtree]; +/* rnd_hid_tree_t *tree = attr->wdata;*/ + csch_lib_t *lroot; + rnd_hid_row_t *r = rnd_dad_tree_get_selected(attr); + const char *rootname; + char *freeme = NULL; + + if (r == NULL) { + rnd_message(RND_MSG_ERROR, "Please select a subtree to refresh\n"); + return; + } + + /* Do not allow refresh */ + for(lroot = r->user_data; lroot->parent != NULL; lroot = lroot->parent) ; + rootname = lroot->name; + if (strcmp(rootname, "") == 0) { + rnd_message(RND_MSG_ERROR, "Can not explicitly refresh , it's refreshed automatically\n"); + return; + } + + if ((rootname == NULL) || (*rootname == '\0')) + rootname = lroot->realpath; + + rootname = freeme = rnd_strdup(rootname); /* rehash may change the ptr */ + + if (csch_lib_rehash(ctx->sheet, ctx->master, r->user_data) == 0) { + rnd_message(RND_MSG_INFO, "Refresh library '%s'\n", rootname); + library_sheet2dlg(ctx); + + r = rnd_dad_tree_get_selected(attr); + if (r != NULL) { + library_update_preview(ctx, r->user_data, NULL); + library_filter_reapply(hid_ctx, ctx); + } + } + else + rnd_message(RND_MSG_ERROR, "Failed to refresh '%s'\n", rootname); + + free(freeme); +} + +static rnd_hid_row_t *find_sym_prefix_(rnd_hid_tree_t *tree, gdl_list_t *rowlist, const char *name, int namelen) +{ + rnd_hid_row_t *r, *pr; + + for(r = gdl_first(rowlist); r != NULL; r = gdl_next(rowlist, r)) { + csch_lib_t *l = r->user_data; + if ((rnd_strncasecmp(r->cell[0], name, namelen) == 0) && (l->type == CSCH_SLIB_PARAMETRIC)) + return r; + pr = find_sym_prefix_(tree, &r->children, name, namelen); + if (pr != NULL) + return pr; + } + return NULL; +} + +static rnd_hid_row_t *find_sym_prefix(library_ctx_t *ctx, const char *name, int namelen) +{ + rnd_hid_attribute_t *attr; + rnd_hid_tree_t *tree; + + attr = &ctx->dlg[ctx->wtree]; + tree = attr->wdata; + + return find_sym_prefix_(tree, &tree->rows, name, namelen); +} + +static void library_edit_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr_inp) +{ + library_ctx_t *ctx = caller_data; + rnd_hid_attribute_t *attr; + rnd_hid_row_t *r, *rnew; + const char *otext = ctx->dlg[ctx->wfilt].val.str; + char *name = NULL, *sep; + int namelen; + + attr = &ctx->dlg[ctx->wtree]; + r = rnd_dad_tree_get_selected(attr); + + if (!ctx->last_clicked && (otext != NULL)) { + get_from_filt:; + name = rnd_strdup(otext); + sep = strchr(name, '('); + if (sep != NULL) + *sep = '\0'; + } + else if (r != NULL) { + csch_lib_t *l = r->user_data; + name = rnd_strdup(l->name); + if (name != NULL) { + rnd_hid_attr_val_t hv; + hv.str = name; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wfilt, &hv); + } + } + else if (otext != NULL) + goto get_from_filt; + + if ((name == NULL) || (*name == '\0')) { + rnd_message(RND_MSG_ERROR, "Failed to figure the name of the parametric symbol\n"); + return; + } + namelen = strlen(name); + + if ((r == NULL) || (rnd_strncasecmp(name, r->cell[0], namelen) != 0)) { + /* no selection or wrong selection: go find the right one */ + rnew = find_sym_prefix(ctx, name, namelen); + } + else + rnew = r; + + if (rnew != NULL) { + if (r != rnew) + rnd_dad_tree_jumpto(attr, rnew); + ctx->param.lib_ctx = ctx; + library_param_dialog(&ctx->param, rnew->user_data, ctx->dlg[ctx->wfilt].val.str); + } + else + rnd_message(RND_MSG_ERROR, "No such parametric symbol: '%s'\n", name); + + free(name); +} + + +static void library_filter_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr_inp__) +{ + library_dlg_ctx_t *ctx = caller_data; + rnd_hid_attribute_t *attr_inp = &ctx->dlg[ctx->wfilt]; + rnd_hid_attribute_t *attr; + rnd_hid_tree_t *tree; + const char *otext; + char *text, *sep, *para_start; + int have_filter_text, is_para, is_para_closed = 0; + + ctx->last_clicked = 0; + + attr = &ctx->dlg[ctx->wtree]; + tree = attr->wdata; + otext = attr_inp->val.str; + if (otext == NULL) otext = ""; + text = rnd_strdup(otext); + have_filter_text = (*text != '\0'); + + para_start = strchr(otext, '('); + is_para = (para_start != NULL); + if (is_para) + is_para_closed = (strchr(para_start, ')') != NULL); + + sep = strpbrk(text, " ()\t\r\n"); + if (sep != NULL) + *sep = '\0'; + + /* if an '(' is entered, stop new filtering, keep filter as is */ + if (is_para) + goto skip_filter; + + /* hide or unhide everything */ + + if (have_filter_text) { + /* need to unhide for expand to work */ + rnd_dad_tree_hide_all(tree, &tree->rows, 0); + rnd_dad_tree_update_hide(attr); + rnd_dad_tree_expcoll(attr, NULL, 1, 1); + rnd_dad_tree_hide_all(tree, &tree->rows, 1); + } + else + rnd_dad_tree_hide_all(tree, &tree->rows, 0); + + if (have_filter_text) { /* unhide hits and all their parents */ + char *tag, *next, *tags = NULL; + vtp0_t taglist; + re_sei_t *regex = NULL; + + if (!is_para) { + tags = strchr(otext, ' '); + if (tags != NULL) { + *tags = '\0'; + tags++; + while(isspace(*tags)) + tags++; + if (*tags == '\0') + tags = NULL; + } + } + + vtp0_init(&taglist); + if (tags != NULL) { + tags = rnd_strdup(tags); + for (tag = tags; tag != NULL; tag = next) { + next = strpbrk(tag, " \t\r\n"); + if (next != NULL) { + *next = '\0'; + next++; + while (isspace(*next)) + next++; + } + vtp0_append(&taglist, tag); + } + } + + if ((text != NULL) && (*text != '\0')) + regex = re_sei_comp(text); + + library_tree_unhide(tree, &tree->rows, regex, &taglist); + + if (regex != NULL) + re_sei_free(regex); + vtp0_uninit(&taglist); + free(tags); + } + + rnd_dad_tree_update_hide(attr); + + skip_filter:; + + /* parametric symbols need to be refreshed on edit */ + if (is_para_closed) + timed_update_preview(ctx, 1); + + update_edit_button(ctx); + + free(text); +} + +static void library_filter_reapply(void *hid_ctx, library_dlg_ctx_t *ctx) +{ + library_filter_cb(hid_ctx, ctx, NULL); +} + + +static csch_lib_t *loclib_get_lib(library_dlg_ctx_t *ctx) +{ + rnd_hid_attribute_t *attr = &ctx->dlg[ctx->wtree]; + rnd_hid_row_t *r = rnd_dad_tree_get_selected(attr); + + if (r == NULL) + return NULL; + + return r->user_data; +} + + +static void loclib_del_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr_btn) +{ + library_dlg_ctx_t *ctx = caller_data; + csch_lib_t *l = loclib_get_lib(ctx); + + if ((l != NULL) && (l->backend != NULL) && (l->backend->loc_del != NULL)) + l->backend->loc_del(ctx->sheet, l); +} + +static void loclib_count_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr_btn) +{ + library_dlg_ctx_t *ctx = caller_data; + csch_lib_t *l = loclib_get_lib(ctx); + + if ((l != NULL) && (l->backend != NULL) && (l->backend->loc_list != NULL)) + l->backend->loc_list(ctx->sheet, l); +} + +static void loclib_refresh_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr_btn) +{ + library_dlg_ctx_t *ctx = caller_data; + csch_lib_t *l = loclib_get_lib(ctx); + rnd_hid_attribute_t *attr = &ctx->dlg[ctx->wtree]; + rnd_hid_row_t *r; + + if ((l != NULL) && (l->backend != NULL) && (l->backend->loc_refresh_from_ext != NULL)) { + l->backend->loc_refresh_from_ext(ctx->sheet, l); + + r = rnd_dad_tree_get_selected(attr); + library_update_preview(ctx, r->user_data, NULL); + } +} + +static void loclib_edit_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr_btn) +{ + library_dlg_ctx_t *ctx = caller_data; + csch_lib_t *l = loclib_get_lib(ctx); + + if ((l != NULL) && (l->backend != NULL) && (l->backend->loc_edit != NULL)) + l->backend->loc_edit(ctx->sheet, l); +} + + +static char *sch_rnd_library_dlg(csch_sheet_t *sheet, const char *lib_type_name, int modal) +{ + library_dlg_ctx_t *ctx; + rnd_hid_dad_buttons_t clbtn[] = {{"Close", 0}, {NULL, 0}}; + rnd_hid_dad_buttons_t clbtn_modal[] = {{"Use selected", 1}, {"Cancel", 0}, {NULL, 0}}; + csch_lib_master_t *master = csch_lib_get_master(lib_type_name, 0); + + if (master == NULL) { + rnd_message(RND_MSG_ERROR, "Library dialog: no such library type: %s\n", lib_type_name); + return NULL; + } + + ctx = sheetlib_lookup(sheet, master); + if ((ctx != NULL) && (ctx->active)) { + TODO("raise?"); + return NULL; + } + + ctx = calloc(sizeof(library_dlg_ctx_t), 1); + ctx->modal = modal; + + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_BEGIN_HPANE(ctx->dlg, "left-right"); + /* left */ + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_TREE(ctx->dlg, 1, 1, NULL); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL | RND_HATF_SCROLL); + RND_DAD_TREE_SET_CB(ctx->dlg, selected_cb, library_select); + RND_DAD_TREE_SET_CB(ctx->dlg, ctx, ctx); + ctx->wtree = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_STRING(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL | RND_HATF_INIT_FOCUS); + RND_DAD_HELP(ctx->dlg, "filter: display only symbols matching this text\n(if empty: display all)"); + RND_DAD_CHANGE_CB(ctx->dlg, library_filter_cb); + ctx->wfilt = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_PICBUTTON(ctx->dlg, xpm_edit_param); + RND_DAD_HELP(ctx->dlg, "open GUI to edit the parameters\nof a parametric symbol"); + RND_DAD_CHANGE_CB(ctx->dlg, library_edit_cb); + ctx->wedit = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_PICBUTTON(ctx->dlg, xpm_refresh); + RND_DAD_HELP(ctx->dlg, "reload and refresh the currently selected\nmain tree of the library\nYou need to select an entry in the tree first and only that subtree will be rehashed.\nIf you have new roots configured/created not shown in the tree view above,\nre-scan the library (e.g. file/maintenance menu)."); + RND_DAD_CHANGE_CB(ctx->dlg, library_refresh_cb); + RND_DAD_END(ctx->dlg); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_FRAME); + ctx->wlocframe = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "local lib:"); + RND_DAD_PICBUTTON(ctx->dlg, xpm_loc_count); + RND_DAD_HELP(ctx->dlg, "list sheet symbols referencing this local lib entry"); + RND_DAD_CHANGE_CB(ctx->dlg, loclib_count_cb); + ctx->wloc_list = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_PICBUTTON(ctx->dlg, xpm_loc_del); + RND_DAD_HELP(ctx->dlg, "remove selected entry from local lib (and unlocalize all refs on sheet)"); + RND_DAD_CHANGE_CB(ctx->dlg, loclib_del_cb); + ctx->wloc_del = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_PICBUTTON(ctx->dlg, xpm_loc_refresh); + RND_DAD_HELP(ctx->dlg, "refresh local version from external lib"); + RND_DAD_CHANGE_CB(ctx->dlg, loclib_refresh_cb); + ctx->wloc_refresh = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_PICBUTTON(ctx->dlg, xpm_loc_edit); + RND_DAD_HELP(ctx->dlg, "Edit local lib entry"); + RND_DAD_CHANGE_CB(ctx->dlg, loclib_edit_cb); + ctx->wloc_edit = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + + /* right */ + RND_DAD_BEGIN_VPANE(ctx->dlg, "right_top-bottom"); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL | RND_HATF_FRAME); + + RND_DAD_BEGIN_VBOX(ctx->dlg); + /* right top: preview */ + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL | RND_HATF_TIGHT); + RND_DAD_PREVIEW(ctx->dlg, library_expose, library_mouse, NULL, NULL, NULL, 100, 100, ctx); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_PRV_GFLIP); + ctx->wpreview = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_END(ctx->dlg); + + /* right bottom */ + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_LABEL(ctx->dlg, "Refreshing"); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_HIDE); + ctx->wpend = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, " "); + ctx->wnopend = RND_DAD_CURRENT(ctx->dlg); + TODO("rich text label"); + RND_DAD_LABEL(ctx->dlg, ""); + ctx->wprev_text = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + + /* bottom */ + RND_DAD_BUTTON_CLOSES(ctx->dlg, modal ? clbtn_modal : clbtn); + RND_DAD_END(ctx->dlg); + + /* set up the context */ + ctx->active = 1; + ctx->sheet = sheet; + ctx->master = master; + csch_sheet_init(&ctx->prsh, NULL); + + uundo_freeze_serial(&ctx->prsh.undo); + library_sheet2dlg(ctx); + + ctx->title = rnd_strdup_printf("%s Library for %s", ctx->master->name, ctx->sheet->hidlib.loadname); + RND_DAD_NEW("library", ctx->dlg, ctx->title, ctx, modal, library_dlg_close_cb); /* type=local */ + + sheetlib_set(sheet, master, ctx); + + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wlocframe, 1); + + if (modal) { + char *rv = NULL; + + if (RND_DAD_RUN(ctx->dlg) == 1) + rv = ctx->last_path == NULL ? NULL : rnd_strdup(ctx->last_path); + RND_DAD_FREE(ctx->dlg); + free(ctx); + return rv; + } + + return NULL; +} + +const char csch_acts_LibraryDialog[] = "LibraryDialog([lib_type_name, [sheet|global, [modal]]])"; +const char csch_acth_LibraryDialog[] = "Bring up the library dialog. Default lib_type_name is \"symbol\". \"Sheet\" is the sheet's local library (one dialog per sheet), \"global\" is all symbols mapped for any sheet seen in this session. In modal mode returns the tree path of the selected entry.\n"; +fgw_error_t csch_act_LibraryDialog(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_design_t *hidlib = RND_ACT_DESIGN; + csch_sheet_t *sheet = (csch_sheet_t *)hidlib; + int cmd = F_Global, modal = 0; + const char *lib_type_name = "symbol", *smodal = NULL; + char *rv = NULL; + + RND_ACT_CONVARG(1, FGW_STR, LibraryDialog, lib_type_name = argv[1].val.cstr); + RND_ACT_MAY_CONVARG(2, FGW_KEYWORD, LibraryDialog, cmd = fgw_keyword(&argv[2])); + RND_ACT_MAY_CONVARG(3, FGW_STR, LibraryDialog, smodal = argv[3].val.cstr); + + if ((smodal != NULL) && ((*smodal == 'm') || (*smodal == 'M'))) + modal = 1; + + RND_ACT_IRES(-1); + + switch(cmd) { + case F_Global: + rv = sch_rnd_library_dlg(NULL, lib_type_name, modal); + RND_ACT_IRES(0); + break; + case F_Sheet: + rv = sch_rnd_library_dlg(sheet, lib_type_name, modal); + RND_ACT_IRES(0); + break; + default: + rnd_message(RND_MSG_ERROR, "Library dialog: invalid first arg\n"); + break; + } + + if (modal) { + res->type = FGW_STR | FGW_DYN; + res->val.str = rv; + } + else if (rv != NULL) + free(rv); + + return 0; +} + +void csch_dlg_library_preunload(csch_sheet_t *sheet) +{ + htip_entry_t *e; + rnd_dad_retovr_t retovr = {0}; + + for(e = htip_first(&sheetlib2dlg); e != NULL; e = htip_next(&sheetlib2dlg, e)) { + library_dlg_ctx_t *ctx = e->value; + if (ctx->sheet == sheet) + rnd_hid_dad_close(ctx->dlg_hid_ctx, &retovr, 0); + } +} + +void csch_dlg_library_changed(csch_sheet_t *sheet) +{ + htip_entry_t *e; + for(e = htip_first(&sheetlib2dlg); e != NULL; e = htip_next(&sheetlib2dlg, e)) { + library_dlg_ctx_t *ctx = e->value; + if (ctx->sheet == sheet) + library_sheet2dlg(ctx); + } +} + +void csch_dlg_library_init(void) +{ + htip_init(&sheetlib2dlg, longhash, longkeyeq); +} + +void csch_dlg_library_uninit(void) +{ + rnd_dad_retovr_t retovr = {0}; + htip_entry_t *e; + + for(e = htip_first(&sheetlib2dlg); e != NULL; e = htip_next(&sheetlib2dlg, e)) { + library_dlg_ctx_t *ctx = e->value; + rnd_hid_dad_close(ctx->dlg_hid_ctx, &retovr, 0); + } + + htip_uninit(&sheetlib2dlg); +} Index: tags/1.0.5/src/plugins/sch_dialogs/dlg_library.h =================================================================== --- tags/1.0.5/src/plugins/sch_dialogs/dlg_library.h (nonexistent) +++ tags/1.0.5/src/plugins/sch_dialogs/dlg_library.h (revision 10414) @@ -0,0 +1,17 @@ + +extern const char csch_acts_LibraryDialog[]; +extern const char csch_acth_LibraryDialog[]; +fgw_error_t csch_act_LibraryDialog(fgw_arg_t *res, int argc, fgw_arg_t *argv); + +/* Called upon CSCH_EVENT_LIBRARY_CHANGED, refreshes active per sheet dialogs */ +void csch_dlg_library_changed(csch_sheet_t *sheet); + +void csch_dlg_library_preunload(csch_sheet_t *sheet); + + +void csch_dlg_library_edit(csch_sheet_t *sheet); +void csch_dlg_library_init(void); +void csch_dlg_library_uninit(void); + + + Index: tags/1.0.5/src/plugins/sch_dialogs/dlg_pen.c =================================================================== --- tags/1.0.5/src/plugins/sch_dialogs/dlg_pen.c (nonexistent) +++ tags/1.0.5/src/plugins/sch_dialogs/dlg_pen.c (revision 10414) @@ -0,0 +1,731 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - GUI - pen dialog + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/* pen selection dialog */ + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +/* This doesn't make a plugin dep as only inlines and macros and structs are used */ +#include +#define RND_TIMED_CHG_TIMEOUT conf_core.editor.edit_time +#include + +typedef struct pendlg_ctx_s pendlg_ctx_t; + +struct pendlg_ctx_s { + RND_DAD_DECL_NOINIT(dlg) + csch_sheet_t *sheet; + int wlist, wname, wsize, wshape, wcolor, wfontheight, wfontfamily, wfontstyle, wdel; + csch_cgrp_t *grp; + int recursive, is_modal; + htsp_t pens; /* key: pen's ->name; value: (csch_cpen_t *) */ + csch_cpen_t *last_pen; /* last selected pen */ + + /* timed changes */ + struct { + rnd_timed_chg_t hdr; + + csch_cpen_t *pen; /* pen to apply these changes to */ + + /* remember what to change */ + unsigned height:1; + unsigned family:1; + unsigned style:1; + } font; + + struct { + rnd_timed_chg_t hdr; + + csch_cpen_t *pen; /* pen to apply these changes to */ + + /* remember what to change */ + unsigned name:1; + unsigned shape:1; + unsigned size:1; + unsigned color:1; + } tip; + + gdl_elem_t link; +}; + +static gdl_list_t pendlgs; /* list of all non-modal pen dialogs */ + +static void pens_map(pendlg_ctx_t *ctx); + +/* finalize all pending operations */ +static void pendlg_finalize(pendlg_ctx_t *ctx) +{ + rnd_timed_chg_finalize(&ctx->font.hdr); + rnd_timed_chg_finalize(&ctx->tip.hdr); +} + +static void pendlg_close_cb(void *caller_data, rnd_hid_attr_ev_t ev) +{ + pendlg_ctx_t *ctx = caller_data; + + pendlg_finalize(ctx); + + htsp_uninit(&ctx->pens); + RND_DAD_FREE(ctx->dlg); + if (!ctx->is_modal) { + gdl_remove(&pendlgs, ctx, link); + free(ctx); /* need to leave this to after RUN() returned because we want to pick up the result */ + } +} + +static int pen_cmp(const void *p1_, const void *p2_) +{ + const csch_cpen_t **p1 = (const csch_cpen_t **)p1_, **p2 = (const csch_cpen_t **)p2_; + return strcmp((*p1)->name.str, (*p2)->name.str); /* never returns 0 because these are coming from a hash table by name */ +} + +static void pens2dlg_load_tree(pendlg_ctx_t *ctx, rnd_hid_attribute_t *attr) +{ + vtp0_t sorted = {0}; + htsp_entry_t *e; + char *cell[3]; + const csch_cpen_t **pen; + long n; + + /* sort items */ + vtp0_enlarge(&sorted, ctx->pens.used); + sorted.used = 0; + for(e = htsp_first(&ctx->pens); e != NULL; e = htsp_next(&ctx->pens, e)) + vtp0_append(&sorted, e->value); + qsort(sorted.array, sorted.used, sizeof(csch_cpen_t *), pen_cmp); + + /* add to table */ + cell[2] = NULL; + for(n = 0, pen = (const csch_cpen_t **)sorted.array; n < sorted.used; n++, pen++) { + rnd_hid_row_t *row; + + cell[0] = rnd_strdup((*pen)->name.str); + cell[1] = rnd_strdup((*pen)->hdr.parent == ctx->grp ? "local" : "inherited"); + row = rnd_dad_tree_append(attr, NULL, cell); + row->user_data = (void *)(*pen); + } + + vtp0_uninit(&sorted); +} + +static void pen_dlg_select_by_name(pendlg_ctx_t *ctx, const char *pen_name) +{ + rnd_hid_attr_val_t hv; + hv.str = pen_name; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wlist, &hv); +} + +static void pens2dlg(pendlg_ctx_t *ctx) +{ + rnd_hid_attribute_t *attr = &ctx->dlg[ctx->wlist]; + rnd_hid_tree_t *tree = attr->wdata; + rnd_hid_row_t *r; + char *cursor_path = NULL; + + /* remember cursor */ + r = rnd_dad_tree_get_selected(attr); + if (r != NULL) + cursor_path = rnd_strdup(r->cell[0]); + + /* remove existing items */ + rnd_dad_tree_clear(tree); + + /* add all items */ + pens2dlg_load_tree(ctx, attr); + + /* restore cursor */ + if (cursor_path != NULL) { + pen_dlg_select_by_name(ctx, cursor_path); + free(cursor_path); + } +} + +static void pen2dlg(pendlg_ctx_t *ctx, csch_cpen_t *pen) +{ + int enab; + + if (pen != NULL) { + RND_DAD_SET_VALUE(ctx->dlg_hid_ctx, ctx->wname, str, pen->name.str); + RND_DAD_SET_VALUE(ctx->dlg_hid_ctx, ctx->wsize, crd, C2P(pen->size)); + RND_DAD_SET_VALUE(ctx->dlg_hid_ctx, ctx->wshape, lng, pen->shape); + RND_DAD_SET_VALUE(ctx->dlg_hid_ctx, ctx->wcolor, clr, pen->color); + RND_DAD_SET_VALUE(ctx->dlg_hid_ctx, ctx->wfontheight, crd, C2P(pen->font_height)); + RND_DAD_SET_VALUE(ctx->dlg_hid_ctx, ctx->wfontfamily, str, RND_EMPTY(pen->font_family)); + RND_DAD_SET_VALUE(ctx->dlg_hid_ctx, ctx->wfontstyle, str, RND_EMPTY(pen->font_style)); + enab = 1; + } + else { + RND_DAD_SET_VALUE(ctx->dlg_hid_ctx, ctx->wname, str, ""); + RND_DAD_SET_VALUE(ctx->dlg_hid_ctx, ctx->wsize, crd, 0); + RND_DAD_SET_VALUE(ctx->dlg_hid_ctx, ctx->wshape, lng, -1); + RND_DAD_SET_VALUE(ctx->dlg_hid_ctx, ctx->wcolor, str, ""); + RND_DAD_SET_VALUE(ctx->dlg_hid_ctx, ctx->wfontheight, crd, 0); + RND_DAD_SET_VALUE(ctx->dlg_hid_ctx, ctx->wfontfamily, str, ""); + RND_DAD_SET_VALUE(ctx->dlg_hid_ctx, ctx->wfontstyle, str, ""); + enab = 0; + } + + rnd_gui->attr_dlg_widget_state(ctx->dlg_hid_ctx, ctx->wname, enab); + rnd_gui->attr_dlg_widget_state(ctx->dlg_hid_ctx, ctx->wsize, enab); + rnd_gui->attr_dlg_widget_state(ctx->dlg_hid_ctx, ctx->wshape, enab); + rnd_gui->attr_dlg_widget_state(ctx->dlg_hid_ctx, ctx->wcolor, enab); + rnd_gui->attr_dlg_widget_state(ctx->dlg_hid_ctx, ctx->wfontheight, enab); + rnd_gui->attr_dlg_widget_state(ctx->dlg_hid_ctx, ctx->wfontfamily, enab); + rnd_gui->attr_dlg_widget_state(ctx->dlg_hid_ctx, ctx->wfontstyle, enab); +} + +static void pen_select_cb(rnd_hid_attribute_t *attrib, void *hid_ctx, rnd_hid_row_t *row) +{ + rnd_hid_tree_t *tree = attrib->wdata; + pendlg_ctx_t *ctx = tree->user_ctx; + int is_local = 0; + + if (row != NULL) { + ctx->last_pen = (csch_cpen_t *)row->user_data; + is_local = (row->cell[1][0] == 'l'); + } + else + ctx->last_pen = NULL; + + pendlg_finalize(ctx); + pen2dlg(ctx, ctx->last_pen); + rnd_gui->attr_dlg_widget_state(ctx->dlg_hid_ctx, ctx->wdel, is_local); /* allow deleting local pens only */ +} + +static csch_cpen_t *get_dlg_pen(pendlg_ctx_t *ctx) +{ + rnd_hid_attribute_t *attr = &ctx->dlg[ctx->wlist]; + rnd_hid_row_t *r = rnd_dad_tree_get_selected(attr); + if (r == NULL) + return NULL; + return r->user_data; +} + +static void pen_dlg_remap_redraw(pendlg_ctx_t *ctx) +{ + pens_map(ctx); + pens2dlg(ctx); + pen2dlg(ctx, NULL); + rnd_gui->invalidate_all(rnd_gui); +} + +static void pen_new_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + csch_cpen_t *pen; + pendlg_ctx_t *ctx = caller_data; + + pendlg_finalize(ctx); + + uundo_freeze_serial(&ctx->sheet->undo); + pen = (csch_cpen_t *)csch_op_create(ctx->sheet, ctx->grp, CSCH_CTYPE_PEN); + if (pen != NULL) { + rnd_color_t clr; + csch_coord_t sz = 1000, tsz=3000; + char *font_family = "sans"; + + memcpy(&clr, rnd_color_red, sizeof(rnd_color_t)); + csch_pen_modify_tip(ctx->sheet, pen, NULL, &sz, &clr, NULL, NULL, NULL, 1); + csch_pen_modify_font(ctx->sheet, pen, &tsz, &font_family, NULL, 1); + pen_dlg_remap_redraw(ctx); + ctx->last_pen = pen; + pen_dlg_select_by_name(ctx, pen->name.str); + pen2dlg(ctx, pen); + } + uundo_unfreeze_serial(&ctx->sheet->undo); + uundo_inc_serial(&ctx->sheet->undo); +} + +static void pen_del_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + pendlg_ctx_t *ctx = caller_data; + csch_cpen_t *pen = get_dlg_pen(ctx); + + if (pen->hdr.parent != ctx->grp) { + rnd_message(RND_MSG_ERROR, "Can not remove inherited pen;\nfind the pen in a parent group and remove there!\n"); + return; + } + + pendlg_finalize(ctx); + csch_op_remove(ctx->sheet, &pen->hdr); + pen_dlg_remap_redraw(ctx); +} + +static void set_pen_tip_timed(void *ctx_) +{ + pendlg_ctx_t *ctx = ctx_; + char *tmp_name, **new_name = NULL; + csch_pen_shape_t tmp_shape, *new_shape = NULL; + csch_coord_t *new_size = NULL, crdtmp; + rnd_color_t *new_color = NULL; + int remap = 0; + + if (ctx->tip.name) { + rnd_hid_attribute_t *attr = &ctx->dlg[ctx->wlist]; + rnd_hid_row_t *r; + + tmp_name = rnd_strdup(ctx->dlg[ctx->wname].val.str); + new_name = &tmp_name; + ctx->font.style = 0; + remap = 0; + + /* update name in the list-of-pens */ + r = rnd_dad_tree_get_selected(attr); + if (r != NULL) + rnd_dad_tree_modify_cell(attr, r, 0, rnd_strdup(tmp_name)); + } + + if (ctx->tip.shape) { + tmp_shape = ctx->dlg[ctx->wshape].val.lng; + new_shape = &tmp_shape; + ctx->tip.shape = 0; + } + + if (ctx->tip.size) { + crdtmp = P2C(ctx->dlg[ctx->wsize].val.crd); + new_size = &crdtmp; + ctx->tip.size = 0; + } + + if (ctx->tip.color) { + new_color = &ctx->dlg[ctx->wcolor].val.clr; + ctx->tip.color = 0; + } + + csch_pen_modify_tip(ctx->sheet, ctx->tip.pen, new_shape, new_size, new_color, new_name, NULL, NULL, 1); + + if (remap) + pen_dlg_remap_redraw(ctx); + rnd_gui->invalidate_all(rnd_gui); +} + +static void set_pen_name_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + pendlg_ctx_t *ctx = caller_data; + csch_cpen_t *pen = get_dlg_pen(ctx); + + if ((pen == NULL) || (strcmp(attr->val.str, pen->name.str) == 0)) + return; + + ctx->tip.pen = pen; + ctx->tip.name = 1; + rnd_timed_chg_schedule(&ctx->tip.hdr); +} + +static void set_pen_shape_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + pendlg_ctx_t *ctx = caller_data; + csch_cpen_t *pen = get_dlg_pen(ctx); + + if (pen == NULL) + return; + + ctx->tip.pen = pen; + ctx->tip.shape = 1; + rnd_timed_chg_schedule(&ctx->tip.hdr); +} + +static void set_pen_size_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + pendlg_ctx_t *ctx = caller_data; + csch_cpen_t *pen = get_dlg_pen(ctx); + + if (pen == NULL) + return; + + ctx->tip.pen = pen; + ctx->tip.size = 1; + rnd_timed_chg_schedule(&ctx->tip.hdr); +} + +static void set_pen_color_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + pendlg_ctx_t *ctx = caller_data; + csch_cpen_t *pen = get_dlg_pen(ctx); + + if (pen == NULL) + return; + + ctx->tip.pen = pen; + ctx->tip.color = 1; + rnd_timed_chg_schedule(&ctx->tip.hdr); + +} + +static void set_pen_font_timed(void *ctx_) +{ + pendlg_ctx_t *ctx = ctx_; + char *tmp_style, **new_style = NULL, *tmp_family, **new_family = NULL; + csch_coord_t *new_height = NULL, ctmp; + + if (ctx->font.height) { + ctmp = P2C(ctx->dlg[ctx->wfontheight].val.crd); + new_height = &ctmp; + ctx->font.height = 0; + } + + if (ctx->font.family) { + tmp_family = rnd_strdup(ctx->dlg[ctx->wfontfamily].val.str); + new_family = &tmp_family; + ctx->font.family = 0; + } + + if (ctx->font.style) { + tmp_style = rnd_strdup(ctx->dlg[ctx->wfontstyle].val.str); + new_style = &tmp_style; + ctx->font.style = 0; + } + + csch_pen_modify_font(ctx->sheet, ctx->font.pen, new_height, new_family, new_style, 1); + rnd_gui->invalidate_all(rnd_gui); +} + +static void set_pen_fontheight_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + pendlg_ctx_t *ctx = caller_data; + csch_cpen_t *pen = get_dlg_pen(ctx); + csch_coord_t newval = P2C(ctx->dlg[ctx->wfontheight].val.crd); + + if ((pen == NULL) || (newval == pen->font_height)) + return; + + ctx->font.pen = pen; + ctx->font.height = 1; + rnd_timed_chg_schedule(&ctx->font.hdr); +} + +static void set_pen_fontfamily_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + pendlg_ctx_t *ctx = caller_data; + csch_cpen_t *pen = get_dlg_pen(ctx); + + if ((pen == NULL) || ((pen->font_family != NULL) && (strcmp(attr->val.str, pen->font_family) == 0))) + return; + + ctx->font.pen = pen; + ctx->font.family = 1; + rnd_timed_chg_schedule(&ctx->font.hdr); +} + +static void set_pen_fontstyle_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + pendlg_ctx_t *ctx = caller_data; + csch_cpen_t *pen = get_dlg_pen(ctx); + + if ((pen == NULL) || ((pen->font_style != NULL) && (strcmp(attr->val.str, pen->font_style) == 0))) + return; + + ctx->font.pen = pen; + ctx->font.style = 1; + rnd_timed_chg_schedule(&ctx->font.hdr); +} + + + +static void pens_map_(pendlg_ctx_t *ctx, const csch_cgrp_t *grp) +{ + csch_chdr_t *h; + csch_grpo_iter_t it; + + for(h = csch_grpo_first(&it, ctx->sheet, grp); h != NULL; h = csch_grpo_next(&it)) { + if (h->type == CSCH_CTYPE_PEN) { + csch_cpen_t *pen = (csch_cpen_t *)h; + if (!htsp_has(&ctx->pens, pen->name.str)) + htsp_set(&ctx->pens, (char *)pen->name.str, pen); + } + } + + if (ctx->recursive && (grp->hdr.parent != NULL)) + pens_map_(ctx, grp->hdr.parent); +} + +static void pens_map(pendlg_ctx_t *ctx) +{ + htsp_clear(&ctx->pens); + pens_map_(ctx, ctx->grp); +} + +const char *sch_rnd_pen_dlg(csch_sheet_t *sheet, csch_cgrp_t *grp, const char *pen_name, int modal, int recursive) +{ + pendlg_ctx_t *ctx = calloc(sizeof(pendlg_ctx_t), 1); + rnd_hid_dad_buttons_t clbtn_modal[] = {{"Cancel", 0}, {"Use selected", 1}, {NULL, 0}}; + rnd_hid_dad_buttons_t clbtn_normal[] = {{"Close", 0}, {NULL, 0}}; + const char *hdr[] = {"pen name", "scope", NULL}; + char *shapes[] = {"round", "square", NULL}; + + ctx->sheet = sheet; + ctx->grp = grp; + ctx->recursive = recursive; + ctx->is_modal = modal; + htsp_init(&ctx->pens, strhash, strkeyeq); + pens_map(ctx); + + rnd_timed_chg_init(&ctx->font.hdr, set_pen_font_timed, ctx); + rnd_timed_chg_init(&ctx->tip.hdr, set_pen_tip_timed, ctx); + + if (!modal) + gdl_append(&pendlgs, ctx, link); + + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_BEGIN_HPANE(ctx->dlg, "left-right"); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + + RND_DAD_BEGIN_VBOX(ctx->dlg); /* left */ + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_TREE(ctx->dlg, 2, 0, hdr); /* top left: tree */ + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_TREE_SET_CB(ctx->dlg, selected_cb, pen_select_cb); + RND_DAD_TREE_SET_CB(ctx->dlg, ctx, ctx); + ctx->wlist = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_BEGIN_HBOX(ctx->dlg); /* bottom left: buttons */ + RND_DAD_BUTTON(ctx->dlg, "new"); + RND_DAD_CHANGE_CB(ctx->dlg, pen_new_cb); + RND_DAD_BUTTON(ctx->dlg, "del"); + RND_DAD_CHANGE_CB(ctx->dlg, pen_del_cb); + ctx->wdel = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + + RND_DAD_BEGIN_VBOX(ctx->dlg); /* right */ + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Pen name:"); + RND_DAD_STRING(ctx->dlg); + ctx->wname = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_CHANGE_CB(ctx->dlg, set_pen_name_cb); + RND_DAD_END(ctx->dlg); + + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Shape:"); + RND_DAD_ENUM(ctx->dlg, shapes); + ctx->wshape = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_CHANGE_CB(ctx->dlg, set_pen_shape_cb); + RND_DAD_END(ctx->dlg); + + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Size:"); + RND_DAD_CSCH_COORD(ctx->dlg); + ctx->wsize = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_CHANGE_CB(ctx->dlg, set_pen_size_cb); + RND_DAD_END(ctx->dlg); + + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Color:"); + RND_DAD_COLOR(ctx->dlg); + ctx->wcolor = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_CHANGE_CB(ctx->dlg, set_pen_color_cb); + RND_DAD_END(ctx->dlg); + + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Font height:"); + RND_DAD_CSCH_COORD(ctx->dlg); + ctx->wfontheight = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_CHANGE_CB(ctx->dlg, set_pen_fontheight_cb); + RND_DAD_END(ctx->dlg); + + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Font family:"); + RND_DAD_STRING(ctx->dlg); + ctx->wfontfamily = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_CHANGE_CB(ctx->dlg, set_pen_fontfamily_cb); + RND_DAD_END(ctx->dlg); + + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Font style:"); + RND_DAD_STRING(ctx->dlg); + ctx->wfontstyle = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_CHANGE_CB(ctx->dlg, set_pen_fontstyle_cb); + RND_DAD_END(ctx->dlg); + + RND_DAD_TIMING(ctx->dlg, &ctx->font.hdr, "font"); + RND_DAD_TIMING(ctx->dlg, &ctx->tip.hdr, "tip"); + + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + + + RND_DAD_BUTTON_CLOSES(ctx->dlg, (modal ? clbtn_modal : clbtn_normal)); + RND_DAD_END(ctx->dlg); + + RND_DAD_DEFSIZE(ctx->dlg, 200, 300); + RND_DAD_NEW("PenDialog", ctx->dlg, "Pen edit", ctx, modal, pendlg_close_cb); /* type=local */ + + rnd_timed_chg_timing_init(&ctx->font.hdr, ctx->dlg_hid_ctx); + rnd_timed_chg_timing_init(&ctx->tip.hdr, ctx->dlg_hid_ctx); + + pens2dlg(ctx); + if (pen_name != NULL) { + pen_dlg_select_by_name(ctx, pen_name); + pen2dlg(ctx, htsp_get(&ctx->pens, pen_name)); + } + else + pen2dlg(ctx, NULL); + + if (modal) { + const char *pn = NULL; + + if (RND_DAD_RUN(ctx->dlg)) { + if (ctx->last_pen != NULL) + pn = ctx->last_pen->name.str; + } + + RND_DAD_FREE(ctx->dlg); + free(ctx); + return pn; + } + + return NULL; +} + + +extern csch_chdr_t *csch_obj_clicked; + +const char csch_acts_PenDialog[] = "PenDialog([object[=idpath]], [non-modal], [recursive], [ret_name], [init_pen_name])"; +const char csch_acth_PenDialog[] = "Bring up a modal pen selecton dialog. If idpath is specified, list pens starting from the group addressed by idpath. If second argument is non-modal, the dialog is not modal; else it is modal and the user selected pen is returned (as idpath). If recursive is set, map pens of parents as well. If ret_name is set, return the name of the selected pen (or NULL on no selection) instead of the usual integer return. If init_pen_name is supplied, the cursor is set to that pen.\n"; +fgw_error_t csch_act_PenDialog(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_design_t *hidlib = RND_ACT_DESIGN; + csch_sheet_t *sheet = (csch_sheet_t *)hidlib; + int cmd, is_modal = 1, recursive = 0, ret_name = 0; + const char *modals = NULL, *recursives = NULL, *ret_names = NULL; + const char *init_pen_name = NULL; + csch_chdr_t *obj; + + CSCH_ACT_CONVARG_OBJ(1, PenDialog, cmd, obj); + RND_ACT_MAY_CONVARG(2, FGW_STR, PenDialog, modals = argv[2].val.cstr); + RND_ACT_MAY_CONVARG(3, FGW_STR, PenDialog, recursives = argv[3].val.cstr); + RND_ACT_MAY_CONVARG(4, FGW_STR, PenDialog, ret_names = argv[4].val.cstr); + RND_ACT_MAY_CONVARG(5, FGW_STR, PenDialog, init_pen_name = argv[5].val.cstr); + + if ((modals != NULL) && (rnd_strcasecmp(modals, "non-modal") == 0)) + is_modal = 0; + + if ((recursives != NULL) && (rnd_strcasecmp(recursives, "recursive") == 0)) + recursive = 1; + + if ((ret_names != NULL) && (rnd_strcasecmp(ret_names, "ret_name") == 0)) + ret_name = 1; + + RND_ACT_IRES(-1); + + switch(cmd) { + case F_Object: + { + csch_coord_t x, y; + + if (obj == NULL) { + if (sch_rnd_get_coords("Click on object to edit pens of", &x, &y, 0) != 0) + break; + + obj = sch_rnd_search_obj_at(sheet, x, y, sch_rnd_slop); + if (obj == NULL) { + rnd_message(RND_MSG_ERROR, "PenDialog(): no object under cursor\n"); + break; + } + } + + if (obj != NULL) { + csch_comm_str_t comms; + int is_grp = csch_obj_is_grp(obj); + csch_cgrp_t *grp = is_grp ? (csch_cgrp_t *)obj : obj->parent; + const char *pen_name; + + if (init_pen_name == NULL) + init_pen_name = obj->stroke_name.str; + + pen_name = sch_rnd_pen_dlg(sheet, grp, init_pen_name, is_modal, recursive); + if (pen_name != NULL) { + if (!is_grp) { + comms = csch_comm_str(sheet, pen_name, 1); + csch_chdr_pen_name_modify(sheet, obj, &comms, NULL, 1); + } + if (ret_name) { + res->type = FGW_STR; + res->val.cstr = pen_name; + return 0; + } + RND_ACT_IRES(0); + } + } + else + rnd_message(RND_MSG_ERROR, "PenDialog(): no object\n"); + } + break; + default: + rnd_message(RND_MSG_ERROR, "PenDialog(): invalid first argument\n"); + } + + if (ret_name) { + res->type = FGW_STR; + res->val.cstr = NULL; + } + return 0; +} + +/* close all non-modal pen dialogs open for this sheet */ +void csch_dlg_pen_preunload(csch_sheet_t *sheet) +{ + pendlg_ctx_t *n, *next; + rnd_dad_retovr_t retovr = {0}; + + for(n = gdl_first(&pendlgs); n != NULL; n = next) { + next = gdl_next(&pendlgs, n); + if (n->sheet == sheet) + rnd_hid_dad_close(n->dlg_hid_ctx, &retovr, 0); + } +} Index: tags/1.0.5/src/plugins/sch_dialogs/dlg_pen.h =================================================================== --- tags/1.0.5/src/plugins/sch_dialogs/dlg_pen.h (nonexistent) +++ tags/1.0.5/src/plugins/sch_dialogs/dlg_pen.h (revision 10414) @@ -0,0 +1,9 @@ +#include +extern const char csch_acts_PenDialog[]; +extern const char csch_acth_PenDialog[]; +fgw_error_t csch_act_PenDialog(fgw_arg_t *res, int argc, fgw_arg_t *argv); + +const char *sch_rnd_pen_dlg(csch_sheet_t *sheet, csch_cgrp_t *grp, const char *pen_name, int modal, int recursive); + +void csch_dlg_pen_preunload(csch_sheet_t *sheet); + Index: tags/1.0.5/src/plugins/sch_dialogs/dlg_pref_apptab.c =================================================================== --- tags/1.0.5/src/plugins/sch_dialogs/dlg_pref_apptab.c (nonexistent) +++ tags/1.0.5/src/plugins/sch_dialogs/dlg_pref_apptab.c (revision 10414) @@ -0,0 +1,53 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - GUI - preferences + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/* The preferences dialog, application specific tabs */ + +#include + +#include + +#undef PREF_TAB +#define PREF_TAB 0 +#include "dlg_pref_general.c" + +#undef PREF_TAB +#define PREF_TAB 1 +#include "dlg_pref_sheet.c" + +#undef PREF_TAB +#define PREF_TAB 2 +#include "dlg_pref_lib.c" + +#undef PREF_TAB +#define PREF_TAB 3 +#include "dlg_pref_color.c" + +int sch_dlg_pref_tab = PREF_TAB; +void (*sch_dlg_pref_first_init)(pref_ctx_t *ctx, int tab) = PREF_INIT_FUNC; + Index: tags/1.0.5/src/plugins/sch_dialogs/dlg_pref_color.c =================================================================== --- tags/1.0.5/src/plugins/sch_dialogs/dlg_pref_color.c (nonexistent) +++ tags/1.0.5/src/plugins/sch_dialogs/dlg_pref_color.c (revision 10414) @@ -0,0 +1,326 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - GUI - preferences + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * Copied from pcb-rnd, interactive printed circuit board design + * Copyright (C) 2018,2021 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/* Preferences dialog, color tab */ + +#include +#include +#include +#include "dlg_pen.h" + +typedef struct { + int *wclr; /* color nodes (dynamic and hardwired items) */ + int nclr; + + int wpen[64]; /* pen (preference list) nodes (hardwired items only) */ + int npen; + + int wenab[64]; /* enable bool nodes (hardwired items only) */ + int nenab; + + int walldeco; /* widget ID for the "all decoration" button */ + int decopen_min, decopen_max; /* wpen[] index bounds for all-deco pen buttons */ +} pref_color_t; + +#undef DEF_TABDATA +#define DEF_TABDATA pref_color_t *tabdata = PREF_TABDATA(ctx) + +static char *all_deco = "all decoration pens"; + +static char *print_cfg_list(rnd_conf_native_t *nat) +{ + gds_t tmp = {0}; + + rnd_conf_listitem_t *ci; + rnd_conflist_t *lst = nat->val.list; + int n = 0; + + for(ci = rnd_conflist_first(lst); ci != NULL; ci = rnd_conflist_next(ci)) { + const char *pn = ci->val.string[0]; + if ((pn != NULL) && (*pn != '\0')) { + if (n > 0) + gds_append_str(&tmp, ", "); + gds_append_str(&tmp, pn); + n++; + } + } + + return tmp.array; +} + +static void pref_color_brd2dlg(pref_ctx_t *ctx, rnd_design_t *dsg) +{ + DEF_TABDATA; + rnd_conf_native_t *nat; + int n; + + for(n = 0; n < tabdata->nclr; n++) { + int w = tabdata->wclr[n]; + const char *path = ctx->dlg[w].user_data; + nat = rnd_conf_get_field(path); + if (nat != NULL) + RND_DAD_SET_VALUE(ctx->dlg_hid_ctx, w, clr, nat->val.color[0]); + } + + for(n = 0; n < tabdata->npen; n++) { + int w = tabdata->wpen[n]; + const char *path = ctx->dlg[w].user_data; + nat = rnd_conf_get_field(path); + if (nat != NULL) { + char *lab = print_cfg_list(nat); + RND_DAD_SET_VALUE(ctx->dlg_hid_ctx, w, str, (lab == NULL ? "" : lab)); + free(lab); + } + } + + for(n = 0; n < tabdata->nenab; n++) { + int w = tabdata->wenab[n]; + const char *path = ctx->dlg[w].user_data; + nat = rnd_conf_get_field(path); + if (nat != NULL) + RND_DAD_SET_VALUE(ctx->dlg_hid_ctx, w, lng, nat->val.integer[0]); + } + + +} + + +void csch_dlg_pref_color_open(pref_ctx_t *ctx, rnd_design_t *dsg, const char *tabdatareq) +{ + pref_color_brd2dlg(ctx, dsg); +} + +void csch_dlg_pref_color_close(pref_ctx_t *ctx, rnd_design_t *dsg) +{ + DEF_TABDATA; + int n; + + for(n = 0; n < tabdata->nclr; n++) { + int w = tabdata->wclr[n]; + free(ctx->dlg[w].user_data); + } + + free(tabdata->wclr); +} + +static void pref_color_click_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + rnd_design_t *hl = rnd_gui->get_dad_design(hid_ctx); + pref_ctx_t *ctx = caller_data; + const char *path = attr->user_data; + + if (rnd_pref_dlg2conf_pre(hl, ctx) == NULL) + return; + + rnd_conf_setf(ctx->role, path, -1, "%s", attr->val.clr.str); + + rnd_pref_dlg2conf_post(hl, ctx); + + rnd_gui->invalidate_all(rnd_gui); /* redraw because global color may have changed */ +} + +static void pref_pen_click_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + rnd_design_t *hl = rnd_gui->get_dad_design(hid_ctx); + csch_sheet_t *sheet = (csch_sheet_t *)hl; + pref_ctx_t *ctx = caller_data; + DEF_TABDATA; + int n, w = attr - ctx->dlg; + const char *path = attr->user_data; + const char *penname; + + if (rnd_pref_dlg2conf_pre(hl, ctx) == NULL) + return; + + penname = sch_rnd_pen_dlg(sheet, &sheet->direct, NULL, 1, 0); + if (penname == NULL) + return; /* cancel */ + + if (w == tabdata->walldeco) { + for(n = tabdata->decopen_min; n < tabdata->decopen_max; n++) { + rnd_hid_attribute_t *btna = &ctx->dlg[tabdata->wpen[n]]; + const char *path = btna->user_data; + rnd_conf_setf(ctx->role, path, -1, "%s", penname); + } + } + else + rnd_conf_setf(ctx->role, path, -1, "%s", penname); + + pref_color_brd2dlg(ctx, hl); + rnd_pref_dlg2conf_post(hl, ctx); +} + +static void pref_enable_click_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + rnd_design_t *hl = rnd_gui->get_dad_design(hid_ctx); + pref_ctx_t *ctx = caller_data; + const char *path = attr->user_data; + + if (rnd_pref_dlg2conf_pre(hl, ctx) == NULL) + return; + + rnd_conf_setf(ctx->role, path, -1, "%d", attr->val.lng); + + rnd_pref_dlg2conf_post(hl, ctx); +} + +static void empty_col(pref_ctx_t *ctx) +{ + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_END(ctx->dlg); +} + +static void enable_col(pref_ctx_t *ctx, const char *enable_path, int *wenable) +{ + if (enable_path != NULL) { + int w; + + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_BOOL(ctx->dlg); + w = *wenable = RND_DAD_CURRENT(ctx->dlg); + ctx->dlg[w].user_data = rnd_strdup(enable_path); + RND_DAD_CHANGE_CB(ctx->dlg, pref_enable_click_cb); + RND_DAD_LABEL(ctx->dlg, "enable"); + RND_DAD_END(ctx->dlg); + } + else + empty_col(ctx); +} + + +static int color_box(pref_ctx_t *ctx, const char *conf_path, const char *desc, const char *enable_path, int *wenable) +{ + int w; + + RND_DAD_LABEL(ctx->dlg, desc); + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COLOR(ctx->dlg); + w = RND_DAD_CURRENT(ctx->dlg); + ctx->dlg[w].user_data = rnd_strdup(conf_path); + RND_DAD_CHANGE_CB(ctx->dlg, pref_color_click_cb); + RND_DAD_END(ctx->dlg); + enable_col(ctx, enable_path, wenable); + + return w; +} + +static int pen_box(pref_ctx_t *ctx, const char *conf_path, const char *desc, const char *enable_path, int *wenable) +{ + int w; + const char *btn = (conf_path == all_deco) ? "" : ""; + + RND_DAD_LABEL(ctx->dlg, desc); + RND_DAD_BUTTON(ctx->dlg, btn); + w = RND_DAD_CURRENT(ctx->dlg); + ctx->dlg[w].user_data = rnd_strdup(conf_path); + RND_DAD_CHANGE_CB(ctx->dlg, pref_pen_click_cb); + enable_col(ctx, enable_path, wenable); + + return w; +} + +void csch_dlg_pref_color_create(pref_ctx_t *ctx, rnd_design_t *dsg) +{ + static const char *tabs[] = { "Tool/pen colors", "Generic colors", NULL }; + rnd_conf_native_t *nat; + htsp_entry_t *e; + int pl, w; + const char *path_prefix = "appearance/color"; + DEF_TABDATA; + + tabdata->nclr = 64; /* make room for hardwired colors plus count dynamic conf colors */ + pl = strlen(path_prefix); + rnd_conf_fields_foreach(e) { + nat = e->value; + if ((strncmp(e->key, path_prefix, pl) == 0) && (nat->type == RND_CFN_COLOR) && (nat->array_size == 1)) + tabdata->nclr++; + } + tabdata->wclr = calloc(sizeof(int), tabdata->nclr); + + tabdata->nclr = 0; + tabdata->npen = 0; + tabdata->nenab = 0; + + + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_BEGIN_TABBED(ctx->dlg, tabs); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL | RND_HATF_LEFT_TAB); + + RND_DAD_BEGIN_VBOX(ctx->dlg); /* tool tab */ + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL | RND_HATF_FRAME); + RND_DAD_LABEL(ctx->dlg, "Decoration:"); + RND_DAD_BEGIN_TABLE(ctx->dlg, 3); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL | RND_HATF_FRAME); + tabdata->decopen_min = tabdata->npen; + tabdata->wpen[tabdata->npen++] = tabdata->walldeco = pen_box(ctx, all_deco, "ALL DECORATION STROKES", NULL, NULL); + tabdata->wpen[tabdata->npen++] = pen_box(ctx, "editor/style/tool_circle_stroke", "Circle tool stroke", NULL, NULL); + tabdata->wpen[tabdata->npen++] = pen_box(ctx, "editor/style/tool_line_stroke", "Line tool stroke", NULL, NULL); + tabdata->wpen[tabdata->npen++] = pen_box(ctx, "editor/style/tool_rect_stroke", "Rect. tool: stroke", "editor/style/tool_rect_has_stroke", &w); + tabdata->wenab[tabdata->nenab++] = w; + tabdata->wpen[tabdata->npen++] = pen_box(ctx, "editor/style/tool_rect_fill", "Rect. tool: fill", "editor/style/tool_rect_has_fill", &w); + tabdata->wenab[tabdata->nenab++] = w; + tabdata->decopen_max = tabdata->npen; + RND_DAD_END(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Wiring:"); + RND_DAD_BEGIN_TABLE(ctx->dlg, 3); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL | RND_HATF_FRAME); + tabdata->wpen[tabdata->npen++] = pen_box(ctx, "editor/style/tool_wire_stroke", "Wire tool: wiring", NULL, NULL); + tabdata->wpen[tabdata->npen++] = pen_box(ctx, "editor/style/tool_wire_junction_stroke", "Wire tool: junction dot", NULL, NULL); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + + + RND_DAD_BEGIN_VBOX(ctx->dlg); /* generic tab */ + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL | RND_HATF_SCROLL); + RND_DAD_BEGIN_TABLE(ctx->dlg, 3); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL | RND_HATF_SCROLL); + rnd_conf_fields_foreach(e) { + nat = e->value; + if ((strncmp(e->key, path_prefix, pl) == 0) && (nat->type == RND_CFN_COLOR) && (nat->array_size == 1)) + tabdata->wclr[tabdata->nclr++] = color_box(ctx, e->key, nat->description, NULL, NULL); + } + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + + RND_DAD_END(ctx->dlg); +} + +static const rnd_pref_tab_hook_t pref_color = { + "Colors", RND_PREFTAB_AUTO_FREE_DATA | RND_PREFTAB_NEEDS_ROLE, + csch_dlg_pref_color_open, csch_dlg_pref_color_close, + csch_dlg_pref_color_create, + pref_color_brd2dlg, pref_color_brd2dlg /* board change, meta change */ +}; + +static void csch_dlg_pref_color_init(pref_ctx_t *ctx, int tab) +{ + PREF_INIT(ctx, &pref_color); + PREF_TABDATA(ctx) = calloc(sizeof(pref_color_t), 1); +} +#undef PREF_INIT_FUNC +#define PREF_INIT_FUNC csch_dlg_pref_color_init Index: tags/1.0.5/src/plugins/sch_dialogs/dlg_pref_general.c =================================================================== --- tags/1.0.5/src/plugins/sch_dialogs/dlg_pref_general.c (nonexistent) +++ tags/1.0.5/src/plugins/sch_dialogs/dlg_pref_general.c (revision 10414) @@ -0,0 +1,101 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - GUI - preferences + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * Copied from pcb-rnd, interactive printed circuit board design + * Copyright (C) 2018,2021 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/* Preferences dialog, general tab */ + +#include + +static pref_confitem_t perf_backup[] = { + {"Save unsaved layout to\nSCH.%i.save at exit", "editor/save_in_tmp", 0, NULL}, + {"Seconds between auto backups\n(set to zero to disable auto backups)", "rc/backup_interval", 0, NULL}, + {NULL, NULL, 0} +}; + +static pref_confitem_t perf_cli[] = { + {"Number of commands to\nremember in the\nhistory list", "plugins/lib_hid_common/cli_history/slots", 0, NULL}, + {NULL, NULL, 0} +}; + +static void pref_general_dlg2conf(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + rnd_design_t *hl = rnd_gui->get_dad_design(hid_ctx); + pref_ctx_t *ctx = caller_data; + + if (rnd_pref_dlg2conf_pre(hl, ctx) == NULL) + return; + + rnd_pref_dlg2conf_table(ctx, perf_backup, attr); + rnd_pref_dlg2conf_table(ctx, perf_cli, attr); + + rnd_pref_dlg2conf_post(hl, ctx); +} + +void sch_dlg_pref_general_close(pref_ctx_t *ctx, rnd_design_t *dsg) +{ + rnd_pref_conflist_remove(ctx, perf_backup); + rnd_pref_conflist_remove(ctx, perf_cli); +} + +void sch_dlg_pref_general_create(pref_ctx_t *ctx, rnd_design_t *dsg) +{ + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_FRAME); + RND_DAD_LABEL(ctx->dlg, "Backup"); + RND_DAD_BEGIN_TABLE(ctx->dlg, 2); + rnd_pref_create_conftable(ctx, perf_backup, pref_general_dlg2conf); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_FRAME); + RND_DAD_LABEL(ctx->dlg, "Command line entry"); + RND_DAD_BEGIN_TABLE(ctx->dlg, 2); + rnd_pref_create_conftable(ctx, perf_cli, pref_general_dlg2conf); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); +} + +void sch_dlg_pref_general_board_chg(pref_ctx_t *ctx, rnd_design_t *dsg) +{ + rnd_pref_dlg2conf_table(ctx, perf_backup, NULL); + rnd_pref_dlg2conf_table(ctx, perf_cli, NULL); +} + +static const rnd_pref_tab_hook_t pref_general = { + "General", RND_PREFTAB_AUTO_FREE_DATA | RND_PREFTAB_NEEDS_ROLE, + NULL, sch_dlg_pref_general_close, + sch_dlg_pref_general_create, + NULL, NULL +}; + +static void sch_dlg_pref_general_init(pref_ctx_t *ctx, int tab) +{ + PREF_INIT(ctx, &pref_general); +} +#undef PREF_INIT_FUNC +#define PREF_INIT_FUNC sch_dlg_pref_general_init Index: tags/1.0.5/src/plugins/sch_dialogs/dlg_pref_lib.c =================================================================== --- tags/1.0.5/src/plugins/sch_dialogs/dlg_pref_lib.c (nonexistent) +++ tags/1.0.5/src/plugins/sch_dialogs/dlg_pref_lib.c (revision 10414) @@ -0,0 +1,542 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - GUI - preferences + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * Copied from pcb-rnd, interactive printed circuit board design + * Copyright (C) 2018,2021 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + + +/* Preferences dialog, library tab */ + +#include +#include +#include +#include +#include +#include +#include +#include + +typedef struct pref_libhelp_ctx_s { + RND_DAD_DECL_NOINIT(dlg) + int active; /* already open - allow only one instance */ +} pref_libhelp_ctx_t; + +typedef struct { + int wlist, whsbutton, wmoveup, wmovedown, wedit, wremove; + int lock; /* a change in on the dialog box causes a change on the sheet but this shouldn't in turn casue a changein the dialog */ + char *cursor_path; + pref_libhelp_ctx_t help; +} pref_lib_t; + +#undef DEF_TABDATA +#define DEF_TABDATA pref_lib_t *tabdata = PREF_TABDATA(ctx) + +static const char *SRC_SHEET = ""; + +static void libhelp_btn2(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr); + +static void pref_lib_update_buttons(rnd_design_t *hl) +{ + pref_ctx_t *ctx = rnd_pref_get_ctx(hl); + DEF_TABDATA; + rnd_hid_attribute_t *attr = &ctx->dlg[tabdata->wlist]; + rnd_hid_row_t *r = rnd_dad_tree_get_selected(attr); + int en = (r != NULL); + + rnd_gui->attr_dlg_widget_state(ctx->dlg_hid_ctx, tabdata->wedit, en); + rnd_gui->attr_dlg_widget_state(ctx->dlg_hid_ctx, tabdata->wremove, en); + rnd_gui->attr_dlg_widget_state(ctx->dlg_hid_ctx, tabdata->wmoveup, en); + rnd_gui->attr_dlg_widget_state(ctx->dlg_hid_ctx, tabdata->wmovedown, en); +} + +static void pref_lib_select_cb(rnd_hid_attribute_t *attrib, void *hid_ctx, rnd_hid_row_t *row) +{ + pref_lib_update_buttons(rnd_gui->get_dad_design(hid_ctx)); +} + +/* Current libraries from config to dialog box: remove everything from + the widget first */ +static void pref_lib_conf2dlg_pre(rnd_conf_native_t *cfg, int arr_idx, void *user_data) +{ + pref_ctx_t *ctx = user_data; + DEF_TABDATA; + rnd_hid_attribute_t *attr; + rnd_hid_tree_t *tree; + rnd_hid_row_t *r; + + if ((tabdata->lock) || (!ctx->active)) + return; + + attr = &ctx->dlg[tabdata->wlist]; + tree = attr->wdata; + + r = rnd_dad_tree_get_selected(attr); + if (r != NULL) { + free(tabdata->cursor_path); + tabdata->cursor_path = rnd_strdup(r->cell[0]); + } + + /* remove all existing entries */ + for(r = gdl_first(&tree->rows); r != NULL; r = gdl_first(&tree->rows)) { + rnd_dad_tree_remove(attr, r); + } +} + +static const char *pref_node_src(lht_node_t *nd) +{ + if (nd->file_name != NULL) + return nd->file_name; + return rnd_conf_role_name(rnd_conf_lookup_role(nd)); +} + +/* Current libraries from config to dialog box: after the change, fill + in all widget rows from the conf */ +static void pref_lib_conf2dlg_post(rnd_conf_native_t *cfg, int arr_idx, void *user_data) +{ + pref_ctx_t *ctx = user_data; + rnd_design_t *hl; + DEF_TABDATA; + rnd_conf_listitem_t *i; + int idx; + const char *s; + char *cell[4]; + rnd_hid_attribute_t *attr; + rnd_hid_attr_val_t hv; + + if ((tabdata->lock) || (!ctx->active)) + return; + + hl = rnd_gui->get_dad_design(ctx->dlg_hid_ctx); + attr = &ctx->dlg[tabdata->wlist]; + + /* copy everything from the config tree to the dialog */ + rnd_conf_loop_list_str(&conf_core.rc.library_search_paths, i, s, idx) { + char *tmp; + cell[0] = rnd_strdup(i->payload); + rnd_path_resolve(hl, cell[0], &tmp, 0, rnd_false); + cell[1] = rnd_strdup(tmp == NULL ? "" : tmp); + cell[2] = rnd_strdup(pref_node_src(i->prop.src)); + cell[3] = NULL; + rnd_dad_tree_append(attr, NULL, cell); + } + + hv.str = tabdata->cursor_path; + if (rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, tabdata->wlist, &hv) == 0) { + free(tabdata->cursor_path); + tabdata->cursor_path = NULL; + } + pref_lib_update_buttons(hl); +} + +/* Dialog box to current libraries in config */ +static void pref_lib_dlg2conf(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + rnd_design_t *hl = rnd_gui->get_dad_design(hid_ctx); + pref_ctx_t *ctx = caller_data; + DEF_TABDATA; + rnd_hid_tree_t *tree = attr->wdata; + lht_node_t *m, *lst, *nd; + rnd_hid_row_t *r; + + + m = rnd_pref_dlg2conf_pre(hl, ctx); + if (m == NULL) + return; + + tabdata->lock++; + /* get the list and clean it */ + + lst = lht_tree_path_(m->doc, m, "rc/library_search_paths", 1, 0, NULL); + if (lst == NULL) + rnd_conf_set(ctx->role, "rc/library_search_paths", 0, "", RND_POL_OVERWRITE); + lst = lht_tree_path_(m->doc, m, "rc/library_search_paths", 1, 0, NULL); + assert(lst != NULL); + lht_tree_list_clean(lst); + + /* append items from the widget */ + for(r = gdl_first(&tree->rows); r != NULL; r = gdl_next(&tree->rows, r)) { + nd = lht_dom_node_alloc(LHT_TEXT, ""); + nd->data.text.value = rnd_strdup(r->cell[0]); + nd->doc = m->doc; + lht_dom_list_append(lst, nd); + rnd_dad_tree_modify_cell(attr, r, 2, rnd_strdup(pref_node_src(nd))); + } + + rnd_conf_update("rc/library_search_paths", -1); + rnd_conf_makedirty(ctx->role); /* low level lht_dom_node_alloc() wouldn't make user config to be saved! */ + + rnd_pref_dlg2conf_post(hl, ctx); + + tabdata->lock--; +} + +static void lib_btn_remove(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *btn_attr) +{ + pref_ctx_t *ctx = caller_data; + DEF_TABDATA; + rnd_hid_attribute_t *attr = &ctx->dlg[tabdata->wlist]; + rnd_hid_row_t *r = rnd_dad_tree_get_selected(attr); + + if (r == NULL) + return; + + if (rnd_dad_tree_remove(attr, r) == 0) { + pref_lib_dlg2conf(hid_ctx, caller_data, attr); + pref_lib_update_buttons(rnd_gui->get_dad_design(hid_ctx)); + } +} + +static void lib_btn_up(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *btn_attr) +{ + pref_ctx_t *ctx = caller_data; + DEF_TABDATA; + rnd_hid_attribute_t *attr = &ctx->dlg[tabdata->wlist]; + rnd_hid_row_t *prev, *r = rnd_dad_tree_get_selected(attr); + rnd_hid_tree_t *tree = attr->wdata; + char *cell[4]; + + if (r == NULL) + return; + + prev = gdl_prev(&tree->rows, r); + if (prev == NULL) + return; + + cell[0] = rnd_strdup(r->cell[0]); /* have to copy because this is also the primary key (path for the hash) */ + cell[1] = r->cell[1]; r->cell[1] = NULL; + cell[2] = r->cell[2]; r->cell[2] = NULL; + cell[3] = NULL; + if (rnd_dad_tree_remove(attr, r) == 0) { + rnd_hid_attr_val_t hv; + rnd_dad_tree_insert(attr, prev, cell); + pref_lib_dlg2conf(hid_ctx, caller_data, attr); + hv.str = cell[0]; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, tabdata->wlist, &hv); + } +} + +static void lib_btn_down(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *btn_attr) +{ + pref_ctx_t *ctx = caller_data; + DEF_TABDATA; + rnd_hid_attribute_t *attr = &ctx->dlg[tabdata->wlist]; + rnd_hid_row_t *next, *r = rnd_dad_tree_get_selected(attr); + rnd_hid_tree_t *tree = attr->wdata; + char *cell[4]; + + if (r == NULL) + return; + + next = gdl_next(&tree->rows, r); + if (next == NULL) + return; + + cell[0] = rnd_strdup(r->cell[0]); /* have to copy because this is also the primary key (path for the hash) */ + cell[1] = r->cell[1]; r->cell[1] = NULL; + cell[2] = r->cell[2]; r->cell[2] = NULL; + cell[3] = NULL; + if (rnd_dad_tree_remove(attr, r) == 0) { + rnd_hid_attr_val_t hv; + rnd_dad_tree_append(attr, next, cell); + pref_lib_dlg2conf(hid_ctx, caller_data, attr); + hv.str = cell[0]; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, tabdata->wlist, &hv); + } +} + +typedef struct { + RND_DAD_DECL_NOINIT(dlg) + int wpath, wexp; + pref_ctx_t *pctx; +} cell_edit_ctx_t; + +static void lib_cell_edit_update(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *btn_attr) +{ + rnd_design_t *hl = rnd_gui->get_dad_design(hid_ctx); + cell_edit_ctx_t *ctx = caller_data; + char *tmp; + + rnd_path_resolve(hl, ctx->dlg[ctx->wpath].val.str, &tmp, 0, rnd_true); + if (tmp != NULL) + RND_DAD_SET_VALUE(hid_ctx, ctx->wexp, str, tmp); +} + +static int lib_cell_edit(pref_ctx_t *pctx, char **cell) +{ + cell_edit_ctx_t ctx; + rnd_hid_dad_buttons_t clbtn[] = {{"Cancel", -1}, {"ok", 0}, {NULL, 0}}; + + memset(&ctx, 0, sizeof(ctx)); + ctx.pctx = pctx; + + RND_DAD_BEGIN_VBOX(ctx.dlg); + RND_DAD_BEGIN_TABLE(ctx.dlg, 2); + RND_DAD_LABEL(ctx.dlg, "Path:"); + RND_DAD_STRING(ctx.dlg); + ctx.wpath = RND_DAD_CURRENT(ctx.dlg); + ctx.dlg[ctx.wpath].val.str = rnd_strdup(cell[0]); + RND_DAD_CHANGE_CB(ctx.dlg, lib_cell_edit_update); + + RND_DAD_LABEL(ctx.dlg, "Expanded\nversion:"); + RND_DAD_LABEL(ctx.dlg, cell[1]); + ctx.wexp = RND_DAD_CURRENT(ctx.dlg); + ctx.dlg[ctx.wexp].val.str = rnd_strdup(cell[1]); + + RND_DAD_LABEL(ctx.dlg, ""); + RND_DAD_BUTTON(ctx.dlg, "Help..."); + RND_DAD_CHANGE_CB(ctx.dlg, libhelp_btn2); + RND_DAD_END(ctx.dlg); + RND_DAD_BUTTON_CLOSES(ctx.dlg, clbtn); + RND_DAD_END(ctx.dlg); + + RND_DAD_NEW("pref_lib_path", ctx.dlg, "Edit library path", &ctx, rnd_true, NULL); /* type=global/modal */ + if (RND_DAD_RUN(ctx.dlg) != 0) { + RND_DAD_FREE(ctx.dlg); + return -1; + } + + free(cell[0]); + cell[0] = rnd_strdup(RND_EMPTY(ctx.dlg[ctx.wpath].val.str)); + free(cell[1]); + cell[1] = rnd_strdup(RND_EMPTY(ctx.dlg[ctx.wexp].val.str)); + + RND_DAD_FREE(ctx.dlg); + return 0; +} + +static void lib_btn_insert(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *btn_attr, int pos) +{ + pref_ctx_t *ctx = caller_data; + DEF_TABDATA; + rnd_hid_attribute_t *attr = &ctx->dlg[tabdata->wlist]; + rnd_hid_row_t *r = rnd_dad_tree_get_selected(attr); + char *cell[4]; + + if (r == NULL) { + rnd_hid_tree_t *tree = attr->wdata; + + switch(pos) { + case 0: /* replace */ + rnd_message(RND_MSG_ERROR, "need to select a library path row first\n"); + return; + + case -1: /* before */ + r = gdl_first(&tree->rows); + break; + case +1: /* after */ + r = gdl_last(&tree->rows); + break; + } + } + + if (pos != 0) { + cell[0] = rnd_strdup(""); + cell[1] = rnd_strdup(""); + cell[2] = rnd_strdup(SRC_SHEET); + } + else { + cell[0] = rnd_strdup(r->cell[0]); + cell[1] = rnd_strdup(r->cell[1]); + cell[2] = rnd_strdup(r->cell[2]); + } + cell[3] = NULL; + + if (lib_cell_edit(ctx, cell) != 0) { + free(cell[0]); + free(cell[1]); + free(cell[2]); + return; + } + + switch(pos) { + case -1: /* before */ + rnd_dad_tree_insert(attr, r, cell); + break; + case +1: /* after */ + rnd_dad_tree_append(attr, r, cell); + break; + case 0: /* replace */ + rnd_dad_tree_modify_cell(attr, r, 0, cell[0]); + rnd_dad_tree_modify_cell(attr, r, 1, cell[1]); + rnd_dad_tree_modify_cell(attr, r, 2, cell[2]); + break; + } + pref_lib_dlg2conf(hid_ctx, caller_data, attr); +} + +static void lib_btn_insert_before(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *btn_attr) +{ + lib_btn_insert(hid_ctx, caller_data, btn_attr, -1); +} + +static void lib_btn_insert_after(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *btn_attr) +{ + lib_btn_insert(hid_ctx, caller_data, btn_attr, +1); +} + +static void lib_btn_edit(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *btn_attr) +{ + lib_btn_insert(hid_ctx, caller_data, btn_attr, 0); +} + +void sch_dlg_pref_lib_close(pref_ctx_t *ctx, rnd_design_t *dsg) +{ + DEF_TABDATA; + if (tabdata->help.active) + RND_DAD_FREE(tabdata->help.dlg); +} + +static void pref_libhelp_close_cb(void *caller_data, rnd_hid_attr_ev_t ev) +{ +/* pref_libhelp_ctx_t *ctx = caller_data;*/ +} + +static void pref_libhelp_open(pref_libhelp_ctx_t *ctx) +{ + htsp_entry_t *e; + rnd_hid_dad_buttons_t clbtn[] = {{"Close", 0}, {NULL, 0}}; + + if (ctx->active) + return; + + RND_DAD_LABEL(ctx->dlg, "The following $(variables) can be used in the path:"); + RND_DAD_BEGIN_TABLE(ctx->dlg, 2); + rnd_conf_fields_foreach(e) { + rnd_conf_native_t *nat = e->value; + char tmp[256]; + + if (strncmp(e->key, "rc/path/", 8) != 0) + continue; + + rnd_snprintf(tmp, sizeof(tmp), "$(rc.path.%s)", e->key + 8); + RND_DAD_LABEL(ctx->dlg, tmp); + RND_DAD_LABEL(ctx->dlg, nat->val.string[0] == NULL ? "" : nat->val.string[0]); + } + RND_DAD_BUTTON_CLOSES(ctx->dlg, clbtn); + RND_DAD_END(ctx->dlg); + + ctx->active = 1; + RND_DAD_NEW("pref_lib_path_help", ctx->dlg, "sch-rnd preferences: symbol library help", ctx, rnd_true, pref_libhelp_close_cb); /* type=global/modal */ + + RND_DAD_RUN(ctx->dlg); + RND_DAD_FREE(ctx->dlg); + memset(ctx, 0, sizeof(pref_libhelp_ctx_t)); /* reset all states to the initial - includes ctx->active = 0; */ +} + +static void libhelp_btn(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + pref_ctx_t *ctx = caller_data; + DEF_TABDATA; + pref_libhelp_open(&tabdata->help); +} + +static void libhelp_btn2(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + cell_edit_ctx_t *cctx = caller_data; + pref_ctx_t *ctx = cctx->pctx; + libhelp_btn(hid_ctx, ctx, attr); +} + +void sch_dlg_pref_lib_create(pref_ctx_t *ctx, rnd_design_t *dsg) +{ + DEF_TABDATA; + static const char *hdr[] = {"configured path", "actual path on the filesystem", "config source", NULL}; + + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); /* get the parent vbox, which is the tab's page vbox, to expand and fill */ + + RND_DAD_LABEL(ctx->dlg, "Ordered list of symbol library search directories."); + + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_FRAME | RND_HATF_EXPFILL); + RND_DAD_TREE(ctx->dlg, 3, 0, hdr); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL | RND_HATF_SCROLL); + tabdata->wlist = RND_DAD_CURRENT(ctx->dlg); + /* rnd_hid_tree_t *tree = ctx->dlg[tabdata->wlist].wdata; */ + RND_DAD_TREE_SET_CB(ctx->dlg, selected_cb, pref_lib_select_cb); + RND_DAD_END(ctx->dlg); + + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "Move up"); + RND_DAD_CHANGE_CB(ctx->dlg, lib_btn_up); + tabdata->wmoveup = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "Move down"); + RND_DAD_CHANGE_CB(ctx->dlg, lib_btn_down); + tabdata->wmovedown = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "Insert before"); + RND_DAD_CHANGE_CB(ctx->dlg, lib_btn_insert_before); + RND_DAD_BUTTON(ctx->dlg, "Insert after"); + RND_DAD_CHANGE_CB(ctx->dlg, lib_btn_insert_after); + RND_DAD_BUTTON(ctx->dlg, "Remove"); + RND_DAD_CHANGE_CB(ctx->dlg, lib_btn_remove); + tabdata->wremove = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "Edit..."); + RND_DAD_CHANGE_CB(ctx->dlg, lib_btn_edit); + tabdata->wedit = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "Help..."); + tabdata->whsbutton = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_CHANGE_CB(ctx->dlg, libhelp_btn); + RND_DAD_END(ctx->dlg); + +} + +void sch_dlg_pref_lib_open(pref_ctx_t *ctx, rnd_design_t *dsg, const char *tabdatareq) +{ + rnd_conf_native_t *cn = rnd_conf_get_field("rc/library_search_paths"); + pref_lib_conf2dlg_post(cn, -1, ctx); +} + +void sch_dlg_pref_lib_board_chg(pref_ctx_t *ctx, rnd_design_t *dsg) +{ + rnd_conf_native_t *cn = rnd_conf_get_field("rc/library_search_paths"); + pref_lib_conf2dlg_pre(cn, -1, ctx); + pref_lib_conf2dlg_post(cn, -1, ctx); +} + +static const rnd_pref_tab_hook_t pref_lib = { + "Library", RND_PREFTAB_AUTO_FREE_DATA | RND_PREFTAB_NEEDS_ROLE, + sch_dlg_pref_lib_open, sch_dlg_pref_lib_close, + sch_dlg_pref_lib_create, + sch_dlg_pref_lib_board_chg, NULL +}; + +void sch_dlg_pref_lib_init(pref_ctx_t *ctx, int tab) +{ + static rnd_conf_hid_callbacks_t cbs_spth; + rnd_conf_native_t *cn = rnd_conf_get_field("rc/library_search_paths"); + + PREF_INIT(ctx, &pref_lib); + PREF_TABDATA(ctx) = calloc(sizeof(pref_lib_t), 1); + + if (cn != NULL) { + memset(&cbs_spth, 0, sizeof(rnd_conf_hid_callbacks_t)); + cbs_spth.val_change_pre = pref_lib_conf2dlg_pre; + cbs_spth.val_change_post = pref_lib_conf2dlg_post; + cbs_spth.user_data = ctx; + rnd_conf_hid_set_cb(cn, pref_hid, &cbs_spth); + } +} + +#undef PREF_INIT_FUNC +#define PREF_INIT_FUNC sch_dlg_pref_lib_init Index: tags/1.0.5/src/plugins/sch_dialogs/dlg_pref_sheet.c =================================================================== --- tags/1.0.5/src/plugins/sch_dialogs/dlg_pref_sheet.c (nonexistent) +++ tags/1.0.5/src/plugins/sch_dialogs/dlg_pref_sheet.c (revision 10414) @@ -0,0 +1,145 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - GUI - preferences + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * Copied from pcb-rnd, interactive printed circuit board design + * Copyright (C) 2018,2021 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/* Preferences dialog, sheet tab */ + +#include +#include +#include +#include +#include +#include +#include "dlg_pen.h" +#include + +typedef struct { + int wname, wthermscale, wtype; +} pref_sheet_t; + +#define RND_EMPTY(a) ((a) ? (a) : "") + +#undef DEF_TABDATA +#define DEF_TABDATA pref_sheet_t *tabdata = PREF_TABDATA(ctx) + +/* Actual sheet meta to dialog box */ +static void pref_sheet_brd2dlg(pref_ctx_t *ctx, rnd_design_t *dsg) +{ + rnd_design_t *hl = rnd_multi_get_current(); + csch_sheet_t *sheet = (csch_sheet_t *)hl; + DEF_TABDATA; + +#ifdef HIDLIB_NAME + RND_DAD_SET_VALUE(ctx->dlg_hid_ctx, tabdata->wname, str, RND_EMPTY(hl->name)); +#endif + + RND_DAD_SET_VALUE(ctx->dlg_hid_ctx, tabdata->wtype, str, (sheet->is_symbol ? "symbol" : "schematics sheet")); +} + +/* Dialog box to actual sheet meta */ +static void pref_sheet_dlg2brd(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + rnd_design_t *hl = rnd_gui->get_dad_design(hid_ctx); + csch_sheet_t *sheet = (csch_sheet_t *)hl; + int changed = 0; + +#ifdef HIDLIB_NAME + pref_ctx_t *ctx = caller_data; + DEF_TABDATA; + const char *newname, *oldname; + newname = RND_EMPTY(ctx->dlg[tabdata->wname].val.str); + oldname = RND_EMPTY(hl->name); + if (strcmp(oldname, newname) != 0) { + free(hl->name); + hl->name = rnd_strdup(newname); + rnd_event(hl, RND_EVENT_DESIGN_FN_CHANGED, NULL); + changed = 1; + } +#endif + + if (changed) { + sheet->changed = 1; + rnd_event(hl, RND_EVENT_DESIGN_META_CHANGED, NULL); /* always generate the event to make sure visible changes are flushed */ + } +} + +static void pref_sheet_edit_attr(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + rnd_design_t *hl = rnd_multi_get_current(); + rnd_actionva(hl, "Propedit", "sheet", NULL); +} + +static void pref_sheet_pen(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + rnd_design_t *hl = rnd_multi_get_current(); + csch_sheet_t *sheet = (csch_sheet_t *)hl; + + sch_rnd_pen_dlg(sheet, &sheet->direct, NULL, 0, 0); +} + +void csch_dlg_pref_sheet_create(pref_ctx_t *ctx, rnd_design_t *dsg) +{ + rnd_design_t *hl = rnd_multi_get_current(); + csch_sheet_t *sheet = (csch_sheet_t *)hl; + DEF_TABDATA; + + RND_DAD_BEGIN_TABLE(ctx->dlg, 2); +#ifdef HIDLIB_NAME + RND_DAD_LABEL(ctx->dlg, "Sheet name"); + RND_DAD_STRING(ctx->dlg); + tabdata->wname = RND_DAD_CURRENT(ctx->dlg); + ctx->dlg[tabdata->wname].val.str = rnd_strdup(RND_EMPTY(hl->name)); + RND_DAD_CHANGE_CB(ctx->dlg, pref_sheet_dlg2brd); +#endif + RND_DAD_LABEL(ctx->dlg, "Type"); + RND_DAD_LABEL(ctx->dlg, ""); + tabdata->wtype = RND_DAD_CURRENT(ctx->dlg); + ctx->dlg[tabdata->wtype].name = rnd_strdup((sheet->is_symbol ? "symbol" : "schematics sheet")); + RND_DAD_CHANGE_CB(ctx->dlg, pref_sheet_dlg2brd); + RND_DAD_LABEL(ctx->dlg, "Sheet attributes"); + RND_DAD_BUTTON(ctx->dlg, "Edit..."); + RND_DAD_CHANGE_CB(ctx->dlg, pref_sheet_edit_attr); + RND_DAD_LABEL(ctx->dlg, "Sheet pens"); + RND_DAD_BUTTON(ctx->dlg, "Edit..."); + RND_DAD_CHANGE_CB(ctx->dlg, pref_sheet_pen); + RND_DAD_END(ctx->dlg); +} + +static const rnd_pref_tab_hook_t pref_sheet = { + "Sheet meta", RND_PREFTAB_AUTO_FREE_DATA, + NULL, NULL, + csch_dlg_pref_sheet_create, + pref_sheet_brd2dlg, pref_sheet_brd2dlg /* sheet change, meta change */ +}; + +static void sch_dlg_pref_sheet_init(pref_ctx_t *ctx, int tab) +{ + PREF_INIT(ctx, &pref_sheet); + PREF_TABDATA(ctx) = calloc(sizeof(pref_sheet_t), 1); +} +#undef PREF_INIT_FUNC +#define PREF_INIT_FUNC sch_dlg_pref_sheet_init Index: tags/1.0.5/src/plugins/sch_dialogs/dlg_project.c =================================================================== --- tags/1.0.5/src/plugins/sch_dialogs/dlg_project.c (nonexistent) +++ tags/1.0.5/src/plugins/sch_dialogs/dlg_project.c (revision 10414) @@ -0,0 +1,259 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - GUI - project dialog + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrist in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/* project properties dialog */ + +#include + + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +typedef struct prjdlg_ctx_s prjdlg_ctx_t; + +struct prjdlg_ctx_s { + RND_DAD_DECL_NOINIT(dlg) + int wlist, wscope; + unsigned active:1; + csch_project_t *prj; + int wtab; +}; + +static prjdlg_ctx_t prjdlg; /* only one instance can be active */ + + +#define SCOPE (ctx->dlg[ctx->wscope].val.lng) +#define PRJDSG ((ctx->prj->hdr.designs.used > 0) ? ctx->prj->hdr.designs.array[0] : NULL) + +static void prjdlg_close_cb(void *caller_data, rnd_hid_attr_ev_t ev) +{ + prjdlg_ctx_t *ctx = caller_data; + + RND_DAD_FREE(ctx->dlg); + ctx->active = 0; +} + +static void prj2dlg_load_tree(prjdlg_ctx_t *ctx) +{ + rnd_hid_attribute_t *attr = &ctx->dlg[ctx->wlist]; + char *cell[2]; + long n; + csch_sheet_type_t ty; + + switch(SCOPE) { + case 0: ty = CSCH_SHTY_ROOT; break; + case 1: ty = CSCH_SHTY_AUX; break; + case 2: ty = CSCH_SHTY_UNLISTED; break; + case 3: ty = CSCH_SHTY_EXTERNAL; break; + default: + rnd_message(RND_MSG_ERROR, "prj2dlg_load_tree(): internal error: invalid SCOPE %d\n", SCOPE); + return; + } + + /* add sheets that match SCOPE's type to table */ + cell[1] = NULL; + for(n = 0; n < ctx->prj->hdr.designs.used; n++) { + csch_sheet_t *sheet = ctx->prj->hdr.designs.array[n]; + if (sheet->stype == ty) { + cell[0] = rnd_strdup(sheet->hidlib.fullpath); + rnd_dad_tree_append(attr, NULL, cell); + } + } +} + +static void prj2dlg(prjdlg_ctx_t *ctx) +{ + rnd_hid_attribute_t *attr = &ctx->dlg[ctx->wlist]; + rnd_hid_tree_t *tree = attr->wdata; + rnd_hid_row_t *r; + char *cursor_path = NULL; + + /* remember cursor */ + r = rnd_dad_tree_get_selected(attr); + if (r != NULL) + cursor_path = rnd_strdup(r->cell[0]); + + /* remove existing items and fill up with the new */ + rnd_dad_tree_clear(tree); + prj2dlg_load_tree(ctx); + + /* restore cursor (will work only in non-modal upon project update from elsewhere) */ + if (cursor_path != NULL) { + rnd_hid_attr_val_t hv; + hv.str = cursor_path; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wlist, &hv); + free(cursor_path); + } +} + +static void prj_set_scope_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + prjdlg_ctx_t *ctx = caller_data; + prj2dlg(ctx); +} + + +static void prj_sheet_select_cb(rnd_hid_attribute_t *attrib, void *hid_ctx, rnd_hid_row_t *row) +{ +/* rnd_hid_tree_t *tree = attrib->wdata;*/ +/* prjdlg_ctx_t *ctx = tree->user_ctx;*/ +/* Nothing to do here yet */ +} + +static void prj_sheet_toggle_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + prjdlg_ctx_t *ctx = caller_data; + rnd_hid_attribute_t *tattr = &ctx->dlg[ctx->wlist]; + rnd_hid_row_t *row = rnd_dad_tree_get_selected(tattr); + const char *target; + + if (row == NULL) + return; + + switch(SCOPE) { + case 0: target="aux"; break; + case 1: + case 2: target="root"; break; + case 3: target="aux"; break; + default: + return; + } + + rnd_actionva(PRJDSG, "ProjectSheetType", "@", row->cell[0], target, NULL); + prj2dlg(ctx); +} + +static void prj_sheet_new_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + prjdlg_ctx_t *ctx = caller_data; + rnd_actionva(PRJDSG, "New", "@", "root", NULL); + prj2dlg(ctx); +} + +static void prj_sheet_load_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + prjdlg_ctx_t *ctx = caller_data; + csch_sheet_t *ns, *curr = (csch_sheet_t *)rnd_multi_get_current(); + + rnd_actionva(PRJDSG, "Load", NULL); + ns = (csch_sheet_t *)rnd_multi_get_current(); + if (ns != curr) { + rnd_actionva(PRJDSG, "ProjectSheetType", "@", ns->hidlib.fullpath, "root", NULL); + prj2dlg(ctx); + } +} + +static void prj_sheet_del_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + prjdlg_ctx_t *ctx = caller_data; + rnd_hid_attribute_t *tattr = &ctx->dlg[ctx->wlist]; + rnd_hid_row_t *row = rnd_dad_tree_get_selected(tattr); + + if (row == NULL) + return; + + rnd_actionva(PRJDSG, "ProjectSheetType", "@", row->cell[0], "unload", NULL); + prj2dlg(ctx); +} + +static void prj_dlg(csch_project_t *prj) +{ + prjdlg_ctx_t *ctx = &prjdlg; + rnd_hid_dad_buttons_t clbtn[] = {{"Close", 0}, {NULL, 0}}; + char *lists[] = {"root sheets (directly compiled)", "aux sheets (referenced by hierarchy)", "unlisted sheets", "external sheets", NULL}; + + ctx->prj = prj; + + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + + RND_DAD_ENUM(ctx->dlg, lists); + ctx->wscope = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_CHANGE_CB(ctx->dlg, prj_set_scope_cb); + + RND_DAD_TREE(ctx->dlg, 1, 0, NULL); /* middle: tree */ + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_TREE_SET_CB(ctx->dlg, selected_cb, prj_sheet_select_cb); + RND_DAD_TREE_SET_CB(ctx->dlg, ctx, ctx); + ctx->wlist = RND_DAD_CURRENT(ctx->dlg); + + RND_DAD_BEGIN_HBOX(ctx->dlg); /* bottom buttons */ + RND_DAD_BUTTON(ctx->dlg, "toggle root"); + RND_DAD_CHANGE_CB(ctx->dlg, prj_sheet_toggle_cb); + RND_DAD_HELP(ctx->dlg, "If the selected sheet is a root sheet, make it an aux sheet;\nif it is an aux sheet, make it a root sheet;\nif it is an unlisted sheet, make it a root sheet;\if it is an external sheet, make it an aux sheet."); + RND_DAD_BUTTON(ctx->dlg, "new"); + RND_DAD_CHANGE_CB(ctx->dlg, prj_sheet_new_cb); + RND_DAD_HELP(ctx->dlg, "Create a new root sheet"); + RND_DAD_BUTTON(ctx->dlg, "load"); + RND_DAD_CHANGE_CB(ctx->dlg, prj_sheet_load_cb); + RND_DAD_HELP(ctx->dlg, "Load a new root sheet"); + RND_DAD_BUTTON(ctx->dlg, "del"); + RND_DAD_CHANGE_CB(ctx->dlg, prj_sheet_del_cb); + RND_DAD_HELP(ctx->dlg, "Remove selected sheet from the project file and unload the sheet file"); + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_END(ctx->dlg); + RND_DAD_BUTTON_CLOSES(ctx->dlg, clbtn); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + + ctx->active = 1; + RND_DAD_DEFSIZE(ctx->dlg, 200, 300); + RND_DAD_NEW("PrjPropDialog", ctx->dlg, "Project properties", ctx, 1, prjdlg_close_cb); /* type=local/modal */ + + prj2dlg(ctx); + + RND_DAD_RUN(ctx->dlg); + RND_DAD_FREE(ctx->dlg); +} + + +const char csch_acts_ProjectDialog[] = "ProjectDialog()"; +const char csch_acth_ProjectDialog[] = "Bring up a modal project edit dialog for editing file listings of a project.\n"; +fgw_error_t csch_act_ProjectDialog(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_design_t *hidlib = RND_ACT_DESIGN; + csch_sheet_t *sheet = (csch_sheet_t *)hidlib; + + prj_dlg((csch_project_t *)sheet->hidlib.project); + + RND_ACT_IRES(0); + return 0; +} + Index: tags/1.0.5/src/plugins/sch_dialogs/dlg_project.h =================================================================== --- tags/1.0.5/src/plugins/sch_dialogs/dlg_project.h (nonexistent) +++ tags/1.0.5/src/plugins/sch_dialogs/dlg_project.h (revision 10414) @@ -0,0 +1,3 @@ +extern const char csch_acts_ProjectDialog[]; +extern const char csch_acth_ProjectDialog[]; +fgw_error_t csch_act_ProjectDialog(fgw_arg_t *res, int argc, fgw_arg_t *argv); Index: tags/1.0.5/src/plugins/sch_dialogs/dlg_stance.c =================================================================== --- tags/1.0.5/src/plugins/sch_dialogs/dlg_stance.c (nonexistent) +++ tags/1.0.5/src/plugins/sch_dialogs/dlg_stance.c (revision 10414) @@ -0,0 +1,369 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - GUI - stance edit dialog + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/* stance configuration dialog */ + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +/* This doesn't make a plugin dep as only inlines and macros and structs are used */ +#include +#define RND_TIMED_CHG_TIMEOUT conf_core.editor.edit_time +#include + +#include "dlg_stance.h" + +typedef struct stance_dlg_ctx_s { + RND_DAD_DECL_NOINIT(dlg) + + csch_project_t *prj; + + int wtree, wpend; + rnd_timed_chg_t timed_update; +} stance_dlg_ctx_t; + +static htpp_t prj2dlg; + +static void stance_dlg_close_cb(void *caller_data, rnd_hid_attr_ev_t ev) +{ + stance_dlg_ctx_t *ctx = caller_data; + + rnd_timed_chg_cancel(&ctx->timed_update); + htpp_pop(&prj2dlg, ctx->prj); + free(ctx); +} + +static void stance_prj2dlg(stance_dlg_ctx_t *ctx) +{ + static const char *paths[] = {"stance/model", "stance/sub_major", "stance/sub_minor", "stance/test_bench", NULL}; + rnd_hid_attribute_t *attr = &ctx->dlg[ctx->wtree]; + rnd_hid_tree_t *tree = attr->wdata; + rnd_hid_row_t *r; + const char **s; + char *cursor_path = NULL, *cell[3]; + + /* remember cursor */ + r = rnd_dad_tree_get_selected(attr); + if (r != NULL) + cursor_path = rnd_strdup(r->path); + + /* remove existing items */ + rnd_dad_tree_clear(tree); + + /* add all items */ + cell[2] = NULL; + for(s = paths; *s != NULL; s++) { + rnd_conf_native_t *nat = rnd_conf_get_field(*s); + cell[0] = rnd_strdup(*s + 7); + cell[1] = (nat->val.string[0] == NULL) ? NULL : rnd_strdup(nat->val.string[0]); + rnd_dad_tree_append(attr, NULL, cell); + } + + /* restore cursor */ + if (cursor_path != NULL) { + rnd_hid_attr_val_t hv; + hv.str = cursor_path; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wtree, &hv); + free(cursor_path); + } +} + +typedef struct stance_val_ctx_s { + RND_DAD_DECL_NOINIT(dlg) + int wenum, wstr; + vts0_t values; +} stance_val_ctx_t; + +static void select_from_enum_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + stance_val_ctx_t *vctx = caller_data; + rnd_hid_attr_val_t hv; + + if ((attr->val.lng >= 0) && (attr->val.lng < vctx->values.used)) { + hv.str = vctx->values.array[attr->val.lng]; + rnd_gui->attr_dlg_set_value(vctx->dlg_hid_ctx, vctx->wstr, &hv); + } +} + +static void val_enter_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + stance_val_ctx_t *vctx = caller_data; + rnd_hid_dad_close(hid_ctx, vctx->dlg_ret_override, 1); +} + + +sch_stance_edit_res_t sch_stance_edit_dlg(const char *stance_name, const char *initval, char **val_out) +{ + rnd_hid_dad_buttons_t clbtn[] = {{"Cancel", 0}, {"OK", 1}, {NULL, 0}}; + rnd_conf_native_t *nat; + gds_t tmp = {0}; + const char *currval; + int res, enum_val = -1; + rnd_hid_attr_val_t hv; + stance_val_ctx_t vctx = {0}; + + *val_out = NULL; + + /* get current value */ + gds_append_str(&tmp, "stance/"); + gds_append_str(&tmp, stance_name); + if (initval == NULL) { + nat = rnd_conf_get_field(tmp.array); + if (nat == NULL) { + rnd_message(RND_MSG_ERROR, "internal error: invalid stance name: '%s' (conf path: '%s')\n", stance_name, tmp.array); + return STE_CANCEL; + } + currval = nat->val.string[0]; + } + else + currval = initval; + + /* get possible values */ + gds_append_str(&tmp, "_values"); + nat = rnd_conf_get_field(tmp.array); + if ((nat != NULL) && (nat->type == RND_CFN_LIST)) { + rnd_conf_listitem_t *item_li; + const char *item_str; + int idx; + + rnd_conf_loop_list_str(nat->val.list, item_li, item_str, idx) { + vts0_append(&vctx.values, (char *)item_str); + if (strcmp(item_str, currval) == 0) + enum_val = idx; + } + } + + /* label */ + tmp.used = 0; + gds_append_str(&tmp, "Value of "); + gds_append_str(&tmp, stance_name); + gds_append(&tmp, ':'); + + + RND_DAD_BEGIN_VBOX(vctx.dlg); + RND_DAD_LABEL(vctx.dlg, tmp.array); + if (vctx.values.array !=NULL) { + RND_DAD_ENUM(vctx.dlg, vctx.values.array); + vctx.wenum = RND_DAD_CURRENT(vctx.dlg); + RND_DAD_CHANGE_CB(vctx.dlg, select_from_enum_cb); + } + RND_DAD_STRING(vctx.dlg); + vctx.wstr = RND_DAD_CURRENT(vctx.dlg); + RND_DAD_ENTER_CB(vctx.dlg, val_enter_cb); + RND_DAD_BUTTON_CLOSES(vctx.dlg, clbtn); + RND_DAD_END(vctx.dlg); + + RND_DAD_NEW("StanceEditDialog", vctx.dlg, "Edit stance value", &vctx, 1, NULL); /* type=local/modal */ + + hv.str = currval; + rnd_gui->attr_dlg_set_value(vctx.dlg_hid_ctx, vctx.wstr, &hv); + + hv.lng = enum_val; + rnd_gui->attr_dlg_set_value(vctx.dlg_hid_ctx, vctx.wenum, &hv); + + res = RND_DAD_RUN(vctx.dlg); + if (res == 1) + *val_out = rnd_strdup(vctx.dlg[vctx.wstr].val.str); + RND_DAD_FREE(vctx.dlg); + + gds_uninit(&tmp); + vts0_uninit(&vctx.values); + + if (res == 0) + return STE_CANCEL; + + if ((*val_out == NULL) || (**val_out == '\0')) + return STE_SET; /* do not save empty in the list of values */ + + return STE_SET | STE_REMEMBER; +} + +static void stance_edit_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + stance_dlg_ctx_t *ctx = caller_data; + csch_sheet_t *sheet = (csch_sheet_t *)ctx->prj->hdr.designs.array[0]; + rnd_hid_attribute_t *tattr = &ctx->dlg[ctx->wtree]; + rnd_hid_row_t *row = rnd_dad_tree_get_selected(tattr); + char *val = NULL; + sch_stance_edit_res_t r; + + if (row == NULL) + return; + + r = sch_stance_edit_dlg(row->cell[0], NULL, &val); + if ((r == STE_CANCEL) || (val == NULL)) { + free(val); + return; + } + + if (sch_rnd_project_create_file_for_sheet_gui(sheet) == 0) { + if (r & STE_REMEMBER) csch_stance_add_to_values(row->cell[0], val); + if (r & STE_SET) csch_stance_set(row->cell[0], val); + } + else + rnd_message(RND_MSG_ERROR, "Failed to save stance change in project file\n"); + + free(val); +} + +static void timed_update_cb(void *uctx) +{ + stance_dlg_ctx_t *ctx = uctx; + stance_prj2dlg(ctx); + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wpend, 1); +} + +static void sch_rnd_stance_dlg(csch_project_t *prj) +{ + stance_dlg_ctx_t *ctx; + rnd_hid_dad_buttons_t clbtn[] = {{"Close", 0}, {NULL, 0}}; + const char *hdr[] = {"name", "value", NULL}; + + ctx = htpp_get(&prj2dlg, prj); + if (ctx != NULL) { + TODO("raise?"); + return; + } + + ctx = calloc(sizeof(stance_dlg_ctx_t), 1); + ctx->prj = prj; + rnd_timed_chg_init(&ctx->timed_update, timed_update_cb, ctx); + htpp_set(&prj2dlg, prj, ctx); + + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + + RND_DAD_BEGIN_VBOX(ctx->dlg); /* left */ + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_TREE(ctx->dlg, 2, 0, hdr); /* top left: tree */ + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL | RND_HATF_SCROLL); + ctx->wtree = RND_DAD_CURRENT(ctx->dlg); + + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "Edit..."); + RND_DAD_CHANGE_CB(ctx->dlg, stance_edit_cb); + RND_DAD_HELP(ctx->dlg, "Change the value of the selected stance."); + RND_DAD_BEGIN_VBOX(ctx->dlg); /* spring */ + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_LABEL(ctx->dlg, "pending change..."); + ctx->wpend = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_END(ctx->dlg); + RND_DAD_BUTTON_CLOSES(ctx->dlg, clbtn); + RND_DAD_END(ctx->dlg); + + RND_DAD_END(ctx->dlg); + + RND_DAD_END(ctx->dlg); + + RND_DAD_DEFSIZE(ctx->dlg, 300, 400); + RND_DAD_NEW("StanceDialog", ctx->dlg, "Project stances", ctx, 0, stance_dlg_close_cb); /* type=local */ + + stance_prj2dlg(ctx); + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wpend, 1); + +} + + + +const char csch_acts_StanceDialog[] = "StanceDialog()"; +const char csch_acth_StanceDialog[] = "Open the current project's stance configuration dialog.\n"; +fgw_error_t csch_act_StanceDialog(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_design_t *hidlib = RND_ACT_DESIGN; + csch_sheet_t *sheet = (csch_sheet_t *)hidlib; + + sch_rnd_stance_dlg((csch_project_t *)sheet->hidlib.project); + return 0; +} + + +/*** Common ***/ + +/* trigger gui update if any stance conf changes */ +static void stance_change_post(rnd_conf_native_t *cfg, int arr_idx, void *user_data) +{ + if ((cfg->hash_path[0] == 's') && (strncmp(cfg->hash_path, "stance/", 7) == 0)) { + rnd_design_t *curr = rnd_multi_get_current(); + if (curr != NULL) { + rnd_project_t *prj = curr->project; + stance_dlg_ctx_t *ctx = htpp_get(&prj2dlg, prj); + if (ctx != NULL) { + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wpend, 0); + rnd_timed_chg_schedule(&ctx->timed_update); + } + rnd_event(curr, CSCH_EVENT_PRJ_STANCE_CHANGED, NULL); + } + } +} + +static rnd_conf_hid_id_t stance_hid_id; +static const char cookie[] = "stance gui"; +void csch_dlg_stance_init(void) +{ + static rnd_conf_hid_callbacks_t cb = {0}; + + htpp_init(&prj2dlg, ptrhash, ptrkeyeq); + + /* get a global conf change callback */ + cb.val_change_post = stance_change_post; + stance_hid_id = rnd_conf_hid_reg(cookie, &cb); +} + +void csch_dlg_stance_uninit(void) +{ + rnd_dad_retovr_t retovr = {0}; + htpp_entry_t *e; + + for(e = htpp_first(&prj2dlg); e != NULL; e = htpp_next(&prj2dlg, e)) { + stance_dlg_ctx_t *ctx = e->value; + rnd_hid_dad_close(ctx->dlg_hid_ctx, &retovr, 0); + } + htpp_uninit(&prj2dlg); + + rnd_conf_hid_unreg(cookie); +} Index: tags/1.0.5/src/plugins/sch_dialogs/dlg_stance.h =================================================================== --- tags/1.0.5/src/plugins/sch_dialogs/dlg_stance.h (nonexistent) +++ tags/1.0.5/src/plugins/sch_dialogs/dlg_stance.h (revision 10414) @@ -0,0 +1,33 @@ +void csch_dlg_stance_init(void); +void csch_dlg_stance_uninit(void); +void csch_dlg_cond_preunload(csch_sheet_t *sheet); + + +extern const char csch_acts_StanceDialog[]; +extern const char csch_acth_StanceDialog[]; +fgw_error_t csch_act_StanceDialog(fgw_arg_t *res, int argc, fgw_arg_t *argv); + +extern const char csch_acts_ConditionalDialog[]; +extern const char csch_acth_ConditionalDialog[]; +fgw_error_t csch_act_ConditionalDialog(fgw_arg_t *res, int argc, fgw_arg_t *argv); + +extern const char csch_acts_quick_attr_forge__if__dnp[]; +extern const char csch_acth_quick_attr_forge__if__dnp[]; +extern const char csch_acts_quick_attr_forge__if__omit[]; +extern const char csch_acth_quick_attr_forge__if__omit[]; +fgw_error_t csch_act_quick_attr_forge__if__dnp_omit(fgw_arg_t *res, int argc, fgw_arg_t *argv); + +/* bitfield */ +typedef enum { + STE_CANCEL = 0, /* no-op */ + STE_SET = 1, /* set the value of the stance */ + STE_REMEMBER = 2 /* append the value to possible values */ +} sch_stance_edit_res_t; + + +/* Present a modal dialog to select a stance from all available stance values + of that stance and/or adding a new value. Initval is the initial value the + dialog box will be filled in with, or NULL to read the value from the config. + Uses the current project (and config). val_out is dynamically allocated, + the caller needs to free it. */ +sch_stance_edit_res_t sch_stance_edit_dlg(const char *stance_name, const char *initval, char **val_out); Index: tags/1.0.5/src/plugins/sch_dialogs/dlg_text.c =================================================================== --- tags/1.0.5/src/plugins/sch_dialogs/dlg_text.c (nonexistent) +++ tags/1.0.5/src/plugins/sch_dialogs/dlg_text.c (revision 10414) @@ -0,0 +1,465 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - GUI - text edit dialog + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/* text object dialogs */ + +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +/* This doesn't make a plugin dep as only inlines and macros and structs are used */ +#include +#define RND_TIMED_CHG_TIMEOUT conf_core.editor.edit_time +#include + +typedef struct { + RND_DAD_DECL_NOINIT(dlg) + csch_sheet_t *sheet; + csch_text_t *text; + int wattr1, wsubst1, wtext; + int start, len; /* character offset of start and length of the first %% substitution */ + int got_val; /* if direct attribute value editing is available */ + int gui_active; + + struct { + rnd_timed_chg_t hdr; + gds_t str; + } timed; + + gds_t tmp; +} dyntext_dlg_ctx_t; + +/* Returns a pointer to the first template %% block, overwrite the next % with \0 + if out_start and out_len are not NULL, fill them in with index values within + the original templ string */ +static char *dyntext_temp_get_first_attr(char *templ, int *out_start, int *out_len) +{ + char *first, *last; + + first = strchr(templ, '%'); + if (first != NULL) { + first++; + last = strchr(first, '%'); + if ((last != NULL) && (last > first+1)) { + *last = '\0'; + if (out_start != NULL) + *out_start = first - templ; + if (out_len != NULL) + *out_len = last - first; + } + else + first = ""; + } + else + first = ""; + + return first; +} + +static void dyntext_attr_edit(rnd_design_t *hidlib, csch_text_t *text, const char *key) +{ + fgw_arg_t res, args[3]; + csch_oidpath_t idp = {0}; + gds_t op = {0}; + + /* prepare first arg */ + csch_oidpath_from_obj(&idp, &text->hdr.parent->hdr); + gds_append_str(&op, "object:"); + csch_oidpath_to_str_append(&op, &idp); + csch_oidpath_free(&idp); + + /* call action, save resulting attr key */ + args[1].type = FGW_STR; + args[1].val.cstr = op.array; + args[2].type = FGW_STR; + args[2].val.cstr = key; + rnd_actionv_bin(hidlib, "attributedialog", &res, 3, args); + + gds_uninit(&op); +} + + +static void dyntext_dlg_text2dlg(dyntext_dlg_ctx_t *ctx) +{ + char *first = ""; + + ctx->got_val = 0; + ctx->start = ctx->len = -1; + ctx->tmp.used = 0; + gds_append_str(&ctx->tmp, ctx->text->text); + + if (ctx->tmp.used > 2) + first = dyntext_temp_get_first_attr(ctx->tmp.array, &ctx->start, &ctx->len); + + if (strncmp(first, "../A.", 5) == 0) { + csch_attrib_t *a = csch_attrib_get(&ctx->text->hdr.parent->attr, first+5); + if ((a != NULL) && (a->val != NULL)) { + RND_DAD_SET_VALUE(ctx->dlg_hid_ctx, ctx->wattr1, str, a->val); + rnd_gui->attr_dlg_widget_state(ctx->dlg_hid_ctx, ctx->wattr1, 1); + ctx->got_val = 1; + } + } + + if (!ctx->got_val) { + RND_DAD_SET_VALUE(ctx->dlg_hid_ctx, ctx->wattr1, str, ""); + rnd_gui->attr_dlg_widget_state(ctx->dlg_hid_ctx, ctx->wattr1, 0); + } + + + RND_DAD_SET_VALUE(ctx->dlg_hid_ctx, ctx->wsubst1, str, first); + RND_DAD_SET_VALUE(ctx->dlg_hid_ctx, ctx->wtext, str, ctx->text->text); +} + +static void set_text_timed(void *ctx_) +{ + dyntext_dlg_ctx_t *ctx = ctx_; + + sch_rnd_op_text_edit(ctx->sheet, ctx->text, ctx->timed.str.array); + rnd_gui->invalidate_all(rnd_gui); + if (ctx->gui_active) + dyntext_dlg_text2dlg(ctx); + ctx->timed.str.used = 0; +} + +RND_INLINE void dyntext_build_timed_subst(dyntext_dlg_ctx_t *ctx, const char *str1, const char *str2) +{ + ctx->timed.str.used = 0; + gds_append_len(&ctx->timed.str, ctx->text->text, ctx->start); + if (str1 != NULL) + gds_append_str(&ctx->timed.str, str1); + if (str2 != NULL) + gds_append_str(&ctx->timed.str, str2); + gds_append_str(&ctx->timed.str, ctx->text->text + ctx->start + ctx->len); +} + +static void dyntext_subst1_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + dyntext_dlg_ctx_t *ctx = caller_data; + + if (ctx->start < 0) + return; + + dyntext_build_timed_subst(ctx, ctx->dlg[ctx->wsubst1].val.str, NULL); + rnd_timed_chg_schedule(&ctx->timed.hdr); +} + +static void dyntext_raw_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + dyntext_dlg_ctx_t *ctx = caller_data; + + ctx->timed.str.used = 0; + gds_append_str(&ctx->timed.str, ctx->dlg[ctx->wtext].val.str); + rnd_timed_chg_schedule(&ctx->timed.hdr); +} + +static void dyntext_pick_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + dyntext_dlg_ctx_t *ctx = caller_data; + fgw_arg_t res, args[2]; + csch_oidpath_t idp = {0}; + gds_t op = {0}; + const char *key = NULL; + + /* prepare first arg */ + csch_oidpath_from_obj(&idp, &ctx->text->hdr.parent->hdr); + gds_append_str(&op, "object:"); + csch_oidpath_to_str_append(&op, &idp); + csch_oidpath_free(&idp); + + /* call action, save resulting attr key */ + args[1].type = FGW_STR; + args[1].val.cstr = op.array; + if (rnd_actionv_bin(&ctx->sheet->hidlib, "attributepick", &res, 2, args) == 0) + key = res.val.cstr; + + /* clean up action call */ + fgw_arg_free(&rnd_fgw, &res); + gds_uninit(&op); + + if ((key == NULL) || (*key == '\0')) + return; /* cancel */ + + /* build and update */ + dyntext_build_timed_subst(ctx, "../A.", key); + sch_rnd_op_text_edit(ctx->sheet, ctx->text, ctx->timed.str.array); + rnd_gui->invalidate_all(rnd_gui); + dyntext_dlg_text2dlg(ctx); + ctx->timed.str.used = 0; +} + + +static void dyntext_attr1_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + csch_source_arg_t *src; + dyntext_dlg_ctx_t *ctx = caller_data; + const char *key = ctx->tmp.array + ctx->start + 5; + const char *val = ctx->dlg[ctx->wattr1].val.str; + + src = csch_attrib_src_c(NULL, 0, 0, "dlg_text user input"); + csch_attr_modify_str(ctx->sheet, ctx->text->hdr.parent, CSCH_ATP_USER_DEFAULT, key, val, src, 1); + ctx->text->bbox_calced = 0; + csch_text_update(ctx->sheet, ctx->text, 1); + csch_sheet_set_changed(ctx->sheet, 1); /* get drawing area recalculated */ + rnd_gui->invalidate_all(rnd_gui); + dyntext_dlg_text2dlg(ctx); + ctx->timed.str.used = 0; +} + +static void dyntext_attredit_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + dyntext_dlg_ctx_t *ctx = caller_data; + + if (ctx->got_val) { /* we have a concrete model attribute to edit directly */ + static rnd_dad_retovr_t retovr; + dyntext_attr_edit(&ctx->sheet->hidlib, ctx->text, ctx->tmp.array + ctx->start + 5); + rnd_hid_dad_close(ctx->dlg_hid_ctx, &retovr, 0); + return; + } + if (ctx->len > 5) { /* may be an abstract attr */ + const char *first = ctx->tmp.array + ctx->start; + if (strncmp(first, "../a.", 5) == 0) { + TODO("invoke AbstractDialog with the given component and attribute"); + rnd_message(RND_MSG_ERROR, "Attribute of the abstract model is referenced\nThe abstract model can not be edited directly, you'll need to find\nwhich concrete model attribute is compiled into abstract attribute\n%s and edit that.\n", first); + return; + } + } + + rnd_message(RND_MSG_ERROR, "No accessible attribute referenced in text template\nso I don't know what attribute to edit.\n"); +} + + +static int sch_rnd_edit_text_dialog_dynamic(csch_sheet_t *sheet, csch_text_t *text) +{ + static const char help_subst1[] = "Quick edit for the first %% substitution"; + static const char help_raw[] = "Edit text string as-is; presents the template without any transformation"; + static const char spaces[] = " "; + rnd_hid_dad_buttons_t clbtn[] = {{"Close", 0}, {NULL, 0}}; + dyntext_dlg_ctx_t ctx = {0}; + + ctx.sheet = sheet; + ctx.text = text; + + rnd_timed_chg_init(&ctx.timed.hdr, set_text_timed, &ctx); + + RND_DAD_BEGIN_VBOX(ctx.dlg); + RND_DAD_COMPFLAG(ctx.dlg, RND_HATF_EXPFILL); + + RND_DAD_BEGIN_HBOX(ctx.dlg); + RND_DAD_BEGIN_VBOX(ctx.dlg); + RND_DAD_LABEL(ctx.dlg, spaces); + RND_DAD_LABEL(ctx.dlg, "First subst val:"); + RND_DAD_LABEL(ctx.dlg, spaces); + RND_DAD_END(ctx.dlg); + + RND_DAD_STRING(ctx.dlg); + RND_DAD_HELP(ctx.dlg, help_subst1); + ctx.wattr1 = RND_DAD_CURRENT(ctx.dlg); + RND_DAD_CHANGE_CB(ctx.dlg, dyntext_attr1_cb); + + RND_DAD_BEGIN_VBOX(ctx.dlg); + RND_DAD_LABEL(ctx.dlg, ""); + RND_DAD_BUTTON(ctx.dlg, "Attr. edit"); + RND_DAD_HELP(ctx.dlg, "Invoke the attribute editor"); + RND_DAD_CHANGE_CB(ctx.dlg, dyntext_attredit_cb); + RND_DAD_LABEL(ctx.dlg, ""); + RND_DAD_END(ctx.dlg); + + RND_DAD_END(ctx.dlg); + + + RND_DAD_BEGIN_HBOX(ctx.dlg); + RND_DAD_BEGIN_VBOX(ctx.dlg); + RND_DAD_LABEL(ctx.dlg, spaces); + RND_DAD_LABEL(ctx.dlg, "First subst key:"); + RND_DAD_HELP(ctx.dlg, help_subst1); + RND_DAD_LABEL(ctx.dlg, spaces); + RND_DAD_END(ctx.dlg); + + RND_DAD_STRING(ctx.dlg); + RND_DAD_HELP(ctx.dlg, help_subst1); + ctx.wsubst1 = RND_DAD_CURRENT(ctx.dlg); + RND_DAD_CHANGE_CB(ctx.dlg, dyntext_subst1_cb); + + RND_DAD_BEGIN_VBOX(ctx.dlg); + RND_DAD_LABEL(ctx.dlg, ""); + RND_DAD_BUTTON(ctx.dlg, "Pick..."); + RND_DAD_HELP(ctx.dlg, "Pick an existing attribute from the parent group"); + RND_DAD_CHANGE_CB(ctx.dlg, dyntext_pick_cb); + RND_DAD_LABEL(ctx.dlg, ""); + RND_DAD_END(ctx.dlg); + + RND_DAD_END(ctx.dlg); + + RND_DAD_BEGIN_HBOX(ctx.dlg); + RND_DAD_BEGIN_VBOX(ctx.dlg); + RND_DAD_LABEL(ctx.dlg, spaces); + RND_DAD_LABEL(ctx.dlg, "Raw (template):"); + RND_DAD_HELP(ctx.dlg, help_raw); + RND_DAD_LABEL(ctx.dlg, spaces); + RND_DAD_END(ctx.dlg); + RND_DAD_STRING(ctx.dlg); + RND_DAD_WIDTH_CHR(ctx.dlg, 32); + RND_DAD_HELP(ctx.dlg, help_raw); + ctx.wtext = RND_DAD_CURRENT(ctx.dlg); + RND_DAD_CHANGE_CB(ctx.dlg, dyntext_raw_cb); + RND_DAD_END(ctx.dlg); + + RND_DAD_TIMING(ctx.dlg, &ctx.timed.hdr, "text"); + + RND_DAD_BUTTON_CLOSES(ctx.dlg, clbtn); + RND_DAD_END(ctx.dlg); + + RND_DAD_NEW("DyntextDialog", ctx.dlg, "Dynamic text edit", &ctx, 1, NULL); /* type=local/modal */ + + rnd_timed_chg_timing_init(&ctx.timed.hdr, ctx.dlg_hid_ctx); + dyntext_dlg_text2dlg(&ctx); + + if (ctx.got_val) + RND_DAD_STRING_SELECT_REGION(ctx.dlg_hid_ctx, ctx.wattr1, 0, 1<<30); + + ctx.gui_active = 1; + RND_DAD_RUN(ctx.dlg); + ctx.gui_active = 0; + ctx.timed.hdr.wtiming = -1; + + rnd_timed_chg_finalize(&ctx.timed.hdr); + + RND_DAD_FREE(ctx.dlg); + + gds_uninit(&ctx.tmp); + gds_uninit(&ctx.timed.str); + return 0; +} + + +static int sch_rnd_edit_text_dialog_static(csch_sheet_t *sheet, csch_text_t *text) +{ + char *new_str = rnd_hid_prompt_for(&sheet->hidlib, "Edit text object:", text->text, "Edit text object"); + + if (new_str != NULL) { + sch_rnd_op_text_edit(sheet, text, new_str); + rnd_gui->invalidate_all(rnd_gui); + free(new_str); + return 0; + } + return -1; +} + + +int sch_rnd_edit_text_dialog(csch_sheet_t *sheet, csch_text_t *text) +{ + return text->dyntext ? sch_rnd_edit_text_dialog_dynamic(sheet, text) : sch_rnd_edit_text_dialog_static(sheet, text); +} + +const char csch_acts_EditText[] = "EditText([object[=idpath]])"; +const char csch_acth_EditText[] = "Bring up a text quick edit dialog.\n"; +fgw_error_t csch_act_EditText(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_design_t *hidlib = RND_ACT_DESIGN; + csch_sheet_t *sheet = (csch_sheet_t *)hidlib; + csch_chdr_t *obj; + int cmd; + + CSCH_ACT_CONVARG_OBJ(1, EditText, cmd, obj); + + RND_ACT_IRES(-1); + + switch(cmd) { + case F_Object: + { + csch_cgrp_t *grp_ref; + csch_text_t *text; + csch_coord_t x, y; + int r, attr_only; + + if (obj == NULL) { + if (sch_rnd_get_coords("Click on text to edit", &x, &y, 0) != 0) + break; + obj = sch_rnd_search_obj_at(sheet, x, y, sch_rnd_slop); + if (obj == NULL) { + rnd_message(RND_MSG_ERROR, "EditText(): no text object under cursor\n"); + break; + } + } + if (obj->type != CSCH_CTYPE_TEXT) { + rnd_message(RND_MSG_ERROR, "EditText(): not a text object\n"); + break; + } + + grp_ref = csch_grp_ref_get_top(obj->sheet, obj); + attr_only = (grp_ref != NULL); + text = (csch_text_t *)obj; + if (attr_only && text->dyntext && (obj->parent == grp_ref)) { + char *tmp, *key; + int edited = 0; + + /* special case: text edit on a direct attribute printout of a group ref */ + tmp = rnd_strdup(text->text); + key = dyntext_temp_get_first_attr(tmp, NULL, NULL); + if (*key != '\0') { + if (strncmp(key, "../A.", 5) == 0) { + dyntext_attr_edit(hidlib, text, key+5); + edited = 1; + } + } + free(tmp); + if (edited) + break; /* no error */ + } + if (attr_only) { + rnd_message(RND_MSG_ERROR, "Can not change text of a group_ref child\nbecause it would change the referenced group's children (probably in local lib)\n"); + break; + } + r = sch_rnd_edit_text_dialog(sheet, text); + RND_ACT_IRES(r); + } + break; + default: + rnd_message(RND_MSG_ERROR, "EditText(): invalid first argument\n"); + } + + return 0; +} + Index: tags/1.0.5/src/plugins/sch_dialogs/dlg_text.h =================================================================== --- tags/1.0.5/src/plugins/sch_dialogs/dlg_text.h (nonexistent) +++ tags/1.0.5/src/plugins/sch_dialogs/dlg_text.h (revision 10414) @@ -0,0 +1,10 @@ +#include +#include + +extern const char csch_acts_EditText[]; +extern const char csch_acth_EditText[]; +fgw_error_t csch_act_EditText(fgw_arg_t *res, int argc, fgw_arg_t *argv); + +/* Prompt for editing text object and make an undoable modify. Returns 0 + on success, non-zero on error/cancel */ +int sch_rnd_edit_text_dialog(csch_sheet_t *sheet, csch_text_t *text); Index: tags/1.0.5/src/plugins/sch_dialogs/dlg_tree.c =================================================================== --- tags/1.0.5/src/plugins/sch_dialogs/dlg_tree.c (nonexistent) +++ tags/1.0.5/src/plugins/sch_dialogs/dlg_tree.c (revision 10414) @@ -0,0 +1,790 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - GUI - tree view dialog + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/* object tree dialog */ + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +typedef enum { + OBJ_ST_NONE = 0, /* do not include in the list */ + OBJ_ST_DIRECT, /* directly member of the list */ + OBJ_ST_INDIRECT /* not really a member, included only because it's a parent group of a member */ +} tree_dlg_obj_state_t; + +typedef struct tree_dlg_ctx_s { + RND_DAD_DECL_NOINIT(dlg) + csch_project_t *prj; + htpi_t only; /* key: (csch_chdr_t *); val: tree_dlg_obj_state_t */ + unsigned only_vis:1; /* if 1, only include objects that are in ->only */ + + int wtree, wupdate, wprev, wdetails, wattredit; + + rnd_box_t prvbb; + + rnd_hidval_t timer; + int timer_active; + + csch_chdr_t *preview_obj; /* last object drawn on preview */ + gds_t path; /* temp storage for building paths on update (alloc cache) */ +} tree_dlg_ctx_t; + +#define CSCH_TREE_CHG_TIMEOUT_NORMAL 3000 +#define CSCH_TREE_CHG_TIMEOUT_QUICK 300 + +static htpp_t prj2dlg; +static vtl0_t hisave; + +static void tree_dlg_close_cb(void *caller_data, rnd_hid_attr_ev_t ev) +{ + tree_dlg_ctx_t *ctx = caller_data; + + if (ctx->timer_active) + rnd_gui->stop_timer(rnd_gui, ctx->timer); + gds_uninit(&ctx->path); + if (ctx->only_vis) + htpi_uninit(&ctx->only); + htpp_pop(&prj2dlg, ctx->prj); + free(ctx); +} + +static const char *get_subtype(csch_chdr_t *obj) +{ + csch_cgrp_t *grp = (csch_cgrp_t *)obj; + + if (obj == &obj->sheet->direct.hdr) + return "Sheet"; + + if (csch_obj_is_grp(obj)) { + if ((grp->srole == NULL) || (*grp->srole == '\0')) { + const char *purp = csch_attrib_get_str(&grp->attr, "purpose"); + if (purp != NULL) + return purp; + } + return grp->srole; + } + + if (obj->parent->role == CSCH_ROLE_WIRE_NET) { + if (csch_obj_is_junction(obj)) + return "junction"; + return "wire"; + } + + return ""; +} + +static const char *get_name(csch_chdr_t *obj) +{ + csch_cgrp_t *grp; + + if (obj == &obj->sheet->direct.hdr) + return obj->sheet->hidlib.loadname; + + if (!csch_obj_is_grp(obj)) + return ""; + + grp = (csch_cgrp_t *)obj; + return csch_attrib_get_str(&grp->attr, "name"); +} + +RND_INLINE int strcmp_safe(const char *s1, const char *s2) +{ + if ((s1 == NULL) && (s2 == NULL)) return 0; + if ((s1 == NULL) || (s2 == NULL)) return 1; + return strcmp(s1, s2); +} + +static void tree_update_(tree_dlg_ctx_t *ctx, rnd_hid_attribute_t *attr, rnd_hid_row_t *parent, csch_chdr_t *obj) +{ + rnd_hid_row_t *row; + rnd_hid_tree_t *tree = attr->wdata; + int save, len, idi, changed = 0, state = 1; + char *cols[5]; + const char *subtype, *name; + + if (obj->oid < 0) + return; + + if (ctx->only_vis) { + state = htpi_get(&ctx->only, obj); + if (state == OBJ_ST_NONE) + return; + } + + /* create path */ + if (ctx->path.alloced < ctx->path.used + 64) { + long save = ctx->path.used; + gds_enlarge(&ctx->path, ctx->path.used + 128); + ctx->path.used = save; + } + + save = ctx->path.used; + if (ctx->path.used != 0) + gds_append(&ctx->path, '/'); + + idi = ctx->path.used; + if (obj == &obj->sheet->direct.hdr) + len = sprintf(ctx->path.array + ctx->path.used, "{%ld} %ld", (long)obj->sheet->uid, (long)obj->oid); + else + len = sprintf(ctx->path.array + ctx->path.used, "%ld", (long)obj->oid); + ctx->path.used += len; + + row = htsp_get(&tree->paths, ctx->path.array); + changed = (row != NULL) && (row->user_data != obj); + + subtype = get_subtype(obj); + name = get_name(obj); + + /* detect content change */ + if ((row != NULL) && (!changed)) + changed = (strcmp_safe(subtype, row->cell[2]) != 0) || (strcmp_safe(name, row->cell[3]) != 0); + + if ((row == NULL) || changed) { + cols[0] = rnd_strdup(ctx->path.array + idi); + if (state == OBJ_ST_INDIRECT) + cols[1] = rnd_strdup_printf("(%s)", csch_ctype_name(obj->type)); + else + cols[1] = rnd_strdup(csch_ctype_name(obj->type)); + cols[2] = rnd_strdup(subtype == NULL ? "" : subtype); + cols[3] = rnd_strdup(name == NULL ? "" : name); + cols[4] = NULL; + } + + if (row == NULL) { + row = rnd_dad_tree_append_under(attr, parent, cols); + } + else if (changed) { + rnd_dad_tree_modify_cell(attr, row, 1, cols[1]); + rnd_dad_tree_modify_cell(attr, row, 2, cols[2]); + rnd_dad_tree_modify_cell(attr, row, 3, cols[3]); + free(cols[0]); + } + row->user_data = obj; + row->user_data2.lng++; + + /* recurse groups */ + if (csch_obj_is_grp(obj)) { + csch_cgrp_t *g = (csch_cgrp_t *)obj; + htip_entry_t *e; + + for(e = htip_first(&g->id2obj); e != NULL; e = htip_next(&g->id2obj, e)) + tree_update_(ctx, attr, row, e->value); + } + + ctx->path.used = save; +} + +static void tree_update_details(tree_dlg_ctx_t *ctx, rnd_hid_row_t *row) +{ + gds_t tmp = {0}; + char *text = NULL; + rnd_hid_attr_val_t hv; + int can_attr_edit = 0; + + if ((row != NULL) && (row->user_data != NULL)) { + csch_chdr_t *obj = row->user_data; + + if (csch_obj_is_grp(obj)) { + csch_cgrp_t *grp = (csch_cgrp_t *)obj; + const char *purp = csch_attrib_get_str(&grp->attr, "purpose"); + const char *name = csch_attrib_get_str(&grp->attr, "name"); + + can_attr_edit = 1; + + gds_append_str(&tmp, "Group object:\n\nrole="); + if (grp->srole != NULL) + gds_append_str(&tmp, grp->srole); + + gds_append_str(&tmp, "\npurpose="); + if (purp != NULL) + gds_append_str(&tmp, purp); + + gds_append_str(&tmp, "\nname="); + if (name != NULL) + gds_append_str(&tmp, name); + + rnd_append_printf(&tmp, "\nxform: r=%.2f mx=%d my=%d", grp->xform.rot, grp->xform.mirx, grp->xform.miry); + + + gds_append(&tmp, '\n'); + text = tmp.array; + } + if (obj->type == CSCH_CTYPE_CONN) { + long n; + csch_conn_t *conn = (csch_conn_t *)obj; + csch_oidpath_t oidp = {0}; + + gds_append_str(&tmp, "Connection object; connects:\n"); + for(n = 0; n < conn->conn.used; n++) { + csch_oidpath_from_obj(&oidp, conn->conn.array[n]); + gds_append(&tmp, ' '); + csch_oidpath_to_str_append(&tmp, &oidp); + gds_append(&tmp, '\n'); + csch_oidpath_free(&oidp); + } + + gds_append(&tmp, '\n'); + text = tmp.array; + } + else + text = "Atomic drawing object."; + } + else + text = "(no object picked)"; + + + hv.str = text; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wdetails, &hv); + + gds_uninit(&tmp); + + rnd_gui->attr_dlg_widget_state(ctx->dlg_hid_ctx, ctx->wattredit, can_attr_edit); +} + +static void tree_update_prj(tree_dlg_ctx_t *ctx, rnd_hid_attribute_t *attr) +{ + long n; + for(n = 0; n < ctx->prj->hdr.designs.used; n++) { + csch_sheet_t *sheet = ctx->prj->hdr.designs.array[n]; + if (sheet != NULL) + tree_update_(ctx, attr, NULL, &sheet->direct.hdr); + } +} + + +static void tree_update(tree_dlg_ctx_t *ctx) +{ + rnd_hid_attribute_t *attr = &ctx->dlg[ctx->wtree]; + rnd_hid_tree_t *tree = attr->wdata; + htsp_entry_t *e; + + /* clear user data on all existing rows */ + for(e = htsp_first(&tree->paths); e != NULL; e = htsp_next(&tree->paths, e)) { + rnd_hid_row_t *row = e->value; + row->user_data2.lng = 0; + } + + ctx->path.used = 0; + tree_update_prj(ctx, attr); + + /* remove any row not identified in update_() */ + for(e = htsp_first(&tree->paths); e != NULL; e = htsp_next(&tree->paths, e)) { + rnd_hid_row_t *row = e->value; + if (row->user_data2.lng == 0) + rnd_dad_tree_remove(attr, row); + } + tree_update_details(ctx, rnd_dad_tree_get_selected(attr)); +} + +static csch_chdr_t *get_dlg_obj(tree_dlg_ctx_t *ctx, int silent) +{ + csch_chdr_t *obj; + rnd_hid_attribute_t *attr = &ctx->dlg[ctx->wtree]; + rnd_hid_row_t *r = rnd_dad_tree_get_selected(attr); + if (r == NULL) + return NULL; + + obj = r->user_data; + if (csch_obj_is_deleted(obj)) { + if (!silent) + rnd_message(RND_MSG_ERROR, "Object is inactive (deleted)\n"); + return NULL; + } + + return obj; +} + +static void tree_preview_bbox(tree_dlg_ctx_t *ctx, csch_chdr_t *obj) +{ + long dx, dy; + + if (obj != NULL) { + if (obj->type == CSCH_CTYPE_CONN) { + long n; + csch_conn_t *conn = (csch_conn_t *)obj; + ctx->prvbb.X1 = ctx->prvbb.Y1 = CSCH_COORD_MAX; + ctx->prvbb.X2 = ctx->prvbb.Y2 = -CSCH_COORD_MAX; + for(n = 0; n < conn->coords.used; n+=2) + rnd_box_bump_point(&ctx->prvbb, conn->coords.array[n], conn->coords.array[n+1]); + dx = dy = 8000; + } + else { + ctx->prvbb.X1 = obj->bbox.x1; ctx->prvbb.Y1 = obj->bbox.y1; + ctx->prvbb.X2 = obj->bbox.x2; ctx->prvbb.Y2 = obj->bbox.y2; + /* 12.5% margin */ + dx = (ctx->prvbb.X2 - ctx->prvbb.X1) / 8; + dy = (ctx->prvbb.Y2 - ctx->prvbb.Y1) / 8; + } + + /* add a dx;dy margin around the box, zooming out a bit, for context */ + ctx->prvbb.X1 = C2P(ctx->prvbb.X1 - dx); + ctx->prvbb.Y1 = C2P(ctx->prvbb.Y1 - dy); + ctx->prvbb.X2 = C2P(ctx->prvbb.X2 + dx); + ctx->prvbb.Y2 = C2P(ctx->prvbb.Y2 + dy); + } + else { + dx = dy = 0; + ctx->prvbb.X1 = ctx->prvbb.Y1 = ctx->prvbb.X2 = ctx->prvbb.Y2 = 0; + } + +} + +static void tree_update_preview(tree_dlg_ctx_t *ctx) +{ + csch_chdr_t *obj = get_dlg_obj(ctx, 1); + + if ((obj != NULL) && (obj != ctx->preview_obj)) { + tree_preview_bbox(ctx, obj); + rnd_dad_preview_zoomto(&ctx->dlg[ctx->wprev], &ctx->prvbb); + } + else + rnd_dad_preview_zoomto(&ctx->dlg[ctx->wprev], NULL); /* redraw only */ + + ctx->preview_obj = obj; +} + +static void tree_select_node_cb(rnd_hid_attribute_t *attrib, void *hid_ctx, rnd_hid_row_t *row) +{ + rnd_hid_tree_t *tree = attrib->wdata; + tree_dlg_ctx_t *ctx = tree->user_ctx; + + tree_update_preview(ctx); + tree_update_details(ctx, row); +} + +static void tree_select_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + tree_dlg_ctx_t *ctx = caller_data; + csch_chdr_t *obj = get_dlg_obj(ctx, 0); + + if ((obj != NULL) && !obj->selected) { + csch_cobj_select(obj->sheet, obj); + tree_update_preview(ctx); + } +} + +static void tree_unselect_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + tree_dlg_ctx_t *ctx = caller_data; + csch_chdr_t *obj = get_dlg_obj(ctx, 0); + + if ((obj != NULL) && obj->selected) { + csch_cobj_unselect(obj->sheet, obj); + tree_update_preview(ctx); + } +} + +static void tree_del_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + tree_dlg_ctx_t *ctx = caller_data; + csch_chdr_t *obj = get_dlg_obj(ctx, 0); + + if (obj != NULL) { + csch_op_remove(obj->sheet, obj); + tree_update_preview(ctx); + } +} + + +static void tree_anyedit_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr, const char *actname) +{ + tree_dlg_ctx_t *ctx = caller_data; + csch_chdr_t *obj = get_dlg_obj(ctx, 0); + + if (obj != NULL) { + rnd_design_t *hl = &obj->sheet->hidlib; + char *arg, *oidp; + + oidp = csch_chdr_to_oidpath_str(obj); + arg = rnd_concat("object:", oidp, NULL); + free(oidp); + + rnd_actionva(hl, actname, arg, NULL); + + free(arg); + } +} + +static void tree_propedit_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + tree_anyedit_cb(hid_ctx, caller_data, attr, "Propedit"); +} + +static void tree_attredit_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + tree_anyedit_cb(hid_ctx, caller_data, attr, "AttributeDialog"); +} + +static void tree_prv_expose_cb(rnd_hid_attribute_t *attrib, rnd_hid_preview_t *prv, rnd_hid_gc_t gc, rnd_hid_expose_ctx_t *e) +{ + tree_dlg_ctx_t *ctx = prv->user_ctx; + rnd_xform_t xform = {0}; + csch_chdr_t *obj = get_dlg_obj(ctx, 1); + int save, n; + + /* draw the sheet */ + if (obj != NULL) { + xform.faded = 1; + save = obj->hilight; + obj->hilight = 1; + + hisave.used = 0; + if (obj->type == CSCH_CTYPE_CONN) { + csch_conn_t *conn = (csch_conn_t *)obj; + for(n = 0; n < conn->conn.used; n++) { + csch_chdr_t *co = conn->conn.array[n]; + vtl0_append(&hisave, co->hilight); + co->hilight = 1; + } + } + } + + if (obj != NULL) + e->design = &obj->sheet->hidlib; + else + e->design = rnd_gui->get_dad_design(ctx->dlg_hid_ctx); + + rnd_app.expose_main(rnd_gui, e, &xform); + + if (obj != NULL) { + obj->hilight = save; + if (obj->type == CSCH_CTYPE_CONN) { + csch_conn_t *conn = (csch_conn_t *)obj; + for(n = 0; n < conn->conn.used; n++) { + csch_chdr_t *co = conn->conn.array[n]; + co->hilight = hisave.array[n]; + } + } + } +} + + +static rnd_bool tree_prv_mouse_cb(rnd_hid_attribute_t *attrib, rnd_hid_preview_t *prv, rnd_hid_mouse_ev_t kind, rnd_coord_t x, rnd_coord_t y) +{ + return rnd_false; /* don't redraw */ +} + +static void tree_set_cursor(tree_dlg_ctx_t *ctx, const char *oidpath) +{ + rnd_hid_attribute_t *attr = &ctx->dlg[ctx->wtree]; + rnd_hid_tree_t *tree = attr->wdata; + rnd_hid_row_t *row; + + if (*oidpath == '/') oidpath++; + + TODO("multi: oidpath will need to start with a sheet uid that can be searched in the current project (linear search is good enough)"); + row = htsp_get(&tree->paths, oidpath); + + rnd_trace("tree set cursor to '%s' %p\n", oidpath, row); + if (row != NULL) { + rnd_hid_attr_val_t hv; + hv.str = oidpath; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wtree, &hv); + tree_update_details(ctx, row); + } + else + rnd_message(RND_MSG_ERROR, "tree view: oid path not found: '%s'\n", oidpath); +} + +static void tree_dlg_set_objarr(tree_dlg_ctx_t *ctx, vtp0_t *objarr) +{ + long n; + + if (!ctx->only_vis) { + htpi_init(&ctx->only, ptrhash, ptrkeyeq); + ctx->only_vis = 1; + } + else + htpi_clear(&ctx->only); + + for(n = 0; n < objarr->used; n++) { + csch_chdr_t *o = objarr->array[n]; + + htpi_set(&ctx->only, o, OBJ_ST_DIRECT); + + /* add all parents too so that group recursion works on update() */ + for(o = &o->parent->hdr; o != NULL; o = &o->parent->hdr) { + if (!htpi_has(&ctx->only, o)) + htpi_set(&ctx->only, o, OBJ_ST_INDIRECT); + } + } +} + +static void sch_rnd_tree_dlg(csch_project_t *prj, csch_sheet_t *oidpath_sheet, const char *oidpath, vtp0_t *objarr) +{ + tree_dlg_ctx_t *ctx; + rnd_hid_dad_buttons_t clbtn[] = {{"Close", 0}, {NULL, 0}}; + const char *hdr[] = {"oid path", "type", "subtype", "name", NULL}; + char *freeme = NULL; + + ctx = htpp_get(&prj2dlg, prj); + if (ctx != NULL) { + if (objarr != NULL) { + tree_dlg_set_objarr(ctx, objarr); + tree_update(ctx); + } + if (oidpath != NULL) + tree_set_cursor(ctx, oidpath); + TODO("raise?"); + return; + } + + if ((oidpath != NULL) && (oidpath[0] != '{')) { + char tmp[64]; + + sprintf(tmp, "{%ld} ", oidpath_sheet->uid); + if (*oidpath == '/') + oidpath++; + oidpath = freeme = rnd_concat(tmp, oidpath, NULL); + } + + ctx = calloc(sizeof(tree_dlg_ctx_t), 1); + ctx->prj = prj; + + /* create hash of only visible objects, if requested */ + if (objarr != NULL) + tree_dlg_set_objarr(ctx, objarr); + + tree_preview_bbox(ctx, NULL); + + htpp_set(&prj2dlg, prj, ctx); + + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_BEGIN_HPANE(ctx->dlg, "left-right"); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + + RND_DAD_BEGIN_VBOX(ctx->dlg); /* left */ + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_TREE(ctx->dlg, 4, 1, hdr); /* top left: tree */ + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL | RND_HATF_SCROLL | RND_HATF_TREE_NO_AUTOEXP); + RND_DAD_TREE_SET_CB(ctx->dlg, selected_cb, tree_select_node_cb); + RND_DAD_TREE_SET_CB(ctx->dlg, ctx, ctx); + ctx->wtree = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_BEGIN_HBOX(ctx->dlg); /* bottom left: buttons */ + RND_DAD_BUTTON(ctx->dlg, "select"); + RND_DAD_CHANGE_CB(ctx->dlg, tree_select_cb); + RND_DAD_BUTTON(ctx->dlg, "unselect"); + RND_DAD_CHANGE_CB(ctx->dlg, tree_unselect_cb); + RND_DAD_BUTTON(ctx->dlg, "propedit"); + RND_DAD_CHANGE_CB(ctx->dlg, tree_propedit_cb); + RND_DAD_BUTTON(ctx->dlg, "attr. edit"); + RND_DAD_CHANGE_CB(ctx->dlg, tree_attredit_cb); + ctx->wattredit = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "del"); + RND_DAD_CHANGE_CB(ctx->dlg, tree_del_cb); + RND_DAD_END(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Pending update..."); + ctx->wupdate = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_END(ctx->dlg); + + RND_DAD_BEGIN_VPANE(ctx->dlg, "right_top/bottom"); /* right */ + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + + RND_DAD_PREVIEW(ctx->dlg, tree_prv_expose_cb, tree_prv_mouse_cb, NULL, NULL, &ctx->prvbb, 150, 150, ctx); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_PRV_GFLIP); + ctx->wprev = RND_DAD_CURRENT(ctx->dlg); + + RND_DAD_BEGIN_VBOX(ctx->dlg); /* right bottom text/close */ + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_LABEL(ctx->dlg, "(no object picked)"); + ctx->wdetails = RND_DAD_CURRENT(ctx->dlg); + + RND_DAD_BEGIN_VBOX(ctx->dlg); /* spring */ + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_END(ctx->dlg); + RND_DAD_BUTTON_CLOSES(ctx->dlg, clbtn); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + + RND_DAD_END(ctx->dlg); + + RND_DAD_DEFSIZE(ctx->dlg, 300, 400); + RND_DAD_NEW("TreeDialog", ctx->dlg, "Tree edit", ctx, 0, tree_dlg_close_cb); /* type=local/project */ + + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wupdate, 1); + rnd_gui->attr_dlg_widget_state(ctx->dlg_hid_ctx, ctx->wattredit, 0); + tree_update(ctx); + if (oidpath != NULL) { + tree_set_cursor(ctx, oidpath); + tree_update_preview(ctx); /* set cursor from code will not call back, need to manually make side effects */ + } + free(freeme); +} + +static void tree_timer_cb(rnd_hidval_t user_data) +{ + tree_dlg_ctx_t *ctx = user_data.ptr; + ctx->timer_active = 0; + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wupdate, 1); + tree_update(ctx); +} + +static void csch_dlg_tree_regen_(csch_sheet_t *sheet, int timeout) +{ + rnd_hidval_t user_data; + tree_dlg_ctx_t *ctx = htpp_get(&prj2dlg, (csch_project_t *)sheet->hidlib.project); + + if (ctx == NULL) return; + + if (ctx->timer_active) + rnd_gui->stop_timer(rnd_gui, ctx->timer); + + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wupdate, 0); + + user_data.ptr = ctx; + ctx->timer_active = 1; + ctx->timer = rnd_gui->add_timer(rnd_gui, tree_timer_cb, timeout, user_data); +} + +void csch_dlg_tree_edit(csch_sheet_t *sheet) +{ + csch_dlg_tree_regen_(sheet, CSCH_TREE_CHG_TIMEOUT_NORMAL); +} + +void csch_dlg_tree_chg_sheet(csch_sheet_t *sheet) +{ + csch_dlg_tree_regen_(sheet, CSCH_TREE_CHG_TIMEOUT_QUICK); +} + +void csch_dlg_tree_prj_compiled(csch_project_t *project) +{ + tree_dlg_ctx_t *ctx = htpp_get(&prj2dlg, project); + if (ctx != NULL) + tree_update_preview(ctx); +} + + +const char csch_acts_TreeDialog[] = "TreeDialog([object[=idpath]|objarr,vtp0ptr])"; +const char csch_acth_TreeDialog[] = "Bring up the sheet's object tree dialog. If object is specified, move cursor to that object in the tree.\n"; +fgw_error_t csch_act_TreeDialog(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_design_t *hidlib = RND_ACT_DESIGN; + csch_sheet_t *sheet = (csch_sheet_t *)hidlib; + int cmd = -1; + const char *cmds = "", *oidps; + + RND_ACT_MAY_CONVARG(1, FGW_STR, TreeDialog, cmds = argv[1].val.str); + + oidps = strpbrk(cmds, ":="); + if (oidps != NULL) { + if (strncmp(cmds, "object", 6) == 0) { + oidps++; + } + else { + rnd_message(RND_MSG_ERROR, "Invalid first arg in TreeDialog\n"); + return FGW_ERR_ARG_CONV; + } + } + else + cmd = rnd_funchash_get(cmds, NULL); + + RND_ACT_IRES(-1); + + switch(cmd) { + case -1: + sch_rnd_tree_dlg((csch_project_t *)sheet->hidlib.project, sheet, oidps, NULL); + break; + case F_Object: + { + csch_chdr_t *obj; + csch_coord_t x, y; + + if (sch_rnd_get_coords("Click on object to view in tree", &x, &y, 0) != 0) + break; + + obj = sch_rnd_search_obj_at(sheet, x, y, sch_rnd_slop); + if (obj != NULL) { + sheet = obj->sheet; + sch_rnd_tree_dlg((csch_project_t *)sheet->hidlib.project, sheet, csch_chdr_to_oidpath_str(obj), NULL); + } + else + rnd_message(RND_MSG_ERROR, "TreeDialog(): no object under cursor\n"); + } + break; + case F_Objarr: + { + vtp0_t *arr = argv[2].val.ptr_void; + if ((argv[2].type != (FGW_PTR | FGW_STRUCT)) || (!fgw_ptr_in_domain(&rnd_fgw, &argv[2], CSCH_PTR_DOMAIN_COBJ_ARR))) { + rnd_message(RND_MSG_ERROR, "TreeDialog(): objarr argument is not an object arr pointer\n"); + break; + } + sch_rnd_tree_dlg((csch_project_t *)sheet->hidlib.project, NULL, NULL, arr); + } + break; + default: + rnd_message(RND_MSG_ERROR, "TreeDialog(): invalid first argument\n"); + } + + return 0; +} + +void csch_dlg_tree_init(void) +{ + htpp_init(&prj2dlg, ptrhash, ptrkeyeq); + vtl0_init(&hisave); +} + +void csch_dlg_tree_uninit(void) +{ + rnd_dad_retovr_t retovr = {0}; + htpp_entry_t *e; + + vtl0_uninit(&hisave); + + for(e = htpp_first(&prj2dlg); e != NULL; e = htpp_next(&prj2dlg, e)) { + tree_dlg_ctx_t *ctx = e->value; + rnd_hid_dad_close(ctx->dlg_hid_ctx, &retovr, 0); + } + + htpp_uninit(&prj2dlg); +} Index: tags/1.0.5/src/plugins/sch_dialogs/dlg_tree.h =================================================================== --- tags/1.0.5/src/plugins/sch_dialogs/dlg_tree.h (nonexistent) +++ tags/1.0.5/src/plugins/sch_dialogs/dlg_tree.h (revision 10414) @@ -0,0 +1,21 @@ + +extern const char csch_acts_TreeDialog[]; +extern const char csch_acth_TreeDialog[]; +fgw_error_t csch_act_TreeDialog(fgw_arg_t *res, int argc, fgw_arg_t *argv); + + +/* Timed regeneration of content */ +void csch_dlg_tree_edit(csch_sheet_t *sheet); + +/* (Almost) immediate regeneration of content */ +void csch_dlg_tree_chg_sheet(csch_sheet_t *sheet); + +/* Redraw preview after compilation */ +void csch_dlg_tree_prj_compiled(csch_project_t *project); + + +void csch_dlg_tree_init(void); +void csch_dlg_tree_uninit(void); + + + Index: tags/1.0.5/src/plugins/sch_dialogs/dlg_undo.c =================================================================== --- tags/1.0.5/src/plugins/sch_dialogs/dlg_undo.c (nonexistent) +++ tags/1.0.5/src/plugins/sch_dialogs/dlg_undo.c (revision 10414) @@ -0,0 +1,214 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - GUI - undo dialog + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * Copyright (C) 2018 Tibor 'Igor2' Palinkas in pcb-rnd + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include + +#include + +#include +#include +#include +#include +#include +#include + +const char *dlg_undo_cookie = "undo dialog"; + +typedef struct{ + RND_DAD_DECL_NOINIT(dlg) + int wlist; + long serial; /* last seen undo serial, for updating the dialog on change */ + int active; /* already open - allow only one instance */ +} undo_ctx_t; + +undo_ctx_t undo_ctx; + +static void undo_close_cb(void *caller_data, rnd_hid_attr_ev_t ev) +{ + undo_ctx_t *ctx = caller_data; + RND_DAD_FREE(ctx->dlg); + memset(ctx, 0, sizeof(undo_ctx_t)); +} + +static void cb_undo(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + csch_sheet_t *sheet = (csch_sheet_t *)rnd_multi_get_current(); + csch_undo(sheet); + rnd_gui->invalidate_all(rnd_gui); +} + +static void cb_redo(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + csch_sheet_t *sheet = (csch_sheet_t *)rnd_multi_get_current(); + csch_redo(sheet); + rnd_gui->invalidate_all(rnd_gui); +} + +static void cb_clear(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + csch_sheet_t *sheet = (csch_sheet_t *)rnd_multi_get_current(); + csch_undo_clear_list(sheet, 1); +} + + +static void undo_data2dlg(undo_ctx_t *ctx, csch_sheet_t *sheet) +{ + rnd_hid_attribute_t *attr; + rnd_hid_tree_t *tree; + rnd_hid_row_t *r; + char *cell[4], *cursor_path = NULL; + uundo_item_t *i; + char *payload, buff[8192], mark[2], ser[64]; + + attr = &ctx->dlg[ctx->wlist]; + tree = attr->wdata; + + /* remember cursor */ + r = rnd_dad_tree_get_selected(attr); + if (r != NULL) + cursor_path = rnd_strdup(r->cell[0]); + + /* remove existing items */ + rnd_dad_tree_clear(tree); + + mark[1] = '\0'; + cell[3] = NULL; + for(i = sheet->undo.head; i != NULL; i = i->next) { + payload = ""; + if (i->oper->item_print != NULL) { + i->oper->item_print(i->udata, buff, sizeof(buff)); + payload = buff; + } + mark[0] = '\0'; + if ((i == sheet->undo.head) && (i == sheet->undo.tail)) + mark[0] = '*'; + else if (i == sheet->undo.head) + mark[0] = 'h'; + else if (i == sheet->undo.tail) + mark[0] = 't'; + sprintf(ser, "%ld", (long)i->serial); + cell[0] = rnd_strdup(ser); + cell[1] = rnd_strdup(mark); + cell[2] = rnd_strdup(payload); + rnd_dad_tree_append(attr, NULL, cell); + } + + /* restore cursor */ + if (cursor_path != NULL) { + rnd_hid_attr_val_t hv; + hv.str = cursor_path; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wlist, &hv); + free(cursor_path); + } +} + +/* global, follows sheet changes */ +static void csch_dlg_undo(csch_sheet_t *sheet) +{ + static const char *hdr[] = {"serial", "flg", "operation", NULL}; + rnd_hid_dad_buttons_t clbtn[] = {{"Close", 0}, {NULL, 0}}; + + if (undo_ctx.active) + return; /* do not open another */ + + RND_DAD_BEGIN_VBOX(undo_ctx.dlg); + RND_DAD_COMPFLAG(undo_ctx.dlg, RND_HATF_EXPFILL); + RND_DAD_TREE(undo_ctx.dlg, 3, 0, hdr); + RND_DAD_COMPFLAG(undo_ctx.dlg, RND_HATF_EXPFILL | RND_HATF_SCROLL); + undo_ctx.wlist = RND_DAD_CURRENT(undo_ctx.dlg); + + RND_DAD_BEGIN_HBOX(undo_ctx.dlg); + RND_DAD_BUTTON(undo_ctx.dlg, "Undo"); + RND_DAD_CHANGE_CB(undo_ctx.dlg, cb_undo); + RND_DAD_BUTTON(undo_ctx.dlg, "Redo"); + RND_DAD_CHANGE_CB(undo_ctx.dlg, cb_redo); + RND_DAD_BUTTON(undo_ctx.dlg, "Clear"); + RND_DAD_CHANGE_CB(undo_ctx.dlg, cb_clear); + RND_DAD_END(undo_ctx.dlg); + RND_DAD_BUTTON_CLOSES(undo_ctx.dlg, clbtn); + RND_DAD_END(undo_ctx.dlg); + + /* set up the context */ + undo_ctx.active = 1; + + RND_DAD_DEFSIZE(undo_ctx.dlg, 300, 400); + RND_DAD_NEW("undo", undo_ctx.dlg, "sch-rnd undo list", &undo_ctx, rnd_false, undo_close_cb); /* type=global */ + undo_data2dlg(&undo_ctx, sheet); +} + +const char csch_acts_UndoDialog[] = "UndoDialog()\n"; +const char csch_acth_UndoDialog[] = "Open the undo dialog."; +fgw_error_t csch_act_UndoDialog(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_design_t *hidlib = RND_ACT_DESIGN; + csch_sheet_t *sheet = (csch_sheet_t *)hidlib; + + csch_dlg_undo(sheet); + RND_ACT_IRES(0); + return 0; +} + +/* update the dialog after an undo operation */ +static void csch_dlg_undo_ev(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + csch_sheet_t *sheet = (csch_sheet_t *)hidlib; + undo_ctx_t *ctx = user_data; + if (!ctx->active) + return; + undo_data2dlg(ctx, sheet); +} + +/* Check if the serial has changed and update the dialog if so */ +static void csch_dlg_undo_ev_chk(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + csch_sheet_t *sheet = (csch_sheet_t *)hidlib; + undo_ctx_t *ctx = user_data; + + if (!ctx->active) + return; + if (ctx->serial != sheet->undo.serial) { + undo_data2dlg(ctx, sheet); + ctx->serial = sheet->undo.serial; + } +} + +void csch_dlg_undo_brd_changed_ev(csch_sheet_t *sheet) +{ + if (undo_ctx.active) + undo_data2dlg(&undo_ctx, sheet); +} + +void csch_dlg_undo_init(void) +{ + rnd_event_bind(CSCH_EVENT_UNDO_POST, csch_dlg_undo_ev, &undo_ctx, dlg_undo_cookie); + rnd_event_bind(RND_EVENT_USER_INPUT_POST, csch_dlg_undo_ev_chk, &undo_ctx, dlg_undo_cookie); +} + +void csch_dlg_undo_uninit(void) +{ + rnd_event_unbind_allcookie(dlg_undo_cookie); +} Index: tags/1.0.5/src/plugins/sch_dialogs/dlg_undo.h =================================================================== --- tags/1.0.5/src/plugins/sch_dialogs/dlg_undo.h (nonexistent) +++ tags/1.0.5/src/plugins/sch_dialogs/dlg_undo.h (revision 10414) @@ -0,0 +1,8 @@ +extern const char csch_acts_UndoDialog[]; +extern const char csch_acth_UndoDialog[]; +fgw_error_t csch_act_UndoDialog(fgw_arg_t *res, int argc, fgw_arg_t *argv); + +void csch_dlg_undo_brd_changed_ev(csch_sheet_t *sheet); + +void csch_dlg_undo_init(void); +void csch_dlg_undo_uninit(void); Index: tags/1.0.5/src/plugins/sch_dialogs/dlg_view.c =================================================================== --- tags/1.0.5/src/plugins/sch_dialogs/dlg_view.c (nonexistent) +++ tags/1.0.5/src/plugins/sch_dialogs/dlg_view.c (revision 10414) @@ -0,0 +1,408 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - GUI - view dialog + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/* pen selection dialog */ + +#include + +#include + +#include +#include + +#include +#include +#include + +#include + +#include "dlg_view.h" + +/* double click timeout, in seconds */ +#define DOUBLE_CLICK_TIME 0.5 + +typedef struct viewdlg_ctx_s { + RND_DAD_DECL_NOINIT(dlg) + int wviewlist, wenglist; + csch_project_t *prj; + long init_sel, last_sel; + unsigned active:1; + double last_click_time; +} viewdlg_ctx_t; + +static viewdlg_ctx_t vctx; + +static void viewdlg_close_cb(void *caller_data, rnd_hid_attr_ev_t ev) +{ + viewdlg_ctx_t *ctx = caller_data; + + ctx->active = 0; +} + +static void view_view2dlg(viewdlg_ctx_t *ctx) +{ + rnd_hid_attribute_t *attr = &ctx->dlg[ctx->wenglist]; + rnd_hid_tree_t *tree = attr->wdata; + rnd_hid_row_t *r; + csch_view_t *view = NULL; + char *cell[3], *cursor_path = NULL; + long n; + + + r = rnd_dad_tree_get_selected(&ctx->dlg[ctx->wviewlist]); + if (r != NULL) + view = csch_view_get(ctx->prj, r->cell[0]); + + + /* remember cursor */ + r = rnd_dad_tree_get_selected(attr); + if (r != NULL) + cursor_path = rnd_strdup(r->cell[0]); + + /* remove existing items */ + rnd_dad_tree_clear(tree); + + if (view != NULL) { + cell[2] = NULL; + for(n = 0; n < view->engines.used; n++) { + rnd_hid_row_t *r; + csch_view_eng_t *eng = view->engines.array[n]; + cell[0] = rnd_strdup(eng->obj->name); + cell[1] = rnd_strdup_printf("%d, %d, %d", eng->eprio + CSCH_PRI_PLUGIN_HIGH, eng->eprio + CSCH_PRI_PLUGIN_NORMAL, eng->eprio + CSCH_PRI_PLUGIN_LOW); + r = rnd_dad_tree_append(attr, NULL, cell); + r->user_data2.lng = n; + } + } + + /* restore cursor */ + if (cursor_path != NULL) { + rnd_hid_attr_val_t hv; + hv.str = cursor_path; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wviewlist, &hv); + free(cursor_path); + } +} + +static void view_prj2dlg(viewdlg_ctx_t *ctx) +{ + rnd_hid_attribute_t *attr = &ctx->dlg[ctx->wviewlist]; + rnd_hid_tree_t *tree = attr->wdata; + rnd_hid_row_t *r; + rnd_hid_attr_val_t hv; + char *cell[2], *cursor_path = NULL; + long n; + + /* remember cursor */ + r = rnd_dad_tree_get_selected(attr); + if (r != NULL) + cursor_path = rnd_strdup(r->cell[0]); + + /* remove existing items */ + rnd_dad_tree_clear(tree); + + cell[1] = NULL; + for(n = 0; n < ctx->prj->views.used; n++) { + csch_view_t *view = ctx->prj->views.array[n]; + cell[0] = rnd_strdup(view->fgw_ctx.name); + r = rnd_dad_tree_append(attr, NULL, cell); + r->user_data2.lng = n; + if ((cursor_path == NULL) && (n == ctx->prj->curr)) { + hv.str = cell[0]; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wviewlist, &hv); + ctx->last_sel = n; + } + } + + /* restore cursor */ + if (cursor_path != NULL) { + hv.str = cursor_path; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wviewlist, &hv); + free(cursor_path); + } + + view_view2dlg(ctx); +} + +static void timed_close_cb(rnd_hidval_t user_data) +{ + void *hid_ctx = user_data.ptr; + static rnd_dad_retovr_t retovr = {0}; + rnd_hid_dad_close(hid_ctx, &retovr, 0); +} + +static void view_select_cb(rnd_hid_attribute_t *attrib, void *hid_ctx, rnd_hid_row_t *row) +{ + rnd_hid_tree_t *tree = attrib->wdata; + viewdlg_ctx_t *ctx = tree->user_ctx; + double now = rnd_dtime(); + int dblclk = (now - ctx->last_click_time) < DOUBLE_CLICK_TIME; + + ctx->last_click_time = now; + view_view2dlg(tree->user_ctx); + + if (dblclk && (row->user_data2.lng == ctx->last_sel)) { + /* second click - needs to be timed, can't close from tree callback */ + rnd_hidval_t user_data; + user_data.ptr = hid_ctx; + rnd_gui->add_timer(rnd_gui, timed_close_cb, 1, user_data); + return; + } + ctx->last_sel = row == NULL ? -1 : row->user_data2.lng; +} + +static void activate_selected(viewdlg_ctx_t *ctx) +{ + if (ctx->last_sel >= 0) + csch_view_activate(ctx->prj, ctx->last_sel); +} + +static void btn_new_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + viewdlg_ctx_t *ctx = &vctx; + rnd_design_t *hl = rnd_gui->get_dad_design(hid_ctx); + csch_sheet_t *sheet = (csch_sheet_t *)hl; + char *name; + + if (ctx->prj->dummy) { + if (sch_rnd_project_create_file_for_sheet_gui(sheet) != 0) + return; + } + + name = rnd_hid_prompt_for(hl, "Name of the new view", "", "Creating new view"); + if ((name == NULL) || (*name == '\0')) { + free(name); + return; + } + + if (sch_rnd_project_append_view(sheet, name, 0) == 0) { + sch_rnd_project_views_save(sheet); + view_prj2dlg(ctx); + } +} + +static void btn_del_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + viewdlg_ctx_t *ctx = &vctx; + rnd_design_t *hl = rnd_gui->get_dad_design(hid_ctx); + csch_sheet_t *sheet = (csch_sheet_t *)hl; + + if (ctx->prj->dummy) { + if (sch_rnd_project_create_file_for_sheet_gui(sheet) != 0) + return; + } + + if (sch_rnd_project_del_view(sheet, ctx->last_sel, 0) == 0) { + sch_rnd_project_views_save(sheet); + ctx->prj->curr = -1; + ctx->last_sel = 0; + view_prj2dlg(ctx); + csch_view_activate(ctx->prj, ctx->last_sel); + } +} + +/* op: -1: insert before; +1: append after; 0: delete */ +static void view_eng_edit(void *hid_ctx, void *caller_data, int op) +{ + viewdlg_ctx_t *ctx = &vctx; + rnd_design_t *hl = rnd_gui->get_dad_design(hid_ctx); + csch_sheet_t *sheet = (csch_sheet_t *)hl; + rnd_hid_attribute_t *tattr = &ctx->dlg[ctx->wenglist]; + rnd_hid_row_t *r; + csch_view_t *view = NULL; + csch_view_eng_t *neng; + + r = rnd_dad_tree_get_selected(&ctx->dlg[ctx->wviewlist]); + if (r != NULL) + view = csch_view_get(ctx->prj, r->cell[0]); + if (view == NULL) + return; + + r = rnd_dad_tree_get_selected(tattr); + if ((op == 0) && (r == NULL)) /* remove requires selection */ + return; + + if (ctx->prj->dummy) { + if (sch_rnd_project_create_file_for_sheet_gui(sheet) != 0) + return; + } + + if (op != 0) { + const char *options = NULL; + char *name = rnd_hid_prompt_for(hl, "Name of the engine", "", "Adding engine to a view"); + if ((name == NULL) || (*name == '\0')) { + free(name); + return; + } + neng = csch_eng_alloc(view, name, name, options); + if (neng == NULL) { + rnd_message(RND_MSG_ERROR, "dlg_view internal error: failed to create engine binding '%s' for view\nThere is probably no engine by that name (typo? missnig plugin?)\n", name); + free(name); + return; + } + free(name); + + } + + if (op < 0) { /* insert before */ + long where = 0; + if (r != NULL) + where = r->user_data2.lng; + vtp0_insert_len(&view->engines, where, (void **)&neng, 1); + } + else if (op > 0) { /* append after */ + long where = 0; + if (r != NULL) + where = r->user_data2.lng; + where++; + if (where > view->engines.used) + vtp0_append(&view->engines, (void *)neng); + else + vtp0_insert_len(&view->engines, where, (void **)&neng, 1); + } + else { /* op == 0: delete */ + fgw_obj_t *obj; + vtp0_remove(&view->engines, r->user_data2.lng, 1); + obj = fgw_obj_lookup(&view->fgw_ctx, r->cell[0]); + if (obj != NULL) + fgw_obj_unreg(&view->fgw_ctx, obj); + } + + csch_view_renum(view); + + if (sch_rnd_project_view_lib2lht(view) != 0) + rnd_message(RND_MSG_ERROR, "dlg_view internal error: failed to save view changes in project lihata"); + + csch_project_flush(); + view_view2dlg(ctx); +} + +static void btn_eng_ins_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + view_eng_edit(hid_ctx, caller_data, -1); +} + +static void btn_eng_app_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + view_eng_edit(hid_ctx, caller_data, +1); +} + + +static void btn_eng_del_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + view_eng_edit(hid_ctx, caller_data, 0); +} + +static const int view_dlg(csch_project_t *prj) +{ + viewdlg_ctx_t *ctx = &vctx; + const char *views_hdr[] = {"view"}; + const char *plugin_hdr[] = {"engine", "range (+10)"}; + rnd_hid_dad_buttons_t clbtn[] = {{"close", 0}, {NULL, 0}}; + + assert(!ctx->active); + + ctx->active = 1; + ctx->prj = prj; + ctx->last_sel = -1; + ctx->init_sel = prj->curr; + + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_BEGIN_HPANE(ctx->dlg, "left-right"); + + RND_DAD_BEGIN_VBOX(ctx->dlg); /* left side */ + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_TREE(ctx->dlg, 1, 0, views_hdr); /* top left: tree */ + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_TREE_SET_CB(ctx->dlg, selected_cb, view_select_cb); + RND_DAD_TREE_SET_CB(ctx->dlg, ctx, ctx); + ctx->wviewlist = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "New"); + RND_DAD_HELP(ctx->dlg, "Append a new view at the end of the list\nand save project file"); + RND_DAD_CHANGE_CB(ctx->dlg, btn_new_cb); + RND_DAD_BUTTON(ctx->dlg, "Del"); + RND_DAD_HELP(ctx->dlg, "Remove currently selected view\nand save project file"); + RND_DAD_CHANGE_CB(ctx->dlg, btn_del_cb); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + + RND_DAD_BEGIN_VBOX(ctx->dlg); /* right side */ + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + + RND_DAD_TREE(ctx->dlg, 2, 0, plugin_hdr); /* top right: tree */ + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + ctx->wenglist = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "Ins. before"); + RND_DAD_CHANGE_CB(ctx->dlg, btn_eng_ins_cb); + RND_DAD_HELP(ctx->dlg, "Insert a new engine before the currently selected one\nand save project file"); + RND_DAD_BUTTON(ctx->dlg, "App. after"); + RND_DAD_CHANGE_CB(ctx->dlg, btn_eng_app_cb); + RND_DAD_HELP(ctx->dlg, "Append a new engine after the currently selected one\nand save project file"); + RND_DAD_BUTTON(ctx->dlg, "Del"); + RND_DAD_CHANGE_CB(ctx->dlg, btn_eng_del_cb); + RND_DAD_HELP(ctx->dlg, "Remove the currently selected engine\nand save project file"); + RND_DAD_END(ctx->dlg); + RND_DAD_BUTTON_CLOSES(ctx->dlg, clbtn); + RND_DAD_END(ctx->dlg); + + RND_DAD_END(ctx->dlg); + + RND_DAD_END(ctx->dlg); + + RND_DAD_DEFSIZE(ctx->dlg, 300, 300); + RND_DAD_NEW("ViewDialog", ctx->dlg, "Change view", ctx, 1, viewdlg_close_cb); /* type=local/modal */ + + view_prj2dlg(ctx); + + RND_DAD_RUN(ctx->dlg); + + activate_selected(ctx); + if (ctx->init_sel != ctx->last_sel) /* compile if changed */ + rnd_actionva(rnd_gui->get_dad_design(ctx->dlg_hid_ctx), "CompileProject", NULL); + + RND_DAD_FREE(ctx->dlg); + + return 0; +} + + +const char csch_acts_ViewDialog[] = "ViewDialog()"; +const char csch_acth_ViewDialog[] = "Bring up a modal dialog for selecting the current view or editing views of the current project.\n"; +fgw_error_t csch_act_ViewDialog(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_design_t *hidlib = RND_ACT_DESIGN; + csch_sheet_t *sheet = (csch_sheet_t *)hidlib; + csch_project_t *prj = (csch_project_t *)sheet->hidlib.project; + + RND_ACT_IRES(view_dlg(prj)); + + return 0; +} + Index: tags/1.0.5/src/plugins/sch_dialogs/dlg_view.h =================================================================== --- tags/1.0.5/src/plugins/sch_dialogs/dlg_view.h (nonexistent) +++ tags/1.0.5/src/plugins/sch_dialogs/dlg_view.h (revision 10414) @@ -0,0 +1,5 @@ +#include +extern const char csch_acts_ViewDialog[]; +extern const char csch_acth_ViewDialog[]; +fgw_error_t csch_act_ViewDialog(fgw_arg_t *res, int argc, fgw_arg_t *argv); + Index: tags/1.0.5/src/plugins/sch_dialogs/quick_attr.c =================================================================== --- tags/1.0.5/src/plugins/sch_dialogs/quick_attr.c (nonexistent) +++ tags/1.0.5/src/plugins/sch_dialogs/quick_attr.c (revision 10414) @@ -0,0 +1,178 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - GUI - quick attribute edit dialog + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/* quick-edit attributes */ + +#include + +#include + +#include +#include +#include +#include +#include + +#include "dlg_attrib.h" +#include "quick_attr.h" +#include "quick_attr_util.h" + +static gds_t key2act_tmp = {0}; + +static const char *key2act(const char *key) +{ + int n; + + if (key2act_tmp.used == 0) + gds_append_str(&key2act_tmp, "quick_attr_"); + else + key2act_tmp.used = 11; + + gds_append_str(&key2act_tmp, key); + + /* replace non-alnum and non-underscore with __ */ + for(n = 0; n < key2act_tmp.used; n++) { + int c = key2act_tmp.array[n]; + if (isalnum(c) || (c == '_')) + continue; + key2act_tmp.array[n] = '_'; + gds_insert_len(&key2act_tmp, n, "_", 1); + n++; + } + + return key2act_tmp.array; +} + +int sch_rnd_attr_quick_editable(csch_sheet_t *sheet, csch_chdr_t *obj, const char *key) +{ + const char *name = key2act(key); + const fgw_func_t *act = rnd_act_lookup(name); + + return (act != NULL); +} + + +int sch_rnd_attr_quick_edit(csch_sheet_t *sheet, csch_chdr_t *obj, const char *key) +{ + const char *name = key2act(key); + fgw_func_t *ffgw = NULL; + fgw_arg_t res = {0}, args[3]; + int ret; + + rnd_find_action(name, &ffgw); + if (ffgw == NULL) + return -1; + + + fgw_ptr_reg(&rnd_fgw, &args[1], CSCH_PTR_DOMAIN_COBJ, FGW_PTR | FGW_STRUCT, (void *)obj); + args[2].type = FGW_STR; + args[2].val.cstr = key; + ret = rnd_actionv_bin(&sheet->hidlib, name, &res, 3, args); + fgw_ptr_unreg(&rnd_fgw, &args[1], CSCH_PTR_DOMAIN_COBJ); + if (ret != 0) + return -1; + + fgw_arg_conv(&rnd_fgw, &res, FGW_INT); + return res.val.nat_int; +} + +/*** stock quick edits (core data model) ***/ + +const char csch_acts_quick_attr_role[] = "quick_attr_role(objptr)"; +const char csch_acth_quick_attr_role[] = "Quick Attribute Edit for core data model's role attribute"; +fgw_error_t csch_act_quick_attr_role(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + RND_DAD_DECL(dlg) + rnd_design_t *hidlib = RND_ACT_DESIGN; + csch_sheet_t *sheet = (csch_sheet_t *)hidlib; + csch_cgrp_t *grp; + const char *roles[] = {"", "bus-net", "bus-terminal", "hub-point", "symbol", "terminal", "wire-net", "junction", NULL}; + rnd_hid_dad_buttons_t clbtn[] = {{"Cancel", 0}, {"Ok", 1}, {NULL, 0}}; + int dres, wenum, orig; + + QUICK_ATTR_GET_GRP(grp, "quick_attr_role"); + orig = grp->role - 1; + + RND_DAD_BEGIN_VBOX(dlg); + RND_DAD_LABEL(dlg, "Select new group role:"); + RND_DAD_ENUM(dlg, roles); + RND_DAD_DEFAULT_NUM(dlg, orig); + wenum = RND_DAD_CURRENT(dlg); + RND_DAD_BUTTON_CLOSES(dlg, clbtn); + RND_DAD_END(dlg); + + RND_DAD_AUTORUN("quick_attr_role", dlg, "Set group role", NULL, dres); + + RND_ACT_IRES(0); + if ((dres == 1) && (dlg[wenum].val.lng) != orig) { + csch_source_arg_t *src; + const char *val = ((dlg[wenum].val.lng == 0) ? "" : roles[dlg[wenum].val.lng]); + + src = csch_attrib_src_c(NULL, 0, 0, "quick_attr_role user input"); + csch_attr_modify_str(sheet, grp, -CSCH_ATP_USER_DEFAULT, "role", val, src, 1); + RND_ACT_IRES(1); + } + return 0; +} + +const char csch_acts_QuickAttr[] = "QuickAttr(last-click|parent|object[:idpath], key)"; +const char csch_acth_QuickAttr[] = "Quick Attribute Edit on key"; +const char csch_acts_QuickAttrEditable[] = "QuickAttrEditable(last-click|parent|object[:idpath], key)"; +const char csch_acth_QuickAttrEditable[] = "Returns 1 if obj:key has a quick attribute edit"; +fgw_error_t csch_act_QuickAttr(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_design_t *hidlib = RND_ACT_DESIGN; + csch_sheet_t *sheet = (csch_sheet_t *)hidlib; + const char *cmd, *key, *fname; + csch_chdr_t *obj; + int ret = -1, has_coords, check; + + fname = argv[0].val.argv0.func->name; + check = (fname[9] == 'e') || (fname[9] == 'E'); + + RND_ACT_CONVARG(1, FGW_STR, QuickAttr, cmd = argv[1].val.str); + RND_ACT_CONVARG(2, FGW_STR, QuickAttr, key = argv[2].val.str); + + obj = sch_dialog_resolve_obj(sheet, "QuickAttr", cmd, &has_coords); + if (obj != NULL) { + if (check) + ret = sch_rnd_attr_quick_editable(obj->sheet, obj, key); + else + ret = sch_rnd_attr_quick_edit(sheet, obj, key); + } + + RND_ACT_IRES(ret); + return 0; +} + +/*** plugin administration ***/ + +void sch_rnd_attr_quick_uninit(void) +{ + gds_uninit(&key2act_tmp); +} Index: tags/1.0.5/src/plugins/sch_dialogs/quick_attr.h =================================================================== --- tags/1.0.5/src/plugins/sch_dialogs/quick_attr.h (nonexistent) +++ tags/1.0.5/src/plugins/sch_dialogs/quick_attr.h (revision 10414) @@ -0,0 +1,32 @@ +#ifndef SCH_DIALOGS_QUICK_ATTR_H +#define SCH_DIALOGS_QUICK_ATTR_H + +#include + +/* Returns non-zero if attribute key is quick-editable */ +int sch_rnd_attr_quick_editable(csch_sheet_t *sheet, csch_chdr_t *obj, const char *key); + +/* Offer GUI for quick-edit an attribute. Returns -1 on error, 0 on no change + or 1 if the user has changed attribute value(s). */ +int sch_rnd_attr_quick_edit(csch_sheet_t *sheet, csch_chdr_t *obj, const char *key); + + +/*** stock quick edits (core data model) ***/ +extern const char csch_acts_quick_attr_role[]; +extern const char csch_acth_quick_attr_role[]; +fgw_error_t csch_act_quick_attr_role(fgw_arg_t *res, int argc, fgw_arg_t *argv); + +/* generic */ +extern const char csch_acts_QuickAttr[]; +extern const char csch_acth_QuickAttr[]; +fgw_error_t csch_act_QuickAttr(fgw_arg_t *res, int argc, fgw_arg_t *argv); + +extern const char csch_acts_QuickAttrEditable[]; +extern const char csch_acth_QuickAttrEditable[]; +#define csch_act_QuickAttrEditable csch_act_QuickAttr + +/*** plugin administration ***/ +void sch_rnd_attr_quick_uninit(void); + + +#endif Index: tags/1.0.5/src/plugins/sch_dialogs/quick_attr_util.h =================================================================== --- tags/1.0.5/src/plugins/sch_dialogs/quick_attr_util.h (nonexistent) +++ tags/1.0.5/src/plugins/sch_dialogs/quick_attr_util.h (revision 10414) @@ -0,0 +1,20 @@ +/* Macros only so that plugins using this file do not start depending on + sch_dialogs - all communication are made through central infra, + e.g. actions */ + +#define QUICK_ATTR_GET_GRP(grp, actname) \ +do { \ + if (argc < 2) { \ + rnd_message(RND_MSG_ERROR, actname ": missing argument 1 (group object)\n"); \ + return FGW_ERR_PTR_DOMAIN; \ + } \ + grp = argv[1].val.ptr_void; \ + if ((argv[1].type != (FGW_PTR | FGW_STRUCT)) || (!fgw_ptr_in_domain(&rnd_fgw, &argv[1], CSCH_PTR_DOMAIN_COBJ))) { \ + rnd_message(RND_MSG_ERROR, actname ": argument 1 needs to be a concrete group object\n"); \ + return FGW_ERR_PTR_DOMAIN; \ + } \ + if (!csch_obj_is_grp(&grp->hdr)) { \ + rnd_message(RND_MSG_ERROR, actname ": object is not a group, can't set role\n"); \ + return FGW_ERR_ARG_CONV; \ + } \ +} while(0) Index: tags/1.0.5/src/plugins/sch_dialogs/sch_dialogs.c =================================================================== --- tags/1.0.5/src/plugins/sch_dialogs/sch_dialogs.c (nonexistent) +++ tags/1.0.5/src/plugins/sch_dialogs/sch_dialogs.c (revision 10414) @@ -0,0 +1,196 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - GUI + * Copyright (C) 2020,2022 Tibor 'Igor2' Palinkas + * (copied from camv-rnd by the author) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "dlg_attrib.h" +#include "dlg_about.h" +#include "dlg_abstract.h" +#include "dlg_stance.h" +#include "dlg_cond.h" +#include "dlg_undo.h" +#include "dlg_pen.h" +#include "dlg_text.h" +#include "dlg_tree.h" +#include "dlg_library.h" +#include "dlg_infobar.c" +#include "dlg_view.h" +#include "dlg_project.h" +#include "quick_attr.h" + +#include "adialogs_conf.h" +#include "conf_internal.c" + +conf_adialogs_t adialogs_conf; + +static const char *sch_dialogs_cookie = "sch_dialogs"; + +static rnd_action_t sch_dialogs_action_list[] = { + {"PrintGUI", rnd_act_PrintDialog, rnd_acth_PrintDialog, rnd_acts_PrintDialog}, + + {"AttributeDialog", csch_act_AttributeDialog, csch_acth_AttributeDialog, csch_acts_AttributeDialog}, + {"AttributePick", csch_act_AttributePick, csch_acth_AttributePick, csch_acts_AttributePick}, + {"PenDialog", csch_act_PenDialog, csch_acth_PenDialog, csch_acts_PenDialog}, + {"EditText", csch_act_EditText, csch_acth_EditText, csch_acts_EditText}, + {"UndoDialog", csch_act_UndoDialog, csch_acth_UndoDialog, csch_acts_UndoDialog}, + {"TreeDialog", csch_act_TreeDialog, csch_acth_TreeDialog, csch_acts_TreeDialog}, + {"AbstractDialog", csch_act_AbstractDialog, csch_acth_AbstractDialog, csch_acts_AbstractDialog}, + {"LibraryDialog", csch_act_LibraryDialog, csch_acth_LibraryDialog, csch_acts_LibraryDialog}, + {"InfoBarFileChanged", csch_act_InfoBarFileChanged, csch_acth_InfoBarFileChanged, csch_acts_InfoBarFileChanged}, + {"ViewDialog", csch_act_ViewDialog, csch_acth_ViewDialog, csch_acts_ViewDialog}, + {"ProjectDialog", csch_act_ProjectDialog, csch_acth_ProjectDialog, csch_acts_ProjectDialog}, + {"About", csch_act_About, csch_acth_About, csch_acts_About}, + {"StanceDialog", csch_act_StanceDialog, csch_acth_StanceDialog, csch_acts_StanceDialog}, + {"ConditionalDialog", csch_act_ConditionalDialog, csch_acth_ConditionalDialog, csch_acts_ConditionalDialog}, + + {"quick_attr_role", csch_act_quick_attr_role, csch_acth_quick_attr_role, csch_acts_quick_attr_role}, + {"quick_attr_forge__if__dnp", csch_act_quick_attr_forge__if__dnp_omit, csch_acth_quick_attr_forge__if__dnp, csch_acts_quick_attr_forge__if__dnp}, + {"quick_attr_forge__if__omit", csch_act_quick_attr_forge__if__dnp_omit, csch_acth_quick_attr_forge__if__omit, csch_acts_quick_attr_forge__if__omit}, + {"QuickAttr", csch_act_QuickAttr, csch_acth_QuickAttr, csch_acts_QuickAttr}, + {"QuickAttrEditable", csch_act_QuickAttrEditable, csch_acth_QuickAttrEditable, csch_acts_QuickAttrEditable} +}; + +extern int sch_dlg_pref_tab; +extern void (*sch_dlg_pref_first_init)(pref_ctx_t *ctx, int tab); + + +static void csch_dlg_ev_preunload(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + csch_sheet_t *sheet = (csch_sheet_t *)hidlib; + csch_dlg_pen_preunload(sheet); + csch_dlg_attr_preunload(sheet); + csch_dlg_library_preunload(sheet); + csch_dlg_tree_chg_sheet(sheet); + csch_dlg_cond_preunload(sheet); +} + +static void csch_dlg_ev_sheet_edit(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + csch_sheet_t *sheet = (csch_sheet_t *)hidlib; + csch_dlg_tree_edit(sheet); + csch_dlg_attr_edit(sheet); +} + +static void csch_dlg_ev_obj_attr_edit(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + csch_sheet_t *sheet = (csch_sheet_t *)hidlib; + if (argv[1].type == RND_EVARG_PTR) + csch_dlg_attr_obj_attr_edit(sheet, argv[1].d.p); +} + +static void csch_dlg_ev_prj_compiled(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + csch_sheet_t *sheet = (csch_sheet_t *)hidlib; + csch_dlg_attr_compiled((csch_project_t *)sheet->hidlib.project); + csch_dlg_abst_compiled((csch_project_t *)sheet->hidlib.project); + csch_dlg_tree_prj_compiled((csch_project_t *)sheet->hidlib.project); +} + +static void csch_dlg_ev_library_changed(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + csch_sheet_t *sheet = (csch_sheet_t *)hidlib; + csch_dlg_library_changed(sheet); +} + +static void csch_dlg_ev_board_changed(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + csch_sheet_t *sheet = (csch_sheet_t *)hidlib; + csch_dlg_undo_brd_changed_ev(sheet); +} + +static void csch_dlg_ev_sheet_postload(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + csch_sheet_t *sheet = (csch_sheet_t *)hidlib; + csch_dlg_library_changed(sheet); + csch_dlg_tree_chg_sheet(sheet); +} + + +int pplg_check_ver_sch_dialogs(int ver_needed) { return 0; } + +void pplg_uninit_sch_dialogs(void) +{ + csch_dlg_undo_uninit(); + rnd_event_unbind_allcookie(sch_dialogs_cookie); + rnd_remove_actions_by_cookie(sch_dialogs_cookie); + csch_dlg_tree_uninit(); + csch_dlg_abst_uninit(); + csch_dlg_stance_uninit(); + csch_dlg_cond_uninit(); + csch_dlg_library_uninit(); + sch_rnd_attr_quick_uninit(); + rnd_dlg_pref_uninit(); + rnd_conf_plug_unreg("plugins/dialogs/", adialogs_conf_internal, sch_dialogs_cookie); + +} + +int pplg_init_sch_dialogs(void) +{ + RND_API_CHK_VER; + + RND_REGISTER_ACTIONS(sch_dialogs_action_list, sch_dialogs_cookie); + rnd_dlg_pref_init(sch_dlg_pref_tab, sch_dlg_pref_first_init); + csch_dlg_tree_init(); + csch_dlg_abst_init(); + csch_dlg_stance_init(); + csch_dlg_cond_init(); + csch_dlg_library_init(); + csch_dlg_undo_init(); + rnd_event_bind(CSCH_EVENT_SHEET_PREUNLOAD, csch_dlg_ev_preunload, NULL, sch_dialogs_cookie); + rnd_event_bind(CSCH_EVENT_SHEET_EDITED, csch_dlg_ev_sheet_edit, NULL, sch_dialogs_cookie); + rnd_event_bind(CSCH_EVENT_OBJ_ATTR_EDITED, csch_dlg_ev_obj_attr_edit, NULL, sch_dialogs_cookie); + rnd_event_bind(CSCH_EVENT_PRJ_COMPILED, csch_dlg_ev_prj_compiled, NULL, sch_dialogs_cookie); + rnd_event_bind(CSCH_EVENT_LIBRARY_CHANGED, csch_dlg_ev_library_changed, NULL, sch_dialogs_cookie); + rnd_event_bind(RND_EVENT_DESIGN_SET_CURRENT, csch_dlg_ev_board_changed, NULL, sch_dialogs_cookie); + rnd_event_bind(CSCH_EVENT_SHEET_POSTLOAD, csch_dlg_ev_sheet_postload, NULL, sch_dialogs_cookie); + + + rnd_conf_plug_reg(adialogs_conf, adialogs_conf_internal, sch_dialogs_cookie); + +#define conf_reg(field,isarray,type_name,cpath,cname,desc,flags) \ + rnd_conf_reg_field(adialogs_conf, field,isarray,type_name,cpath,cname,desc,flags); +#include "adialogs_conf_fields.h" + + return 0; +} Index: tags/1.0.5/src/plugins/sch_dialogs/sch_dialogs.pup =================================================================== --- tags/1.0.5/src/plugins/sch_dialogs/sch_dialogs.pup (nonexistent) +++ tags/1.0.5/src/plugins/sch_dialogs/sch_dialogs.pup (revision 10414) @@ -0,0 +1,8 @@ +$class gui +$short base dialogs +$long Standard schematics editor dialog boxes +$state works +$package lib-gui +default buildin +dep lib_hid_common +autoload 1 Index: tags/1.0.5/src/plugins/sim/Makefile =================================================================== --- tags/1.0.5/src/plugins/sim/Makefile (nonexistent) +++ tags/1.0.5/src/plugins/sim/Makefile (revision 10414) @@ -0,0 +1,2 @@ +all: + cd ../../sch-rnd && make mod_sim Index: tags/1.0.5/src/plugins/sim/Plug.tmpasm =================================================================== --- tags/1.0.5/src/plugins/sim/Plug.tmpasm (nonexistent) +++ tags/1.0.5/src/plugins/sim/Plug.tmpasm (revision 10414) @@ -0,0 +1,18 @@ +put /local/rnd/mod {sim} +put /local/rnd/mod/OBJS [@ + $(PLUGDIR)/sim/sim.o + $(PLUGDIR)/sim/sim_conf.o + $(PLUGDIR)/sim/mods.o + $(PLUGDIR)/sim/util.o + $(PLUGDIR)/sim/actions.o +@] + +put /local/rnd/mod/CONFFILE {sim.conf} +put /local/rnd/mod/CONF {$(PLUGDIR)/sim/sim_conf.h} +put /local/rnd/mod/CONFVAR {sim_conf_internal} + +switch /local/module/sim/controls + case {buildin} include /local/csch/tmpasm/buildin; end; + case {plugin} include /local/csch/tmpasm/plugin; end; + case {disable} include /local/csch/tmpasm/disable; end; +end Index: tags/1.0.5/src/plugins/sim/actions.c =================================================================== --- tags/1.0.5/src/plugins/sim/actions.c (nonexistent) +++ tags/1.0.5/src/plugins/sim/actions.c (revision 10414) @@ -0,0 +1,347 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - high level sim (non-GUI) + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include + +#include +#include + +#include +#include +#include +#include "sim.h" +#include "sim_conf.h" +#include "util.h" + +#include "actions.h" + + +int sch_sim_activate(csch_project_t *prj, const char *sim_setup_name, const char *view_name, int compile_now) +{ + long view_id; + + /* this also switches to the first sheet of the project if needed */ + if (sch_sim_get_setup(prj, sim_setup_name, 0) == NULL) { + rnd_message(RND_MSG_ERROR, "sch_sim_activate: no such simulation setup: '%s'\n", sim_setup_name); + return -1; + } + + view_id = csch_view_get_id(prj, view_name); + + if (view_id < 0) { + rnd_message(RND_MSG_ERROR, "sch_sim_activate: no such view: '%s'\n", view_name); + return -1; + } + + rnd_conf_set(RND_CFR_CLI, "plugins/sim/active_setup", 0, sim_setup_name, RND_POL_OVERWRITE); + csch_view_activate(prj, view_id); + + if (compile_now) /* compile immediately */ + rnd_actionva(rnd_multi_get_current(), "CompileProject", NULL); + else /* trigger autocompilation restart */ + rnd_event(rnd_multi_get_current(), CSCH_EVENT_SHEET_EDITED, NULL); + + return 0; +} + + +sch_sim_setup_t *sch_sim_run_prepare(csch_project_t *prj, const char *setup_name) +{ + sch_sim_exec_t *se = sch_sim_get_sim_exec(prj, -1); + sch_sim_setup_t *ssu; + lht_node_t *nsetup, *noutput, *n; + int res = -1; + + if (se == NULL) { + rnd_message(RND_MSG_ERROR, "sim_dlg_run(): view does not have simulator execution bindings\n"); + return NULL; + } + + nsetup = sch_sim_get_setup(prj, setup_name, 0); + if ((nsetup == NULL) || (nsetup->type != LHT_HASH)) { + rnd_message(RND_MSG_ERROR, "sim_dlg_run(): failed to find setup called '%s'\n", setup_name); + return NULL; + } + + noutput = lht_dom_hash_get(nsetup, "output"); + if ((noutput == NULL) || (noutput->type != LHT_LIST)) { + rnd_message(RND_MSG_ERROR, "sim_dlg_run(): failed to find output list in setup called '%s'\n", setup_name); + return NULL; + } + + ssu = se->alloc(); + if (ssu == NULL) { + rnd_message(RND_MSG_ERROR, "sim_dlg_run(): failed to allocate simulator setup in execution\n"); + return NULL; + } + + if (se->add_circuit(ssu) != 0) { + rnd_message(RND_MSG_ERROR, "sim_dlg_run(): failed to add the circuit to the simulation setup\n"); + goto error; + } + + + res = 0; + + /* add output nodes */ + for(n = noutput->data.list.first; n != NULL; n = n->next) { + int erra, errp; + sch_sim_analysis_t *analysis; + sch_sim_presentation_t *pres; + + if (n->type != LHT_HASH) { + rnd_message(RND_MSG_ERROR, "sim_dlg_run(): output '%s' in sim setup '%s' is not a hash (ignoring node)\n", n->name, setup_name); + continue; + } + + analysis = calloc(sizeof(sch_sim_analysis_t), 1); + pres = calloc(sizeof(sch_sim_presentation_t), 1); + erra = sch_sim_analysis_build(analysis, prj->abst, n, 0); + if (erra != 0) + rnd_message(RND_MSG_ERROR, "sim_dlg_run(): output '%s' in sim setup '%s': failed to parse analysis\n", n->name, setup_name); + errp = sch_sim_presentation_build(pres, prj->abst, n, 0); + if (errp != 0) + rnd_message(RND_MSG_ERROR, "sim_dlg_run(): output '%s' in sim setup '%s': failed to parse presentation\n", n->name, setup_name); + + if (erra || errp) { + sch_sim_analysis_free(analysis); + sch_sim_presentation_free(pres); + free(analysis); + free(pres); + res = -1; + } + else if (se->add_output(ssu, analysis, pres) != 0) { + rnd_message(RND_MSG_ERROR, "sim_dlg_run(): output '%s' in sim setup '%s': failed to add output to the simulation\n", n->name, setup_name); + res = -1; + } + } + + + error:; + if (res != 0) { + se->free(ssu); + return NULL; + } + return ssu; +} + +int sch_sim_exec(csch_project_t *prj, sch_sim_setup_t *ssu) +{ + sch_sim_exec_t *se = sch_sim_get_sim_exec(prj, -1); + return se->exec(prj, ssu); +} + +void sch_sim_free(csch_project_t *prj, sch_sim_setup_t *ssu) +{ + sch_sim_exec_t *se = sch_sim_get_sim_exec(prj, -1); + se->free(ssu); +} + +static const char *x_axis_name(lht_node_t *nantype, const char **prev) +{ + static const char *unknown = "UNKNOWN"; + sch_sim_analysis_type_t ty; + + if ((nantype == NULL) || (nantype->type != LHT_TEXT)) + return unknown; + + ty = sch_sim_str2analysis_type(nantype->data.text.value); + if (ty == SCH_SIMAN_invalid) + return unknown; + + if (ty == SCH_SIMAN_PREVIOUS) { + if (*prev == NULL) + *prev = unknown; + return *prev; + } + + *prev = sch_siman_x_axis_name[ty]; + return *prev; +} + + +int sch_sim_save_text(rnd_design_t *dsg, sch_sim_setup_t *ssu, const char *setup_name, const char *ofn) +{ + csch_project_t *prj = (csch_project_t *)dsg->project; + sch_sim_exec_t *se = sch_sim_get_sim_exec(prj, -1); + FILE *f; + lht_node_t *nsetup, *nout, *no; + int idx; + const char *prev_xname = NULL; + + nsetup = sch_sim_get_setup(prj, setup_name, 0); + if ((nsetup == NULL) || (nsetup->type != LHT_HASH)) { + rnd_message(RND_MSG_ERROR, "sim_save: no such sim setup: %s\n", setup_name); + return -1; + } + + nout = lht_dom_hash_get(nsetup, "output"); + if ((nout == NULL) || (nout->type != LHT_LIST)) { + rnd_message(RND_MSG_ERROR, "sim_save: invalid output node in setup: %s\n", setup_name); + return -1; + } + + f = rnd_fopen(dsg, ofn, "w"); + if (f == NULL) { + rnd_message(RND_MSG_ERROR, "sim_save: failed to open %s for write\n", ofn); + return -1; + } + + fprintf(f, "Simulation setup: %s\n", setup_name); + for(no = nout->data.list.first, idx = 0; no != NULL; no = no->next, idx++) { + lht_node_t *npres, *nanalysis, *nantype, *n; + lht_dom_iterator_t it; + + fprintf(f, "\n Output: %s\n", no->name); + + if (no->type != LHT_HASH) continue; + + nanalysis = lht_dom_hash_get(no, "analysis"); + nantype = NULL; + if ((nanalysis != NULL) && (nanalysis->type == LHT_HASH)) { + nantype = lht_dom_hash_get(nanalysis, "type"); + fprintf(f, " analysis\n"); + fprintf(f, " config begin\n"); + for(n = lht_dom_first(&it, nanalysis); n != NULL; n = lht_dom_next(&it)) + if (n->type == LHT_TEXT) + fprintf(f, " %s=%s\n", n->name, n->data.text.value); + fprintf(f, " config end\n"); + } + + npres = lht_dom_hash_get(no, "presentation"); + if ((npres != NULL) && (npres->type == LHT_HASH)) { + lht_node_t *nprops; + + fprintf(f, " presentation\n"); + fprintf(f, " config begin\n"); + for(n = lht_dom_first(&it, npres); n != NULL; n = lht_dom_next(&it)) + if (n->type == LHT_TEXT) + fprintf(f, " %s=%s\n", n->name, n->data.text.value); + fprintf(f, " config end\n"); + + nprops = lht_dom_hash_get(npres, "props"); + if ((nprops != NULL) && (nprops->type == LHT_LIST)) { + fprintf(f, " props begin (columns)\n"); + fprintf(f, " x: %s\n", x_axis_name(nantype, &prev_xname)); + for(n = nprops->data.list.first; n != NULL; n = n->next) { + if (n->type == LHT_TEXT) + fprintf(f, " %s\n", n->data.text.value); + else + fprintf(f, " \n"); + } + fprintf(f, " props end\n"); + } + } + + if (se != NULL) { + void *stream = se->result_open(prj, ssu, idx); + if (stream != NULL) { + vts0_t cols = {0}; + fprintf(f, " data begin (first column is position on the x axis, the remaining columns are y values)\n"); + while(se->result_read(ssu, stream, &cols) == 0) { + long n; + fprintf(f, " %s", cols.array[cols.used-1]); + for(n = 0; n < cols.used-1; n++) + fprintf(f, " %s", cols.array[n]); + fprintf(f, "\n"); + } + fprintf(f, " data end\n"); + se->result_close(ssu, stream); + } + } + + } + + fclose(f); + return 0; +} + +const char csch_acts_SimActivate[] = "SimActivate(setup_name, view_name)"; +const char csch_acth_SimActivate[] = "Activate the simulation for the setup_name+veiw_name combo; setup_name is the name of the sim setup to use, view name is the name of a view that has a suitable sim target. Triggers timed autocompile.\n"; +fgw_error_t csch_act_SimActivate(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_design_t *dsg = RND_ACT_DESIGN; + csch_project_t *prj = (csch_project_t *)dsg->project; + const char *setup_name, *view_name; + + RND_ACT_CONVARG(1, FGW_STR, SimActivate, setup_name = argv[1].val.str); + RND_ACT_CONVARG(2, FGW_STR, SimActivate, view_name = argv[2].val.str); + + RND_ACT_IRES(sch_sim_activate(prj, setup_name, view_name, 0)); + return 0; +} + +const char csch_acts_SimRun[] = "SimRun(setup_name, view_name, [output_filename])"; +const char csch_acth_SimRun[] = "Activate and run the simulation, see SimActivate()\n"; +fgw_error_t csch_act_SimRun(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_design_t *dsg = RND_ACT_DESIGN; + csch_project_t *prj = (csch_project_t *)dsg->project; + const char *setup_name, *view_name, *outfn = "sim.txt"; + sch_sim_setup_t *ssu; + + RND_ACT_CONVARG(1, FGW_STR, SimRun, setup_name = argv[1].val.str); + RND_ACT_CONVARG(2, FGW_STR, SimRun, view_name = argv[2].val.str); + RND_ACT_MAY_CONVARG(3, FGW_STR, SimRun, outfn = argv[3].val.str); + + if (sch_sim_activate(prj, setup_name, view_name, 1) != 0) { + rnd_message(RND_MSG_ERROR, "Failed to activate simulation\n"); + RND_ACT_IRES(-1); + return 0; + } + + RND_ACT_IRES(0); + + ssu = sch_sim_run_prepare(prj, setup_name); + if (sch_sim_exec(prj, ssu) != 0) { + rnd_message(RND_MSG_ERROR, "Simulation failed\n"); + RND_ACT_IRES(-1); + } + + if (sch_sim_save_text(dsg, ssu, setup_name, outfn) == 0) + rnd_message(RND_MSG_INFO, "Simulation output written to file %s\n", outfn); + + sch_sim_free(prj, ssu); + return 0; +} + +static rnd_action_t sim_action_list[] = { + {"SimActivate", csch_act_SimActivate, csch_acth_SimActivate, csch_acts_SimActivate}, + {"SimRun", csch_act_SimRun, csch_acth_SimRun, csch_acts_SimRun} +}; + +void sch_sim_uninit_act(const char *sim_cookie) +{ + rnd_remove_actions_by_cookie(sim_cookie); +} + +void sch_sim_init_act(const char *sim_cookie) +{ + RND_REGISTER_ACTIONS(sim_action_list, sim_cookie); +} + Index: tags/1.0.5/src/plugins/sim/actions.h =================================================================== --- tags/1.0.5/src/plugins/sim/actions.h (nonexistent) +++ tags/1.0.5/src/plugins/sim/actions.h (revision 10414) @@ -0,0 +1,14 @@ +#include + + +/*** for direct calls from the sim_gui plugin ***/ +int sch_sim_activate(csch_project_t *prj, const char *sim_setup_name, const char *view_name, int compile_now); + +sch_sim_setup_t *sch_sim_run_prepare(csch_project_t *prj, const char *setup_name); +int sch_sim_exec(csch_project_t *prj, sch_sim_setup_t *ssu); +void sch_sim_free(csch_project_t *prj, sch_sim_setup_t *ssu); + + +/*** internal calls ***/ +void sch_sim_uninit_act(const char *sim_cookie); +void sch_sim_init_act(const char *sim_cookie); Index: tags/1.0.5/src/plugins/sim/mods.c =================================================================== --- tags/1.0.5/src/plugins/sim/mods.c (nonexistent) +++ tags/1.0.5/src/plugins/sim/mods.c (revision 10414) @@ -0,0 +1,396 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - high level sim (non-GUI) + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include + +#include +#include +#include +#include + +#include +#include + +#include "sim.h" +#include "sim_conf.h" + +#include "mods.h" + +static const char *get_node_str(lht_node_t *hash, const char *name) +{ + lht_node_t *nd; + assert(hash->type == LHT_HASH); + + nd = lht_dom_hash_get(hash, name); + if (nd == NULL) + return NULL; + + if (nd->type != LHT_TEXT) { + rnd_message(RND_MSG_ERROR, "sim mod execution: expected %s/%s to be a text node\n", hash->name, name); + return NULL; + } + + return nd->data.text.value; +} + +/* refdes-portname; sep is pointing to the '-' within addr; if sep is NULL + it is searched for */ +static csch_aport_t *lookup_port(csch_abstract_t *abst, const char *addr, const char *sep) +{ + csch_acomp_t *comp; + const char *pname; + char *cname; + + if (sep == NULL) + sep = strchr(addr, '-'); + + if (sep == NULL) + return NULL; + + cname = rnd_strndup(addr, sep-addr); + comp = csch_acomp_get(abst, cname); + free(cname); + + if (comp == NULL) + return NULL; + + pname = sep+1; + return csch_aport_get(abst, comp, pname, 0); +} + +csch_anet_t *sch_sim_lookup_net(csch_abstract_t *abst, const char *addr, int create) +{ + const char *sep = strchr(addr, '-'); + csch_anet_t *net; + csch_aport_t *port = NULL; + + /* if it has a dash, try comp-port first */ + if ((sep != NULL) && (sep > addr)) { + port = lookup_port(abst, addr, sep); + if ((port != NULL) && (port->conn.net != NULL)) + return port->conn.net; + + /* port is not connected anywhere, create a dummy net */ + new_dummy_net:; + { + char tmpname[128]; + + if (!create) { + rnd_message(RND_MSG_ERROR, "sim lookup_net(): can't find net '%s'\n", addr); + return NULL; + } + + abst->ucnt.wirenet++; + sprintf(tmpname, "__sim_net_%ld", abst->ucnt.wirenet); + net = csch_anet_new(abst, NULL, CSCH_ASCOPE_GLOBAL, tmpname, tmpname, 1); + if (net == NULL) + rnd_message(RND_MSG_ERROR, "sim lookup_net(): internal error: can't allocate new dummy net\n"); + if (port != NULL) { + if (csch_compile_connect_net_to(&net, &port->hdr, 0) != 0) + rnd_message(RND_MSG_ERROR, "sim lookup_net(): internal error: failed to connect port to new dummy net\n"); + } + return net; + } + } + + /* fall back to net */ + net = csch_anet_get(abst, addr); + if (net == NULL) + goto new_dummy_net; + + return net; +} + +static csch_ahdr_t *lookup_type_and_name(csch_abstract_t *abst, const char *type, const char *name) +{ + sch_sim_mod_target_type_t tt = sch_sim_str2mod_target_type(type); + + switch(tt) { + case SCH_SIMTT_COMP: return (csch_ahdr_t *)csch_acomp_get(abst, name); break; + case SCH_SIMTT_PORT: return (csch_ahdr_t *)lookup_port(abst, name, NULL); break; + case SCH_SIMTT_NET: return (csch_ahdr_t *)csch_anet_get(abst, name); break; + default: return NULL; + } + return NULL; +} + + +static int mod_do_add(csch_project_t *prj, csch_abstract_t *abst, sch_sim_exec_t *sim_exec, int eng_prio, lht_node_t *mod, long mod_idx) +{ + const char *device = get_node_str(mod, "device"), *addr; + const char *value = get_node_str(mod, "value"); + const char *name = get_node_str(mod, "name"); + const char *ac_value = get_node_str(mod, "ac_value"); + const char *stdf = get_node_str(mod, "tdf"); + sch_sim_mod_device_t dt = sch_sim_str2mod_device(device); + sch_sim_mod_tdf_t tdf = sch_sim_str2mod_tdf(stdf); + csch_source_arg_t *src; + csch_acomp_t *comp; + csch_aport_t *port; + csch_anet_t *net_pos, *net_neg; + char name_tmp[128]; + lht_node_t *tdf_params; + + if (dt == SCH_SIMDEV_invalid) { + rnd_message(RND_MSG_ERROR, "sim mod execution: expected %s/mods/add (mod #%ld): unknown device '%s'\n", mod->parent->parent->name, mod_idx, device); + return -1; + } + + if ((name == NULL) || (*name == '\0')) { + sprintf(name_tmp, "%c__sim_mod_%ld", device[0], mod_idx); + name = name_tmp; + } + comp = csch_acomp_get(abst, name); + if (comp == NULL) + comp = csch_acomp_new(abst, abst->hroot, CSCH_ASCOPE_GLOBAL, name, name); + + /* connect positive */ + addr = get_node_str(mod, "pos"); + if (addr == NULL) { + rnd_message(RND_MSG_ERROR, "sim mod execution: %s/mods/add (mod #%ld): positive pin is not connected anywhere\n", mod->parent->parent->name, mod_idx); + return -1; + } + + net_pos = sch_sim_lookup_net(abst, addr, 1); + if (net_pos == NULL) + return -1; + + port = csch_aport_get(abst, comp, "1", 1); + if (csch_compile_connect_net_to(&net_pos, &port->hdr, 0) != 0) { + rnd_message(RND_MSG_ERROR, "sim mod execution: %s/mods/add (mod #%ld): failed to connect positive pin '%s' to net '%s'\n", mod->parent->parent->name, mod_idx, addr, net_pos->name); + return -1; + } + + + /* connect negative */ + addr = get_node_str(mod, "neg"); + if (addr == NULL) { + net_neg = sch_sim_lookup_net(abst, "GND", 0); + if (net_neg == NULL) + net_neg = sch_sim_lookup_net(abst, "gnd", 0); + if (net_neg == NULL) { + rnd_message(RND_MSG_ERROR, "sim mod execution: %s/mods/add (mod #%ld): failed to find gnd net for implicit negative connection on pin '%s'\n", mod->parent->parent->name, mod_idx, addr); + return -1; + } + } + else + net_neg = sch_sim_lookup_net(abst, addr, 1); + + if (net_neg == NULL) { + rnd_message(RND_MSG_ERROR, "sim mod execution: %s/mods/add (mod #%ld): failed to find gnd net for negative connection on pin '%s' failed\n", mod->parent->parent->name, mod_idx, addr); + return -1; + } + + port = csch_aport_get(abst, comp, "2", 1); + if (csch_compile_connect_net_to(&net_neg, &port->hdr, 0) != 0) { + rnd_message(RND_MSG_ERROR, "sim mod execution: %s/mods/add (mod #%ld): failed to connect negative pin '%s' to net '%s'\n", mod->parent->parent->name, mod_idx, addr, net_pos->name); + return -1; + } + + src = csch_attrib_src_p("sim_mods", "'add' modifier"); + csch_attrib_set(&comp->hdr.attr, eng_prio + CSCH_PRI_PLUGIN_NORMAL, "name", name, src, NULL); + + tdf_params = lht_dom_hash_get(mod, "tdf_params"); + + if ((sim_exec != NULL) && (sim_exec->mod_add_params != NULL)) { + sim_exec->mod_add_params(prj, comp, dt, value, ac_value, tdf, tdf_params, eng_prio, mod, mod_idx); + } + else { + rnd_message(RND_MSG_ERROR, "mod_do_add(): sim_exec doesn't have mod_add_params(), %s is left without a value\n", name); + return -1; + } + + return 0; +} + + +static int mod_do_omit(csch_project_t *prj, csch_abstract_t *abst, sch_sim_exec_t *sim_exec, int eng_prio, lht_node_t *mod, long mod_idx) +{ + const char *type = get_node_str(mod, "type"); + const char *name = get_node_str(mod, "name"); + csch_ahdr_t *obj = lookup_type_and_name(abst, type, name); + csch_source_arg_t *src; + + if (obj != NULL) { + src = csch_attrib_src_p("sim_mods", "'omit' modifier"); + csch_attrib_set(&obj->attr, eng_prio + CSCH_PRI_PLUGIN_NORMAL, "omit", "yes", src, NULL); + csch_compile_update_obj_cache(obj); + } + else { + rnd_message(RND_MSG_ERROR, "sim mod execution: %s/mods/omit (mod #%ld): invalid or missing type or name\n", mod->parent->parent->name, mod_idx); + return -1; + } + + return 0; +} + +static int mod_do_edit_attr(csch_project_t *prj, csch_abstract_t *abst, sch_sim_exec_t *sim_exec, int eng_prio, lht_node_t *mod, long mod_idx) +{ + const char *type = get_node_str(mod, "type"); + const char *name = get_node_str(mod, "name"); + const char *key = get_node_str(mod, "key"); + const char *value = get_node_str(mod, "value"); + csch_ahdr_t *obj = lookup_type_and_name(abst, type, name); + csch_source_arg_t *src; + + if (obj == NULL) { + rnd_message(RND_MSG_ERROR, "sim mod execution: %s/mods/edit_attr (mod #%ld): invalid or missing type or name\n", mod->parent->parent->name, mod_idx); + return -1; + } + + if (key != NULL) + while(isspace(*key)) key++; + + if ((key == NULL) || (*key == '\0')) { + rnd_message(RND_MSG_ERROR, "sim mod execution: %s/mods/edit_attr (mod #%ld): missing or empty key\n", mod->parent->parent->name, mod_idx); + return -1; + } + + src = csch_attrib_src_p("sim_mods", "'edit_attr' modifier"); + csch_attrib_set(&obj->attr, eng_prio + CSCH_PRI_PLUGIN_NORMAL, key, value, src, NULL); + + return 0; +} + +static int mod_do_disconn(csch_project_t *prj, csch_abstract_t *abst, sch_sim_exec_t *sim_exec, int eng_prio, lht_node_t *mod, long mod_idx) +{ + const char *scomp = get_node_str(mod, "comp"); + const char *sport = get_node_str(mod, "port"); + csch_acomp_t *comp; + csch_aport_t *port; + + if (scomp != NULL) + while(isspace(*scomp)) scomp++; + + if (sport != NULL) + while(isspace(*sport)) sport++; + + + if ((scomp == NULL) || (*scomp == '\0')) { + rnd_message(RND_MSG_ERROR, "sim mod execution: %s/mods/disconn (mod #%ld): missing or comp\n", mod->parent->parent->name, mod_idx); + return -1; + } + + if ((sport == NULL) || (*sport == '\0')) { + rnd_message(RND_MSG_ERROR, "sim mod execution: %s/mods/disconn (mod #%ld): missing or port\n", mod->parent->parent->name, mod_idx); + return -1; + } + + comp = csch_acomp_get(abst, scomp); + if (comp == NULL) { + rnd_message(RND_MSG_ERROR, "sim mod execution: %s/mods/disconn (mod #%ld): component '%s' not found\n", mod->parent->parent->name, mod_idx, scomp); + return -1; + } + + port = csch_aport_get(abst, comp, sport, 0); + if (port == NULL) { + rnd_message(RND_MSG_ERROR, "sim mod execution: %s/mods/disconn (mod #%ld): port '%s' of component '%s' not found\n", mod->parent->parent->name, mod_idx, sport, scomp); + return -1; + } + + csch_compile_disconnect(&port->hdr); + + return 0; +} + +static int mod_do_temp(csch_project_t *prj, csch_abstract_t *abst, sch_sim_exec_t *sim_exec, int eng_prio, lht_node_t *mod, long mod_idx) +{ + fgw_arg_t val; + const char *scomp = get_node_str(mod, "temp"); + + + val.type = FGW_STR; + val.val.cstr = scomp; + if (sim_exec->set_global(abst, eng_prio, "temp", &val) != 0) { + rnd_message(RND_MSG_ERROR, "sim mod execution: %s/mods/temp (mod #%ld): sim backend failed to set temperature\n", mod->parent->parent->name, mod_idx); + return -1; + } + fgw_arg_free(&rnd_fgw, &val); + + return 0; +} + + +static int mod_perform(csch_project_t *prj, csch_abstract_t *abst, sch_sim_exec_t *sim_exec, int eng_prio, lht_node_t *mod, long mod_idx) +{ + sch_sim_mod_type_t t = sch_sim_str2mod_type(mod->name); + + switch(t) { + case SCH_SIMOD_ADD: return mod_do_add(prj, abst, sim_exec, eng_prio, mod, mod_idx); + case SCH_SIMOD_OMIT: return mod_do_omit(prj, abst, sim_exec, eng_prio, mod, mod_idx); + case SCH_SIMOD_EDIT_ATTR: return mod_do_edit_attr(prj, abst, sim_exec, eng_prio, mod, mod_idx); + case SCH_SIMOD_DISCON: return mod_do_disconn(prj, abst, sim_exec, eng_prio, mod, mod_idx); + case SCH_SIMOD_TEMP: return mod_do_temp(prj, abst, sim_exec, eng_prio, mod, mod_idx); + default: + rnd_message(RND_MSG_ERROR, "Can not perform modification for sim:\n'%s' is not a valid modifcation type\n", mod->name); + } + return -1; +} + +int sch_sim_mods_perform(csch_project_t *prj, const char *setup_name, csch_abstract_t *abst, sch_sim_exec_t *sim_exec, int eng_prio) +{ + lht_node_t *setup, *mods, *mod; + int res; + long idx; + + if (setup_name == NULL) + setup_name = sch_sim_conf.plugins.sim.active_setup; + + if ((setup_name == NULL) || (*setup_name == '\0')) { + rnd_message(RND_MSG_ERROR, "Failed to perform modifications for simulation setup:\nactive simulation setup name is empty\n"); + return -1; + } + + setup = sch_sim_get_setup(prj, setup_name, 0); + if (setup == NULL) { + rnd_message(RND_MSG_ERROR, "No such simulation setup: '%s'\n", setup_name); + return -1; + } + + mods = lht_dom_hash_get(setup, "mods"); + if (mods == NULL) + return 0; /* no mods */ + + if (mods->type != LHT_LIST) { + rnd_message(RND_MSG_ERROR, "The mods conf node in setup '%s' is not a list as it needs to be\n", setup_name); + return -1; + } + + res = 0; + for(mod = mods->data.list.first, idx = 0; mod != NULL; mod = mod->next, idx++) { + if (mod->type != LHT_HASH) { + rnd_message(RND_MSG_ERROR, "The mods conf node '%s' in setup '%s' must be a hash\n", mod->name, setup_name); + res = -1; + } + else + res |= mod_perform(prj, abst, sim_exec, eng_prio, mod, idx); + } + + return res; +} + Index: tags/1.0.5/src/plugins/sim/mods.h =================================================================== --- tags/1.0.5/src/plugins/sim/mods.h (nonexistent) +++ tags/1.0.5/src/plugins/sim/mods.h (revision 10414) @@ -0,0 +1,14 @@ +#include +#include +#include + +/* Look at the current project's setup called setup_name and execute all + the mods it has on abst. If setup_name is NULL, get it from the current + config. */ +int sch_sim_mods_perform(csch_project_t *prj, const char *setup_name, csch_abstract_t *abst, sch_sim_exec_t *sim_exec, int eng_prio); + + +/* Look up addr and return the corresponding network; addr is either a netname + or a component-port pair. If create is 1, enable creating new abstract nets, + else NULL is returned when net is not found */ +csch_anet_t *sch_sim_lookup_net(csch_abstract_t *abst, const char *addr, int create); Index: tags/1.0.5/src/plugins/sim/sim.c =================================================================== --- tags/1.0.5/src/plugins/sim/sim.c (nonexistent) +++ tags/1.0.5/src/plugins/sim/sim.c (revision 10414) @@ -0,0 +1,411 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - high level sim (non-GUI) + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "sim.h" + +#include "sim_conf.h" +#include "actions.h" +#include "conf_internal.c" + +static const char sim_cookie[] = "sim"; + +conf_sim_t sch_sim_conf; + +const char *sch_siman_names[] = { + "op", + "tran_lin", + "ac_dec", + "ac_oct", + "ac_lin", + "dc_lin", + "dc_disto_dec", + "dc_disto_oct", + "dc_disto_lin", + "dc_noise_dec", + "previous", + NULL +}; + +const char *sch_siman_description[] = { + "op: dc operating point", + "transient (linear)", + "ac (dec)", + "ac (oct)", + "ac (linear)", + "dc (linear)", + "dc distortion (dec)", + "dc distortion (oct)", + "dc distortion (lin)", + "dc noise (lin)", + "previous analysis", + NULL +}; + +const char *sch_siman_x_axis_name[] = { + "n/a (op)", + "time [s]", + "freq [Hz]", + "freq [Hz]", + "freq [Hz]", + "input value", + "freq [Hz]", + "freq [Hz]", + "freq [Hz]", + "n/a (noise)", + "n/a (prev)", + NULL +}; + +const int sch_siman_x_axis_log[] = { + -1, + 0, + 10, + 8, + 0, + 0, + 10, + 8, + 0, + 0, + -1, + -1, + -1 +}; + +const char *sch_simpres_names[] = { + "print", + "plot", + NULL +}; + +const char *sch_simmod_type_names[] = { + "add", + "omit", + "edit_attr", + "disconn", + "temp", + NULL +}; + +const char *sch_simmod_dev_names[] = { + "V", + "I", + "R", + "C", + "L", + NULL +}; + +const int sch_sim_device_has_ac[] = { + /* V */ 1, + /* I */ 1, + /* R */ 0, + /* C */ 0, + /* L */ 0 +}; + +const int sch_sim_device_has_tdf[] = { + /* V */ 1, + /* I */ 1, + /* R */ 0, + /* C */ 0, + /* L */ 0 +}; + +const char *sch_simmod_target_type_names[] = { + "comp", + "port", + "net", + NULL +}; + +const char *sch_simmod_tdf_names[] = { + "none", + "pulse", + "sin", + "exp", + "pwl", + NULL +}; + +static const sch_sim_mod_tdf_param_t tdf_none[] = { + {0} +}; + +static const sch_sim_mod_tdf_param_t tdf_pulse[] = { + {"V1", "Initial value [V,A]", 0}, + {"V2", "Pulsed value [V,A]", 0}, + {"TD", "Delay time [sec]", 1}, + {"TR", "Rise time [sec]", 1}, + {"TF", "Fall time [sec]", 1}, + {"PW", "Pulse width [sec]", 1}, + {"PER", "Period [sec]", 1}, + {0} +}; + +static const sch_sim_mod_tdf_param_t tdf_sin[] = { + {"VO", "Offset (vertical) [V,A]", 0}, + {"VA", "Amplitude [V,A]", 0}, + {"FREQ", "Frequency [Hz]", 1}, + {"TD", "Delay [sec]", 1}, + {"THETA", "Damping factor [sec]", 1}, + {0} +}; + +static const sch_sim_mod_tdf_param_t tdf_exp[] = { + {"V1", "Initial value [V,A]", 0}, + {"V2", "Pulsed value [V,A]", 0}, + {"TD1", "rise delay time [sec]", 1}, + {"TAU1", "rise time constant [sec]", 1}, + {"TD2", "fall delay time [sec]", 1}, + {"TAU2", "fall time constant [sec]", 1}, + {0} +}; + +static const sch_sim_mod_tdf_param_t tdf_pwl[] = { + {"TAB", "space sep list of time value pairs [sec V,A]", 0}, + {"r", "repeat initial section [sec]", 1}, /* empty or -1: no repeat; else */ + {"td", "delay the whole signal [sec]", 1}, + {0} +}; + + +const sch_sim_mod_tdf_param_t *sch_sim_mod_tdf_params[] = { + tdf_none, + tdf_pulse, + tdf_sin, + tdf_exp, + tdf_pwl, + NULL +}; + +sch_sim_exec_t *sch_sim_get_sim_exec(csch_project_t *proj, int viewid) +{ + csch_view_t *view; + void **v; + int argc = 1; + long n; + fgw_arg_t argv[2], ares; + + if (viewid < 0) + viewid = proj->curr; + + v = vtp0_get(&proj->views, viewid, 0); + if (v == NULL) + return NULL; + view = *v; + + argv[1].type = 0; /* avoid invalid memory handling in corner case */ + + for(n = 0; n < view->engines.used; n++) { + csch_view_eng_t *eng = view->engines.array[n]; + fgw_func_t *hk = fgw_func_lookup_in(eng->obj, "sim_exec_get"); + + if (hk == NULL) + continue; + + ares.type = FGW_PTR | FGW_STRUCT; + ares.val.ptr_void = NULL; + argv[0].type = FGW_FUNC; + argv[0].val.argv0.func = hk; + if (hk->func(&ares, argc, argv) == 0) { + if ((ares.type & (FGW_PTR | FGW_STRUCT)) == (FGW_PTR | FGW_STRUCT)) { + void *tmp = ares.val.ptr_void; + ares.val.ptr_void = NULL; + fgw_argv_free(&view->fgw_ctx, argc, argv); + fgw_arg_free(&view->fgw_ctx, &ares); + return tmp; + } + fgw_arg_free(&view->fgw_ctx, &ares); + } + } + + fgw_argv_free(&view->fgw_ctx, argc, argv); + return NULL; +} + +sch_sim_analysis_type_t sch_sim_str2analysis_type(const char *stype) +{ + if ((stype == NULL) || (*stype == '\0')) + return SCH_SIMAN_invalid; + + if ((stype[0] == 'o') && (stype[1] == 'p') && (stype[2] == '\0')) + return SCH_SIMAN_OP; + + if (stype[0] == 't') { + stype++; + if (strcmp(stype, "ran") == 0) return SCH_SIMAN_TRAN_LIN; + if (strcmp(stype, "ran_lin") == 0) return SCH_SIMAN_TRAN_LIN; + return SCH_SIMAN_invalid; + } + + if ((stype[0] == 'a') && (stype[1] == 'c') && (stype[2] == '_')) { + stype += 3; + if (strcmp(stype, "dec") == 0) return SCH_SIMAN_AC_DEC; + if (strcmp(stype, "oct") == 0) return SCH_SIMAN_AC_OCT; + if (strcmp(stype, "lin") == 0) return SCH_SIMAN_AC_LIN; + return SCH_SIMAN_invalid; + } + + if ((stype[0] == 'd') && (stype[1] == 'c') && (stype[2] == '_')) { + stype += 3; + if (strcmp(stype, "lin") == 0) return SCH_SIMAN_DC_LIN; + if (stype[0] == 'd') { + stype++; + if (strcmp(stype, "isto_dec") == 0) return SCH_SIMAN_DC_DISTO_DEC; + if (strcmp(stype, "isto_oct") == 0) return SCH_SIMAN_DC_DISTO_OCT; + if (strcmp(stype, "isto_lin") == 0) return SCH_SIMAN_DC_DISTO_LIN; + return SCH_SIMAN_invalid; + } + if (strcmp(stype, "noise_dec") == 0) return SCH_SIMAN_DC_NOISE_DEC; + + return SCH_SIMAN_invalid; + } + + if ((stype[0] == 'p') && (strcmp(stype, "previous") == 0)) + return SCH_SIMAN_PREVIOUS; + + return SCH_SIMAN_invalid; +} + +sch_sim_mod_type_t sch_sim_str2mod_type(const char *mtype) +{ + if (mtype == NULL) + return SCH_SIMOD_invalid; + + switch(*mtype) { + case 'a': if (strcmp(mtype, "add") == 0) return SCH_SIMOD_ADD; + case 'o': if (strcmp(mtype, "omit") == 0) return SCH_SIMOD_OMIT; + case 'e': if (strcmp(mtype, "edit_attr") == 0) return SCH_SIMOD_EDIT_ATTR; + case 'd': if (strcmp(mtype, "disconn") == 0) return SCH_SIMOD_DISCON; + case 't': if (strcmp(mtype, "temp") == 0) return SCH_SIMOD_TEMP; + } + + return SCH_SIMOD_invalid; +} + +sch_sim_mod_device_t sch_sim_str2mod_device(const char *mdev) +{ + if ((mdev == NULL) || (mdev[0] == '\0') || (mdev[1] != '\0')) + return SCH_SIMDEV_invalid; + + switch(*mdev) { + case 'V': return SCH_SIMDEV_V; + case 'I': return SCH_SIMDEV_I; + case 'R': return SCH_SIMDEV_R; + case 'C': return SCH_SIMDEV_C; + case 'L': return SCH_SIMDEV_L; + } + + return SCH_SIMDEV_invalid; +} + +sch_sim_presentation_type_t sch_sim_str2presentation_type(const char *ptype) +{ + if ((ptype == NULL) || (*ptype == '\0')) + return SCH_SIMPRES_invalid; + + switch(*ptype) { + case 'p': + if (strcmp(ptype, "print") == 0) return SCH_SIMPRES_PRINT; + if (strcmp(ptype, "plot") == 0) return SCH_SIMPRES_PLOT; + return SCH_SIMPRES_invalid; + } + + return SCH_SIMPRES_invalid; +} + +sch_sim_mod_tdf_t sch_sim_str2mod_tdf(const char *tdf) +{ + if ((tdf == NULL) || (*tdf == '\0')) + return SCH_SIMTDF_NONE; + + switch(*tdf) { + case 'n': if (strcmp(tdf, "none") == 0) return SCH_SIMTDF_NONE; + case 's': if (strcmp(tdf, "sin") == 0) return SCH_SIMTDF_SIN; + case 'e': if (strcmp(tdf, "exp") == 0) return SCH_SIMTDF_EXP; + case 'p': + if (strcmp(tdf, "pulse") == 0) return SCH_SIMTDF_PULSE; + if (strcmp(tdf, "pwl") == 0) return SCH_SIMTDF_PWL; + break; + } + + return SCH_SIMTDF_invalid; +} + +sch_sim_mod_target_type_t sch_sim_str2mod_target_type(const char *typ) +{ + if ((typ == NULL) || (*typ == '\0')) + return SCH_SIMTT_invalid; + + switch(*typ) { + case 'c': if (strcmp(typ, "comp") == 0) return SCH_SIMTT_COMP; + case 'p': if (strcmp(typ, "port") == 0) return SCH_SIMTT_PORT; + case 'n': if (strcmp(typ, "net") == 0) return SCH_SIMTT_NET; + } + + return SCH_SIMTT_invalid; +} + +#ifndef DOC_ONLY + +int pplg_check_ver_sim(int ver_needed) { return 0; } + +void pplg_uninit_sim(void) +{ + rnd_conf_plug_unreg("plugins/sim/", sim_conf_internal, sim_cookie); + sch_sim_uninit_act(sim_cookie); +} + +int pplg_init_sim(void) +{ + RND_API_CHK_VER; + + rnd_conf_plug_reg(sch_sim_conf, sim_conf_internal, sim_cookie); +#define conf_reg(field,isarray,type_name,cpath,cname,desc,flags) \ + rnd_conf_reg_field(sch_sim_conf, field,isarray,type_name,cpath,cname,desc,flags); +#include "sim_conf_fields.h" + + sch_sim_init_act(sim_cookie); + + return 0; +} + +#endif Index: tags/1.0.5/src/plugins/sim/sim.conf =================================================================== --- tags/1.0.5/src/plugins/sim/sim.conf (nonexistent) +++ tags/1.0.5/src/plugins/sim/sim.conf (revision 10414) @@ -0,0 +1,10 @@ +li:pcb-rnd-conf-v1 { + ha:overwrite { + ha:plugins { + ha:sim { + li:setups { + } + } + } + } +} Index: tags/1.0.5/src/plugins/sim/sim.h =================================================================== --- tags/1.0.5/src/plugins/sim/sim.h (nonexistent) +++ tags/1.0.5/src/plugins/sim/sim.h (revision 10414) @@ -0,0 +1,244 @@ +#ifndef SCH_RND_SIM_H +#define SCH_RND_SIM_H + +#include +#include +#include + +/* setup: sim implementation specific opaque data for simulator state */ +typedef struct sch_sim_setup_s sch_sim_setup_t; + +/*** Mod(ification)s ***/ + +typedef enum sch_sim_mod_type_s { + SCH_SIMOD_ADD = 0, + SCH_SIMOD_OMIT, + SCH_SIMOD_EDIT_ATTR, + SCH_SIMOD_DISCON, + SCH_SIMOD_TEMP, + + SCH_SIMOD_invalid = -1 +} sch_sim_mod_type_t; + +extern const char *sch_simmod_type_names[]; +sch_sim_mod_type_t sch_sim_str2mod_type(const char *mtype); + +typedef enum sch_sim_mod_device_s { + SCH_SIMDEV_V, + SCH_SIMDEV_I, + SCH_SIMDEV_R, + SCH_SIMDEV_C, + SCH_SIMDEV_L, + + SCH_SIMDEV_max, + SCH_SIMDEV_invalid = -1 +} sch_sim_mod_device_t; + +extern const char *sch_simmod_dev_names[]; +sch_sim_mod_device_t sch_sim_str2mod_device(const char *mdev); +extern const int sch_sim_device_has_ac[]; /* 0 or 1 for each device above; tells whether the device has AC component */ +extern const int sch_sim_device_has_tdf[]; /* 0 or 1 for each device above; tells whether the device has TDF component */ + + +typedef enum sch_sim_mod_target_type_s { + SCH_SIMTT_COMP, + SCH_SIMTT_PORT, + SCH_SIMTT_NET, + SCH_SIMTT_invalid = -1 +} sch_sim_mod_target_type_t; + +extern const char *sch_simmod_target_type_names[]; +sch_sim_mod_target_type_t sch_sim_str2mod_target_type(const char *typ); + + +typedef enum sch_sim_mod_tdf_s { + SCH_SIMTDF_NONE, + SCH_SIMTDF_PULSE, + SCH_SIMTDF_SIN, + SCH_SIMTDF_EXP, + SCH_SIMTDF_PWL, + + + SCH_SIMTDF_max, + SCH_SIMTDF_invalid = -1 +} sch_sim_mod_tdf_t; + +extern const char *sch_simmod_tdf_names[]; +sch_sim_mod_tdf_t sch_sim_str2mod_tdf(const char *mtype); + +typedef struct sch_sim_mod_tdf_param_s { + const char *name; + const char *desc; + unsigned optional:1; +} sch_sim_mod_tdf_param_t; + +extern const sch_sim_mod_tdf_param_t *sch_sim_mod_tdf_params[]; /* indexed with sch_sim_mod_tdf_t */ + + +typedef struct sch_sim_mod_add_s { + sch_sim_mod_device_t device; + char *pos, *neg; /* terminal or network; if neg is not specified, gnd is assumed */ + char *val; /* main value; for V and I: dc component */ + + sch_sim_mod_tdf_t tdf; /* for V and I: name of the time dependant function */ + vts0_t *params; /* for tdf */ +} sch_sim_mod_add_t; + +typedef struct sch_sim_mod_omit_s { + sch_sim_mod_target_type_t type; /* should be comp or net */ + char *name; +} sch_sim_mod_omit_t; + +typedef struct sch_sim_edit_attr_s { + sch_sim_mod_target_type_t type; + char *name; + char *key; + char *val; +} sch_sim_mod_edit_attr_t; + +typedef struct sch_sim_mod_disconn_s { + char *comp_name, *port_name; +} sch_sim_mod_disconn_t; + +typedef struct sch_sim_mod_temp_s { + double C; /* temperature in celsius */ +} sch_sim_mod_temp_t; + +typedef struct sch_sim_mod_s { + sch_sim_mod_type_t type; + union { + sch_sim_mod_add_t add; + sch_sim_mod_omit_t omit; + sch_sim_mod_edit_attr_t edit_attr; + sch_sim_mod_disconn_t disconn; + sch_sim_mod_temp_t temp; + } data; +} sch_sim_mod_t; + +/*** Analysis ***/ + +typedef enum sch_sim_analysis_type_s { + SCH_SIMAN_invalid = -1, + + /* order and value does matter, see: + afld[], sch_siman_names[], sch_siman_description[] */ + SCH_SIMAN_OP = 0, /* dc operating point; no params */ + + /* transient; params: [start], stop, incr, [incr_max] */ + SCH_SIMAN_TRAN_LIN, + + /* frequency domain; params: numpt, start, stop */ + SCH_SIMAN_AC_DEC, + SCH_SIMAN_AC_OCT, + SCH_SIMAN_AC_LIN, + + /* dc transfer; params: src, start, stop, incr */ + SCH_SIMAN_DC_LIN, + + + /* distortion; params: numpt, start, stop */ + SCH_SIMAN_DC_DISTO_DEC, + SCH_SIMAN_DC_DISTO_OCT, + SCH_SIMAN_DC_DISTO_LIN, + + SCH_SIMAN_DC_NOISE_DEC, /* noise; params: port1, port2, numpt, start, stop */ + + SCH_SIMAN_PREVIOUS /* keep the results of the previous run but extract a different output */ + + + /* TODO: PZ (pole zero), sens, sp, tf */ +} sch_sim_analysis_type_t; + +extern const char *sch_siman_names[]; +extern const char *sch_siman_description[]; +extern const char *sch_siman_x_axis_name[]; +extern const int sch_siman_x_axis_log[]; /* 0 for lin; 10 or 8 for logarithmic, -1 for non-graph data */ + +sch_sim_analysis_type_t sch_sim_str2analysis_type(const char *stype); + + +typedef struct sch_sim_analysis_s { + sch_sim_analysis_type_t type; + char *start, *stop, *incr, *incr_max; /* measurement range */ + int numpt; /* number of points, per decade, per octave or over the range in LIN */ + char *src; + char *port1[2]; + char *port2[2]; + + void *user_data; +} sch_sim_analysis_t; + +/*** Presentation ***/ + +typedef enum sch_sim_presentation_type_s { + SCH_SIMPRES_PRINT, + SCH_SIMPRES_PLOT, + + SCH_SIMPRES_invalid = -1 +} sch_sim_presentation_type_t; +extern const char *sch_simpres_names[]; +sch_sim_presentation_type_t sch_sim_str2presentation_type(const char *ptype); + +typedef struct sch_sim_presentation_s { + sch_sim_presentation_type_t type; + vts0_t props; /* property names to print or plot (e.g. nodes) */ + + char *outfn; /* file anme of the output; used by the sim backend */ + + void *user_data; +} sch_sim_presentation_t; + +/*** Execution ***/ + +typedef struct sch_sim_exec_s { + const char *name; + + /* allocater (or free) a simulation setup for the currently active project (sheet) */ + sch_sim_setup_t *(*alloc)(void); + void (*free)(sch_sim_setup_t *setup); + + /* compile and export the current circuit; shall be called only once per setup */ + int (*set_global)(csch_abstract_t *abst, int eng_prio, const char *name, fgw_arg_t *val); + + /* compile and export the current circuit; shall be called only once per setup */ + int (*add_circuit)(sch_sim_setup_t *setup); + + /* add an output; can be called multiple times; an and pres are free'd by the + sim backend (immediately upon error or at ->free()) */ + int (*add_output)(sch_sim_setup_t *setup, sch_sim_analysis_t *an, sch_sim_presentation_t *pres); + + /* callback from the compiler: add mod 'add' value parameters to an abstract + component (should add attributes to comp) */ + void (*mod_add_params)(csch_project_t *prj, csch_acomp_t *comp, sch_sim_mod_device_t device, const char *value, const char *ac_value, sch_sim_mod_tdf_t tdf, lht_node_t *tdf_params, int eng_prio, lht_node_t *mod, long mod_idx); + + /* execute the setup as prepared */ + int (*exec)(csch_project_t *prj, sch_sim_setup_t *setup); + + + /*** accessors for data and plots ***/ + + /* open and close an opaque result stream; NULL means error */ + void *(*result_open)(csch_project_t *prj, sch_sim_setup_t *setup, int output_idx); + void (*result_close)(sch_sim_setup_t *setup, void *stream); + + /* read the next item of data into dst; the first N items of data are + the presentation props values, one item per prop. An extra item is + added at the end for time, when available. The stream is acquired from a + result_open earlier. Returns 0 on success, -1 on error or eof. The strings + in dst are owned by the sim backend and shall not be freed; they are + valud until the next call to any sim backend function. If dst is NULL, + no string is parsed or stored, but lines are read (useful for counting + lines of input) */ + int (*result_read)(sch_sim_setup_t *setup, void *stream, vts0_t *dst); + + /* Next call to result_read() will return the first line */ + void (*result_rewind)(sch_sim_setup_t *setup, void *stream); + + /* TODO: SOA (warnings; safe operating area) */ +} sch_sim_exec_t; + +/* If viewid is -1, use current view. Return NULL on error */ +sch_sim_exec_t *sch_sim_get_sim_exec(csch_project_t *proj, int viewid); + + +#endif Index: tags/1.0.5/src/plugins/sim/sim.pup =================================================================== --- tags/1.0.5/src/plugins/sim/sim.pup (nonexistent) +++ tags/1.0.5/src/plugins/sim/sim.pup (revision 10414) @@ -0,0 +1,7 @@ +$class feature +$short high level simulation +$long abstract differences of circuit simiulation implementations, provide an unified interface (infrastructure, CLI and actions) +$state works +$package sim +default buildin +autoload 1 Index: tags/1.0.5/src/plugins/sim/sim_conf.c =================================================================== --- tags/1.0.5/src/plugins/sim/sim_conf.c (nonexistent) +++ tags/1.0.5/src/plugins/sim/sim_conf.c (revision 10414) @@ -0,0 +1,227 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - high level sim (non-GUI) + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "sim.h" + +#include "sim_conf.h" + +#define MKDIR_ND(outnode, parent, ntype, nname, errinstr) \ +do { \ + lht_node_t *nnew; \ + lht_err_t err; \ + char *nname0 = (char *)nname; \ + if (parent->type == LHT_LIST) nname0 = rnd_concat(nname, ":0", NULL); \ + nnew = lht_tree_path_(parent->doc, parent, nname0, 1, 1, &err); \ + if (parent->type == LHT_LIST) free(nname0); \ + if ((nnew != NULL) && (nnew->type != ntype)) { \ + rnd_message(RND_MSG_ERROR, "Internal error: invalid existing node type for %s: %d, rule is NOT saved\n", nname, nnew->type); \ + errinstr; \ + } \ + else if (nnew == NULL) { \ + nnew = lht_dom_node_alloc(ntype, nname); \ + switch(parent->type) { \ + case LHT_HASH: err = lht_dom_hash_put(parent, nnew); break; \ + case LHT_LIST: err = lht_dom_list_append(parent, nnew); break; \ + default: \ + rnd_message(RND_MSG_ERROR, "Internal error: invalid parent node type for %s: %d, rule is NOT saved\n", parent->name, parent->type); \ + errinstr; \ + } \ + } \ + outnode = nnew; \ +} while(0) + + +lht_node_t *sch_sim_get_setup(csch_project_t *prj, const char *name, int create) +{ + rnd_design_t *dsg = rnd_multi_get_current(); + gdl_iterator_t it; + rnd_conf_listitem_t *i; + + if ((dsg == NULL) || (dsg->project != &prj->hdr)) { + rnd_trace("switching to project...\n"); + sch_rnd_multi_switch_to(prj->hdr.designs.array[0]); + dsg = rnd_multi_get_current(); + if (dsg->project != &prj->hdr) { + rnd_message(RND_MSG_ERROR, "sch_sim_get_setup(): failed to switch to project\n"); + return NULL; + } + } + + rnd_conflist_foreach(&SCH_SIM_CONF_SETUPS_CONLIST, &it, i) { + lht_node_t *nsetup = i->prop.src; + if ((nsetup != NULL) && (strcmp(nsetup->name, name) == 0)) + return nsetup; + } + + if (create) { + lht_node_t *nd = rnd_conf_lht_get_first_crpol(RND_CFR_PROJECT, RND_POL_OVERWRITE, 1); + if (nd == NULL) { + rnd_message(RND_MSG_ERROR, "Internal error: sch_sim_get_setup() failed to create root\n"); + return NULL; + } + MKDIR_ND(nd, nd, LHT_HASH, "plugins", goto error); + MKDIR_ND(nd, nd, LHT_HASH, "sim", goto error); + MKDIR_ND(nd, nd, LHT_LIST, "setups", goto error); + MKDIR_ND(nd, nd, LHT_HASH, name, goto error); + return nd; + } + + return NULL; + + error:; + rnd_message(RND_MSG_ERROR, "Internal error: sch_sim_get_setup() failed to create the config subtree\n"); + return NULL; +} + +lht_node_t *sch_sim_get_output(csch_project_t *prj, const char *setup_name, const char *output_name, int create) +{ + lht_node_t *n, *noutput, *nsetup = sch_sim_get_setup(prj, setup_name, create); + + if ((nsetup == NULL) || (nsetup->type != LHT_HASH)) + return NULL; + + noutput = lht_dom_hash_get(nsetup, "output"); + if ((noutput == NULL) || (noutput->type != LHT_LIST)) + return NULL; + + for(n = noutput->data.list.first; n != NULL; n = n->next) + if ((n->type == LHT_HASH) && (n->name != NULL) && (strcmp(n->name, output_name) == 0)) + return n; + + if (create) { + n = lht_dom_node_alloc(LHT_HASH, output_name); + lht_dom_list_append(noutput, n); + return n; + } + + return NULL; +} + + +int sch_sim_flush_prj_file(csch_project_t *prj) +{ + rnd_design_t *dsg = prj->hdr.designs.array[0]; + const char *try, *pfn; + + rnd_conf_makedirty(RND_CFR_PROJECT); + rnd_conf_update(NULL, -1); + + if ((dsg->loadname == NULL) || (*dsg->loadname == '<')) { + rnd_message(RND_MSG_ERROR, "Failed to determine project file name (save sheet first!)\n"); + return -1; + } + + pfn = rnd_conf_get_project_conf_name(prj->hdr.fullpath, dsg->loadname, &try); + if (pfn == NULL) { + FILE *f = rnd_fopen(dsg, try, "a"); + if (f == NULL) { + rnd_message(RND_MSG_ERROR, "Failed to create project file:\n%s\n", try); + return -1; + } + fclose(f); + } + + rnd_conf_save_file(dsg, prj->hdr.fullpath, dsg->loadname, RND_CFR_PROJECT, NULL); + return 0; +} + +int sch_sim_update_text_node(lht_node_t *parent_hash, const char *chname, const char *newval) +{ + lht_node_t *dst; + + if ((newval != NULL) && (*newval == '\0')) + newval = NULL; + + if ((parent_hash == NULL) || (parent_hash->type != LHT_HASH)) + return -1; + + dst = lht_dom_hash_get(parent_hash, chname); + + if (dst == NULL) { + if (newval != NULL) { + /* need to create the new node */ + dst = lht_dom_node_alloc(LHT_TEXT, chname); + dst->data.text.value = rnd_strdup(newval); + lht_dom_hash_put(parent_hash, dst); + } + return 1; + } + else { + const char *oldval = dst->data.text.value; + if (newval != NULL) { + if ((oldval == NULL) || (strcmp(oldval, newval) != 0)) { + free(dst->data.text.value); + dst->data.text.value = rnd_strdup(newval); + return 1; + } + } + else + lht_tree_del(dst); + } + + return 0; +} + +lht_node_t *sch_sim_lht_dom_hash_ensure(lht_node_t *parent_hash, lht_node_type_t type, const char *node_name) +{ + lht_node_t *n; + + if ((parent_hash == NULL) || (parent_hash->type != LHT_HASH)) + return NULL; + + n = lht_dom_hash_get(parent_hash, node_name); + if (n != NULL) { + if (n->type == type) + return n; + return NULL; + } + + n = lht_dom_node_alloc(type, node_name); + lht_dom_hash_put(parent_hash, n); + return n; +} + +void sch_sim_lht_dom_hash_clean(lht_node_t *hash) +{ + lht_dom_iterator_t it; + lht_node_t *n; + + while((n = lht_dom_first(&it, hash)) != NULL) + lht_tree_del(n); +} + Index: tags/1.0.5/src/plugins/sim/sim_conf.h =================================================================== --- tags/1.0.5/src/plugins/sim/sim_conf.h (nonexistent) +++ tags/1.0.5/src/plugins/sim/sim_conf.h (revision 10414) @@ -0,0 +1,53 @@ +#ifndef SCH_RND_SIM_CONF_H +#define SCH_RND_SIM_CONF_H + +#include +#include + +typedef struct { + const struct { + const struct { + RND_CFT_HLIST setups; /* simulation setups, insluding test bench spec and analysis and plot */ + RND_CFT_STRING active_setup; /* name of the setup last activated; used when compiling */ + RND_CFT_BOOLEAN preserve_tmp;/* do not remove the temp dir after executing the simulator; useful for debugging */ + } sim; + } plugins; +} conf_sim_t; + +extern conf_sim_t sch_sim_conf; + +#define SCH_SIM_CONF_SETUPS_PATH "plugins/sim/setups" + +/* evaluates to (rnd_conflist_t *) of the setups hlist */ +#define SCH_SIM_CONF_SETUPS_CONLIST sch_sim_conf.plugins.sim.setups + +/* Look up hashlist node for prj:name in setups. Switch to first sheet of + prj if prj is not the current project. If create is non-zero, create the + subtree in the project file's config if it does not exist. */ +lht_node_t *sch_sim_get_setup(csch_project_t *prj, const char *name, int create); + +/* Look up hashlist node for prj:setup:output. Switch to first sheet of + prj if prj is not the current project. If create is non-zero, create the + subtree in the project file's config if it does not exist. */ +lht_node_t *sch_sim_get_output(csch_project_t *prj, const char *setup_name, const char *output_name, int create); + +/* Merge all pending changes of the project config and save it in the + project file (create the file if needed). Return 0 on success. */ +int sch_sim_flush_prj_file(csch_project_t *prj); + +/* Make sure parent_hash has an LHT_TEXT child called chname with the value + newval. Returns: + 0: the node already exists and has the correct value + 1: the node had to be created or modified + -1: error (parent_hash doesn't exist or is not a hash) */ +int sch_sim_update_text_node(lht_node_t *parent_hash, const char *chname, const char *newval); + +/* Ensure the named child node of a hash exists and has the right type; + if it doesn't exist, create it. Returns NULL on error (parent_hash is not + a hash or child exists but has a different type) */ +lht_node_t *sch_sim_lht_dom_hash_ensure(lht_node_t *parent_hash, lht_node_type_t type, const char *node_name); + +/* Remove all children of hash */ +void sch_sim_lht_dom_hash_clean(lht_node_t *hash); + +#endif Index: tags/1.0.5/src/plugins/sim/util.c =================================================================== --- tags/1.0.5/src/plugins/sim/util.c (nonexistent) +++ tags/1.0.5/src/plugins/sim/util.c (revision 10414) @@ -0,0 +1,540 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - high level sim (non-GUI) + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "sim_conf.h" + +#include "util.h" + +static int skip_composite(lht_node_t *nmod, lht_node_t *n) +{ + if (strcmp(n->name, "tdf_params") == 0) { + n = lht_dom_hash_get(nmod, "tdf"); + if ((n == NULL) || (n->type != LHT_TEXT)) + return 0; + return (strcmp(n->data.text.value, "none") == 0); + } + return 0; +} + +static void render_text(gds_t *tmp, lht_node_t *n) +{ + gds_append_str(tmp, n->name); + gds_append(tmp, '='); + gds_append_str(tmp, n->data.text.value); +} + +static void render_composite(gds_t *tmp, lht_node_t *nd, const char *fld_sep) +{ + gds_append_str(tmp, nd->name); + gds_append(tmp, '='); + + if ((nd->type == LHT_HASH) || (nd->type == LHT_LIST)) { + lht_dom_iterator_t it; + lht_node_t *n; + int first = 1; + + gds_append(tmp, '{'); + for(n = lht_dom_first(&it, nd); n != NULL; n = lht_dom_next(&it)) { + if (!first) + gds_append_str(tmp, fld_sep); + if (n->type == LHT_TEXT) + render_text(tmp, n); + else + render_composite(tmp, n, fld_sep); + first = 0; + } + gds_append(tmp, '}'); + } + else + gds_append_str(tmp, ""); +} + +void sch_sim_append_print_mod(gds_t *tmp, lht_node_t *nmod, const char *fld_sep) +{ + int first = 1; + lht_node_t *n, *skip = NULL, *lead = NULL; + lht_dom_iterator_t it; + + assert(nmod->type == LHT_HASH); + + if (strcmp(nmod->name, "add") == 0) { + lht_node_t *ntype = lht_dom_hash_get(nmod, "type"), *ndev = lht_dom_hash_get(nmod, "device"); + + if (ntype != NULL) { + skip = ntype; + gds_append_str(tmp, ntype->data.text.value); + first = 0; + } + + if (ndev != NULL) { + lead = ndev; + gds_append_str(tmp, ndev->data.text.value); + first = 0; + } + } + + for(n = lht_dom_first(&it, nmod); n != NULL; n = lht_dom_next(&it)) { + if ((n == skip) || (n == lead)) + continue; + + if (!first) + gds_append_str(tmp, fld_sep); + if (n->type == LHT_TEXT) + render_text(tmp, n); + else if (!skip_composite(nmod, n)) + render_composite(tmp, n, fld_sep); + + first = 0; + } +} + +#define MAN SCH_SIMREQ_MANDATORY +#define OPT SCH_SIMREQ_OPTIONAL +#define NO SCH_SIMREQ_NO + +/* indexed by sch_sim_analysis_type_t */ +static const sch_sim_analysis_field_tab_t afld[] = { + /* start stop incr incr_max numpt port1 port2 src */ + /* SCH_SIMAN_OP */ {NO, NO, NO, NO, NO, NO, NO, NO}, + /* SCH_SIMAN_TRAN_LIN */ {OPT, MAN, MAN, OPT, NO, NO, NO, NO}, + /* SCH_SIMAN_AC_DEC */ {MAN, MAN, NO, NO, OPT, NO, NO, NO}, + /* SCH_SIMAN_AC_OCT */ {MAN, MAN, NO, NO, OPT, NO, NO, NO}, + /* SCH_SIMAN_AC_LIN */ {MAN, MAN, NO, NO, NO, NO, NO, NO}, + /* SCH_SIMAN_DC_LIN */ {MAN, MAN, MAN, NO, NO, NO, NO, MAN}, + /* SCH_SIMAN_DC_DISTO_DEC */ {MAN, MAN, NO, NO, OPT, NO, NO, NO}, + /* SCH_SIMAN_DC_DISTO_OCT */ {MAN, MAN, NO, NO, OPT, NO, NO, NO}, + /* SCH_SIMAN_DC_DISTO_LIN */ {MAN, MAN, NO, NO, NO, NO, NO, NO}, + /* SCH_SIMAN_DC_NOISE_DEC */ {MAN, MAN, NO, NO, MAN, MAN, MAN, NO}, + /* SCH_SIMAN_PREVIOUS */ {NO, NO, NO, NO, NO, NO, NO, NO} +}; + +#undef MAN +#undef OPT +#undef NO + +const sch_sim_analysis_field_tab_t *sch_sim_get_analysis_fieldreq(sch_sim_analysis_type_t type) +{ + if ((type < 0) || (type >= sizeof(afld)/sizeof(afld[0]))) + return NULL; + return &afld[type]; +} + +void sch_sim_analysis_free(sch_sim_analysis_t *sa) +{ + free(sa->start); sa->start = NULL; + free(sa->stop); sa->stop = NULL; + free(sa->incr); sa->incr = NULL; + free(sa->incr_max); sa->incr_max = NULL; + free(sa->src); + free(sa->port1[0]); sa->port1[0] = NULL; + free(sa->port1[1]); sa->port1[1] = NULL; + free(sa->port2[0]); sa->port2[0] = NULL; + free(sa->port2[1]); sa->port2[1] = NULL; + sa->type = 0; + sa->numpt = 0; +} + + +RND_INLINE int load_cstr(const char **dst, lht_node_t *nanalysis, const char *path, sch_sim_field_req_t req, int quiet) +{ + lht_node_t *nd = lht_dom_hash_get(nanalysis, path); + const char *tval = NULL; + + *dst = NULL; + + /* determine text value (tval) */ + if (nd != NULL) { + if (nd->type == LHT_TEXT) { + char *s = nd->data.text.value; + if (s == NULL) s = ""; + else while(isspace(*s)) s++; + if (*s == '\0') + tval = NULL; + else + tval = s; + } + } + + /* validate existence of the field */ + switch(req) { + case SCH_SIMREQ_NO: + if (tval != NULL) { + if (!quiet) rnd_message(RND_MSG_WARNING, "Ignoring configured %s for sim analysis %s\n(the specific analysis doesn't have such parameter)\n", path, nanalysis->name); + } + return 0; + + case SCH_SIMREQ_MANDATORY: + if (tval == NULL) { + if (!quiet) rnd_message(RND_MSG_ERROR, "analysis %s requires a %s field\n", nanalysis->name, path); + return -1; + } + break; + case SCH_SIMREQ_OPTIONAL: + /* okay either-way */ + break; + } + + *dst = tval; + return 0; +} + +static int load_str(char **dst, lht_node_t *nanalysis, const char *path, sch_sim_field_req_t req, int quiet) +{ + const char *tval; + + if (load_cstr(&tval, nanalysis, path, req, quiet) != 0) + return -1; + + *dst = (tval != NULL) ? rnd_strdup(tval) : NULL; + return 0; +} + + +static int load_int(int *dst, lht_node_t *nanalysis, const char *path, sch_sim_field_req_t req, int quiet) +{ + const char *tval; + char *end; + long l; + + *dst = 0; + + if (load_cstr(&tval, nanalysis, path, req, quiet) != 0) + return -1; + + if (tval == NULL) { + TODO("default numpts?"); + *dst = 4; + return 0; + } + + l = strtol(tval, &end, 10); + if (*end != '\0') { + if (!quiet) rnd_message(RND_MSG_ERROR, "analysis %s requires %s field to be an integer, but it is '%s' instead\n", nanalysis->name, path, tval); + return -1; + } + + *dst = l; + return 0; +} + +static int load_port(char *dst[2], lht_node_t *nanalysis, const char *path, const char *path_neg, sch_sim_field_req_t req, int quiet) +{ + int res1, res2; + + res1 = load_str(dst+0, nanalysis, path, req, quiet); + + /* the negative node is either not accepted or optional */ + if (req == SCH_SIMREQ_MANDATORY) + req = SCH_SIMREQ_OPTIONAL; + + res2 = load_str(dst+1, nanalysis, path_neg, req, quiet); + + if ((res1 != 0) || (res2 != 0)) + return -1; + + return 0; +} + +int sch_sim_analysis_build(sch_sim_analysis_t *dst, csch_abstract_t *abst, lht_node_t *noutput, int quiet) +{ + lht_node_t *nanalysis, *natype; + sch_sim_analysis_type_t atype; + const sch_sim_analysis_field_tab_t *reqs; + + memset(dst, 0, (char *)&dst->user_data - (char *)dst); + + if (noutput->type != LHT_HASH) + return -1; + + nanalysis = lht_dom_hash_get(noutput, "analysis"); + if ((nanalysis == NULL) || (nanalysis->type != LHT_HASH)) { + if (!quiet) rnd_message(RND_MSG_ERROR, "Invalid node analysis: must be exist and must be a hash\n"); + return -1; + } + + /* convert analysis type */ + natype = lht_dom_hash_get(nanalysis, "type"); + if ((natype == NULL) || (natype->type != LHT_TEXT)) { + if (!quiet) rnd_message(RND_MSG_ERROR, "Invalid node analysis/type: must exist and must be a text\n"); + return -1; + } + atype = sch_sim_str2analysis_type(natype->data.text.value); + if (atype == SCH_SIMAN_invalid) { + if (!quiet) rnd_message(RND_MSG_ERROR, "Invalid value of analysis/type (#1)\n"); + return -1; + } + + reqs = sch_sim_get_analysis_fieldreq(atype); + if (reqs == NULL) { + if (!quiet) rnd_message(RND_MSG_ERROR, "Invalid value of analysis/type (#2)\n"); + return -1; + } + + if (load_str(&dst->start, nanalysis, "start", reqs->start, quiet) != 0) goto error; + if (load_str(&dst->stop, nanalysis, "stop", reqs->stop, quiet) != 0) goto error; + if (load_str(&dst->incr, nanalysis, "incr", reqs->incr, quiet) != 0) goto error; + if (load_str(&dst->incr_max, nanalysis, "incr_max", reqs->incr_max, quiet) != 0) goto error; + if (load_int(&dst->numpt, nanalysis, "numpt", reqs->numpt, quiet) != 0) goto error; + if (load_str(&dst->src, nanalysis, "src", reqs->src, quiet) != 0) goto error; + if (load_port(dst->port1, nanalysis, "port1", "port1_neg", reqs->port1, quiet) != 0) goto error; + if (load_port(dst->port2, nanalysis, "port2", "port2_neg", reqs->port2, quiet) != 0) goto error; + + dst->type = atype; + + return 0; + error:; + sch_sim_analysis_free(dst); + return -1; +} + +static void free_strlist_items(vts0_t *dst) +{ + long n; + for(n = 0; n < dst->used; n++) + free(dst->array[n]); + dst->used = 0; +} + +static int load_strlist(vts0_t *dst, lht_node_t *npresentation, const char *path, sch_sim_field_req_t req, int quiet) +{ + lht_node_t *n, *nd = lht_dom_hash_get(npresentation, path); + + free_strlist_items(dst); + + if ((nd != NULL) && (nd->type != LHT_LIST)) + nd = NULL; + + /* validate existence of the field */ + switch(req) { + case SCH_SIMREQ_NO: + if (nd != NULL) { + if (!quiet) rnd_message(RND_MSG_WARNING, "Ignoring configured %s for sim presentation %s\n(the specific presentation doesn't have such parameter)\n", path, npresentation->name); + } + return 0; + + case SCH_SIMREQ_MANDATORY: + if (nd == NULL) { + if (!quiet) rnd_message(RND_MSG_ERROR, "presentations %s requires a %s field (list of text nodes)\n", npresentation->name, path); + return -1; + } + break; + case SCH_SIMREQ_OPTIONAL: + /* okay either-way */ + break; + } + + for(n = nd->data.list.first; n != NULL; n = n->next) { + if (n->type != LHT_TEXT) { + if (!quiet) rnd_message(RND_MSG_ERROR, "presentations %s's field %s needs to be a list containing text nodes\n", npresentation->name, path); + continue; + } + vts0_append(dst, rnd_strdup(n->data.text.value)); + } + + return 0; +} + +void sch_sim_presentation_free(sch_sim_presentation_t *sp) +{ + if (sp->outfn != NULL) + free(sp->outfn); + free_strlist_items(&sp->props); + vts0_uninit(&sp->props); +} + +int sch_sim_presentation_build(sch_sim_presentation_t *dst, csch_abstract_t *abst, lht_node_t *noutput, int quiet) +{ + lht_node_t *npresentation, *nptype; + sch_sim_presentation_type_t ptype; + + memset(dst, 0, (char *)&dst->user_data - (char *)dst); + + if (noutput->type != LHT_HASH) + return -1; + + npresentation = lht_dom_hash_get(noutput, "presentation"); + + if ((npresentation == NULL) || (npresentation->type != LHT_HASH)) { + if (!quiet) rnd_message(RND_MSG_ERROR, "Invalid node presentation: must exist and must be a hash\n"); + return -1; + } + + /* convert presentation type */ + nptype = lht_dom_hash_get(npresentation, "type"); + if ((nptype == NULL) || (nptype->type != LHT_TEXT)) { + if (!quiet) rnd_message(RND_MSG_ERROR, "Invalid node presentation/type: must exist and must be a text\n"); + return -1; + } + ptype = sch_sim_str2presentation_type(nptype->data.text.value); + if (ptype == SCH_SIMPRES_invalid) { + if (!quiet) rnd_message(RND_MSG_ERROR, "Invalid value of presentation/type\n"); + return -1; + } + + if (load_strlist(&dst->props, npresentation, "props", SCH_SIMREQ_MANDATORY, quiet) != 0) goto error; + + + switch(ptype) { + case SCH_SIMPRES_PRINT: + case SCH_SIMPRES_PLOT: + /* no extra fields */ + break; + case SCH_SIMPRES_invalid: + goto error; + } + + dst->type = ptype; + + return 0; + error:; + sch_sim_presentation_free(dst); + return -1; +} + + +void sch_sim_hook_eng_call(fgw_obj_t *obj, const char *funcname, fgw_error_t (**origf)(fgw_arg_t *, int , fgw_arg_t *), fgw_error_t (*newf)(fgw_arg_t *, int , fgw_arg_t *)) +{ + fgw_func_t *fun = fgw_func_lookup_in(obj, funcname); + if (fun != NULL) { + *origf = fun->func; + fgw_func_unreg(obj, funcname); + htsp_pop(&obj->func_tbl, funcname); + free(fun->name); + free(fun); + } + else + *origf = NULL; + + fgw_func_reg(obj, funcname, newf); +} + +void sch_sim_omit_no_test_bench_comp(csch_acomp_t *comp, int eng_prio) +{ + if (csch_attrib_get(&comp->hdr.attr, "forge-if/test_bench") == NULL) { + csch_source_arg_t *src; + src = csch_attrib_src_p("sim", "omit_no_test_bench"); + csch_attrib_set(&comp->hdr.attr, eng_prio + CSCH_PRI_PLUGIN_NORMAL, "omit", "yes", src, NULL); +/* csch_compile_update_obj_cache(&comp->hdr); -- no need to run this here, the compiler does it automatically*/ + } +} + +static void sch_sim_omit_no_test_bench_(csch_abstract_t *abst, int eng_prio) +{ + htsp_entry_t *e; + + for(e = htsp_first(&abst->comps); e != NULL; e = htsp_next(&abst->comps, e)) + sch_sim_omit_no_test_bench_comp(e->value, eng_prio); +} + +int sch_sim_omit_no_test_bench_is_on(csch_project_t *prj) +{ + int omit = 0; + lht_node_t *nsetup = sch_sim_get_setup(prj, sch_sim_conf.plugins.sim.active_setup, 0); + if ((nsetup != NULL) && (nsetup->type == LHT_HASH)) { + lht_node_t *nomit = lht_dom_hash_get(nsetup, "omit_no_test_bench"); + lht_node_t *ntb = lht_dom_hash_get(nsetup, "test_bench"); + int ntb_valid, nomit_valid; + + ntb_valid = ((ntb != NULL) && (ntb->type == LHT_TEXT)); + nomit_valid = ((nomit != NULL) && (nomit->type == LHT_TEXT)); + + omit = nomit_valid ? rnd_istrue(nomit->data.text.value) : 0; + + /* if whole circuit is selected, ignore the value of omit and never omit anything */ + if (!ntb_valid || *ntb->data.text.value == '\0') + omit = 0; + } + + return omit; +} + +void sch_sim_omit_no_test_bench(csch_project_t *prj, csch_abstract_t *abst, int engprio) +{ + /* apply the omit_no_test_bench directive */ + if (sch_sim_conf.plugins.sim.active_setup != NULL) { + if (sch_sim_omit_no_test_bench_is_on(prj)) + sch_sim_omit_no_test_bench_(abst, engprio); + } +} + +void sch_sim_set_test_bench(csch_project_t *prj, csch_abstract_t *abst, const char *cookie, int engprio) +{ + const char *new_tb = NULL; + int new_tb_valid = 0; + rnd_conf_native_t *nat; + + if (sch_sim_conf.plugins.sim.active_setup != NULL) { + lht_node_t *nsetup = sch_sim_get_setup(prj, sch_sim_conf.plugins.sim.active_setup, 0); + if ((nsetup != NULL) && (nsetup->type == LHT_HASH)) { + lht_node_t *ntb = lht_dom_hash_get(nsetup, "test_bench"); + + if ((ntb == NULL) || (ntb->type == LHT_TEXT)) + new_tb_valid = 1; + + if ((ntb != NULL) && (ntb->type == LHT_TEXT)) + new_tb = ntb->data.text.value; + } + } + + if (!new_tb_valid) + rnd_message(RND_MSG_INFO, "simulation setup has invalid test bench or simulation is not activated\n"); + + if ((new_tb != NULL) || (conf_core.stance.test_bench != NULL)) { + if (RND_NSTRCMP(conf_core.stance.test_bench, new_tb) != 0) + rnd_message(RND_MSG_INFO, "simulation target overrides test bench from '%s' to '%s'\n", RND_EMPTY(conf_core.stance.test_bench), RND_EMPTY(new_tb)); + } + + htpp_set(&abst->eng_transient, (void *)cookie, (void *)conf_core.stance.test_bench); + + nat = rnd_conf_get_field("stance/test_bench"); + nat->val.string[0] = new_tb; + rnd_conf_force_set_str(conf_core.stance.test_bench, new_tb); +} + + +void sch_sim_restore_test_bench(csch_project_t *prj, csch_abstract_t *abst, const char *cookie, int engprio) +{ + const char *old_tb; + rnd_conf_native_t *nat; + + old_tb = htpp_pop(&abst->eng_transient, (void *)cookie); + rnd_conf_force_set_str(conf_core.stance.test_bench, old_tb); + nat = rnd_conf_get_field("stance/test_bench"); + nat->val.string[0] = old_tb; +} + Index: tags/1.0.5/src/plugins/sim/util.h =================================================================== --- tags/1.0.5/src/plugins/sim/util.h (nonexistent) +++ tags/1.0.5/src/plugins/sim/util.h (revision 10414) @@ -0,0 +1,51 @@ +#include +#include +#include + +#include + +#include + +/* print the content of a sim mod item (hash) appending it to tmp */ +void sch_sim_append_print_mod(gds_t *tmp, lht_node_t *nmod, const char *fld_sep); + +/* Allocate and build an analysis or presentation from an named output lihata + subtree (of a sim setup). Returns 0 on success. */ +int sch_sim_analysis_build(sch_sim_analysis_t *dst, csch_abstract_t *abst, lht_node_t *noutput, int quiet); +int sch_sim_presentation_build(sch_sim_presentation_t *dst, csch_abstract_t *abst, lht_node_t *noutput, int quiet); + +/* Free all fields (but not the pointer itself) */ +void sch_sim_analysis_free(sch_sim_analysis_t *sa); +void sch_sim_presentation_free(sch_sim_presentation_t *sp); + + +typedef enum {SCH_SIMREQ_NO=0, SCH_SIMREQ_MANDATORY, SCH_SIMREQ_OPTIONAL} sch_sim_field_req_t; + +typedef struct { + sch_sim_field_req_t start, stop, incr, incr_max, numpt, port1, port2, src; +} sch_sim_analysis_field_tab_t; + +/* Return the field req table row for type; returns NULL if type is invalid */ +const sch_sim_analysis_field_tab_t *sch_sim_get_analysis_fieldreq(sch_sim_analysis_type_t type); + + +/* Replace funcname in obj with newf; save the original function in origf. + Useful for e.g. binding target_spice but then hooking into some of its + engine calls. */ +void sch_sim_hook_eng_call(fgw_obj_t *obj, const char *funcname, fgw_error_t (**origf)(fgw_arg_t *, int , fgw_arg_t *), fgw_error_t (*newf)(fgw_arg_t *, int , fgw_arg_t *)); + + +/* Called from compile_project_before and compile_project_after hooks of + sim_ngspice and sim_* backends in general, to temporarily change the + test bench for cmpilation as requested by the currently active sim setup + and then to restore the original value in the config after compilation*/ +void sch_sim_set_test_bench(csch_project_t *prj, csch_abstract_t *abst, const char *cookie, int engprio); +void sch_sim_restore_test_bench(csch_project_t *prj, csch_abstract_t *abst, const char *cookie, int engprio); + +/* Called in component0 to apply the omit_no_test_bench mechanism */ +void sch_sim_omit_no_test_bench_comp(csch_acomp_t *comp, int eng_prio); +void sch_sim_omit_no_test_bench_all(csch_project_t *prj, csch_abstract_t *abst, int engprio); + +/* Returns whether omit_no_test_bench is configured in the currently active + sim setup for prj */ +int sch_sim_omit_no_test_bench_is_on(csch_project_t *prj); Index: tags/1.0.5/src/plugins/sim_gui/Makefile =================================================================== --- tags/1.0.5/src/plugins/sim_gui/Makefile (nonexistent) +++ tags/1.0.5/src/plugins/sim_gui/Makefile (revision 10414) @@ -0,0 +1,2 @@ +all: + cd ../../sch-rnd && make mod_sim_gui Index: tags/1.0.5/src/plugins/sim_gui/Plug.tmpasm =================================================================== --- tags/1.0.5/src/plugins/sim_gui/Plug.tmpasm (nonexistent) +++ tags/1.0.5/src/plugins/sim_gui/Plug.tmpasm (revision 10414) @@ -0,0 +1,14 @@ +put /local/rnd/mod {sim_gui} +put /local/rnd/mod/OBJS [@ + $(PLUGDIR)/sim_gui/sim_gui.o +@] + +put /local/rnd/mod/CONFFILE {sim_gui.conf} +put /local/rnd/mod/CONF {$(PLUGDIR)/sim_gui/sim_gui_conf.h} +put /local/rnd/mod/CONFVAR {sim_gui_conf_internal} + +switch /local/module/sim_gui/controls + case {buildin} include /local/csch/tmpasm/buildin; end; + case {plugin} include /local/csch/tmpasm/plugin; end; + case {disable} include /local/csch/tmpasm/disable; end; +end Index: tags/1.0.5/src/plugins/sim_gui/plot_test.c =================================================================== --- tags/1.0.5/src/plugins/sim_gui/plot_test.c (nonexistent) +++ tags/1.0.5/src/plugins/sim_gui/plot_test.c (revision 10414) @@ -0,0 +1,103 @@ +#include +#include +#include +#include + +#include + +static long fnc_cos(long x) +{ + return cos((double)x/200.0) * 200.0; +} + +static long fnc_sq(long x) +{ + double tmp = (double)x / 100; + return tmp*tmp; +} + +static int fill(plot_trace_t *tr, plot_trdata_t *trdata, plot_which_t which, long from, long len, long (*fnc)(long x)) +{ + double tmp[1024]; + long n; + plot_pos_t pw; + + if (plot_write_init(&pw, tr, trdata, PLOT_MAIN, 0, 0, tmp, sizeof(tmp)/sizeof(tmp[0])) != 0) + return -1; + + for(n = 0; n < len; n++) + plot_write(&pw, fnc(n)); + + plot_flush(&pw); + return 0; +} + + + +typedef struct plotdlg_ctx_s { + RND_DAD_DECL_NOINIT(dlg) + plot_preview_t prv; + FILE *fc; +} plotdlg_ctx_t; + +static void plotdlg_close_cb(void *caller_data, rnd_hid_attr_ev_t ev) +{ + plotdlg_ctx_t *ctx = caller_data; + plot_data_uninit(&ctx->prv.pdata); + fclose(ctx->fc); + free(ctx); +} + +static void readout_cb(plot_preview_t *ctx, int trace_idx, long x, double y) +{ + rnd_trace("[%d] %d %f\n", trace_idx, x, y); +} + +static void plot_test_dlg(void) +{ + rnd_hid_dad_buttons_t clbtn[] = {{"Close", 0}, {NULL, 0}}; + plotdlg_ctx_t *ctx = calloc(sizeof(plotdlg_ctx_t), 1); + static rnd_box_t prvbb = {0, 0, 200*200, 200*200}; + plot_trace_t *tr; + plot_trdata_t *td; + + ctx->fc = rnd_fopen(NULL, "cache", "w+"); + ctx->prv.user_data = ctx; + ctx->prv.readout_cb = readout_cb; + plot_data_init(&ctx->prv.pdata, 2); + +#define LEN 10000 + + tr = &ctx->prv.pdata.trace[0]; + plot_trace_init(tr, ctx->fc); + td = plot_trdata_alloc(tr, 0, LEN); + fill(tr, td, PLOT_MAIN, 0, LEN, fnc_cos); + + tr = &ctx->prv.pdata.trace[1]; + plot_trace_init(tr, ctx->fc); + td = plot_trdata_alloc(tr, 0, LEN); + fill(tr, td, PLOT_MAIN, 0, LEN, fnc_sq); + + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + + RND_DAD_PREVIEW(ctx->dlg, plot_preview_expose_cb, plot_mouse_cb, NULL, NULL, &prvbb, 150, 150, &ctx->prv); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + + + RND_DAD_BUTTON_CLOSES(ctx->dlg, clbtn); + RND_DAD_END(ctx->dlg); + + RND_DAD_DEFSIZE(ctx->dlg, 200, 300); + RND_DAD_NEW("PlotTest", ctx->dlg, "Plot test", ctx, 0, plotdlg_close_cb); /* type=dummy */ + + +} + +const char csch_acts_PlotTest[] = "PlotTest()"; +const char csch_acth_PlotTest[] = "Open the plot test dialog\n"; +fgw_error_t csch_act_PlotTest(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + plot_test_dlg(); + return 0; +} Index: tags/1.0.5/src/plugins/sim_gui/sim_dlg.c =================================================================== --- tags/1.0.5/src/plugins/sim_gui/sim_dlg.c (nonexistent) +++ tags/1.0.5/src/plugins/sim_gui/sim_dlg.c (revision 10414) @@ -0,0 +1,270 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - high level sim, GUI + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "sim_setup_dlg.h" + +static const char sim_dlg_cookie[] = "sim_gui/sim_dlg"; + +typedef struct sim_dlg_ctx_s { + RND_DAD_DECL_NOINIT(dlg) + csch_project_t *prj; + int wlist; +} sim_dlg_ctx_t; + +static htpp_t prj2dlg; + +static void sim_dlg_close_cb(void *caller_data, rnd_hid_attr_ev_t ev) +{ + sim_dlg_ctx_t *ctx = caller_data; + + htpp_pop(&prj2dlg, ctx->prj); + free(ctx); +} + +static void sch_sim_sch2dlg(sim_dlg_ctx_t *ctx) +{ + rnd_hid_attribute_t *attr = &ctx->dlg[ctx->wlist]; + rnd_hid_tree_t *tree = attr->wdata; + rnd_hid_row_t *r; + char *cursor_path = NULL; + gdl_iterator_t it; + rnd_conf_listitem_t *i; + char *cell[2]; + + /* remember cursor */ + r = rnd_dad_tree_get_selected(attr); + if (r != NULL) + cursor_path = rnd_strdup(r->cell[0]); + + /* remove existing items and fill up with the new */ + rnd_dad_tree_clear(tree); + + /* fill in the table */ + cell[1] = NULL; + rnd_conflist_foreach(&SCH_SIM_CONF_SETUPS_CONLIST, &it, i) { + lht_node_t *nsetup = i->prop.src; + if (nsetup == NULL) continue; + cell[0] = rnd_strdup(nsetup->name); + rnd_dad_tree_append(attr, NULL, cell); + } + + /* restore cursor (will work only in non-modal upon project update from elsewhere) */ + if (cursor_path != NULL) { + rnd_hid_attr_val_t hv; + hv.str = cursor_path; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wlist, &hv); + free(cursor_path); + } +} + +static void dlg_sim_open_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr_btn) +{ + sim_dlg_ctx_t *ctx = caller_data; + rnd_hid_attribute_t *attr = &ctx->dlg[ctx->wlist]; + rnd_hid_row_t *r = rnd_dad_tree_get_selected(attr); + + if (r == NULL) { + rnd_message(RND_MSG_ERROR, "Select a simulation setup first!\n"); + return; + } + + sim_setup_dlg(ctx->prj, r->cell[0]); +} + +static void dlg_sim_new_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr_btn) +{ + sim_dlg_ctx_t *ctx = caller_data; + rnd_design_t *dsg = ctx->prj->hdr.designs.array[0]; + char *name; + lht_node_t *nold, *nnew; + + name = rnd_hid_prompt_for(dsg, "Name for the new simulation setup", NULL, "Simulation setup naming"); + if ((name == NULL) || (*name == '\0')) { + free(name); + return; /* cancel */ + } + nold = sch_sim_get_setup(ctx->prj, name, 0); + if (nold != NULL) { + rnd_message(RND_MSG_ERROR, "Setup of that name already exists\nPlease choose a different name\n"); + free(name); + return; + } + + nnew = sch_sim_get_setup(ctx->prj, name, 1); + if (nnew == NULL) { + rnd_message(RND_MSG_ERROR, "Failed to create new simulation setup\n"); + free(name); + return; + } + + sch_sim_flush_prj_file(ctx->prj); + sim_setup_dlg(ctx->prj, name); + free(name); +} + +static void dlg_sim_del_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr_btn) +{ + sim_dlg_ctx_t *ctx = caller_data; +/* rnd_design_t *dsg = ctx->prj->hdr.designs.array[0];*/ + rnd_hid_attribute_t *attr = &ctx->dlg[ctx->wlist]; + rnd_hid_row_t *r = rnd_dad_tree_get_selected(attr); + lht_node_t *nd; + + if (r == NULL) { + rnd_message(RND_MSG_ERROR, "Select a simulation setup first!\n"); + return; + } + + nd = sch_sim_get_setup(ctx->prj, r->cell[0], 0); + if (nd == NULL) { + rnd_message(RND_MSG_ERROR, "Failed to find simulation setup\n"); + return; + } + + sim_setup_dlg_setup_removed(nd->name); + + lht_tree_del(nd); + + sch_sim_flush_prj_file(ctx->prj); +} + + +static void sim_dlg(csch_project_t *prj) +{ + sim_dlg_ctx_t *ctx; + rnd_hid_dad_buttons_t clbtn[] = {{"Close", 0}, {NULL, 0}}; + + if (htpp_has(&prj2dlg, prj)) + return; + + ctx = calloc(sizeof(sim_dlg_ctx_t), 1); + ctx->prj = prj; + htpp_set(&prj2dlg, prj, ctx); + + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + + RND_DAD_TREE(ctx->dlg, 1, 0, NULL); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL | RND_HATF_SCROLL); + ctx->wlist = RND_DAD_CURRENT(ctx->dlg); + + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "Open..."); + RND_DAD_HELP(ctx->dlg, "Open the simulation setup dialog to edit or run the simulation"); + RND_DAD_CHANGE_CB(ctx->dlg, dlg_sim_open_cb); + RND_DAD_BUTTON(ctx->dlg, "New..."); + RND_DAD_HELP(ctx->dlg, "Create a new simulation setup and append to the list"); + RND_DAD_CHANGE_CB(ctx->dlg, dlg_sim_new_cb); + RND_DAD_BUTTON(ctx->dlg, "Remove"); + RND_DAD_HELP(ctx->dlg, "Remove selected simulation setup from the project config"); + RND_DAD_CHANGE_CB(ctx->dlg, dlg_sim_del_cb); + + RND_DAD_BEGIN_VBOX(ctx->dlg); /* spring */ + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_END(ctx->dlg); + + RND_DAD_BUTTON_CLOSES(ctx->dlg, clbtn); + RND_DAD_END(ctx->dlg); + + RND_DAD_END(ctx->dlg); + + RND_DAD_DEFSIZE(ctx->dlg, 300, 200); + RND_DAD_NEW("SimulationDialog", ctx->dlg, "Simulation selector", ctx, 0, sim_dlg_close_cb); /* type=local */ + + sch_sim_sch2dlg(ctx); +} + +const char csch_acts_SimDlg[] = "SimDlg()"; +const char csch_acth_SimDlg[] = "Open the sim(ulation) dialog\n"; +fgw_error_t csch_act_SimDlg(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_design_t *dsg = RND_ACT_DESIGN; + sim_dlg((csch_project_t *)dsg->project); + return 0; +} + +static void sim_dlg_cfgchg(rnd_conf_native_t *cfg, int v, void *user_data) +{ + rnd_design_t *dsg = rnd_multi_get_current(); + sim_dlg_ctx_t *ctx; + + if (dsg == NULL) + return; + ctx = htpp_get(&prj2dlg, dsg->project); + if (ctx != NULL) + sch_sim_sch2dlg(ctx); +} + +static void sim_dlg_prj_unload(rnd_project_t *prj) +{ + rnd_dad_retovr_t retovr = {0}; + sim_dlg_ctx_t *ctx = htpp_get(&prj2dlg, prj); + + /* close dialog referring to this project */ + if (ctx != NULL) + rnd_hid_dad_close(ctx->dlg_hid_ctx, &retovr, 0); +} + +static void sim_dlg_uninit(void) +{ + genht_uninit_deep(htpp, &prj2dlg, { + rnd_dad_retovr_t retovr = {0}; + sim_dlg_ctx_t *ctx = htent->value; + rnd_hid_dad_close(ctx->dlg_hid_ctx, &retovr, 0); + }); + + rnd_conf_hid_unreg(sim_dlg_cookie); +} + + +static void sim_dlg_init(void) +{ + static rnd_conf_hid_callbacks_t cbs; + static rnd_conf_hid_callbacks_t cbs2; + static rnd_conf_hid_id_t cfgid; + + htpp_init(&prj2dlg, ptrhash, ptrkeyeq); + + cfgid = rnd_conf_hid_reg(sim_dlg_cookie, &cbs); + cbs2.val_change_post = sim_dlg_cfgchg; + rnd_conf_hid_set_cb(rnd_conf_get_field("plugins/sim/setups"), cfgid, &cbs2); +} + Index: tags/1.0.5/src/plugins/sim_gui/sim_gui.c =================================================================== --- tags/1.0.5/src/plugins/sim_gui/sim_gui.c (nonexistent) +++ tags/1.0.5/src/plugins/sim_gui/sim_gui.c (revision 10414) @@ -0,0 +1,101 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - high level sim, GUI + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +static const char sim_gui_cookie[] = "sim_gui"; + +#include "sim_setup_dlg.h" + +#include "plot_test.c" +#include "sim_dlg.c" +#include "sim_setup_dlg.c" + +#include "sim_gui_conf.h" + +conf_sim_gui_t sch_sim_gui_conf; + +#include "conf_internal.c" + +static rnd_action_t sim_gui_action_list[] = { + {"SimDlg", csch_act_SimDlg, csch_acth_SimDlg, csch_acts_SimDlg}, + {"SimDialog", csch_act_SimDlg, csch_acth_SimDlg, csch_acts_SimDlg}, + {"SimSetupDlg", csch_act_SimSetupDlg, csch_acth_SimSetupDlg, csch_acts_SimSetupDlg}, + {"SimSetupDialog", csch_act_SimSetupDlg, csch_acth_SimSetupDlg, csch_acts_SimSetupDlg}, + {"PlotTest", csch_act_PlotTest, csch_acth_PlotTest, csch_acts_PlotTest} +}; + +static void sim_gui_sheet_pre_unload(rnd_design_t *dsg, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + if (dsg->project->designs.used == 1) { + /* last sheet being unloaded, the project becomes empty */ + sim_setup_dlg_prj_unload(dsg->project); + sim_dlg_prj_unload(dsg->project); + } +} + +int pplg_check_ver_sim_gui(int ver_needed) { return 0; } + +void pplg_uninit_sim_gui(void) +{ + rnd_remove_actions_by_cookie(sim_gui_cookie); + sim_dlg_uninit(); + sim_setup_dlg_uninit(); + rnd_event_unbind_allcookie(sim_gui_cookie); + rnd_conf_plug_unreg("plugins/sim_gui/", sim_gui_conf_internal, sim_gui_cookie); +} + +int pplg_init_sim_gui(void) +{ + RND_API_CHK_VER; + + rnd_conf_plug_reg(sch_sim_gui_conf, sim_gui_conf_internal, sim_gui_cookie); +#define conf_reg(field,isarray,type_name,cpath,cname,desc,flags) \ + rnd_conf_reg_field(sch_sim_gui_conf, field,isarray,type_name,cpath,cname,desc,flags); +#include "sim_gui_conf_fields.h" + + RND_REGISTER_ACTIONS(sim_gui_action_list, sim_gui_cookie); + + sim_dlg_init(); + sim_setup_dlg_init(); + + rnd_event_bind(CSCH_EVENT_SHEET_PREUNLOAD, sim_gui_sheet_pre_unload, NULL, sim_gui_cookie); + + return 0; +} + Index: tags/1.0.5/src/plugins/sim_gui/sim_gui.conf =================================================================== --- tags/1.0.5/src/plugins/sim_gui/sim_gui.conf (nonexistent) +++ tags/1.0.5/src/plugins/sim_gui/sim_gui.conf (revision 10414) @@ -0,0 +1,10 @@ +li:pcb-rnd-conf-v1 { + ha:overwrite { + ha:plugins { + ha:sim_gui { + plot_height_px = 200 + plot_grid_color = {#777777} + } + } + } +} Index: tags/1.0.5/src/plugins/sim_gui/sim_gui.pup =================================================================== --- tags/1.0.5/src/plugins/sim_gui/sim_gui.pup (nonexistent) +++ tags/1.0.5/src/plugins/sim_gui/sim_gui.pup (revision 10414) @@ -0,0 +1,10 @@ +$class feature +$short high level simulation GUI +$long GUI for the the a unified high level simulation interface +$state works +$package sim +default buildin +dep lib_plot +dep sim +dep sch_dialogs +autoload 1 Index: tags/1.0.5/src/plugins/sim_gui/sim_gui_conf.h =================================================================== --- tags/1.0.5/src/plugins/sim_gui/sim_gui_conf.h (nonexistent) +++ tags/1.0.5/src/plugins/sim_gui/sim_gui_conf.h (revision 10414) @@ -0,0 +1,18 @@ +#ifndef SCH_RND_SIM_GUI_CONF_H +#define SCH_RND_SIM_GUI_CONF_H + +#include +#include + +typedef struct { + const struct { + const struct { + RND_CFT_INTEGER plot_height_px; /* plot widget height in pixels */ + RND_CFT_COLOR plot_grid_color; /* color of the background grid drawn parallel to x and y axis to mark notable values */ + } sim_gui; + } plugins; +} conf_sim_gui_t; + +extern conf_sim_gui_t sch_sim_gui_conf; + +#endif Index: tags/1.0.5/src/plugins/sim_gui/sim_mod_dlg.c =================================================================== --- tags/1.0.5/src/plugins/sim_gui/sim_mod_dlg.c (nonexistent) +++ tags/1.0.5/src/plugins/sim_gui/sim_mod_dlg.c (revision 10414) @@ -0,0 +1,475 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - high level sim, GUI + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/* Simulation setup, sim modification edit dialog, #included */ + +#define MAX_TDF_PARAMS 8 + +typedef struct sim_mod_dlg_ctx_s { + RND_DAD_DECL_NOINIT(dlg) + lht_node_t *nmod; /* this works only because the dialog is modal and the node won't be deleted during operation */ + + int wtype; + int wadd_name, wadd_name_box; + int wadd_device, wadd_pos, wadd_neg; + int wadd_what, wadd_value; + int wadd_ac_value_box, wadd_ac_value; + int wadd_tdf_box, wadd_tdf; + int wadd_tdf_parkey[MAX_TDF_PARAMS], wadd_tdf_parval[MAX_TDF_PARAMS]; + int womit_type, womit_name; + int wattr_key, wattr_val; + int wdisc_comp, wdisc_port; + int wtemp_temp; + + int wbox_add, wbox_omit, wbox_edit_attr, wbox_disconn, wbox_temp; +} sim_mod_dlg_ctx_t; + +static void mod_uninit(sim_mod_dlg_ctx_t *ctx) +{ + +} + + +static void mod_update(sim_mod_dlg_ctx_t *ctx) +{ + int *show = NULL, has_name = 0; + rnd_hid_attr_val_t hv; + + /* arrange the right box to show, hide the rest */ + switch(ctx->dlg[ctx->wtype].val.lng) { + case SCH_SIMOD_ADD: show = &ctx->wbox_add; has_name = 1; break; + case SCH_SIMOD_OMIT: show = &ctx->wbox_omit; break; + case SCH_SIMOD_EDIT_ATTR: show = &ctx->wbox_edit_attr; break; + case SCH_SIMOD_DISCON: show = &ctx->wbox_disconn; break; + case SCH_SIMOD_TEMP: show = &ctx->wbox_temp; break; + } + + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wbox_add, (show != &ctx->wbox_add)); + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wbox_omit, (show != &ctx->wbox_omit) && (show != &ctx->wbox_edit_attr)); + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wbox_edit_attr, (show != &ctx->wbox_edit_attr)); + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wbox_disconn, (show != &ctx->wbox_disconn)); + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wbox_temp, (show != &ctx->wbox_temp)); + + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wadd_name_box, !has_name); + + + /* update type-specific fields and labels */ + switch(ctx->dlg[ctx->wtype].val.lng) { + case SCH_SIMOD_ADD: + { + int hide_ac = 1, hide_tdf = 1; + static const char *what_strs[] = { + /* V */ "voltage, dc value", + /* I */ "current, dc value", + /* R */ "resistance [ohm]", + /* C */ "capacitance [farad]", + /* L */ "inductace [henry]" + }; + int val = ctx->dlg[ctx->wadd_device].val.lng; + + if ((val >= 0) && (val < sizeof(what_strs)/sizeof(what_strs[0]))) { + hv.str = what_strs[val]; + hide_ac = !sch_sim_device_has_ac[val]; + hide_tdf = !sch_sim_device_has_tdf[val]; + } + else + hv.str = "(?)"; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wadd_what, &hv); + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wadd_ac_value_box, hide_ac); + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wadd_tdf_box, hide_tdf); + } + break; + } +} + +static void fillin_str(sim_mod_dlg_ctx_t *ctx, const char *confpath, int widx) +{ + rnd_hid_attr_val_t hv; + + hv.str = get_path_str(ctx->nmod, confpath, "", NULL); + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, widx, &hv); +} + +static void mod_conf2dlg_tdf(sim_mod_dlg_ctx_t *ctx) +{ + int n; + rnd_hid_attr_val_t hv; + sch_sim_mod_tdf_t tdf = ctx->dlg[ctx->wadd_tdf].val.lng; + const sch_sim_mod_tdf_param_t tp_none = {0}, *tp = &tp_none; + lht_node_t *ntdfp = lht_dom_hash_get(ctx->nmod, "tdf_params"); + gds_t tmp = {0}; + + if ((ntdfp != NULL) && (ntdfp->type != LHT_HASH)) + ntdfp = NULL; + + if ((tdf >= 0) && (tdf < SCH_SIMTDF_max)) + tp = sch_sim_mod_tdf_params[tdf]; + + for(n = 0; (n < MAX_TDF_PARAMS) && (tp->name != NULL); n++, tp++) { + tmp.used = 0; + gds_append_str(&tmp, tp->name); + gds_append_str(&tmp, " ("); + gds_append_str(&tmp, tp->desc); + gds_append(&tmp, ')'); + hv.str = tmp.array; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wadd_tdf_parkey[n], &hv); + + if (ntdfp != NULL) + hv.str = get_path_str(ntdfp, tp->name, "", NULL); + else + hv.str = ""; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wadd_tdf_parval[n], &hv); + + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wadd_tdf_parkey[n], 0); + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wadd_tdf_parval[n], 0); + } + + for(; n < MAX_TDF_PARAMS; n++) { + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wadd_tdf_parkey[n], 1); + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wadd_tdf_parval[n], 1); + } + + gds_uninit(&tmp); +} + +static void mod_dlg2conf_tdf(sim_mod_dlg_ctx_t *ctx, int del_all) +{ + sch_sim_mod_tdf_t tdf = ctx->dlg[ctx->wadd_tdf].val.lng; + lht_node_t *nd, *ntdfp = lht_dom_hash_get(ctx->nmod, "tdf_params"); + const sch_sim_mod_tdf_param_t *tp; + int n; + + if (ntdfp != NULL) + lht_tree_del(ntdfp); + + if (del_all) + return; + + ntdfp = lht_dom_node_alloc(LHT_HASH, "tdf_params"); + lht_dom_hash_put(ctx->nmod, ntdfp); + + if ((tdf < 0) || (tdf >= SCH_SIMTDF_max)) + return; /* leave ntdfp empty */ + + if ((tdf < 0) || (tdf >= SCH_SIMTDF_max)) + return; /* invalid */ + + tp = sch_sim_mod_tdf_params[tdf]; + + for(n = 0; (n < MAX_TDF_PARAMS); n++, tp++) { + const char *key = tp->name; + const char *val; + + if (key == NULL) + break; + + val = ctx->dlg[ctx->wadd_tdf_parval[n]].val.str; + if (val != NULL) { + nd = lht_dom_node_alloc(LHT_TEXT, key); + nd->data.text.value = rnd_strdup(val); + lht_dom_hash_put(ntdfp, nd); + } + } +} + + +static void mod_conf2dlg(sim_mod_dlg_ctx_t *ctx) +{ + rnd_hid_attr_val_t hv; + + hv.lng = sch_sim_str2mod_type(ctx->nmod->name); + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wtype, &hv); + + switch(ctx->dlg[ctx->wtype].val.lng) { + case SCH_SIMOD_ADD: + + hv.lng = sch_sim_str2mod_device(get_path_str(ctx->nmod, "device", NULL, NULL)); + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wadd_device, &hv); + + fillin_str(ctx, "pos", ctx->wadd_pos); + fillin_str(ctx, "neg", ctx->wadd_neg); + fillin_str(ctx, "value", ctx->wadd_value); + fillin_str(ctx, "name", ctx->wadd_name); + fillin_str(ctx, "ac_value", ctx->wadd_ac_value); + + hv.lng = sch_sim_str2mod_tdf(get_path_str(ctx->nmod, "tdf", NULL, NULL)); + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wadd_tdf, &hv); + + mod_conf2dlg_tdf(ctx); + break; + + case SCH_SIMOD_EDIT_ATTR: + fillin_str(ctx, "key", ctx->wattr_key); + fillin_str(ctx, "value", ctx->wattr_val); + /* fall thru for reusing widgets */ + + case SCH_SIMOD_OMIT: + hv.lng = sch_sim_str2mod_target_type(get_path_str(ctx->nmod, "type", NULL, NULL)); + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->womit_type, &hv); + + fillin_str(ctx, "name", ctx->womit_name); + + break; + case SCH_SIMOD_DISCON: + fillin_str(ctx, "comp", ctx->wdisc_comp); + fillin_str(ctx, "port", ctx->wdisc_port); + break; + + case SCH_SIMOD_TEMP: + fillin_str(ctx, "temp", ctx->wtemp_temp); + break; + } + + mod_update(ctx); +} + + +static void mod_dlg2conf(sim_mod_dlg_ctx_t *ctx) +{ + const char *str; + + switch(ctx->dlg[ctx->wtype].val.lng) { + case SCH_SIMOD_ADD: + str = ctx->dlg[ctx->wadd_device].val.lng < 0 ? NULL : sch_simmod_dev_names[ctx->dlg[ctx->wadd_device].val.lng]; + sch_sim_update_text_node(ctx->nmod, "device", str); + + sch_sim_update_text_node(ctx->nmod, "pos", ctx->dlg[ctx->wadd_pos].val.str); + sch_sim_update_text_node(ctx->nmod, "neg", ctx->dlg[ctx->wadd_neg].val.str); + sch_sim_update_text_node(ctx->nmod, "value", ctx->dlg[ctx->wadd_value].val.str); + sch_sim_update_text_node(ctx->nmod, "name", ctx->dlg[ctx->wadd_name].val.str); + + if ((ctx->dlg[ctx->wadd_device].val.lng >= 0) && sch_sim_device_has_ac[ctx->dlg[ctx->wadd_device].val.lng]) + sch_sim_update_text_node(ctx->nmod, "ac_value", ctx->dlg[ctx->wadd_ac_value].val.str); + else + sch_sim_update_text_node(ctx->nmod, "ac_value", NULL); + + if ((ctx->dlg[ctx->wadd_device].val.lng >= 0) && sch_sim_device_has_tdf[ctx->dlg[ctx->wadd_device].val.lng]) + str = ctx->dlg[ctx->wadd_tdf].val.lng < 0 ? NULL : sch_simmod_tdf_names[ctx->dlg[ctx->wadd_tdf].val.lng]; + else + str = NULL; + sch_sim_update_text_node(ctx->nmod, "tdf", str); + + mod_dlg2conf_tdf(ctx, ((ctx->dlg[ctx->wadd_device].val.lng < 0) || !sch_sim_device_has_tdf[ctx->dlg[ctx->wadd_device].val.lng])); + break; + + case SCH_SIMOD_EDIT_ATTR: + sch_sim_update_text_node(ctx->nmod, "key", ctx->dlg[ctx->wattr_key].val.str); + sch_sim_update_text_node(ctx->nmod, "value", ctx->dlg[ctx->wattr_val].val.str); + /* fall thru for reusing widgets */ + + case SCH_SIMOD_OMIT: + str = ctx->dlg[ctx->womit_type].val.lng < 0 ? NULL : sch_simmod_target_type_names[ctx->dlg[ctx->womit_type].val.lng]; + sch_sim_update_text_node(ctx->nmod, "type", str); + + sch_sim_update_text_node(ctx->nmod, "name", ctx->dlg[ctx->womit_name].val.str); + break; + case SCH_SIMOD_DISCON: + sch_sim_update_text_node(ctx->nmod, "comp", ctx->dlg[ctx->wdisc_comp].val.str); + sch_sim_update_text_node(ctx->nmod, "port", ctx->dlg[ctx->wdisc_port].val.str); + break; + case SCH_SIMOD_TEMP: + sch_sim_update_text_node(ctx->nmod, "temp", ctx->dlg[ctx->wtemp_temp].val.str); + break; + } +} + +static void mod_regen_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr_btn) +{ + sim_mod_dlg_ctx_t *ctx = caller_data; + mod_update(ctx); +} + +static void mod_type_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr_btn) +{ + const char *str; + sim_mod_dlg_ctx_t *ctx = caller_data; + /* when type is switched there would be some type-specific fields in the + config left over from the previous type; rather clean the hash */ + + sch_sim_lht_dom_hash_clean(ctx->nmod); + + str = ctx->dlg[ctx->wtype].val.lng < 0 ? NULL : sch_simmod_type_names[ctx->dlg[ctx->wtype].val.lng]; + + /* we can do this because our parent is not a hash */ + free(ctx->nmod->name); + ctx->nmod->name = rnd_strdup(str); + + mod_update(ctx); +} + +static void mod_tdf_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr_btn) +{ + sim_mod_dlg_ctx_t *ctx = caller_data; + mod_update(ctx); + mod_conf2dlg_tdf(ctx); +} + +int dlg_mod_edit(lht_node_t *nmod) +{ + sim_mod_dlg_ctx_t ctx_ = {0}, *ctx = &ctx_; + rnd_hid_dad_buttons_t clbtn[] = {{"Close", 0}, {NULL, 0}}; + int n; + + if ((nmod == NULL) || (nmod->type != LHT_HASH)) + return -1; + + ctx->nmod = nmod; + + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + + RND_DAD_ENUM(ctx->dlg, sch_simmod_type_names); + ctx->wtype = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_CHANGE_CB(ctx->dlg, mod_type_cb); + + RND_DAD_BEGIN_VBOX(ctx->dlg); /* add */ + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + ctx->wbox_add = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_ENUM(ctx->dlg, sch_simmod_dev_names); + ctx->wadd_device = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_CHANGE_CB(ctx->dlg, mod_regen_cb); + + RND_DAD_BEGIN_HBOX(ctx->dlg); + ctx->wadd_name_box = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Name (optional)"); + RND_DAD_LABEL(ctx->dlg, ":"); + RND_DAD_STRING(ctx->dlg); + ctx->wadd_name = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_END(ctx->dlg); + + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Connect positive to:"); + RND_DAD_STRING(ctx->dlg); + ctx->wadd_pos = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_END(ctx->dlg); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Connect negative to:"); + RND_DAD_STRING(ctx->dlg); + ctx->wadd_neg = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_END(ctx->dlg); + + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Value "); + RND_DAD_LABEL(ctx->dlg, "(what)"); + ctx->wadd_what = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, ":"); + RND_DAD_STRING(ctx->dlg); + ctx->wadd_value = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_END(ctx->dlg); + + + RND_DAD_BEGIN_HBOX(ctx->dlg); + ctx->wadd_ac_value_box = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "AC value:"); + RND_DAD_HELP(ctx->dlg, "set to AC magnitude (V or A) when this is the source for ac analysis"); + RND_DAD_STRING(ctx->dlg); + ctx->wadd_ac_value = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_END(ctx->dlg); + + RND_DAD_BEGIN_VBOX(ctx->dlg); + ctx->wadd_tdf_box = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Time dependent value:"); + RND_DAD_ENUM(ctx->dlg, sch_simmod_tdf_names); + ctx->wadd_tdf = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_CHANGE_CB(ctx->dlg, mod_tdf_cb); + RND_DAD_END(ctx->dlg); + + RND_DAD_BEGIN_TABLE(ctx->dlg, 2); + for(n = 0; n < MAX_TDF_PARAMS; n++) { + RND_DAD_LABEL(ctx->dlg, ""); + ctx->wadd_tdf_parkey[n] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_STRING(ctx->dlg); + ctx->wadd_tdf_parval[n] = RND_DAD_CURRENT(ctx->dlg); + } + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + + RND_DAD_BEGIN_HBOX(ctx->dlg); /* omit */ + ctx->wbox_omit = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_ENUM(ctx->dlg, sch_simmod_target_type_names); + ctx->womit_type = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_STRING(ctx->dlg); + ctx->womit_name = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_END(ctx->dlg); + + RND_DAD_BEGIN_VBOX(ctx->dlg); /* edit attr */ + ctx->wbox_edit_attr = RND_DAD_CURRENT(ctx->dlg); + /* NOTE: reuses target type from above */ + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Attribute key:"); + RND_DAD_STRING(ctx->dlg); + ctx->wattr_key = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_END(ctx->dlg); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Attribute value:"); + RND_DAD_STRING(ctx->dlg); + ctx->wattr_val = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + + RND_DAD_BEGIN_VBOX(ctx->dlg); /* disconn */ + ctx->wbox_disconn = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Component:"); + RND_DAD_STRING(ctx->dlg); + ctx->wdisc_comp = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_END(ctx->dlg); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Port name:"); + RND_DAD_STRING(ctx->dlg); + ctx->wdisc_port = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + + RND_DAD_BEGIN_VBOX(ctx->dlg); /* temp */ + ctx->wbox_temp = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Temperature in Celsius:"); + RND_DAD_STRING(ctx->dlg); + ctx->wtemp_temp = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + + RND_DAD_BUTTON_CLOSES(ctx->dlg, clbtn); + RND_DAD_END(ctx->dlg); + + RND_DAD_DEFSIZE(ctx->dlg, 300, 300); + RND_DAD_NEW("SimModConfig", ctx->dlg, "Simulation mod(ification) config", ctx, 1, NULL); /* type=local/modal */ + + mod_conf2dlg(ctx); + RND_DAD_RUN(ctx->dlg); + mod_dlg2conf(ctx); + RND_DAD_FREE(ctx->dlg); + + mod_uninit(ctx); + + return -1; +} + Index: tags/1.0.5/src/plugins/sim_gui/sim_outcfg_dlg.c =================================================================== --- tags/1.0.5/src/plugins/sim_gui/sim_outcfg_dlg.c (nonexistent) +++ tags/1.0.5/src/plugins/sim_gui/sim_outcfg_dlg.c (revision 10414) @@ -0,0 +1,579 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - high level sim, GUI + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/* Simulation setup, output config edit dialog, #included */ + +#include + +typedef struct { + int wbox; /* widget of the whole box */ + int winp; /* widget of the main input */ + int winp2; /* widget of the the secondary input (neg ports) */ + int wopt; /* the "optional" text */ + int is_int; /* if input is an integer */ + size_t req_offs; + const char *conf_name, *conf_name2; +} ocfg_field_t; + +#define NUM_FIELDS 8 + +typedef struct ocfg_dlg_ctx_s { + RND_DAD_DECL_NOINIT(dlg) + csch_project_t *prj; + char *setup_name; + lht_node_t *noutput, *nanalysis, *npresentation; + ocfg_field_t fld_analisys[NUM_FIELDS]; + int watype; + int wptype, wplist; +} ocfg_dlg_ctx_t; + +static void outcfg_uninit(ocfg_dlg_ctx_t *ctx) +{ + free(ctx->setup_name); +} + +static void outcfg_conf2dlg_analysis(ocfg_dlg_ctx_t *ctx) +{ + sch_sim_analysis_type_t type; + const sch_sim_analysis_field_tab_t *tab, tab_inval = {0}; + const char *tmp; + ocfg_field_t *fld; + rnd_hid_attr_val_t hv; + int n; + + tmp = get_path_str(ctx->nanalysis, "type", NULL, NULL); + type = sch_sim_str2analysis_type(tmp); + tab = sch_sim_get_analysis_fieldreq(type); + if (tab == NULL) + tab = &tab_inval; + + hv.lng = type; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->watype, &hv); + + for(n = 0, fld = ctx->fld_analisys; n < NUM_FIELDS; n++, fld++) { + sch_sim_field_req_t *req = (sch_sim_field_req_t *)((char *)tab + fld->req_offs); + int hide, opt; + + switch(*req) { + case SCH_SIMREQ_NO: hide = 1; break; + case SCH_SIMREQ_MANDATORY: hide = 0; opt = 0; break; + case SCH_SIMREQ_OPTIONAL: hide = 0; opt = 1; break; + } + + tmp = get_path_str(ctx->nanalysis, fld->conf_name, NULL, NULL); + if (fld->is_int) { + if (tmp != NULL) + hv.lng = strtol(tmp, NULL, 0); + else + hv.lng = 10; /* default val */ + } + else { + if (tmp == NULL) + tmp = ""; + hv.str = tmp; + } + + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, fld->winp, &hv); + + if (fld->wbox != 0) + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, fld->wbox, hide); + if (fld->wopt != 0) + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, fld->wopt, !opt); + } +} + +static int outcfg_dlg2conf_analysis(ocfg_dlg_ctx_t *ctx) +{ + int n, changed = 0; + const char *santype; + const char *inp; + char inp_tmp[128]; + const sch_sim_analysis_field_tab_t *tab; + ocfg_field_t *fld; + + tab = sch_sim_get_analysis_fieldreq(ctx->dlg[ctx->watype].val.lng); + if (tab == NULL) + return 0; + + santype = sch_siman_names[ctx->dlg[ctx->watype].val.lng]; + + switch(sch_sim_update_text_node(ctx->nanalysis, "type", santype)) { + case 0: break; + case 1: changed = 1; break; + case -1: rnd_message(RND_MSG_ERROR, "Failed to set analysis conf field: type\n"); break; + } + + for(n = 0, fld = ctx->fld_analisys; n < NUM_FIELDS; n++, fld++) { + sch_sim_field_req_t *req = (sch_sim_field_req_t *)((char *)tab + fld->req_offs); + int hide; + + switch(*req) { + case SCH_SIMREQ_NO: hide = 1; break; + case SCH_SIMREQ_MANDATORY: hide = 0; break; + case SCH_SIMREQ_OPTIONAL: hide = 0; break; + } + + if (!hide) { + if (fld->is_int) { + sprintf(inp_tmp, "%ld", ctx->dlg[fld->winp].val.lng); + inp = inp_tmp; + } + else + inp = ctx->dlg[fld->winp].val.str; + } + else + inp = NULL; + + switch(sch_sim_update_text_node(ctx->nanalysis, fld->conf_name, inp)) { + case 0: break; + case 1: changed = 1; break; + case -1: rnd_message(RND_MSG_ERROR, "Failed to set analysis conf node %s\n", fld->conf_name); break; + } + } + + return changed; +} + +static int is_log(const char *s) +{ + if (s == NULL) return 0; + return (strcmp(s, "log") == 0); +} + +static void outcfg_conf2dlg_presentation(ocfg_dlg_ctx_t *ctx) +{ + sch_sim_presentation_type_t type; + const char *tmp; + rnd_hid_attr_val_t hv; + rnd_hid_attribute_t *attr = &ctx->dlg[ctx->wplist]; + rnd_hid_tree_t *tree = attr->wdata; + rnd_hid_row_t *r; + char *cursor_path = NULL, *cell[2]; + lht_node_t *n, *nlst; + + tmp = get_path_str(ctx->npresentation, "type", NULL, NULL); + type = sch_sim_str2presentation_type(tmp); + + hv.lng = type; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wptype, &hv); + + /*** fill in props ***/ + + /* remember cursor */ + r = rnd_dad_tree_get_selected(attr); + if (r != NULL) + cursor_path = rnd_strdup(r->cell[0]); + + /* remove existing items and fill up with the new */ + rnd_dad_tree_clear(tree); + + nlst = lht_dom_hash_get(ctx->npresentation, "props"); + if ((nlst != NULL) && (nlst->type == LHT_LIST)) { + /* fill in the table */ + cell[1] = NULL; + + for(n = nlst->data.list.first; n != NULL; n = n->next) { + if (n->type == LHT_TEXT) + cell[0] = rnd_strdup(n->data.text.value); + else + cell[0] = rnd_strdup(""); + r = rnd_dad_tree_append(attr, NULL, cell); + r->user_data = n; + } + } + + /* restore cursor (will work only in non-modal upon project update from elsewhere) */ + if (cursor_path != NULL) { + rnd_hid_attr_val_t hv; + hv.str = cursor_path; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wplist, &hv); + free(cursor_path); + } + +} + +static int outcfg_dlg2conf_presentation(ocfg_dlg_ctx_t *ctx) +{ + sch_sim_presentation_type_t type = ctx->dlg[ctx->wptype].val.lng; + int changed = 0; + const char *sptype; + + if (ctx->dlg[ctx->wptype].val.lng < 0) { + rnd_message(RND_MSG_ERROR, "Failed to set presentation conf field: invalid type\n"); + return 0; + } + + sptype = sch_simpres_names[type]; + + switch(sch_sim_update_text_node(ctx->npresentation, "type", sptype)) { + case 0: break; + case 1: changed = 1; break; + case -1: rnd_message(RND_MSG_ERROR, "Failed to set presentation conf field: type\n"); break; + } + + return changed; +} + +static void outcfg_conf2dlg(ocfg_dlg_ctx_t *ctx) +{ + outcfg_conf2dlg_analysis(ctx); + outcfg_conf2dlg_presentation(ctx); +} + +static int setup_is_in_prj(ocfg_dlg_ctx_t *ctx) { + lht_node_t *nsetup, *nroot; + + nsetup = sch_sim_get_setup(ctx->prj, ctx->setup_name, 0); /* switch to project for get_first_crpol() */ + if (nsetup == NULL) + return 0; + + nroot = rnd_conf_lht_get_first_crpol(RND_CFR_PROJECT, RND_POL_OVERWRITE, 1); + if (nsetup->doc != nroot->doc) + return 0; + + return 1; +} + +static int outcfg_dlg2conf(ocfg_dlg_ctx_t *ctx) +{ + int changed = 0; + + if (!setup_is_in_prj(ctx)) { + rnd_message(RND_MSG_ERROR, "Can not save changes: this sim setup is not in the project file but in another config\n"); + return 0; + } + + changed |= outcfg_dlg2conf_analysis(ctx); + changed |= outcfg_dlg2conf_presentation(ctx); + + if (changed) + sch_sim_flush_prj_file(ctx->prj); + + return changed; +} + + +static void outcfg_save_conf_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr_btn) +{ + ocfg_dlg_ctx_t *ctx = caller_data; + if (outcfg_dlg2conf(ctx)) + outcfg_conf2dlg(ctx); +} + +static void outcfg_prop_new_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr_btn) +{ + ocfg_dlg_ctx_t *ctx = caller_data; + rnd_design_t *dsg = ctx->prj->hdr.designs.array[0]; + char *s, *ent; + lht_node_t *nlst, *n; + + ent = rnd_hid_prompt_for(dsg, "Add new presentation property: a netname or a port name (refdes-pinnum)", "", "Simulation presentation property"); + if (ent == NULL) + return; + + s = ent; + while(isspace(*s)) s++; + if (*s == '\0') { + free(ent); + return; + } + + nlst = lht_dom_hash_get(ctx->npresentation, "props"); + if (nlst == NULL) { + nlst = lht_dom_node_alloc(LHT_LIST, "props"); + lht_dom_hash_put(ctx->npresentation, nlst); + } + n = lht_dom_node_alloc(LHT_TEXT, NULL); + n->data.text.value = rnd_strdup(s); + lht_dom_list_append(nlst, n); + + sch_sim_flush_prj_file(ctx->prj); + outcfg_conf2dlg_presentation(ctx); + + free(ent); +} + +static void outcfg_prop_edit_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr_btn) +{ + ocfg_dlg_ctx_t *ctx = caller_data; + rnd_design_t *dsg = ctx->prj->hdr.designs.array[0]; + char *s, *ent; + lht_node_t *n; + rnd_hid_attribute_t *tattr = &ctx->dlg[ctx->wplist]; + rnd_hid_row_t *row = rnd_dad_tree_get_selected(tattr); + + if (row == NULL) { + rnd_message(RND_MSG_ERROR, "Select a property first!\n"); + return; + } + + n = row->user_data; + if ((n == NULL) || (n->type != LHT_TEXT)) { + rnd_message(RND_MSG_ERROR, "Invalid property node type, can't edit\n"); + return; + } + + ent = rnd_hid_prompt_for(dsg, "Edit presentation property: a netname or a port name (refdes-pinnum)", n->data.text.value, "Simulation presentation property"); + if (ent == NULL) + return; + + s = ent; + while(isspace(*s)) s++; + if (*s == '\0') { + free(ent); + return; + } + + free(n->data.text.value); + n->data.text.value = rnd_strdup(s); + + sch_sim_flush_prj_file(ctx->prj); + outcfg_conf2dlg_presentation(ctx); + + free(ent); +} + +static void outcfg_prop_del_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr_btn) +{ + ocfg_dlg_ctx_t *ctx = caller_data; + lht_node_t *n; + rnd_hid_attribute_t *tattr = &ctx->dlg[ctx->wplist]; + rnd_hid_row_t *row = rnd_dad_tree_get_selected(tattr); + + if (row == NULL) { + rnd_message(RND_MSG_ERROR, "Select a property first!\n"); + return; + } + + n = row->user_data; + if (n == NULL) { + rnd_message(RND_MSG_ERROR, "Invalid property node, can't delete\n"); + return; + } + + lht_tree_del(n); + + sch_sim_flush_prj_file(ctx->prj); + outcfg_conf2dlg_presentation(ctx); +} + + +int dlg_outcfg_edit(csch_project_t *prj, const char *setup_name, const char *output_name) +{ + ocfg_dlg_ctx_t ctx_ = {0}, *ctx = &ctx_; + rnd_hid_dad_buttons_t clbtn[] = {{"Close", 1}, {NULL, 0}}; + const char *pres_tbl_hdr[] = {"Properties to include", NULL}; + ocfg_field_t *fld; + + ctx->prj = prj; + + ctx->noutput = sch_sim_get_output(prj, setup_name, output_name, 0); + if (ctx->noutput == NULL) { + rnd_message(RND_MSG_ERROR, "Output %s not found.\n", output_name); + return -1; + } + + ctx->setup_name = rnd_strdup(setup_name); + ctx->nanalysis = sch_sim_lht_dom_hash_ensure(ctx->noutput, LHT_HASH, "analysis"); + ctx->npresentation = sch_sim_lht_dom_hash_ensure(ctx->noutput, LHT_HASH, "presentation"); + if ((ctx->nanalysis == NULL) || (ctx->npresentation == NULL)) { + rnd_message(RND_MSG_ERROR, "Can't find or create output's analysis or presentation subtree.\n"); + return -1; + } + + fld = ctx->fld_analisys; + + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_FRAME); + RND_DAD_LABEL(ctx->dlg, "Analysis"); + RND_DAD_ENUM(ctx->dlg, sch_siman_description); + ctx->watype = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_CHANGE_CB(ctx->dlg, outcfg_save_conf_cb); + + RND_DAD_BEGIN_HBOX(ctx->dlg); + fld->wbox = RND_DAD_CURRENT(ctx->dlg); + fld->req_offs = offsetof(sch_sim_analysis_field_tab_t, start); + fld->conf_name = "start"; + RND_DAD_STRING(ctx->dlg); + fld->winp = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "start of range"); + RND_DAD_LABEL(ctx->dlg, "(optional)"); + RND_DAD_END(ctx->dlg); + fld++; + + RND_DAD_BEGIN_HBOX(ctx->dlg); + fld->wbox = RND_DAD_CURRENT(ctx->dlg); + fld->req_offs = offsetof(sch_sim_analysis_field_tab_t, stop); + fld->conf_name = "stop"; + RND_DAD_STRING(ctx->dlg); + fld->winp = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "stop: end of range"); + RND_DAD_LABEL(ctx->dlg, "(optional)"); + fld->wopt = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_END(ctx->dlg); + fld++; + + RND_DAD_BEGIN_HBOX(ctx->dlg); + fld->wbox = RND_DAD_CURRENT(ctx->dlg); + fld->req_offs = offsetof(sch_sim_analysis_field_tab_t, incr); + fld->conf_name = "incr"; + RND_DAD_STRING(ctx->dlg); + fld->winp = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "increment"); + RND_DAD_LABEL(ctx->dlg, "(optional)"); + fld->wopt = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_END(ctx->dlg); + fld++; + + RND_DAD_BEGIN_HBOX(ctx->dlg); + fld->wbox = RND_DAD_CURRENT(ctx->dlg); + fld->req_offs = offsetof(sch_sim_analysis_field_tab_t, incr_max); + fld->conf_name = "incr_max"; + RND_DAD_STRING(ctx->dlg); + fld->winp = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "increment maximum"); + RND_DAD_LABEL(ctx->dlg, "(optional)"); + fld->wopt = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_END(ctx->dlg); + fld++; + + RND_DAD_BEGIN_HBOX(ctx->dlg); + fld->wbox = RND_DAD_CURRENT(ctx->dlg); + fld->req_offs = offsetof(sch_sim_analysis_field_tab_t, numpt); + fld->conf_name = "numpt"; + fld->is_int = 1; + RND_DAD_INTEGER(ctx->dlg); + fld->winp = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_MINVAL(ctx->dlg, 0); + RND_DAD_MAXVAL(ctx->dlg, 20000); + RND_DAD_LABEL(ctx->dlg, "number of points per range div"); + RND_DAD_LABEL(ctx->dlg, "(optional)"); + fld->wopt = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_END(ctx->dlg); + fld++; + + RND_DAD_BEGIN_HBOX(ctx->dlg); + fld->wbox = RND_DAD_CURRENT(ctx->dlg); + fld->req_offs = offsetof(sch_sim_analysis_field_tab_t, port1); + fld->conf_name = "port1"; + fld->conf_name2 = "port1_neg"; + RND_DAD_STRING(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "port 1 pos"); + fld->winp = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "(optional)"); + fld->wopt = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, " "); + RND_DAD_STRING(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "neg"); + fld->winp2 = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_END(ctx->dlg); + fld++; + + RND_DAD_BEGIN_HBOX(ctx->dlg); + fld->wbox = RND_DAD_CURRENT(ctx->dlg); + fld->req_offs = offsetof(sch_sim_analysis_field_tab_t, port2); + fld->conf_name = "port2"; + fld->conf_name2 = "port2_neg"; + RND_DAD_STRING(ctx->dlg); + fld->winp = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "port 2 pos"); + RND_DAD_LABEL(ctx->dlg, "(optional)"); + fld->wopt = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, " "); + RND_DAD_STRING(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "neg"); + fld->winp2 = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_END(ctx->dlg); + fld++; + + + RND_DAD_BEGIN_HBOX(ctx->dlg); + fld->wbox = RND_DAD_CURRENT(ctx->dlg); + fld->req_offs = offsetof(sch_sim_analysis_field_tab_t, incr); + fld->conf_name = "src"; + RND_DAD_STRING(ctx->dlg); + fld->winp = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "source name"); + RND_DAD_LABEL(ctx->dlg, "(optional)"); + fld->wopt = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_END(ctx->dlg); + fld++; + + RND_DAD_END(ctx->dlg); + + RND_DAD_LABEL(ctx->dlg, ""); + + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL | RND_HATF_FRAME); + RND_DAD_LABEL(ctx->dlg, "Presentation"); + + /* type and axes */ + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_ENUM(ctx->dlg, sch_simpres_names); + ctx->wptype = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_CHANGE_CB(ctx->dlg, outcfg_save_conf_cb); + RND_DAD_END(ctx->dlg); + + + RND_DAD_TREE(ctx->dlg, 1, 0, pres_tbl_hdr); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL | RND_HATF_SCROLL); + ctx->wplist = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_HELP(ctx->dlg, "Typically net or port names on which voltages are printed or plotted\nPort names are of refdes-pinnum format, e.g. U37-2"); + + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "New..."); + RND_DAD_CHANGE_CB(ctx->dlg, outcfg_prop_new_cb); + RND_DAD_BUTTON(ctx->dlg, "Edit..."); + RND_DAD_CHANGE_CB(ctx->dlg, outcfg_prop_edit_cb); + RND_DAD_BUTTON(ctx->dlg, "Remove"); + RND_DAD_CHANGE_CB(ctx->dlg, outcfg_prop_del_cb); + RND_DAD_END(ctx->dlg); + + + RND_DAD_END(ctx->dlg); + + RND_DAD_BUTTON_CLOSES(ctx->dlg, clbtn); + + RND_DAD_END(ctx->dlg); + + RND_DAD_DEFSIZE(ctx->dlg, 300, 300); + RND_DAD_NEW("SimOutputConfig", ctx->dlg, "Simulation output config", ctx, 1, NULL); /* type=local/modal */ + + outcfg_conf2dlg(ctx); + + RND_DAD_RUN(ctx->dlg); + outcfg_dlg2conf(ctx); /* text field changes are not triggering a conversion, pick them up at the end */ + RND_DAD_FREE(ctx->dlg); + + outcfg_uninit(ctx); + + return 0; +} Index: tags/1.0.5/src/plugins/sim_gui/sim_setup_dlg.c =================================================================== --- tags/1.0.5/src/plugins/sim_gui/sim_setup_dlg.c (nonexistent) +++ tags/1.0.5/src/plugins/sim_gui/sim_setup_dlg.c (revision 10414) @@ -0,0 +1,1305 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - high level sim, GUI + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "sim_gui_conf.h" + +#define MAX_ANALS 16 + +/* Y height of the plot preview widget */ +#define PLOT_PRV_Y sch_sim_gui_conf.plugins.sim_gui.plot_height_px + +typedef struct sim_setup_dlg_ctx_s { + RND_DAD_DECL_NOINIT(dlg) + csch_project_t *prj; + char *name; + int wview; + + /* TAB: test bench & mods cfg */ + int wtest_bench, womit_no_test_bench, wmods_tree; + + /* TAB: output config */ + int wanals_tree; + + /* TAB: run & output cfg */ + struct { + int wbox, wname, wreadout, wplot, wplot_ctrl, wplot_reset, wplot_yzoom, wtext; + plot_preview_t pprv; + int x_scale_type; /* see sch_siman_x_axis_log[] */ + vtd0_t xval; /* all x values converted to double */ + + unsigned has_data:1; /* whether pprv is loaded with data */ + } out[MAX_ANALS]; + + FILE *fc; /* plot cache file */ + char *fc_name; + unsigned subsequent_plot:1; /* set to 1 after the first plot */ + + vts0_t view_names; + gds_t readout_tmp; + int readout_idx; + + gdl_elem_t link; +} sim_setup_dlg_ctx_t; + +static gdl_list_t dlgs; + +static void plot_reset(sim_setup_dlg_ctx_t *ctx) +{ + int n; + for(n = 0; n < MAX_ANALS; n++) { + if (ctx->out[n].has_data) { + plot_data_uninit(&ctx->out[n].pprv.pdata); + ctx->out[n].has_data = 0; + } + ctx->out[n].xval.used = 0; + } + + if (ctx->fc_name != NULL) { + rnd_tempfile_unlink(ctx->fc_name); + ctx->fc_name = NULL; + } + if (ctx->fc != NULL) { + fclose(ctx->fc); + ctx->fc = NULL; + } +} + +static void sim_setup_dlg_close_cb(void *caller_data, rnd_hid_attr_ev_t ev) +{ + sim_setup_dlg_ctx_t *ctx = caller_data; + int n; + + for(n = 0; n < ctx->view_names.used; n++) + free(ctx->view_names.array[n]); + vts0_uninit(&ctx->view_names); + + if (ctx->link.parent != NULL) + gdl_remove(&dlgs, ctx, link); + free(ctx->name); + + plot_reset(ctx); + for(n = 0; n < MAX_ANALS; n++) + vtd0_uninit(&ctx->out[n].xval); + + gds_uninit(&ctx->readout_tmp); + + free(ctx); +} + +static lht_node_t *get_path(lht_node_t *parent, const char *path) +{ + lht_err_t err; + return lht_tree_path_(parent->doc, parent, path, 1, 1, &err); +} + +static const char *get_path_str(lht_node_t *parent, const char *path, const char *defval, lht_node_t **nout) +{ + const char *s; + lht_err_t err; + lht_node_t *nd = lht_tree_path_(parent->doc, parent, path, 1, 1, &err); + + if ((nd == NULL) || (nd->type != LHT_TEXT)) { + if (nout != NULL) + *nout = NULL; + return defval; + } + + s = nd->data.text.value; + while(isspace(*s)) s++; + if (*s == '\n') { + if (nout != NULL) + *nout = NULL; + return defval; + } + + if (nout != NULL) + *nout = nd; + return s; +} + +static void sch2dlg_test_bench_mods(sim_setup_dlg_ctx_t *ctx, lht_node_t *nsetup, gds_t *tmp) +{ + rnd_hid_attribute_t *attr = &ctx->dlg[ctx->wmods_tree]; + rnd_hid_tree_t *tree = attr->wdata; + rnd_hid_row_t *r; + char *cursor_path = NULL, *cell[4]; + rnd_hid_attr_val_t hv; + lht_node_t *ntb, *nmods; + const char *whole_circ = ""; + const char *ov; + int omit_no_test_bench; + int sim_whole_circ = 0; + + ov = get_path_str(nsetup, "omit_no_test_bench", whole_circ, &ntb); + omit_no_test_bench = rnd_istrue(ov); + + hv.str = get_path_str(nsetup, "test_bench", whole_circ, &ntb); + /* special case: explicity set to empty */ + if (*hv.str == '\0') { + omit_no_test_bench = 0; + hv.str = whole_circ; + sim_whole_circ = 1; + } + + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wtest_bench, &hv); + + hv.lng = omit_no_test_bench; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->womit_no_test_bench, &hv); + + /* disable checkbox if whole circ */ + hv.lng = !sim_whole_circ; + rnd_gui->attr_dlg_widget_state(ctx->dlg_hid_ctx, ctx->womit_no_test_bench, hv.lng); + + /*** update the mods list ***/ + nmods = get_path(nsetup, "mods"); + + /* remember cursor */ + r = rnd_dad_tree_get_selected(attr); + if (r != NULL) + cursor_path = rnd_strdup(r->cell[0]); + + /* remove existing items and fill up with the new */ + rnd_dad_tree_clear(tree); + + /* fill in the table */ + cell[3] = NULL; + if ((nmods != NULL) && (nmods->type == LHT_LIST)) { + lht_node_t *nmod; + long idx; + for(idx = 0, nmod = nmods->data.list.first; nmod != NULL; idx++, nmod = nmod->next) { + cell[0] = rnd_strdup_printf("%ld", idx); + cell[1] = rnd_strdup(nmod->name); + if (nmod->type == LHT_HASH) { + tmp->used = 0; + sch_sim_append_print_mod(tmp, nmod, " "); + cell[2] = tmp->array; + tmp->used = tmp->alloced = 0; + tmp->array = NULL; + } + else + cell[2] = rnd_strdup(""); + rnd_dad_tree_append(attr, NULL, cell); + } + } + + /* restore cursor (will work only in non-modal upon project update from elsewhere) */ + if (cursor_path != NULL) { + rnd_hid_attr_val_t hv; + hv.str = cursor_path; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wmods_tree, &hv); + free(cursor_path); + } +} + +static void dlg2sch_test_bench_mods(sim_setup_dlg_ctx_t *ctx, lht_node_t *nsetup) +{ + +} + +static void sch2dlg_anals_plot(sim_setup_dlg_ctx_t *ctx, lht_node_t *nsetup, gds_t *tmp) +{ + rnd_hid_attribute_t *attr = &ctx->dlg[ctx->wanals_tree]; + rnd_hid_tree_t *tree = attr->wdata; + rnd_hid_row_t *r; + char *cursor_path = NULL, *cell[4]; + lht_node_t *noutput; + + noutput = get_path(nsetup, "output"); + + /* remember cursor */ + r = rnd_dad_tree_get_selected(attr); + if (r != NULL) + cursor_path = rnd_strdup(r->cell[0]); + + /* remove existing items and fill up with the new */ + rnd_dad_tree_clear(tree); + + /* fill in the table */ + cell[3] = NULL; + if ((noutput != NULL) && (noutput->type == LHT_LIST)) { + lht_node_t *nout; + for(nout = noutput->data.list.first; nout != NULL; nout = nout->next) { + cell[0] = rnd_strdup(nout->name); + cell[1] = rnd_strdup(get_path_str(nout, "analysis/type", "N/A", NULL)); + cell[2] = rnd_strdup(get_path_str(nout, "presentation/type", "N/A", NULL)); + rnd_dad_tree_append(attr, NULL, cell); + } + } + + + /* restore cursor (will work only in non-modal upon project update from elsewhere) */ + if (cursor_path != NULL) { + rnd_hid_attr_val_t hv; + hv.str = cursor_path; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wanals_tree, &hv); + free(cursor_path); + } +} + +static void dlg2sch_anals_plot(sim_setup_dlg_ctx_t *ctx, lht_node_t *nsetup) +{ + /* nothing to do here, the list in the conf is updated by the GUI code */ +} + +static void sch_sim_setup_sch2dlg(sim_setup_dlg_ctx_t *ctx) +{ + lht_node_t *nsetup = sch_sim_get_setup(ctx->prj, ctx->name, 0); + gds_t tmp = {0}; + + if (nsetup == NULL) { + rnd_message(RND_MSG_ERROR, "Can't update sim setup dialog: setup node not found in config\n"); + return; + } + + sch2dlg_test_bench_mods(ctx, nsetup, &tmp); + sch2dlg_anals_plot(ctx, nsetup, &tmp); +/* sch2dlg_run_out(ctx, nsetup, &tmp); - done once after run */ + + gds_uninit(&tmp); +} + +static void sch_sim_setup_dlg2sch(sim_setup_dlg_ctx_t *ctx, int tab1, int tab2, int tab3) +{ + lht_node_t *nsetup = sch_sim_get_setup(ctx->prj, ctx->name, 0); + + if (nsetup == NULL) { + rnd_message(RND_MSG_ERROR, "Can't update the project file from the setup dialog:\nsetup node not found in config\n"); + return; + } + + if (tab1) dlg2sch_test_bench_mods(ctx, nsetup); + if (tab2) dlg2sch_anals_plot(ctx, nsetup); +/* if (tab3) dlg2sch_run_out(ctx, nsetup); - done once after run */ +} + +static void setup1_save_conf_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr_btn) +{ + sim_setup_dlg_ctx_t *ctx = caller_data; + sch_sim_setup_dlg2sch(ctx, 1, 0, 0); +} + +static void setup_test_bench_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr_btn) +{ + sim_setup_dlg_ctx_t *ctx = caller_data; + const char *initval; + char *val = NULL; + sch_stance_edit_res_t r; + lht_node_t *nsetup = sch_sim_get_setup(ctx->prj, ctx->name, 0); + + if (nsetup == NULL) { + rnd_message(RND_MSG_ERROR, "Can't find simulation setup '%s'\n", ctx->name); + return; + } + + initval = get_path_str(nsetup, "test_bench", "", NULL); + r = sch_stance_edit_dlg("test_bench", initval, &val); + if ((r == STE_CANCEL) || (val == NULL)) + return; + + if (r & STE_REMEMBER) csch_stance_add_to_values("test_bench", val); + if (r & STE_SET) { + lht_node_t *nd; + const char *oldval; + oldval = get_path_str(nsetup, "test_bench", "", &nd); + if (nd == NULL) { + nd = lht_dom_node_alloc(LHT_TEXT, "test_bench"); + lht_dom_hash_put(nsetup, nd); + } + if (strcmp(val, oldval) != 0) { + free(nd->data.text.value); + nd->data.text.value = val; /* pass on ownership... */ + val = NULL; /* ... don't free here */ + sch_sim_flush_prj_file(ctx->prj); + sch_sim_setup_sch2dlg(ctx); + } + } + + free(val); +} + +static void setup_omit_no_test_bench_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr_btn) +{ + sim_setup_dlg_ctx_t *ctx = caller_data; + lht_node_t *nd; + const char *soldval; + int newval, oldval; + lht_node_t *nsetup = sch_sim_get_setup(ctx->prj, ctx->name, 0); + + newval = ctx->dlg[ctx->womit_no_test_bench].val.lng; + + soldval = get_path_str(nsetup, "omit_no_test_bench", "0", &nd); + if (nd == NULL) { + nd = lht_dom_node_alloc(LHT_TEXT, "omit_no_test_bench"); + lht_dom_hash_put(nsetup, nd); + } + oldval = rnd_istrue(soldval); + + if (oldval != newval) { + free(nd->data.text.value); + nd->data.text.value = rnd_strdup(newval ? "1" : "0"); + sch_sim_flush_prj_file(ctx->prj); + sch_sim_setup_sch2dlg(ctx); + } +} + + +#include "sim_mod_dlg.c" + +/* Return the mod node corresponding to the the given tree table row, counting + both rows and conf nodes */ +lht_node_t *setup_mod_get_node(sim_setup_dlg_ctx_t *ctx, rnd_hid_row_t *row) +{ + lht_node_t *nsetup = sch_sim_get_setup(ctx->prj, ctx->name, 0); + rnd_hid_attribute_t *tattr = &ctx->dlg[ctx->wmods_tree]; + rnd_hid_tree_t *tree = tattr->wdata; + rnd_hid_row_t *r; + lht_node_t *nmods, *n; + + if (nsetup == NULL) + return NULL; + + nmods = get_path(nsetup, "mods"); + if (nmods == NULL) + return NULL; + + for(n = nmods->data.list.first, r = gdl_first(&tree->rows); n != NULL; n = n->next, r = gdl_next(&tree->rows, r)) + if (r == row) + return n; + + return NULL; +} + +static void setup_mod_edit_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + sim_setup_dlg_ctx_t *ctx = caller_data; + rnd_hid_attribute_t *tattr = &ctx->dlg[ctx->wmods_tree]; + rnd_hid_row_t *row = rnd_dad_tree_get_selected(tattr); + lht_node_t *nmod; + + if (row == NULL) { + rnd_message(RND_MSG_ERROR, "Select a modification from the list first!\n"); + return; + } + + nmod = setup_mod_get_node(ctx, row); + if (nmod == NULL) { + rnd_message(RND_MSG_ERROR, "Failed to find the conf node for the selected row\n"); + return; + } + + dlg_mod_edit(nmod); + sch_sim_flush_prj_file(ctx->prj); + + TODO("this should be automatic via conf change callback"); + sch_sim_setup_sch2dlg(ctx); +} + +static void setup_mod_add_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + sim_setup_dlg_ctx_t *ctx = caller_data; + lht_node_t *nnew, *nmods, *nsetup; + + nsetup = sch_sim_get_setup(ctx->prj, ctx->name, 1); + if ((nsetup == NULL) || (nsetup->type != LHT_HASH)) { + rnd_message(RND_MSG_ERROR, "Failed to get or create the setup node"); + return; + } + + nmods = get_path(nsetup, "mods"); + if (nmods == NULL) { + nmods = lht_dom_node_alloc(LHT_LIST, "mods"); + lht_dom_hash_put(nsetup, nmods); + } + + if (nmods->type != LHT_LIST) { + rnd_message(RND_MSG_ERROR, "Setup's mods is not a list"); + return; + } + + nnew = lht_dom_node_alloc(LHT_HASH, "unknown"); + if (nnew == NULL) { + rnd_message(RND_MSG_ERROR, "Failed to allocate hash node for the new mod"); + return; + } + lht_dom_list_append(nmods, nnew); + + dlg_mod_edit(nnew); + sch_sim_flush_prj_file(ctx->prj); + + TODO("this should be automatic via conf change callback"); + sch_sim_setup_sch2dlg(ctx); +} + +static void setup_mod_del_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + sim_setup_dlg_ctx_t *ctx = caller_data; + rnd_hid_attribute_t *tattr = &ctx->dlg[ctx->wmods_tree]; + rnd_hid_row_t *row = rnd_dad_tree_get_selected(tattr); + lht_node_t *nmod; + + if (row == NULL) { + rnd_message(RND_MSG_ERROR, "Select a modification from the list first!\n"); + return; + } + + nmod = setup_mod_get_node(ctx, row); + if (nmod == NULL) { + rnd_message(RND_MSG_ERROR, "Failed to find the conf node for the selected row\n"); + return; + } + + lht_tree_del(nmod); + sch_sim_flush_prj_file(ctx->prj); + + TODO("this should be automatic via conf change callback"); + sch_sim_setup_sch2dlg(ctx); +} + +#include "sim_outcfg_dlg.c" + +static void output_edit_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + sim_setup_dlg_ctx_t *ctx = caller_data; + rnd_hid_attribute_t *tattr = &ctx->dlg[ctx->wanals_tree]; + rnd_hid_row_t *row = rnd_dad_tree_get_selected(tattr); + + if (row == NULL) { + rnd_message(RND_MSG_ERROR, "Select an output from the list first!\n"); + return; + } + + dlg_outcfg_edit(ctx->prj, ctx->name, row->cell[0]); + + TODO("this should be automatic via conf change callback"); + sch_sim_setup_sch2dlg(ctx); +} + +static void output_add_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + sim_setup_dlg_ctx_t *ctx = caller_data; + rnd_design_t *dsg = ctx->prj->hdr.designs.array[0]; + char *an_name; + lht_node_t *nnew, *nold, *noutput, *nsetup; + + nsetup = sch_sim_get_setup(ctx->prj, ctx->name, 1); + if ((nsetup == NULL) || (nsetup->type != LHT_HASH)) { + rnd_message(RND_MSG_ERROR, "Failed to get or create the setup node"); + return; + } + + noutput = get_path(nsetup, "output"); + if (noutput == NULL) { + noutput = lht_dom_node_alloc(LHT_LIST, "output"); + lht_dom_hash_put(nsetup, noutput); + } + + if (noutput->type != LHT_LIST) { + rnd_message(RND_MSG_ERROR, "Setup's output is not a list"); + return; + } + + an_name = rnd_hid_prompt_for(dsg, "Name for the new output", NULL, "Simulation output naming"); + if ((an_name == NULL) || (*an_name == '\0')) { + free(an_name); + return; /* cancel */ + } + nold = sch_sim_get_output(ctx->prj, ctx->name, an_name, 0); + if (nold != NULL) { + rnd_message(RND_MSG_ERROR, "Setup's output of that name already exists\nPlease choose a different name\n"); + return; + } + + + nnew = lht_dom_node_alloc(LHT_HASH, an_name); + if (nnew == NULL) { + rnd_message(RND_MSG_ERROR, "Failed to allocate hash node for the new output"); + free(an_name); + return; + } + lht_dom_list_append(noutput, nnew); + + dlg_outcfg_edit(ctx->prj, ctx->name, an_name); + free(an_name); + + TODO("this should be automatic via conf change callback"); + sch_sim_setup_sch2dlg(ctx); +} + +static void output_del_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + sim_setup_dlg_ctx_t *ctx = caller_data; + rnd_hid_attribute_t *tattr = &ctx->dlg[ctx->wanals_tree]; + rnd_hid_row_t *row = rnd_dad_tree_get_selected(tattr); + lht_node_t *nd; + + if (row == NULL) { + rnd_message(RND_MSG_ERROR, "Select an output from the list first!\n"); + return; + } + + nd = sch_sim_get_output(ctx->prj, ctx->name, row->cell[0], 0); + if (nd == NULL) { + rnd_message(RND_MSG_ERROR, "Failed to find that output\n"); + return; + } + + lht_tree_del(nd); + sch_sim_flush_prj_file(ctx->prj); + + TODO("this should be automatic via conf change callback"); + sch_sim_setup_sch2dlg(ctx); +} + +static int sim_dlg_activate(sim_setup_dlg_ctx_t *ctx, int compile_now) +{ + return sch_sim_activate(ctx->prj, ctx->name, ctx->view_names.array[ctx->dlg[ctx->wview].val.lng], compile_now); +} + +static void activate_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + sim_setup_dlg_ctx_t *ctx = caller_data; + sim_dlg_activate(ctx, 1); +} + +static void run2out_reset(sim_setup_dlg_ctx_t *ctx) +{ + int n; + + for(n = 0; n < MAX_ANALS; n++) + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->out[n].wbox, 1); + + plot_reset(ctx); +} + +static void gen_lin_labels(plot_alabel_t **dst_arr, long *dst_len, double min, double max) +{ + double v = min, step = (max-min) / 10; + int n, num_pts; + plot_alabel_t *arr; + + if (step > 1000) { + step = floor(step/1000.0) * 1000; + v = floor(v/1000.0) * 1000; + } + else if (step > 100) { + step = floor(step/100.0) * 100; + v = floor(v/100.0) * 100; + } + else if (step > 10) { + step = floor(step/10.0) * 10; + v = floor(v/10.0) * 10; + } + else if (step > 1) { + step = floor(step); + v = floor(v); + } + else if (step > 0.1) { + step = floor(step*10)/10; + v = floor(v*10)/10; + } + else if (step > 0.01) { + step = floor(step*100)/100; + v = floor(v*100)/100; + } + else if (step > 0.001) { + step = floor(step*1000)/1000; + v = floor(v*1000)/1000; + } + + num_pts = floor((max-min) / step)+1; + + /* don't include 0, that's going to be indicated differently */ + if (v == 0) { + v += step; + num_pts--; + } + + *dst_len = num_pts; + *dst_arr = arr = malloc(sizeof(plot_alabel_t) * num_pts); + +/* rnd_trace("lin_labels: %f %f: num_pts %ld step: %f start: %f\n", min, max, num_pts, step, v);*/ + + for(n = 0; n < num_pts; n++, v += step) { + arr[n].plot_val = arr[n].print_val = v; + arr[n].text = NULL; + } +} + +static const char *x_axis_name(sim_setup_dlg_ctx_t *ctx, sch_sim_setup_t *ssu, lht_node_t *npres, int idx) +{ + lht_node_t *nout = npres->parent, *nanalysis = get_path(nout, "analysis"), *ntype; + sch_sim_analysis_type_t antype; + + ctx->out[idx].x_scale_type = 0; + + if ((nanalysis == NULL) || (nanalysis->type != LHT_HASH)) + return "ERROR: analysis is not a hash"; + + ntype = get_path(nanalysis, "type"); + if ((ntype == NULL) || (ntype->type != LHT_TEXT)) + return "ERROR: analysis/type is not a text"; + + antype = sch_sim_str2analysis_type(ntype->data.text.value); + if (antype < 0) + return "ERROR: invalid analysis/type"; + + if ((antype == SCH_SIMAN_PREVIOUS) && (idx > 0)) { + ctx->out[idx].x_scale_type = ctx->out[idx-1].x_scale_type; + return ctx->out[idx-1].pprv.pdata.x_axis_name; + } + + ctx->out[idx].x_scale_type = sch_siman_x_axis_log[antype]; + return sch_siman_x_axis_name[antype]; +} + +static void plot_autozoom(sim_setup_dlg_ctx_t *ctx, int idx) +{ + long mx = (ctx->out[idx].pprv.maxx)/20; + double my = (ctx->out[idx].pprv.maxy - ctx->out[idx].pprv.miny) / 20; + plot_zoomto(&ctx->dlg[ctx->out[idx].wplot], &ctx->out[idx].pprv, 0-mx, ctx->out[idx].pprv.miny-my, ctx->out[idx].pprv.maxx+mx, ctx->out[idx].pprv.maxy+my); +} + +static void run2out_plot(sim_setup_dlg_ctx_t *ctx, sch_sim_setup_t *ssu, lht_node_t *npres, int idx) +{ + sch_sim_exec_t *se = sch_sim_get_sim_exec(ctx->prj, -1); + rnd_design_t *dsg = ctx->prj->hdr.designs.array[0]; + lht_node_t *nd, *nout = npres->parent, *nprops; + void *stream; + vts0_t cols = {0}; + long num_props, num_rows, xm; + double min_y = 0, max_y = 0; + rnd_hid_attr_val_t hv; + + if (se == NULL) { + rnd_message(RND_MSG_ERROR, "sim_dlg_run(): simulation setup '%s' output '%s': no sim exec\n", ctx->name, nout->name); + return; + } + + nprops = get_path(npres, "props"); + if ((nprops == NULL) || (nprops->type != LHT_LIST)) { + rnd_message(RND_MSG_ERROR, "sim_dlg_run(): simulation setup '%s' output '%s': wrong or missing props subtree\n", ctx->name, nout->name); + return; + } + + stream = se->result_open(ctx->prj, ssu, idx); + if (stream == NULL) { + rnd_message(RND_MSG_ERROR, "sim_dlg_run(): simulation setup '%s' output '%s': can't open stream\n", ctx->name, nout->name); + return; + } + + /* count properties and rows*/ + for(nd = nprops->data.list.first, num_props = 0; nd != NULL; nd = nd->next, num_props++) ; + + num_rows = 0; + while(se->result_read(ssu, stream, NULL) == 0) + num_rows++; + + /* draw traces */ + if (num_rows > 0) { + long n, xi; + plot_trace_t *tr; + plot_trdata_t *td[MAX_ANALS]; + plot_pos_t pw[MAX_ANALS]; + int pw_err[MAX_ANALS], xmark_skip; + struct { + double buff[256]; + } tmp[MAX_ANALS]; + + plot_data_init(&ctx->out[idx].pprv.pdata, num_props); + ctx->out[idx].has_data = 0; + + ctx->fc_name = rnd_tempfile_name_new("plot_cache"); + ctx->fc = rnd_fopen(dsg, ctx->fc_name, "w+"); + + /* as a side effect this also fills in ctx->out[idx].x_scale_type */ + ctx->out[idx].pprv.pdata.x_axis_name = rnd_strdup(x_axis_name(ctx, ssu, npres, idx)); + ctx->out[idx].pprv.pdata.y_axis_name = rnd_strdup("value"); + ctx->out[idx].pprv.pdata.trace_name = malloc(sizeof(char *) * num_props); + + switch(ctx->out[idx].x_scale_type) { + case 8: + xmark_skip = 10; + ctx->out[idx].pprv.type_x = PLAXTY_OCTAVE; + break; + case 10: + xmark_skip = 10; + ctx->out[idx].pprv.type_x = PLAXTY_DECADE; + break; + case 0: + case -1: + default: + xmark_skip = 10; + break; + } + + ctx->out[idx].pprv.pdata.num_x_labels = xm = (num_rows/xmark_skip)+1; + ctx->out[idx].pprv.pdata.x_labels = malloc(sizeof(plot_alabel_t) * xm); + xm = xi = 0; + + for(n = 0, nd = nprops->data.list.first; n < num_props; n++, nd = nd->next) { + tr = &ctx->out[idx].pprv.pdata.trace[n]; + plot_trace_init(tr, ctx->fc); + td[n] = plot_trdata_alloc(tr, 0, num_rows); + + pw_err[n] = plot_write_init(&pw[n], tr, td[n], PLOT_MAIN, 0, 0, tmp[n].buff, sizeof(tmp[n].buff)/sizeof(tmp[n].buff[0])); + + ctx->out[idx].pprv.pdata.trace_name[n] = rnd_strdup(nd->data.text.value); + } + + se->result_rewind(ssu, stream); + while(se->result_read(ssu, stream, &cols) == 0) { + if (cols.used != num_props + 1) { + rnd_message(RND_MSG_ERROR, "sim_dlg_run(): simulation setup '%s' output '%s': broken output (number of cols)\n", ctx->name, nout->name); + break; + } + + /* read and store traces */ + for(n = 0; n < num_props; n++) { + char *end; + double val = strtod(cols.array[n], &end); + if (*end != '\0') { + rnd_message(RND_MSG_ERROR, "sim_dlg_run(): simulation setup '%s' output '%s': wrong numeric value '%s'\n", ctx->name, nout->name, cols.array[n]); + val = 0; + } + if (pw_err[n] == 0) { + plot_write(&pw[n], val); + if (val > max_y) max_y = val; + if (val < min_y) min_y = val; + } + } + + + { + char *end; + double val = strtod(cols.array[num_props], &end); + if ((xi > 0) && (xi % xmark_skip) == 0) { + /* read and store every 10th x marker in the plot */ + assert(xm < ctx->out[idx].pprv.pdata.num_x_labels); + ctx->out[idx].pprv.pdata.x_labels[xm].plot_val = xi; + ctx->out[idx].pprv.pdata.x_labels[xm].print_val = val; + xm++; + } + vtd0_append(&ctx->out[idx].xval, val); + } + xi++; + } + + for(n = 0; n < num_props; n++) + plot_flush(&pw[n]); + } + + ctx->out[idx].pprv.pdata.num_x_labels = xm; /* off-by-one: xm may be one less */ + + if (!ctx->subsequent_plot) { + /* set only on first plot, preserve for updates so user choice is not overridden */ + ctx->out[idx].pprv.zoom_y = (double)PLOT_PRV_Y / (max_y - min_y); + } + + ctx->out[idx].pprv.miny = min_y; + ctx->out[idx].pprv.maxy = max_y; + ctx->out[idx].pprv.maxx = num_rows; + + if (!ctx->subsequent_plot) { + /* set only on first plot, preserve for updates so user choice is not overridden */ + hv.dbl = ctx->out[idx].pprv.zoom_y; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->out[idx].wplot_yzoom, &hv); + } + + /* generate y labels */ + gen_lin_labels(&ctx->out[idx].pprv.pdata.y_labels, &ctx->out[idx].pprv.pdata.num_y_labels, min_y, max_y); + + ctx->out[idx].pprv.grid_color = &sch_sim_gui_conf.plugins.sim_gui.plot_grid_color; + if (!ctx->subsequent_plot) { + /* first plot: auto-zoom */ + plot_autozoom(ctx, idx); + } + + se->result_close(ssu, stream); + vts0_uninit(&cols); + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->out[idx].wplot, 0); + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->out[idx].wplot_ctrl, 0); +} + +static void run2out_print(sim_setup_dlg_ctx_t *ctx, sch_sim_setup_t *ssu, lht_node_t *npres, int idx) +{ + sch_sim_exec_t *se = sch_sim_get_sim_exec(ctx->prj, -1); + lht_node_t *nd, *nout = npres->parent, *nprops; + rnd_hid_attribute_t *atxt = &ctx->dlg[ctx->out[idx].wtext]; + rnd_hid_text_t *txt = atxt->wdata; + vts0_t cols = {0}; + gds_t tmp = {0}; + void *stream; + int n; + + if (se == NULL) { + rnd_message(RND_MSG_ERROR, "sim_dlg_run(): simulation setup '%s' output '%s': no sim exec\n", ctx->name, nout->name); + return; + } + + nprops = get_path(npres, "props"); + if ((nprops == NULL) || (nprops->type != LHT_LIST)) { + rnd_message(RND_MSG_ERROR, "sim_dlg_run(): simulation setup '%s' output '%s': wrong or missing props subtree\n", ctx->name, nout->name); + return; + } + + /* expect only a single row of data */ + stream = se->result_open(ctx->prj, ssu, idx); + if (stream == NULL) { + rnd_message(RND_MSG_ERROR, "sim_dlg_run(): simulation setup '%s' output '%s': can't open stream\n", ctx->name, nout->name); + return; + } + se->result_read(ssu, stream, &cols); + se->result_close(ssu, stream); + + + for(nd = nprops->data.list.first, n = 0; nd != NULL; nd = nd->next, n++) { + if (nd->type == LHT_TEXT) { + gds_append_str(&tmp, nd->data.text.value); + gds_append_str(&tmp, " = "); + if (n < cols.used) + gds_append_str(&tmp, cols.array[n]); + gds_append(&tmp, '\n'); + } + } + + txt->hid_set_text(atxt, ctx->dlg_hid_ctx, RND_HID_TEXT_REPLACE, tmp.array); + + vts0_uninit(&cols); + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->out[idx].wtext, 0); +} + + +static void run2out(sim_setup_dlg_ctx_t *ctx, sch_sim_setup_t *ssu, lht_node_t *nout, int idx) +{ + lht_node_t *ntype, *npres = get_path(nout, "presentation"); + rnd_hid_attr_val_t hv; + + if (idx >= MAX_ANALS) + return; + + if ((npres == NULL) || (npres->type != LHT_HASH)) { + rnd_message(RND_MSG_ERROR, "sim_dlg_run(): simulation setup '%s' output '%s' has missing or invalid presentation subtree\n", ctx->name, nout->name); + return; + } + + ntype = get_path(npres, "type"); + if ((ntype == NULL) || (ntype->type != LHT_TEXT)) { + rnd_message(RND_MSG_ERROR, "sim_dlg_run(): simulation setup '%s' output '%s' invalid presentation type (empty or missing)\n", ctx->name, nout->name); + return; + } + + hv.str = nout->name; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->out[idx].wname, &hv); + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->out[idx].wbox, 0); + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->out[idx].wplot, 1); + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->out[idx].wplot_ctrl, 1); + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->out[idx].wtext, 1); + + + switch(sch_sim_str2presentation_type(ntype->data.text.value)) { + case SCH_SIMPRES_PLOT: + run2out_plot(ctx, ssu, npres, idx); + break; + + case SCH_SIMPRES_PRINT: + run2out_print(ctx, ssu, npres, idx); + break; + + case SCH_SIMPRES_invalid: + rnd_message(RND_MSG_ERROR, "sim_dlg_run(): simulation setup '%s' output '%s' invalid presentation type (%s)\n", ctx->name, nout->name, ntype->data.text.value); + break; + } +} + +static void run_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + sch_sim_setup_t *ssu; + sim_setup_dlg_ctx_t *ctx = caller_data; + lht_node_t *no, *noutput, *nsetup = sch_sim_get_setup(ctx->prj, ctx->name, 0); + int idx; + + run2out_reset(ctx); + + if (nsetup == NULL) { + rnd_message(RND_MSG_ERROR, "sim_dlg_run(): failed to find simulation setup '%s'\n", ctx->name); + return; + } + + sim_dlg_activate(ctx, 1); + ssu = sch_sim_run_prepare(ctx->prj, ctx->name); + if (ssu == NULL) + return; + + if (sch_sim_exec(ctx->prj, ssu) != 0) + rnd_message(RND_MSG_ERROR, "sim_dlg_run(): failed to execute sim setup '%s'\n", ctx->name); + + + /* load output into the dialog box */ + noutput = get_path(nsetup, "output"); + if ((noutput != NULL) && (noutput->type == LHT_LIST)) { + for(no = noutput->data.list.first, idx = 0; no != NULL; no = no->next, idx++) + run2out(ctx, ssu, no, idx); + ctx->subsequent_plot = 1; + } + + sch_sim_free(ctx->prj, ssu); +} + +static void reset_zoom_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + sim_setup_dlg_ctx_t *ctx = caller_data; + int idx; + + for(idx = 0; idx < MAX_ANALS; idx++) { + if (attr == &ctx->dlg[ctx->out[idx].wplot_reset]) { + plot_autozoom(ctx, idx); + return; + } + } +} + +static void yzoom_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + sim_setup_dlg_ctx_t *ctx = caller_data; + int idx; + + for(idx = 0; idx < MAX_ANALS; idx++) { + if (attr == &ctx->dlg[ctx->out[idx].wplot_yzoom]) { + ctx->out[idx].pprv.zoom_y = ctx->dlg[ctx->out[idx].wplot_yzoom].val.dbl; + plot_redraw(&ctx->dlg[ctx->out[idx].wplot]); + return; + } + } +} + +static void readout_plot_begin_cb(plot_preview_t *pprv, long xi) +{ + sim_setup_dlg_ctx_t *ctx = pprv->user_data; + int n, out_idx = -1; + + ctx->readout_tmp.used = 0; + + for(n = 0; n < MAX_ANALS; n++) { + if (&ctx->out[n].pprv == pprv) { + out_idx = n; + break; + } + } + ctx->readout_idx = out_idx; + + if ((out_idx >= 0) && (xi >= 0) && (xi < ctx->out[out_idx].xval.used)) { + double x = ctx->out[out_idx].xval.array[xi]; + rnd_append_printf(&ctx->readout_tmp, " x=%f", x); + } + +} + +static void readout_plot_end_cb(plot_preview_t *pprv, long xi) +{ + sim_setup_dlg_ctx_t *ctx = pprv->user_data; + + if (ctx->readout_idx >= 0) { + rnd_hid_attr_val_t hv; + hv.str = ctx->readout_tmp.array; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->out[ctx->readout_idx].wreadout, &hv); + } + + ctx->readout_tmp.used = 0; +} + +static void readout_plot_cb(plot_preview_t *pprv, int trace_idx, long xi, double y) +{ + sim_setup_dlg_ctx_t *ctx = pprv->user_data; + + rnd_append_printf(&ctx->readout_tmp, " %s=%f", pprv->pdata.trace_name[trace_idx], y); +} + + +static void list_sim_views(csch_project_t *prj, vts0_t *dst) +{ + long n, m; + + for(n = 0; n < prj->views.used; n++) { + csch_view_t *v = prj->views.array[n]; + const char *view_name = v->fgw_ctx.name; + for(m = 0; m < v->engines.used; m++) { + csch_view_eng_t *ve = v->engines.array[m]; + if (fgw_func_lookup_in(ve->obj, "sim_exec_get") != 0) { + vts0_append(dst, rnd_strdup(view_name)); + break; /* no need to check the rest of the engines in this view */ + } + } + } +} + +static void sim_setup_dlg(csch_project_t *prj, const char *name) +{ + sim_setup_dlg_ctx_t *ctx; + rnd_hid_dad_buttons_t clbtn[] = {{"Close", 0}, {NULL, 0}}; + char *title; + int n; + const char *tabs[] = {"test bench & mods cfg", "output config", "run & output", NULL}; + const char *test_bench_help = "test_bench setting is in attribute forge-if/test_bench\nsee also: File menu, project, project stances -> test_bench stance\nsee also: Select menu, change selected objects, testbench affiliation menu"; + const char *mods_tbl_hdr[] = {"#", "mod", "arguments", NULL}; + const char *anals_tbl_hdr[] = {"name", "analysis", "presentation", NULL}; + static rnd_box_t prvbb = {0, 0, 200*200, 200*200}; + + /* skip if already open */ + for(ctx = gdl_first(&dlgs); ctx != NULL; ctx = gdl_next(&dlgs, ctx)) + if ((ctx->prj == prj) && (strcmp(ctx->name, name) == 0)) + return; + + ctx = calloc(sizeof(sim_setup_dlg_ctx_t), 1); + ctx->prj = prj; + ctx->name = rnd_strdup(name); + gdl_append(&dlgs, ctx, link); + list_sim_views(prj, &ctx->view_names); + + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + + RND_DAD_BEGIN_TABBED(ctx->dlg, tabs); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + + RND_DAD_BEGIN_VBOX(ctx->dlg); /* TAB: test bench & mods cfg */ + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, " "); + RND_DAD_HELP(ctx->dlg, test_bench_help); + ctx->wtest_bench = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_CHANGE_CB(ctx->dlg, setup_test_bench_cb); + RND_DAD_LABEL(ctx->dlg, "Test bench to use"); + RND_DAD_HELP(ctx->dlg, test_bench_help); + RND_DAD_END(ctx->dlg); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_BOOL(ctx->dlg); + RND_DAD_HELP(ctx->dlg, test_bench_help); + ctx->womit_no_test_bench = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_CHANGE_CB(ctx->dlg, setup_omit_no_test_bench_cb); + RND_DAD_LABEL(ctx->dlg, "Omit symbols that do not have test_bench setting"); + RND_DAD_HELP(ctx->dlg, test_bench_help); + RND_DAD_END(ctx->dlg); + + RND_DAD_TREE(ctx->dlg, 3, 0, mods_tbl_hdr); /* mods */ + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL | RND_HATF_SCROLL); + ctx->wmods_tree = RND_DAD_CURRENT(ctx->dlg); + + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "Edit..."); + RND_DAD_HELP(ctx->dlg, "Edit selected modification"); + RND_DAD_CHANGE_CB(ctx->dlg, setup_mod_edit_cb); + RND_DAD_BUTTON(ctx->dlg, "Add..."); + RND_DAD_HELP(ctx->dlg, "Create a new modification"); + RND_DAD_CHANGE_CB(ctx->dlg, setup_mod_add_cb); + RND_DAD_BUTTON(ctx->dlg, "Remove"); + RND_DAD_HELP(ctx->dlg, "Remove selected modification"); + RND_DAD_CHANGE_CB(ctx->dlg, setup_mod_del_cb); + RND_DAD_END(ctx->dlg); + + RND_DAD_END(ctx->dlg); + + RND_DAD_BEGIN_VBOX(ctx->dlg); /* TAB: output config */ + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_TREE(ctx->dlg, 3, 0, anals_tbl_hdr); + ctx->wanals_tree = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL | RND_HATF_SCROLL); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "Edit..."); + RND_DAD_CHANGE_CB(ctx->dlg, output_edit_cb); + RND_DAD_HELP(ctx->dlg, "Edit selected output"); + RND_DAD_BUTTON(ctx->dlg, "Add..."); + RND_DAD_CHANGE_CB(ctx->dlg, output_add_cb); + RND_DAD_HELP(ctx->dlg, "Create a new output"); + RND_DAD_BUTTON(ctx->dlg, "Remove"); + RND_DAD_CHANGE_CB(ctx->dlg, output_del_cb); + RND_DAD_HELP(ctx->dlg, "Remove selected output"); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + + RND_DAD_BEGIN_VBOX(ctx->dlg); /* TAB: run & output cfg */ + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL | RND_HATF_SCROLL); + for(n = 0; n < MAX_ANALS; n++) { + RND_DAD_BEGIN_VBOX(ctx->dlg); + ctx->out[n].wbox = RND_DAD_CURRENT(ctx->dlg); + if (n != 0) + RND_DAD_LABEL(ctx->dlg, "\n\n"); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, ""); + ctx->out[n].wname = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, ""); + ctx->out[n].wreadout = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_END(ctx->dlg); + RND_DAD_TEXT(ctx->dlg, NULL); + ctx->out[n].wtext = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_PREVIEW(ctx->dlg, plot_preview_expose_cb, plot_mouse_cb, NULL, NULL, &prvbb, 200, PLOT_PRV_Y, &ctx->out[n].pprv); + ctx->out[n].wplot = RND_DAD_CURRENT(ctx->dlg); + ctx->out[n].pprv.readout_cb = readout_plot_cb; + ctx->out[n].pprv.readout_begin_cb = readout_plot_begin_cb; + ctx->out[n].pprv.readout_end_cb = readout_plot_end_cb; + ctx->out[n].pprv.user_data = ctx; + ctx->out[n].pprv.widget_idx = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_BEGIN_HBOX(ctx->dlg); + ctx->out[n].wplot_ctrl = RND_DAD_CURRENT(ctx->dlg); +/* RND_DAD_BUTTON(ctx->dlg, "view");*/ + RND_DAD_BUTTON(ctx->dlg, "reset zoom"); + ctx->out[n].wplot_reset = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_CHANGE_CB(ctx->dlg, reset_zoom_cb); + RND_DAD_LABEL(ctx->dlg, " y zoom:"); + RND_DAD_REAL(ctx->dlg); + RND_DAD_HELP(ctx->dlg, "multiply values (y coords) to change aspect of the drawing"); + RND_DAD_MINMAX(ctx->dlg, 0.01, 10000); + ctx->out[n].wplot_yzoom = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_CHANGE_CB(ctx->dlg, yzoom_cb); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + } + RND_DAD_END(ctx->dlg); + + RND_DAD_END(ctx->dlg); + + + /* bottom buttons */ + RND_DAD_BEGIN_HBOX(ctx->dlg); + if (ctx->view_names.used > 0) { + RND_DAD_LABEL(ctx->dlg, "view:"); + RND_DAD_ENUM(ctx->dlg, ctx->view_names.array); + ctx->wview = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "activate"); + RND_DAD_HELP(ctx->dlg, "activate the sim target and the test_bench stance associated with this simulation setup"); + RND_DAD_CHANGE_CB(ctx->dlg, activate_cb); + RND_DAD_BUTTON(ctx->dlg, "run"); + RND_DAD_HELP(ctx->dlg, "activate this simulation setup, run the simulator and present the results in the \"run & output\" tab"); + RND_DAD_CHANGE_CB(ctx->dlg, run_cb); + } + else { + RND_DAD_LABEL(ctx->dlg, "There's no sim capable view"); + RND_DAD_HELP(ctx->dlg, "There must be at least one view that has a target_sim_* target, else activating or running the simulation is not possible"); + } + + RND_DAD_BEGIN_VBOX(ctx->dlg); /* spring */ + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_END(ctx->dlg); + + RND_DAD_BUTTON_CLOSES(ctx->dlg, clbtn); + RND_DAD_END(ctx->dlg); + + RND_DAD_END(ctx->dlg); + + title = rnd_concat("Simulation setup \"", name, "\"", NULL); + + RND_DAD_DEFSIZE(ctx->dlg, 300, 500); + RND_DAD_NEW("SimulationSetupDialog", ctx->dlg, title, ctx, 0, sim_setup_dlg_close_cb); /* type=local */ + + for(n = 0; n < MAX_ANALS; n++) + ctx->out[n].pprv.hid_ctx = ctx->dlg_hid_ctx; + + free(title); + sch_sim_setup_sch2dlg(ctx); + run2out_reset(ctx); +} + +const char csch_acts_SimSetupDlg[] = "SimDlg(setup_name)"; +const char csch_acth_SimSetupDlg[] = "Open the sim(ulation) setup/run dialog for the named setup in the current project\n"; +fgw_error_t csch_act_SimSetupDlg(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_design_t *dsg = RND_ACT_DESIGN; + const char *name; + + RND_ACT_CONVARG(1, FGW_STR, SimSetupDlg, name = argv[1].val.str); + + sim_setup_dlg((csch_project_t *)dsg->project, name); + return 0; +} + +static void sim_setup_dlg_prj_unload(rnd_project_t *prj) +{ + sim_setup_dlg_ctx_t *ctx, *next; + + /* close all dialogs referring to this project */ + for(ctx = gdl_first(&dlgs); ctx != NULL; ctx = next) { + next = gdl_next(&dlgs, ctx); + + if (&ctx->prj->hdr == prj) { + rnd_dad_retovr_t retovr = {0}; + gdl_remove(&dlgs, ctx, link); + rnd_hid_dad_close(ctx->dlg_hid_ctx, &retovr, 0); + } + } +} + +void sim_setup_dlg_setup_removed(const char *setup_name) +{ + sim_setup_dlg_ctx_t *ctx, *next; + + /* close all dialogs referring to this project */ + for(ctx = gdl_first(&dlgs); ctx != NULL; ctx = next) { + next = gdl_next(&dlgs, ctx); + + if (strcmp(ctx->name, setup_name) == 0) { + rnd_dad_retovr_t retovr = {0}; + gdl_remove(&dlgs, ctx, link); + rnd_hid_dad_close(ctx->dlg_hid_ctx, &retovr, 0); + } + } +} + +static void sim_setup_dlg_uninit(void) +{ + sim_setup_dlg_ctx_t *ctx; + + while((ctx = gdl_first(&dlgs)) != NULL) { + rnd_dad_retovr_t retovr = {0}; + + gdl_remove(&dlgs, ctx, link); + rnd_hid_dad_close(ctx->dlg_hid_ctx, &retovr, 0); + } +} + + +static void sim_setup_dlg_init(void) +{ +} + Index: tags/1.0.5/src/plugins/sim_gui/sim_setup_dlg.h =================================================================== --- tags/1.0.5/src/plugins/sim_gui/sim_setup_dlg.h (nonexistent) +++ tags/1.0.5/src/plugins/sim_gui/sim_setup_dlg.h (revision 10414) @@ -0,0 +1,9 @@ +#include + +static void sim_setup_dlg(csch_project_t *prj, const char *name); + +static void sim_setup_dlg_uninit(void); +static void sim_setup_dlg_init(void); + +void sim_setup_dlg_setup_removed(const char *setup_name); + Index: tags/1.0.5/src/plugins/sim_ngspice/Makefile =================================================================== --- tags/1.0.5/src/plugins/sim_ngspice/Makefile (nonexistent) +++ tags/1.0.5/src/plugins/sim_ngspice/Makefile (revision 10414) @@ -0,0 +1,2 @@ +all: + cd ../../sch-rnd && make mod_sim_ngspice Index: tags/1.0.5/src/plugins/sim_ngspice/Plug.tmpasm =================================================================== --- tags/1.0.5/src/plugins/sim_ngspice/Plug.tmpasm (nonexistent) +++ tags/1.0.5/src/plugins/sim_ngspice/Plug.tmpasm (revision 10414) @@ -0,0 +1,10 @@ +put /local/rnd/mod {sim_ngspice} +put /local/rnd/mod/OBJS [@ + $(PLUGDIR)/sim_ngspice/sim_ngspice.o +@] + +switch /local/module/sim_ngspice/controls + case {buildin} include /local/csch/tmpasm/buildin; end; + case {plugin} include /local/csch/tmpasm/plugin; end; + case {disable} include /local/csch/tmpasm/disable; end; +end Index: tags/1.0.5/src/plugins/sim_ngspice/sim_ngspice.c =================================================================== --- tags/1.0.5/src/plugins/sim_ngspice/sim_ngspice.c (nonexistent) +++ tags/1.0.5/src/plugins/sim_ngspice/sim_ngspice.c (revision 10414) @@ -0,0 +1,633 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - ngspice to high level sim glue + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +static const fgw_eng_t *target_spice; /* wrap target_spice */ + +static const char sim_ngspice_cookie[] = "sim_ngspice"; + +struct sch_sim_setup_s { /* per simulation data */ + gds_t tmpdir; + int tmpdir_restore; + vtp0_t output; /* pairs of analysis + presentation */ + gds_t read_buff; +}; + +static void tempdir_restore(sch_sim_setup_t *setup) +{ + if (setup->tmpdir.array != NULL) + setup->tmpdir.used = setup->tmpdir_restore; +} + + +static sch_sim_setup_t *se_ngspice_alloc(void) +{ + sch_sim_setup_t *setup = calloc(sizeof(sch_sim_setup_t), 1); + rnd_design_t *dsg = rnd_multi_get_current(); + + if (setup == NULL) + return NULL; + + + if (rnd_mktempdir(dsg, &setup->tmpdir, "sch-rnd-sim") != 0) { + free(setup); + return NULL; + } + + gds_append(&setup->tmpdir, RND_DIR_SEPARATOR_C); + setup->tmpdir_restore = setup->tmpdir.used; + + return setup; +} + +static void se_ngspice_free(sch_sim_setup_t *setup) +{ + rnd_design_t *dsg = rnd_multi_get_current(); + long n; + + for(n = 0; n < setup->output.used; n+=2) { + sch_sim_analysis_free(setup->output.array[n+0]); + sch_sim_presentation_free(setup->output.array[n+1]); + } + + tempdir_restore(setup); + setup->tmpdir.array[setup->tmpdir.used] = '\0'; + if (sch_sim_conf.plugins.sim.preserve_tmp) + rnd_message(RND_MSG_INFO, "Not removing sim tmp dir %s\n(as requested by the config node plugins/sim/preserve_tmp)\n", setup->tmpdir); + else + rnd_rmtempdir(dsg, &setup->tmpdir); + + gds_uninit(&setup->read_buff); + + free(setup); +} + +#include +#include +#include +#include + +static int sim_export(rnd_design_t *dsg, char *exporter_name, int argc, char *args[]) +{ + if (rnd_hid_export_using(dsg, exporter_name, argc, args) < 0) { + rnd_message(RND_MSG_ERROR, "sim_ngspice circuit export failed: spice exporter not found (see above).\n"); + return -1; + } + + return 0; +} + +static const char *cirname(sch_sim_setup_t *setup) +{ + gds_append_str(&setup->tmpdir, "prj.cir"); + tempdir_restore(setup); + return setup->tmpdir.array; +} + +static int se_ngspice_set_global(csch_abstract_t *abst, int eng_prio, const char *name, fgw_arg_t *val) +{ + gds_t tmp = {0}; + + if (strcmp(name, "temp") == 0) { + csch_acomp_t *comp; + csch_source_arg_t *src; + + fgw_arg_conv(&rnd_fgw, val, FGW_STR); + gds_append_str(&tmp, ".temp "); + gds_append_str(&tmp, val->val.str); + + comp = csch_acomp_get(abst, "sim_ngspice_env_temp"); + if (comp == NULL) + csch_acomp_new(abst, abst->hroot, CSCH_ASCOPE_GLOBAL, "sim_ngspice_env_temp", "sim_ngspice_env_temp"); + + + src = csch_attrib_src_p("sim_ngspice", "'temp' modifier"); + csch_attrib_set(&comp->hdr.attr, eng_prio + CSCH_PRI_PLUGIN_NORMAL, "spice/command", tmp.array, src, NULL); + } + + gds_uninit(&tmp); + return 0; +} + + +static int se_ngspice_add_circuit(sch_sim_setup_t *setup) +{ + rnd_design_t *dsg = rnd_multi_get_current(); + char *args[128]; + int argc, res; + + + argc = 0; + args[argc++] = "--outfile"; + args[argc++] = (char *)cirname(setup); /* as of 4.0.x the export API doesn't yet take const char *[] but it won't modify the strings anyway */ + args[argc] = NULL; + + res = sim_export(dsg, "spice", argc, args); + + return res; +} + +static int se_ngspice_add_output(sch_sim_setup_t *setup, sch_sim_analysis_t *an, sch_sim_presentation_t *pres) +{ + vtp0_append(&setup->output, an); + vtp0_append(&setup->output, pres); + return 0; +} + +static void se_ngspice_mod_add_params(csch_project_t *prj, csch_acomp_t *comp, sch_sim_mod_device_t device, const char *value, const char *ac_value, sch_sim_mod_tdf_t tdf, lht_node_t *tdf_params, int eng_prio, lht_node_t *mod, long mod_idx) +{ + csch_source_arg_t *src; + int val_appended = 0, supports_tdf = 0; + gds_t tmp = {0}; + + if ((device >= 0) && (device < SCH_SIMDEV_max)) + supports_tdf = sch_sim_device_has_tdf[device]; + + if (tdf == SCH_SIMTDF_invalid) + rnd_message(RND_MSG_ERROR, "Ignoring invalid tdf in sim mod 'add' #%ld\n", mod_idx); + + switch(device) { + case SCH_SIMDEV_V: + case SCH_SIMDEV_I: + if (value != NULL) { + gds_append_str(&tmp, "dc "); + gds_append_str(&tmp, value); + val_appended = 1; + } + if (ac_value != NULL) { + if (val_appended) + gds_append(&tmp, ' '); + gds_append_str(&tmp, "ac "); + gds_append_str(&tmp, ac_value); + val_appended = 1; + } + break; + default: + val_appended = 0; + } + + + if ((tdf > SCH_SIMTDF_NONE) && (tdf < SCH_SIMTDF_max) && supports_tdf) { + const sch_sim_mod_tdf_param_t *p, *partab = sch_sim_mod_tdf_params[tdf]; + + if (!val_appended && (value != NULL)) + rnd_message(RND_MSG_ERROR, "Ignoring value (in sim mod 'add' #%ld) because tdf is also specified\n", mod_idx); + + if (val_appended) + gds_append(&tmp, ' '); + + gds_append_str(&tmp, sch_simmod_tdf_names[tdf]); + gds_append(&tmp, '('); + + for(p = partab; p->name != NULL; p++) { + lht_node_t *nd = lht_dom_hash_get(tdf_params, p->name); + const char *nds = NULL; + + if ((nd != NULL) && (nd->type == LHT_TEXT)) { + nds = nd->data.text.value; + while(isspace(*nds)) nds++; + if (*nds == '\0') nds = NULL; + } + + if (nds == NULL) { + if (p->optional) + break; /* first missing optional; stop emitting parameters */ + rnd_message(RND_MSG_ERROR, "Missing mandatory tdf parameter '%s' (in sim mod 'add' #%ld)\n", p->name, mod_idx); + continue; /* do not append */ + } + + if (p != partab) + gds_append_str(&tmp, ", "); + gds_append_str(&tmp, nds); + } + gds_append(&tmp, ')'); + src = csch_attrib_src_p("sim_ngspice", "'add' modifier, tdf value"); + csch_attrib_set(&comp->hdr.attr, eng_prio + CSCH_PRI_PLUGIN_NORMAL, "value", tmp.array, src, NULL); + } + else if (value != NULL) { + src = csch_attrib_src_p("sim_ngspice", "'add' modifier, scalar value"); + if (val_appended) + csch_attrib_set(&comp->hdr.attr, eng_prio + CSCH_PRI_PLUGIN_NORMAL, "value", tmp.array, src, NULL); + else + csch_attrib_set(&comp->hdr.attr, eng_prio + CSCH_PRI_PLUGIN_NORMAL, "value", value, src, NULL); + } + else { + rnd_message(RND_MSG_ERROR, "No value for %c (in sim mod 'add' #%ld)\n", comp->name[0], mod_idx); + } + + gds_uninit(&tmp); +} + +static void fprint_prop_nets(FILE *f, csch_project_t *prj, vts0_t *props) +{ + long m; + + for(m = 0; m < props->used; m++) { + const char *addr = props->array[m]; + char *sep; + csch_anet_t *anet; + + /* remove function wrapping, like vdb() */ + sep = strchr(addr, '('); + if (sep != NULL) { + char *end, *freeme = rnd_strdup(sep+1); + end = strrchr(freeme, ')'); + if (end != NULL) + *end = '\0'; + anet = sch_sim_lookup_net(prj->abst, freeme, 0); + if (anet != NULL) { + gds_t tmp = {0}; + gds_append_len(&tmp, addr, sep-addr+1); + gds_append_str(&tmp, anet->name); + gds_append(&tmp, ')'); + free(freeme); + fprintf(f, " %s", tmp.array); + gds_uninit(&tmp); + } + else + rnd_message(RND_MSG_ERROR, "sim: can't print or plot %s: not found\n", addr); + } + else { + anet = sch_sim_lookup_net(prj->abst, addr, 0); + if (anet != NULL) + fprintf(f, " %s", anet->name); + else + rnd_message(RND_MSG_ERROR, "sim: can't print or plot %s: not found\n", addr); + } + } +} + +static int se_ngspice_exec(csch_project_t *prj, sch_sim_setup_t *setup) +{ + FILE *fcmd, *f; + rnd_design_t *dsg = prj->hdr.designs.array[0]; + const char *cmdname = "cmd"; + char *line, line_[1024], *cmd; + long n; + + gds_append_str(&setup->tmpdir, "cmd"); + tempdir_restore(setup); + cmdname = setup->tmpdir.array; + cmd = rnd_concat("ngspice -b ", cmdname, NULL); + + fcmd = rnd_fopen(dsg, cmdname, "w"); + + fprintf(fcmd, ".include %s\n\n", cirname(setup)); + fprintf(fcmd, ".control\n"); + + for(n = 0; n < setup->output.used; n+=2) { + sch_sim_analysis_t *an = setup->output.array[n+0]; + sch_sim_presentation_t *pres = setup->output.array[n+1]; + + rnd_append_printf(&setup->tmpdir, "out.%ld", n); + tempdir_restore(setup); + pres->outfn = rnd_strdup(setup->tmpdir.array); + + fprintf(fcmd, "echo @@@output %ld of %ld to %s\n", n/2, setup->output.used/2, pres->outfn); + switch(an->type) { + case SCH_SIMAN_OP: fprintf(fcmd, "op\n"); break; + case SCH_SIMAN_TRAN_LIN: fprintf(fcmd, "tran %s %s\n", an->incr, an->stop); break; + case SCH_SIMAN_AC_DEC: fprintf(fcmd, "ac dec %d %s %s\n", an->numpt, an->start, an->stop); break; + case SCH_SIMAN_AC_OCT: fprintf(fcmd, "ac oct %d %s %s\n", an->numpt, an->start, an->stop); break; + case SCH_SIMAN_AC_LIN: fprintf(fcmd, "ac lin %d %s %s\n", an->numpt, an->start, an->stop); break; + case SCH_SIMAN_DC_LIN: fprintf(fcmd, "dc %s %s %s %s\n", an->src, an->start, an->stop, an->incr); break; + case SCH_SIMAN_DC_DISTO_DEC: fprintf(fcmd, "disto dec %d %s %s\n", an->numpt, an->start, an->stop); break; + case SCH_SIMAN_DC_DISTO_OCT: fprintf(fcmd, "disto oct %d %s %s\n", an->numpt, an->start, an->stop); break; + case SCH_SIMAN_DC_DISTO_LIN: fprintf(fcmd, "disto lin %d %s %s\n", an->numpt, an->start, an->stop); break; + case SCH_SIMAN_DC_NOISE_DEC: fprintf(fcmd, "noise v(%s) %s dec %d %s %s\n", an->port2, an->port1, an->numpt, an->start, an->stop); break; + + case SCH_SIMAN_PREVIOUS: break; /* do not print anything */ + + case SCH_SIMAN_invalid: + rnd_message(RND_MSG_ERROR, "se_ngspice_exec(): invalid analysis type - using previous\n"); + break; + } + + switch(pres->type) { + case SCH_SIMPRES_PRINT: +/* Rather use wrdata so the same result reader works */ +/* fprintf(fcmd, "print"); + fprint_prop_nets(fcmd, prj, &pres->props); + fprintf(fcmd, " > %s\n", pres->outfn); + break;*/ + + case SCH_SIMPRES_PLOT: + fprintf(fcmd, "wrdata %s", pres->outfn); + fprint_prop_nets(fcmd, prj, &pres->props); + fprintf(fcmd, "\n"); + break; + + case SCH_SIMPRES_invalid: + rnd_message(RND_MSG_ERROR, "se_ngspice_exec(): invalid presentation type\n"); + break; + } + } + + fprintf(fcmd, ".endc\n"); + fclose(fcmd); + + f = rnd_popen(dsg, cmd, "r"); + while((line = fgets(line_, sizeof(line_), f)) != NULL) + printf(" line=%s", line); + + rnd_pclose(f); + + free(cmd); + + return 0; +} + +static void *se_ngspice_result_open(csch_project_t *prj, sch_sim_setup_t *setup, int output_idx) +{ + sch_sim_presentation_t *pres; + long n = output_idx*2+1; + rnd_design_t *dsg = prj->hdr.designs.array[0]; + + if ((n < 0) || (n >= setup->output.used)) + return NULL; + + pres = setup->output.array[n]; + if (pres == NULL) + return NULL; + + return rnd_fopen(dsg, pres->outfn, "r"); +} + +static void se_ngspice_result_close(sch_sim_setup_t *setup, void *stream) +{ + if (stream != NULL) + fclose(stream); +} + +static int se_ngspice_result_read(sch_sim_setup_t *setup, void *stream, vts0_t *dst) +{ + char *s, *start; + + if (dst != NULL) { + setup->read_buff.used = 0; + dst->used = 0; + } + + for(;;) { + int c = fgetc(stream); + if (c == EOF) + return -1; + if (((c == '\n') || (c == '\r')) && ((setup->read_buff.used > 0) || (dst == NULL))) + break; + if (dst != NULL) + gds_append(&setup->read_buff, c); + } + + /* append every 2nd field */ + if (dst != NULL) { + int idx = 0; + + /* ltrim */ + for(s = setup->read_buff.array; isspace(*s); s++) ; + + for(start = s; *s != '\0'; s++) { + if (isspace(*s)) { + *s = '\0'; + if ((idx % 2) == 1) + vts0_append(dst, start); + idx++; + s++; + while(isspace(*s)) s++; + start = s; + s--; + } + } + + /* append time */ + vts0_append(dst, setup->read_buff.array); + } + return 0; +} + +void se_ngspice_result_rewind(sch_sim_setup_t *setup, void *stream) +{ + if (stream != NULL) + rewind(stream); +} + + + +static sch_sim_exec_t sim_ngspice_sim_exec = { + "ngspice", + se_ngspice_alloc, se_ngspice_free, + se_ngspice_set_global, + se_ngspice_add_circuit, + se_ngspice_add_output, + se_ngspice_mod_add_params, + se_ngspice_exec, + se_ngspice_result_open, + se_ngspice_result_close, + se_ngspice_result_read, + se_ngspice_result_rewind +}; + + +/*** hooks ***/ + +static fgw_error_t (*spice_compile_project_after)(fgw_arg_t *res, int argc, fgw_arg_t *argv); +static fgw_error_t (*spice_compile_project_before)(fgw_arg_t *res, int argc, fgw_arg_t *argv); +static fgw_error_t (*spice_compile_component0)(fgw_arg_t *res, int argc, fgw_arg_t *argv); + +typedef struct sim_ngspice_trans_s { + int ontb; +} sim_ngspice_trans_t; + +static fgw_error_t sim_ngspice_compile_project_before(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + csch_hook_call_ctx_t *cctx = argv[0].val.argv0.user_call_ctx; +/* fgw_obj_t *obj = argv[0].val.argv0.func->obj;*/ +/* spicelib_ctx_t *ctx = obj->script_data; - because the object is used there */ + csch_abstract_t *abst; + csch_project_t *prj; + sim_ngspice_trans_t *trans; + + CSCH_HOOK_CONVARG(1, FGW_STRUCT|FGW_PTR, std_cschem_comp_update, abst = argv[1].val.ptr_void); + CSCH_HOOK_CONVARG(2, FGW_STRUCT|FGW_PTR, std_cschem_comp_update, prj = argv[2].val.ptr_void); + + sch_sim_set_test_bench(prj, abst, sim_ngspice_cookie, cctx->view_eng->eprio); + + trans = malloc(sizeof(sim_ngspice_trans_t)); + trans->ontb = sch_sim_omit_no_test_bench_is_on(prj); + htpp_set(&abst->eng_transient, (void *)sim_ngspice_cookie, trans); + + + /* call through to the spice backend */ + if (spice_compile_project_before != NULL) + return spice_compile_project_before(res, argc, argv); + + return 0; +} + +static fgw_error_t sim_ngspice_compile_project_after(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + int r = 0; + csch_hook_call_ctx_t *cctx = argv[0].val.argv0.user_call_ctx; +/* fgw_obj_t *obj = argv[0].val.argv0.func->obj;*/ +/* spicelib_ctx_t *ctx = obj->script_data; - because the object is used there */ + csch_abstract_t *abst; + csch_project_t *prj; + sim_ngspice_trans_t *trans; + + CSCH_HOOK_CONVARG(1, FGW_STRUCT|FGW_PTR, std_cschem_comp_update, abst = argv[1].val.ptr_void); + CSCH_HOOK_CONVARG(2, FGW_STRUCT|FGW_PTR, std_cschem_comp_update, prj = argv[2].val.ptr_void); + + /* call through to the spice backend */ + if (spice_compile_project_after != NULL) + r = spice_compile_project_after(res, argc, argv); + + sch_sim_restore_test_bench(prj, abst, sim_ngspice_cookie, cctx->view_eng->eprio); + + trans = htpp_pop(&abst->eng_transient, (void *)sim_ngspice_cookie); + free(trans); + + if (sch_sim_mods_perform(prj, NULL, abst, &sim_ngspice_sim_exec, cctx->view_eng->eprio) != 0) + return -1; + + return r; +} + +static fgw_error_t sim_ngspice_compile_component0(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + int r = 0; + csch_hook_call_ctx_t *cctx = argv[0].val.argv0.user_call_ctx; + csch_acomp_t *comp; + sim_ngspice_trans_t *trans; + csch_abstract_t *abst; + + + CSCH_HOOK_CONVARG(1, FGW_AOBJ, std_forge_comp_update, comp = fgw_aobj(&argv[1])); + assert(comp->hdr.type == CSCH_ATYPE_COMP); + + abst = comp->hdr.abst; + trans = htpp_get(&abst->eng_transient, (void *)sim_ngspice_cookie); + + if ((trans != NULL) && trans->ontb) + sch_sim_omit_no_test_bench_comp(comp, cctx->view_eng->eprio); + + /* call through to the spice backend */ + if (spice_compile_component0 != NULL) + r = spice_compile_component0(res, argc, argv); + + return r; +} + +static fgw_error_t sim_ngspice_sim_exec_get(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + res->type = FGW_PTR | FGW_STRUCT; + res->val.ptr_void = &sim_ngspice_sim_exec; + return 0; +} + +static int on_load(fgw_obj_t *obj, const char *filename, const char *opts) +{ + int res; + + fgw_func_reg(obj, "sim_exec_get", sim_ngspice_sim_exec_get); + + /* on the target level we are mostly a transparent wrapper around target_spice */ + res = target_spice->load(obj, filename, opts); + if (res != 0) + return res; + + + /* hook some of the calls */ + sch_sim_hook_eng_call(obj, "compile_project_before", &spice_compile_project_before, sim_ngspice_compile_project_before); + sch_sim_hook_eng_call(obj, "compile_project_after", &spice_compile_project_after, sim_ngspice_compile_project_after); + sch_sim_hook_eng_call(obj, "compile_component0", &spice_compile_component0, sim_ngspice_compile_component0); + + return 0; +} + +static int on_unload(fgw_obj_t *obj) +{ + target_spice->unload(obj); + return 0; +} + + +static const fgw_eng_t fgw_sim_ngspice_eng = { + "target_sim_ngspice", + csch_c_call_script, + NULL, + on_load, + on_unload +}; + +int pplg_check_ver_sim_ngspice(int ver_needed) { return 0; } + +void pplg_uninit_sim_ngspice(void) +{ +} + +int pplg_init_sim_ngspice(void) +{ + RND_API_CHK_VER; + + target_spice = fgw_eng_lookup("target_spice"); + if (target_spice == NULL) { + rnd_message(RND_MSG_ERROR, "target_sim_spice: can't find target_spice\n"); + return -1; + } + + fgw_eng_reg(&fgw_sim_ngspice_eng); + + return 0; +} + Index: tags/1.0.5/src/plugins/sim_ngspice/sim_ngspice.pup =================================================================== --- tags/1.0.5/src/plugins/sim_ngspice/sim_ngspice.pup (nonexistent) +++ tags/1.0.5/src/plugins/sim_ngspice/sim_ngspice.pup (revision 10414) @@ -0,0 +1,9 @@ +$class feature +$short sim exec for ngspice +$long ngspice specific execution glue (for the GUI) +$state works +$package sim +default buildin +dep target_spice +dep sim +autoload 1 Index: tags/1.0.5/src/plugins/std_cschem/Makefile =================================================================== --- tags/1.0.5/src/plugins/std_cschem/Makefile (nonexistent) +++ tags/1.0.5/src/plugins/std_cschem/Makefile (revision 10414) @@ -0,0 +1,2 @@ +all: + cd ../../sch-rnd && make mod_std_cschem Index: tags/1.0.5/src/plugins/std_cschem/Plug.tmpasm =================================================================== --- tags/1.0.5/src/plugins/std_cschem/Plug.tmpasm (nonexistent) +++ tags/1.0.5/src/plugins/std_cschem/Plug.tmpasm (revision 10414) @@ -0,0 +1,14 @@ +put /local/rnd/mod {std_cschem} +put /local/rnd/mod/OBJS [@ + $(PLUGDIR)/std_cschem/std_cschem.o +@] + +put /local/rnd/mod/CONFFILE {std_cschem.conf} +put /local/rnd/mod/CONF {$(PLUGDIR)/std_cschem/std_cschem_conf.h} +put /local/rnd/mod/CONFVAR {std_cschem_conf_internal} + +switch /local/module/std_cschem/controls + case {buildin} include /local/csch/tmpasm/buildin; end; + case {plugin} include /local/csch/tmpasm/plugin; end; + case {disable} include /local/csch/tmpasm/disable; end; +end Index: tags/1.0.5/src/plugins/std_cschem/quick_attr_connect.c =================================================================== --- tags/1.0.5/src/plugins/std_cschem/quick_attr_connect.c (nonexistent) +++ tags/1.0.5/src/plugins/std_cschem/quick_attr_connect.c (revision 10414) @@ -0,0 +1,242 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - GUI + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/* quick-edit attribute: symbol connect list */ + +#include + +#include +#include + +typedef struct { + RND_DAD_DECL_NOINIT(dlg) + csch_sheet_t *sheet; + csch_cgrp_t *grp; + int changed; + int wlist, wadd, wsym, wnet; +} qa_connect_t; + +static void qa_connect_close_cb(void *caller_data, rnd_hid_attr_ev_t ev) +{ + +} + +static void qa_connect_sheet2dlg(qa_connect_t *ctx) +{ + rnd_hid_attribute_t *attr = &ctx->dlg[ctx->wlist]; + rnd_hid_tree_t *tree = attr->wdata; + rnd_hid_row_t *r; + char *cursor_path = NULL; + const vts0_t *arr; + + /* remember cursor */ + r = rnd_dad_tree_get_selected(attr); + if (r != NULL) + cursor_path = rnd_strdup(r->cell[0]); + + /* remove existing items */ + rnd_dad_tree_clear(tree); + + /* add all items */ + arr = csch_attrib_get_arr(&ctx->grp->attr, "connect"); + if (arr != NULL) { + long n; + char *cell[3]; + + cell[2] = NULL; + for(n = 0; n < arr->used; n++) { + char *c, *sep; + int found = 0; + + c = arr->array[n]; + for(sep = c; *sep != '\0'; sep++) { + if (sep[0] == ':') { + found = 1; + break; + } + } + if (found) { + cell[0] = rnd_strndup(c, sep-c); + cell[1] = rnd_strdup(sep+1); + } + else { + cell[0] = rnd_strdup(c); + cell[1] = NULL; + } + rnd_dad_tree_append(attr, NULL, cell); + } + } + + /* restore cursor */ + if (cursor_path != NULL) { + rnd_hid_attr_val_t hv; + hv.str = cursor_path; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wlist, &hv); + free(cursor_path); + } +} + +static void qa_connect_select_cb(rnd_hid_attribute_t *attrib, void *hid_ctx, rnd_hid_row_t *row) +{ + rnd_hid_tree_t *tree = attrib->wdata; + qa_connect_t *ctx = tree->user_ctx; + + if (row != NULL) { + rnd_hid_attr_val_t hv; + + hv.str = row->cell[0]; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wsym, &hv); + hv.str = row->cell[1]; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wnet, &hv); + } +} + +static long sym2idx(qa_connect_t *ctx, long *totlen, int err) +{ + const vts0_t *arr = csch_attrib_get_arr(&ctx->grp->attr, "connect"); + long n, len; + const char *sym = ctx->dlg[ctx->wsym].val.str, *end; + + if (totlen != NULL) { + if (arr == NULL) + *totlen = 0; + else + *totlen = arr->used; + } + + if (sym != NULL) + while(isspace(*sym)) sym++; + + if (((sym == NULL) || (*sym == '\0')) && err) { + rnd_message(RND_MSG_ERROR, "Please fill in the symbol side name\n"); + return -1; + } + + if ((arr == NULL) || (sym == NULL) || (*sym == '\0')) + return -1; + + end = strpbrk(sym, " \t\r\n"); + if (end != NULL) + len = end - sym; + else + len = strlen(sym); + + for(n = 0; n < arr->used; n++) { + char *a = arr->array[n]; + if ((strncmp(a, sym, len) == 0) && (a[len] == ':')) + return n; + } + + if (err) + rnd_message(RND_MSG_ERROR, "No entry found for symbol side name '%s'\n", sym); + + return -1; +} + +static void qa_connect_del_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + qa_connect_t *ctx = caller_data; + long idx = sym2idx(ctx, NULL, 1); + if (idx < 0) + return; + csch_attr_arr_modify_del(ctx->sheet, ctx->grp, "connect", idx, 1); + qa_connect_sheet2dlg(ctx); +} + +static void qa_connect_add_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + qa_connect_t *ctx = caller_data; + long totlen, idx = sym2idx(ctx, &totlen, 0); + const char *sym = ctx->dlg[ctx->wsym].val.str; + const char *net = ctx->dlg[ctx->wnet].val.str; + gds_t tmp = {0}; + + if ((sym == NULL) || (*sym == '\0') || (net == NULL) || (*net == '\0')) { + rnd_message(RND_MSG_ERROR, "Please fill in both symbol and terminal side names first!\n"); + return; + } + + gds_append_str(&tmp, sym); + gds_append_str(&tmp, ":"); + gds_append_str(&tmp, net); + + if (idx >= 0) + csch_attr_arr_modify_str(ctx->sheet, ctx->grp, "connect", idx, tmp.array, 1); + else + csch_attr_arr_modify_ins_before(ctx->sheet, ctx->grp, "connect", totlen, tmp.array, 1); + + qa_connect_sheet2dlg(ctx); + gds_uninit(&tmp); +} + +const char csch_acts_quick_attr_connect[] = "quick_attr_connect(objptr)"; +const char csch_acth_quick_attr_connect[] = "Quick Attribute Edit for core data model's symbol connect attribute (attribute based symbol terminal to network connection table)"; +fgw_error_t csch_act_quick_attr_connect(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + qa_connect_t ctx = {0}; + rnd_design_t *hidlib = RND_ACT_DESIGN; + rnd_hid_dad_buttons_t clbtn[] = {{"Close", 1}, {NULL, 0}}; + const char *hdr[] = {"Symbol term name", "Network name", NULL}; + + ctx.sheet = (csch_sheet_t *)hidlib; + ctx.changed = 0; + QUICK_ATTR_GET_GRP(ctx.grp, "quick_attr_connect"); + + RND_DAD_BEGIN_VBOX(ctx.dlg); + RND_DAD_COMPFLAG(ctx.dlg, RND_HATF_EXPFILL); + RND_DAD_TREE(ctx.dlg, 2, 0, hdr); + RND_DAD_COMPFLAG(ctx.dlg, RND_HATF_EXPFILL | RND_HATF_SCROLL); + ctx.wlist = RND_DAD_CURRENT(ctx.dlg); + RND_DAD_TREE_SET_CB(ctx.dlg, selected_cb, qa_connect_select_cb); + RND_DAD_TREE_SET_CB(ctx.dlg, ctx, &ctx); + RND_DAD_BEGIN_HBOX(ctx.dlg); + RND_DAD_LABEL(ctx.dlg, "Symbol term name:"); + RND_DAD_STRING(ctx.dlg); + ctx.wsym = RND_DAD_CURRENT(ctx.dlg); + RND_DAD_BUTTON(ctx.dlg, "Del"); + RND_DAD_CHANGE_CB(ctx.dlg, qa_connect_del_cb); + RND_DAD_END(ctx.dlg); + RND_DAD_BEGIN_HBOX(ctx.dlg); + RND_DAD_LABEL(ctx.dlg, "Network name:"); + RND_DAD_STRING(ctx.dlg); + ctx.wnet = RND_DAD_CURRENT(ctx.dlg); + RND_DAD_BUTTON(ctx.dlg, "Add/edit"); + ctx.wadd = RND_DAD_CURRENT(ctx.dlg); + RND_DAD_CHANGE_CB(ctx.dlg, qa_connect_add_cb); + RND_DAD_END(ctx.dlg); + RND_DAD_BUTTON_CLOSES(ctx.dlg, clbtn); + RND_DAD_END(ctx.dlg); + + RND_DAD_NEW("quick_attr_connect", ctx.dlg, "Set symbol connect list", &ctx, 1, qa_connect_close_cb); /* type=local/modal */ + qa_connect_sheet2dlg(&ctx); + RND_DAD_RUN(ctx.dlg); + + RND_ACT_IRES(ctx.changed); + + return 0; +} Index: tags/1.0.5/src/plugins/std_cschem/std_cschem.c =================================================================== --- tags/1.0.5/src/plugins/std_cschem/std_cschem.c (nonexistent) +++ tags/1.0.5/src/plugins/std_cschem/std_cschem.c (revision 10414) @@ -0,0 +1,298 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - standard cschem attributes + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "std_cschem_conf.h" +#include "conf_internal.c" + +static conf_std_cschem_t std_cschem_conf; + +#if 0 +typedef struct { +} std_cschem_ctx_t; /* per view data */ +#endif + +static const char std_cschem_cookie[] = "std_cschem"; + +/*** hooks ***/ + +RND_INLINE fgw_error_t render_hier_netname(fgw_arg_t *res, gds_t *prefix, const char *sname) +{ + gds_t tmp; + + gds_init(&tmp); + gds_append_len(&tmp, prefix->array, prefix->used); + gds_append_str(&tmp, sname); + res->type = FGW_STR | FGW_DYN; + res->val.str = tmp.array; + + return 0; +} + +fgw_error_t std_cschem_wirenet_name_to_net_name(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *sname; + csch_hier_path_t *hpath; + csch_chdr_t *wnet; + + CSCH_HOOK_CONVARG(1, FGW_STR, std_cschem_wirenet_name_to_net_name, sname = argv[1].val.cstr); + CSCH_HOOK_CONVARG(2, FGW_COBJ, std_cschem_wirenet_name_to_net_name, wnet = fgw_cobj(&argv[2])); + CSCH_HOOK_CONVARG(3, FGW_HPATH, std_cschem_wirenet_name_to_net_name, hpath = fgw_hpath(&argv[3])); + + if (sname == NULL) + return 0; + + return render_hier_netname(res, &hpath->prefix, sname); +} + +fgw_error_t std_cschem_attrib_net_name_to_net_name(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *sname; + csch_hier_path_t *hpath; + csch_acomp_t *acomp; + gds_t prefix = {0}; + fgw_error_t retval; + + CSCH_HOOK_CONVARG(1, FGW_STR, std_cschem_attrib_net_name_to_net_name, sname = argv[1].val.cstr); + CSCH_HOOK_CONVARG(2, FGW_AOBJ, std_cschem_attrib_net_name_to_net_name, acomp = fgw_aobj(&argv[2])); + + if (sname == NULL) + return 0; + + csch_hier_build_path(&prefix, acomp->hlev); + retval = render_hier_netname(res, &prefix, sname); + gds_uninit(&prefix); + + return retval; +} + +fgw_error_t std_cschem_symbol_name_to_component_name(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *sname, *end; + int preflen; + gds_t tmp; + csch_chdr_t *sym, *o; + csch_hier_path_t *hpath; + +/* fgw_obj_t *obj = argv[0].val.argv0.func->obj;*/ +/* std_cschem_ctx_t *ctx = obj->script_data; */ + + CSCH_HOOK_CONVARG(1, FGW_STR, std_cschem_symbol_name_to_component_name, sname = argv[1].val.cstr); + CSCH_HOOK_CONVARG(2, FGW_COBJ, std_cschem_symbol_name_to_component_name, sym = fgw_cobj(&argv[2])); + CSCH_HOOK_CONVARG(3, FGW_HPATH, std_cschem_symbol_name_to_component_name, hpath = fgw_hpath(&argv[3])); + + if (sname == NULL) + return 0; + + + if (!std_cschem_conf.plugins.std_cschem.fix_unnamed_syms) { + normal_hprefix:; + if (hpath->prefix.used > 0) { /* apply hierarchic prefix */ + gds_init(&tmp); + gds_append_len(&tmp, hpath->prefix.array, hpath->prefix.used); + gds_append_str(&tmp, sname); + res->type = FGW_STR | FGW_DYN; + res->val.str = tmp.array; + } + return 0; + } + + end = sname + strlen(sname) - 1; + if (*end != '?') + goto normal_hprefix; + + while((*end == '?') && (end >= sname)) end--; + preflen = end - sname + 1; + + gds_init(&tmp); + + if (hpath->prefix.used > 0) + gds_append_len(&tmp, hpath->prefix.array, hpath->prefix.used); + + if (preflen > 0) + gds_append_len(&tmp, sname, preflen); + else + gds_append_str(&tmp, "anon"); + + gds_append(&tmp, '_'); + + for(o = sym; o->parent != NULL; o = &o->parent->hdr) + rnd_append_printf(&tmp, "_%ld", o->oid); + + rnd_message(RND_MSG_INFO, "Compile: renaming component '%s' to '%s'; please name your symbols!\n", sname, tmp.array); + + res->type = FGW_STR | FGW_DYN; + res->val.str = tmp.array; + return 0; +} + + +fgw_error_t std_cschem_compile_comp1(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ +/* fgw_obj_t *obj = argv[0].val.argv0.func->obj;*/ +/* std_cschem_ctx_t *ctx = obj->script_data; */ + csch_hook_call_ctx_t *cctx = argv[0].val.argv0.user_call_ctx; + csch_acomp_t *comp; + const csch_attrib_t *conn; + long n; + + CSCH_HOOK_CONVARG(1, FGW_AOBJ, std_cschem_comp_update, comp = fgw_aobj(&argv[1])); + assert(comp->hdr.type == CSCH_ATYPE_COMP); + + if (comp->hdr.omit) + return 0; + + conn = csch_attrib_get(&comp->hdr.attr, "connect"); + if (conn == NULL) + return 0; + + if (conn->val != NULL) { + rnd_message(RND_MSG_ERROR, "Abstract component's 'connect' attribute is not an array in '%s'\n", comp->name); + return -1; + } + + for(n = 0; n < conn->arr.used; n++) { + char tmp[1024]; + const char *sep; + char *portname, *netname; + int len; + + sep = strchr(conn->arr.array[n], ':'); + if (sep == NULL) { + rnd_message(RND_MSG_ERROR, "Abstract component ('%s') 'connect' attribute item doesn't have a ':' separator: '%s' (ignoring item)\n", comp->name, conn->arr.array[n]); + continue; + } + + len = strlen(conn->arr.array[n]); + if (len >= sizeof(tmp)) { + rnd_message(RND_MSG_ERROR, "Abstract component ('%s') 'connect' attribute too long: '%s' (ignoring item)\n", comp->name, conn->arr.array[n]); + continue; + } + len = sep - conn->arr.array[n]; + strcpy(tmp, conn->arr.array[n]); + portname = tmp; + netname = tmp+len; + *netname = '\0'; + netname++; + + if (csch_cmp_nameconn_port_net(cctx->project, comp, portname, netname, 1, cctx->view_id, cctx->hpath) < 0) { + csch_aport_t *port = csch_aport_get(comp->hdr.abst, comp, portname, 1); + rnd_message(RND_MSG_ERROR, "Abstract component ('%s') 'connect' attribute failed: '%s'\n", comp->name, conn->arr.array[n]); + if (port->conn.net == NULL) { + rnd_message(RND_MSG_ERROR, " Reason: symbol's connect attribute on an explicitly drawn terminal that's not connected to a wire\n"); + } + + + return -1; + } + } + + return 0; +} + +#include "quick_attr_connect.c" + + +static int on_load(fgw_obj_t *obj, const char *filename, const char *opts) +{ + fgw_func_reg(obj, "wirenet_name_to_net_name", std_cschem_wirenet_name_to_net_name); + fgw_func_reg(obj, "attrib_net_name_to_net_name", std_cschem_attrib_net_name_to_net_name); + fgw_func_reg(obj, "symbol_name_to_component_name", std_cschem_symbol_name_to_component_name); + fgw_func_reg(obj, "compile_component1", std_cschem_compile_comp1); + + /* initialize view-local cache */ + obj->script_data = /*calloc(sizeof(std_cschem_ctx_t), 1)*/ NULL; + + return 0; +} + +static int on_unload(fgw_obj_t *obj) +{ +/* std_cschem_ctx_t *ctx = obj->script_data; + free(ctx);*/ + return 0; +} + + +static const fgw_eng_t fgw_std_cschem_eng = { + "std_cschem", + csch_c_call_script, + NULL, + on_load, + on_unload +}; + +static rnd_action_t std_cschem_action_list[] = { + {"quick_attr_connect", csch_act_quick_attr_connect, csch_acth_quick_attr_connect, csch_acts_quick_attr_connect} +}; + +int pplg_check_ver_std_cschem(int ver_needed) { return 0; } + +void pplg_uninit_std_cschem(void) +{ + rnd_remove_actions_by_cookie(std_cschem_cookie); + rnd_conf_plug_unreg("plugins/std_cschem/", std_cschem_conf_internal, std_cschem_cookie); +} + +int pplg_init_std_cschem(void) +{ + RND_API_CHK_VER; + + fgw_eng_reg(&fgw_std_cschem_eng); + + RND_REGISTER_ACTIONS(std_cschem_action_list, std_cschem_cookie); + + rnd_conf_plug_reg(std_cschem_conf, std_cschem_conf_internal, std_cschem_cookie); +#define conf_reg(field,isarray,type_name,cpath,cname,desc,flags) \ + rnd_conf_reg_field(std_cschem_conf, field,isarray,type_name,cpath,cname,desc,flags); +#include "std_cschem_conf_fields.h" + + return 0; +} + Index: tags/1.0.5/src/plugins/std_cschem/std_cschem.conf =================================================================== --- tags/1.0.5/src/plugins/std_cschem/std_cschem.conf (nonexistent) +++ tags/1.0.5/src/plugins/std_cschem/std_cschem.conf (revision 10414) @@ -0,0 +1,9 @@ +li:pcb-rnd-conf-v1 { + ha:append { + ha:plugins { + ha:std_cschem { + fix_unnamed_syms = 1 + } + } + } +} Index: tags/1.0.5/src/plugins/std_cschem/std_cschem.pup =================================================================== --- tags/1.0.5/src/plugins/std_cschem/std_cschem.pup (nonexistent) +++ tags/1.0.5/src/plugins/std_cschem/std_cschem.pup (revision 10414) @@ -0,0 +1,7 @@ +$class engine +$short standard cschem attributes +$long Handles: component connect +$state works +$package (core) +default buildin +autoload 1 Index: tags/1.0.5/src/plugins/std_cschem/std_cschem_conf.h =================================================================== --- tags/1.0.5/src/plugins/std_cschem/std_cschem_conf.h (nonexistent) +++ tags/1.0.5/src/plugins/std_cschem/std_cschem_conf.h (revision 10414) @@ -0,0 +1,14 @@ +#ifndef SCH_RND_STD_CSCHEM_CONF_H +#define SCH_RND_STD_CSCHEM_CONF_H + +#include + +typedef struct { + const struct { + const struct { + RND_CFT_BOOLEAN fix_unnamed_syms; /* If a symbol's name ends in ?, rename it to something unqiue in the abstract model */ + } std_cschem; + } plugins; +} conf_std_cschem_t; + +#endif Index: tags/1.0.5/src/plugins/std_devmap/Makefile =================================================================== --- tags/1.0.5/src/plugins/std_devmap/Makefile (nonexistent) +++ tags/1.0.5/src/plugins/std_devmap/Makefile (revision 10414) @@ -0,0 +1,2 @@ +all: + cd ../../sch-rnd && make mod_std_devmap Index: tags/1.0.5/src/plugins/std_devmap/Plug.tmpasm =================================================================== --- tags/1.0.5/src/plugins/std_devmap/Plug.tmpasm (nonexistent) +++ tags/1.0.5/src/plugins/std_devmap/Plug.tmpasm (revision 10414) @@ -0,0 +1,14 @@ +put /local/rnd/mod {std_devmap} +put /local/rnd/mod/OBJS [@ + $(PLUGDIR)/std_devmap/std_devmap.o +@] + +put /local/rnd/mod/CONFFILE {std_devmap.conf} +put /local/rnd/mod/CONF {$(PLUGDIR)/std_devmap/std_devmap_conf.h} +put /local/rnd/mod/CONFVAR {std_devmap_conf_internal} + +switch /local/module/std_devmap/controls + case {buildin} include /local/csch/tmpasm/buildin; end; + case {plugin} include /local/csch/tmpasm/plugin; end; + case {disable} include /local/csch/tmpasm/disable; end; +end Index: tags/1.0.5/src/plugins/std_devmap/compiler.c =================================================================== --- tags/1.0.5/src/plugins/std_devmap/compiler.c (nonexistent) +++ tags/1.0.5/src/plugins/std_devmap/compiler.c (revision 10414) @@ -0,0 +1,225 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - standard device mapper + * Copyright (C) 2019,2020,2022,2023 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/*** compiler hooks ***/ + +fgw_error_t devmap_term2port(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ +/* csch_acomp_t *comp;*/ + csch_cgrp_t *term, *sym; + const char *pname; + const char *slot; + gds_t tmp; + csch_hier_path_t *hpath; + + CSCH_HOOK_CONVARG(1, FGW_STR, devmap_term2port, pname = argv[1].val.cstr); +/* CSCH_HOOK_CONVARG(2, FGW_AOBJ, devmap_term2port, comp = fgw_aobj(&argv[2]));*/ + CSCH_HOOK_CONVARG(3, FGW_COBJ, devmap_term2port, term = fgw_cobj(&argv[3])); + CSCH_HOOK_CONVARG(4, FGW_HPATH, devmap_term2port, hpath = fgw_hpath(&argv[4])); + + sym = term->hdr.parent; + slot = csch_attrib_get_str(&sym->attr, "-slot"); + if (slot == NULL) + slot = csch_attrib_get_str(&sym->attr, "slot"); + if (slot == NULL) + return 0; + + /* output port name is slot/input port name */ + gds_init(&tmp); + gds_append_str(&tmp, slot); + gds_append(&tmp, '/'); + gds_append_str(&tmp, pname); + res->type = FGW_STR | FGW_DYN; + res->val.str = tmp.array; + return 0; +} + + +fgw_error_t devmap_symbol_joined_comp(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ +/* csch_cgrp_t *sym;*/ + csch_acomp_t *comp; + csch_hook_call_ctx_t *cctx = argv[0].val.argv0.user_call_ctx; + csch_source_arg_t *del_src; + + +/* CSCH_HOOK_CONVARG(1, FGW_COBJ, devmap_comp_update, sym = fgw_cobj(&argv[1]));*/ + CSCH_HOOK_CONVARG(2, FGW_AOBJ, devmap_comp_update, comp = fgw_aobj(&argv[2])); + + del_src = csch_attrib_src_p("std_devmp", "symbol_joined_comp"); + + csch_attrib_del(&comp->hdr.attr, cctx->view_eng->eprio + CSCH_PRI_PLUGIN_NORMAL, "slot", del_src); + return 0; +} + +fgw_error_t devmap_compile_comp1(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + csch_project_t *prj; + anymap_ctx_t *actx; + csch_hook_call_ctx_t *cctx = argv[0].val.argv0.user_call_ctx; + csch_acomp_t *comp; + csch_attribs_t *comp_attrs; + csch_attrib_t *adevmap; + csch_source_arg_t *src; + int prio; + + CSCH_HOOK_CONVARG(1, FGW_AOBJ, devmap_comp_update, comp = fgw_aobj(&argv[1])); + assert(comp->hdr.type == CSCH_ATYPE_COMP); + + adevmap = csch_attrib_get(&comp->hdr.attr, "devmap"); + if (adevmap == NULL) + return 0; + + + prj = comp->hdr.abst->prj; + actx = csch_p4_get_by_project(&p4_devmap, prj); + + comp_attrs = anymap_get_from_any_lib(actx, comp, adevmap, argv[0].val.argv0.user_call_ctx); + if (comp_attrs == NULL) { + rnd_message(RND_MSG_ERROR, "Can't find devmap %s for component %s\n", (adevmap->val == NULL ? "" : adevmap->val), comp->name); + return -1; + } + + src = csch_attrib_src_pa(&comp->hdr, "devmap", "std_devmap", "devmap_compile_comp1"); + prio = cctx->view_eng->eprio + CSCH_PRI_PLUGIN_NORMAL; + csch_attrib_apply(&comp->hdr.attr, comp_attrs, src, &prio); + return 0; +} + +fgw_error_t devmap_compile_port(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + csch_hook_call_ctx_t *cctx = argv[0].val.argv0.user_call_ctx; + csch_source_arg_t *pm_src; + csch_acomp_t *comp; + csch_aport_t *port; + csch_attrib_t *portmap; + const char *slot = NULL; + long n, port_len, slot_len = 0; + int slot_inited = 0; + + CSCH_HOOK_CONVARG(1, FGW_AOBJ, devmap_comp_update, port = fgw_aobj(&argv[1])); + assert(port->hdr.type == CSCH_ATYPE_PORT); + comp = port->parent; + if ((comp == NULL) || (comp->hdr.type != CSCH_ATYPE_COMP)) + return 0; /* ignore sheet ports */ + + portmap = csch_attrib_get(&comp->hdr.attr, "portmap"); + if (portmap == NULL) + return 0; + + if (portmap->val != NULL) { + rnd_message(RND_MSG_ERROR, "Portmap of component '%s' is not an array but a string\n", comp->name); + return -1; + } + + port_len = strlen(port->name); + for(n = 0; n < portmap->arr.used; n++) { + char tmp[256], *ktmp = NULL, *key; + const char *pm = portmap->arr.array[n], *set = NULL, *sep, *val; +/* const char *pm_port = pm;*/ + int pm_slotlen = 0; + int pm_portlen; + + /* parse: find '->' and '/' on the left side of it */ + for(sep = pm; *sep != '\0'; sep++) { + if ((sep[0] == '-') && (sep[1] == '>')) { + pm_portlen = sep - pm - 1; + while((pm_portlen > 0) && isspace(pm[pm_portlen])) pm_portlen--; + pm_portlen++; + set = sep + 2; + break; + } + else if ((*sep == '/') && (sep > pm)) { + pm_slotlen = sep - pm; +/* pm_port = sep + 1;*/ + } + } + + if (set == NULL) /* no "->" in string */ + continue; + + /* match slot if pm has slash on the left side */ + if (pm_slotlen > 0) { + if (!slot_inited) { + vtp0_t *srcs = &port->hdr.srcs; + long n; + + for(n = 0; n < srcs->used; n++) { + csch_cgrp_t *cgrp = srcs->array[n]; + const char *stmp; + + if (cgrp->role == CSCH_ROLE_TERMINAL) + cgrp = cgrp->hdr.parent; + + stmp = csch_attrib_get_str(&cgrp->attr, "-slot"); + if (stmp == NULL) + stmp = csch_attrib_get_str(&cgrp->attr, "slot"); + if (slot != NULL) { + if (strcmp(slot, stmp) != 0) + rnd_message(RND_MSG_ERROR, "std_devmap: incompatible slot names found for component '%s' port '%s': '%s' and '%s'\n", comp->name, port->name, slot, stmp); + } + else + slot = stmp; + } + if (slot != NULL) + slot_len = strlen(slot); + /* NOTE: slot == NULL is not an error: in inhomogoeneous slotting + single-instance slots, like power of a 74xx would have no slot= + argument */ + slot_inited = 1; + } + + if ((slot == NULL) || (slot_len != pm_slotlen)) continue; + if (strncmp(pm, slot, slot_len) != 0) continue; + } + + /* match left side of "->" with port name, assuming port->name is already in slot/name format */ + if ((pm_portlen != port_len) || (strncmp(pm, port->name, port_len) != 0)) continue; + + /* parse the right side */ + sep = strchr(set, '='); + if (sep == NULL) { + rnd_message(RND_MSG_ERROR, "Portmap of component '%s' contains invalid line (missing '='):\n'%s'\n", comp->name, pm); + continue; + } + val = sep+1; + if (sep - set < sizeof(tmp)-2) { + strncpy(tmp, set, sep-set); + tmp[sep-set] = '\0'; + key = tmp; + } + else + key = ktmp = rnd_strndup(set, sep - set); + + while(isspace(*key)) key++; /* eat up spaces after the "->" separator */ + + pm_src = csch_attrib_src_pa(&comp->hdr, "portmap", "std_devmap", "applied portmap"); + csch_attrib_set(&port->hdr.attr, cctx->view_eng->eprio + CSCH_PRI_PLUGIN_NORMAL, key, val, pm_src, NULL); + free(ktmp); + } + + return 0; +} Index: tags/1.0.5/src/plugins/std_devmap/libs.c =================================================================== --- tags/1.0.5/src/plugins/std_devmap/libs.c (nonexistent) +++ tags/1.0.5/src/plugins/std_devmap/libs.c (revision 10414) @@ -0,0 +1,95 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - standard device mapper + * Copyright (C) 2022,2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust Fund in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/*** devmap library handling ***/ + +static char *devmap_lib_lookup(ldch_ctx_t *ctx, const char *load_name, ldch_low_parser_t *low, ldch_high_parser_t *high, void *low_call_ctx, void *high_call_ctx) +{ +/* csch_hook_call_ctx_t *cctx = high_call_ctx; for cctx->project */ +/* fgw_obj_t *obj = ctx->user_data;*/ + csch_lib_t *le; + + /* if full path is known */ + if (strchr(load_name, '/') != NULL) + return rnd_strdup(load_name); + + TODO("we shouldn't search master, only sheet's devmap libs, but the" + "abstract model doesn't have sheets"); + le = csch_lib_search_master(devmaster, load_name, CSCH_SLIB_STATIC); + if (le == NULL) { + char *load_name2 = rnd_concat(load_name, ".devmap", NULL); + le = csch_lib_search_master(devmaster, load_name2, CSCH_SLIB_STATIC); + free(load_name2); + } +/* rnd_trace("devmap lookup: %s -> %p\n", load_name, le);*/ + + return le == NULL ? NULL : rnd_strdup(le->realpath); +} + +/* effectively a test-parse */ +csch_lib_type_t devmap_lht_file_type(rnd_design_t *hl, const char *fn) +{ + FILE *f; + int n; + csch_lib_type_t res = CSCH_SLIB_invalid; + + f = rnd_fopen(hl, fn, "r"); + if (f == NULL) + return res; + + for(n = 0; n < 16; n++) { + char *s, line[1024]; + s = fgets(line, sizeof(line), f); + if (s == NULL) break; + if (strstr(s, "ha:std_devmap.v") == 0) { + res = CSCH_SLIB_STATIC; + break; + } + } + fclose(f); + return res; +} + + +static char *devmap_lht_realpath(rnd_design_t *hl, const char *root) +{ + /* accept only non-prefixed paths for now */ + if (strchr(root, '@') != NULL) + return NULL; + + return csch_lib_fs_realpath(hl, root); +} + +static int devmap_lht_map(rnd_design_t *hl, csch_lib_t *root_dir) +{ + gds_t tmp = {0}; + gds_append_str(&tmp, root_dir->realpath); + csch_lib_fs_map(hl, &be_devmap_lht, root_dir, &tmp, devmap_lht_file_type); + gds_uninit(&tmp); + return 0; +} Index: tags/1.0.5/src/plugins/std_devmap/loclib.c =================================================================== --- tags/1.0.5/src/plugins/std_devmap/loclib.c (nonexistent) +++ tags/1.0.5/src/plugins/std_devmap/loclib.c (revision 10414) @@ -0,0 +1,77 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - standard device mapper + * Copyright (C) 2022,2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust Fund in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/*** local lib support ***/ + +static int devmap_lht_map_local(rnd_design_t *hl, csch_lib_t *root_dir, const csch_cgrp_t *indirect) +{ + csch_sheet_t *sheet = (csch_sheet_t *)hl; + anymap_ctx_t *actx = devmap_get_anymap(sheet); + const csch_cgrp_t *root_grp; + + /* do not automatically create a local devmap dir (we are at opening a sheet) */ + root_grp = csch_loclib_get_root(sheet, devmaster, NULL, 0, NULL); + if (root_grp != NULL) + anymap_sheet_init_(actx, hl, root_dir, root_grp); + + return 0; +} + +static void devmap_sheet_init(anymap_ctx_t *actx, csch_sheet_t *sheet, csch_lib_t **root_dir_out, int alloc) +{ + csch_lib_t *root_dir = NULL; + int alloced; + csch_cgrp_t *root_grp; + csch_source_arg_t *src; + + src = csch_attrib_src_p("std_devmap", NULL); + if (csch_loclib_get_roots(&root_dir, &root_grp, devmaster, sheet, src, alloc, &alloced) == 0) + anymap_sheet_init_(actx, &sheet->hidlib, root_dir, root_grp); + + if (root_dir_out != NULL) + *root_dir_out = root_dir; +} + +static int devmap_lht_load(csch_sheet_t *sheet, void *dst_, csch_lib_t *src, const char *params) +{ + /* real loading happens through devmap_lib_lookup(); this is called from the + lib window (will be needed for the preview) */ + return -1; +} + +static int devmap_loc_list(csch_sheet_t *sheet, csch_lib_t *src) +{ + return anymap_loc_list(sheet, src, "devmap"); +} + +static int devmap_loc_refresh_from_ext(csch_sheet_t *sheet, csch_lib_t *src) +{ + anymap_ctx_t *actx = devmap_get_anymap(sheet); + return anymap_loc_refresh_from_ext(actx, sheet, src); +} + Index: tags/1.0.5/src/plugins/std_devmap/parse.c =================================================================== --- tags/1.0.5/src/plugins/std_devmap/parse.c (nonexistent) +++ tags/1.0.5/src/plugins/std_devmap/parse.c (revision 10414) @@ -0,0 +1,66 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - standard device mapper + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/*** devmap parser ***/ + +static void parse_error(void *ectx, lht_node_t *n, const char *msg) +{ + rnd_message(RND_MSG_ERROR, "devmap: parse error '%s' near %ld:%ld\n", msg, n->line, n->col); +} + +static ldch_data_t *devmap_parse(ldch_high_parser_t *parser, void *call_ctx, ldch_file_t *file) +{ + ldch_data_t *data; + devmap_t *devmap; + lht_doc_t *doc = ldch_lht_get_doc(file); + + if ((doc->root == NULL) && rnd_is_dir(NULL, file->real_name)) + return NULL; /* happens on refresh on a dir */ + + if ((doc->root == NULL) || (doc->root->type != LHT_HASH) || (strcmp(doc->root->name, "std_devmap.v1") != 0)) { + rnd_message(RND_MSG_ERROR, "devmap: invalid root node in '%s'; expected 'ha:std_devmap.v1'\n", file->real_name); + return NULL; + } + + data = ldch_data_alloc(file, parser, sizeof(devmap_t)); + devmap = (devmap_t *)&data->payload; + csch_attrib_init(&devmap->comp_attribs); + if (csch_lht_parse_attribs(&devmap->comp_attribs, lht_dom_hash_get(doc->root, "comp_attribs"), parse_error, NULL) != 0) { + rnd_message(RND_MSG_ERROR, "devmap: failed to load any component attributes from '%s''\n", file->real_name); + ldch_data_free(parser->ctx, data); + return NULL; + } + + return data; +} + +static void devmap_free_payload(ldch_data_t *data) +{ + devmap_t *devmap = (devmap_t *)&data->payload; + + csch_attrib_uninit(&devmap->comp_attribs); +} + Index: tags/1.0.5/src/plugins/std_devmap/preview.c =================================================================== --- tags/1.0.5/src/plugins/std_devmap/preview.c (nonexistent) +++ tags/1.0.5/src/plugins/std_devmap/preview.c (revision 10414) @@ -0,0 +1,33 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - standard device mapper + * Copyright (C) 2022,2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust Fund in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +static char *devmap_lht_preview_text(csch_sheet_t *sheet, csch_lib_t *src, const char *parametric) +{ + anymap_ctx_t *actx = devmap_get_anymap(sheet); + return anymap_lht_preview_text(actx, sheet, src, parametric); +} Index: tags/1.0.5/src/plugins/std_devmap/quick_attr_portmap.c =================================================================== --- tags/1.0.5/src/plugins/std_devmap/quick_attr_portmap.c (nonexistent) +++ tags/1.0.5/src/plugins/std_devmap/quick_attr_portmap.c (revision 10414) @@ -0,0 +1,297 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - standard device mapper + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/* quick-edit attribute: symbol portmap list, in sym->fp format */ + +#include +#include + +#include + +typedef struct { + RND_DAD_DECL_NOINIT(dlg) + csch_sheet_t *sheet; + csch_cgrp_t *grp; + int changed; + int wlist, wadd, wsym, wkey, wval; +} qa_portmap_t; + +static void qa_portmap_close_cb(void *caller_data, rnd_hid_attr_ev_t ev) +{ + +} + +static void qa_portmap_sheet2dlg(qa_portmap_t *ctx) +{ + rnd_hid_attribute_t *attr = &ctx->dlg[ctx->wlist]; + rnd_hid_tree_t *tree = attr->wdata; + rnd_hid_row_t *r; + char *cursor_path = NULL; + const vts0_t *arr; + + /* remember cursor */ + r = rnd_dad_tree_get_selected(attr); + if (r != NULL) + cursor_path = rnd_strdup(r->cell[0]); + + /* remove existing items */ + rnd_dad_tree_clear(tree); + + /* add all items */ + arr = csch_attrib_get_arr(&ctx->grp->attr, "portmap"); + if (arr != NULL) { + long n; + char *cell[4]; + + cell[3] = NULL; + for(n = 0; n < arr->used; n++) { + char *c, *sep, *s, *key, *val; + int found = 0; + + c = arr->array[n]; + for(sep = c; *sep != '\0'; sep++) { + if ((sep[0] == '-') && (sep[1] == '>')) { + found = 1; + break; + } + } + if (found) { + s = sep-1; + while((s >= c) && isspace(*s)) + s--; + cell[0] = rnd_strndup(c, s-c+1); + s = sep+2; + while(isspace(*s)) s++; + + key = rnd_strdup(s); + val = strchr(key, '='); + if (val != NULL) { + *val = '\0'; + val++; + } + cell[1] = key; + cell[2] = rnd_strdup(val); + } + else { + cell[0] = rnd_strdup(c); + cell[1] = NULL; + } + rnd_dad_tree_append(attr, NULL, cell); + } + } + + /* restore cursor */ + if (cursor_path != NULL) { + rnd_hid_attr_val_t hv; + hv.str = cursor_path; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wlist, &hv); + free(cursor_path); + } +} + +static void qa_portmap_select_cb(rnd_hid_attribute_t *attrib, void *hid_ctx, rnd_hid_row_t *row) +{ + rnd_hid_tree_t *tree = attrib->wdata; + qa_portmap_t *ctx = tree->user_ctx; + + if (row != NULL) { + rnd_hid_attr_val_t hv; + + hv.str = row->cell[0]; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wsym, &hv); + hv.str = row->cell[1]; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wkey, &hv); + hv.str = row->cell[2]; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wval, &hv); + } +} + +static long sym2idx(qa_portmap_t *ctx, long *totlen, int err) +{ + const vts0_t *arr = csch_attrib_get_arr(&ctx->grp->attr, "portmap"); + long n, len, cmplen; + const char *sym = ctx->dlg[ctx->wsym].val.str, *end; + const char *key = ctx->dlg[ctx->wkey].val.str, *attrkey; + + if (totlen != NULL) { + if (arr == NULL) + *totlen = 0; + else + *totlen = arr->used; + } + + if (sym != NULL) + while(isspace(*sym)) sym++; + + if (((sym == NULL) || (*sym == '\0')) && err) { + rnd_message(RND_MSG_ERROR, "Please fill in the symbol side name\n"); + return -1; + } + + if ((arr == NULL) || (sym == NULL) || (*sym == '\0')) + return -1; + + if ((key == NULL) || (*key == '\0')) { + key = NULL; + cmplen = 0; + } + else + cmplen = strlen(key); + + + end = strpbrk(sym, " \t\r\n"); + if (end != NULL) + len = end - sym; + else + len = strlen(sym); + + for(n = 0; n < arr->used; n++) { + char *a = arr->array[n]; + if ((strncmp(a, sym, len) == 0) && ((a[len] == '-') || isspace(a[len]))) { + end = a+len; + while(isspace(*end)) end++; + if ((end[0] == '-') && (end[1] == '>')) { + end += 2; + while(isspace(*end)) end++; + attrkey = end; + } + else { + /* no -> means no attr key */ + attrkey = NULL; + } + + if ((key == NULL) && (attrkey == NULL)) + return n; + if ((strncmp(key, attrkey, cmplen) == 0) && (attrkey[cmplen] == '=')) + return n; + } + } + + if (err) + rnd_message(RND_MSG_ERROR, "No entry found for symbol side name '%s'\n", sym); + + return -1; +} + +static void qa_portmap_del_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + qa_portmap_t *ctx = caller_data; + long idx = sym2idx(ctx, NULL, 1); + if (idx < 0) + return; + csch_attr_arr_modify_del(ctx->sheet, ctx->grp, "portmap", idx, 1); + qa_portmap_sheet2dlg(ctx); +} + +static void qa_portmap_add_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + qa_portmap_t *ctx = caller_data; + long totlen, idx = sym2idx(ctx, &totlen, 0); + const char *sym = ctx->dlg[ctx->wsym].val.str; + const char *key = ctx->dlg[ctx->wkey].val.str; + const char *val = ctx->dlg[ctx->wval].val.str; + gds_t tmp = {0}; + + if ((sym == NULL) || (*sym == '\0') || (key == NULL) || (*key == '\0')) { + rnd_message(RND_MSG_ERROR, "Please fill in both symbol and output side first!\n"); + return; + } + + gds_append_str(&tmp, sym); + gds_append_str(&tmp, "->"); + gds_append_str(&tmp, key); + gds_append(&tmp, '='); + gds_append_str(&tmp, val); + + if (idx >= 0) + csch_attr_arr_modify_str(ctx->sheet, ctx->grp, "portmap", idx, tmp.array, 1); + else + csch_attr_arr_modify_ins_before(ctx->sheet, ctx->grp, "portmap", totlen, tmp.array, 1); + + ctx->changed = 1; + + qa_portmap_sheet2dlg(ctx); + gds_uninit(&tmp); +} + +const char csch_acts_quick_attr_portmap[] = "quick_attr_portmap(objptr)"; +const char csch_acth_quick_attr_portmap[] = "Quick Attribute Edit for core data model's symbol portmap attribute (attribute based \"symbol terminal to network\" portmap table)"; +fgw_error_t csch_act_quick_attr_portmap(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + qa_portmap_t ctx = {0}; + rnd_design_t *hidlib = RND_ACT_DESIGN; + rnd_hid_dad_buttons_t clbtn[] = {{"Close", 1}, {NULL, 0}}; + const char *hdr[] = {"Symbol term name", "Attrib key", "Attrib value", NULL}; + + ctx.sheet = (csch_sheet_t *)hidlib; + ctx.changed = 0; + QUICK_ATTR_GET_GRP(ctx.grp, "quick_attr_portmap"); + + RND_DAD_BEGIN_VBOX(ctx.dlg); + RND_DAD_COMPFLAG(ctx.dlg, RND_HATF_EXPFILL); + RND_DAD_TREE(ctx.dlg, 3, 0, hdr); + RND_DAD_COMPFLAG(ctx.dlg, RND_HATF_EXPFILL | RND_HATF_SCROLL); + ctx.wlist = RND_DAD_CURRENT(ctx.dlg); + RND_DAD_TREE_SET_CB(ctx.dlg, selected_cb, qa_portmap_select_cb); + RND_DAD_TREE_SET_CB(ctx.dlg, ctx, &ctx); + RND_DAD_BEGIN_HBOX(ctx.dlg); + RND_DAD_LABEL(ctx.dlg, "Symbol term name:"); + RND_DAD_STRING(ctx.dlg); + ctx.wsym = RND_DAD_CURRENT(ctx.dlg); + RND_DAD_BUTTON(ctx.dlg, "Del"); + RND_DAD_CHANGE_CB(ctx.dlg, qa_portmap_del_cb); + RND_DAD_END(ctx.dlg); + RND_DAD_BEGIN_HBOX(ctx.dlg); + RND_DAD_BEGIN_VBOX(ctx.dlg); + RND_DAD_BEGIN_HBOX(ctx.dlg); + RND_DAD_LABEL(ctx.dlg, "Output attrib key:"); + RND_DAD_STRING(ctx.dlg); + RND_DAD_DEFAULT_PTR(ctx.dlg, rnd_strdup("pcb/pinnum")); + ctx.wkey = RND_DAD_CURRENT(ctx.dlg); + RND_DAD_END(ctx.dlg); + RND_DAD_BEGIN_HBOX(ctx.dlg); + RND_DAD_LABEL(ctx.dlg, "Output attrib value:"); + RND_DAD_STRING(ctx.dlg); + ctx.wval = RND_DAD_CURRENT(ctx.dlg); + RND_DAD_END(ctx.dlg); + RND_DAD_END(ctx.dlg); + RND_DAD_BUTTON(ctx.dlg, "Add/edit"); + ctx.wadd = RND_DAD_CURRENT(ctx.dlg); + RND_DAD_CHANGE_CB(ctx.dlg, qa_portmap_add_cb); + RND_DAD_END(ctx.dlg); + RND_DAD_BUTTON_CLOSES(ctx.dlg, clbtn); + RND_DAD_END(ctx.dlg); + + RND_DAD_NEW("quick_attr_portmap", ctx.dlg, "Set symbol portmap list", &ctx, 1, qa_portmap_close_cb); /* type=local/modal */ + qa_portmap_sheet2dlg(&ctx); + RND_DAD_RUN(ctx.dlg); + + RND_ACT_IRES(ctx.changed); + + return 0; +} Index: tags/1.0.5/src/plugins/std_devmap/std_devmap.c =================================================================== --- tags/1.0.5/src/plugins/std_devmap/std_devmap.c (nonexistent) +++ tags/1.0.5/src/plugins/std_devmap/std_devmap.c (revision 10414) @@ -0,0 +1,293 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - standard device mapper + * Copyright (C) 2019,2020,2022,2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust Fund in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "std_devmap_conf.h" +#include "conf_internal.c" + +static conf_std_devmap_t std_devmap_conf; +static csch_p4cfg_t p4_devmap; +static csch_lib_backend_t be_devmap_lht; + +#define devmap_get_anymap(sheet) \ + ((anymap_ctx_t *)csch_p4_get_by_sheet(&p4_devmap, sheet)) + +typedef anymap_obj_t devmap_t; + +static const char devmap_cookie[] = "devmap"; +static csch_lib_master_t *devmaster; + +#include "parse.c" +#include "loclib.c" +#include "libs.c" +#include "preview.c" +#include "compiler.c" + +static int on_load(fgw_obj_t *obj, const char *filename, const char *opts) +{ + fgw_func_reg(obj, "terminal_name_to_port_name", devmap_term2port); + fgw_func_reg(obj, "symbol_joined_component", devmap_symbol_joined_comp); + fgw_func_reg(obj, "compile_component1", devmap_compile_comp1); + fgw_func_reg(obj, "compile_port", devmap_compile_port); + + return 0; +} + +static const fgw_eng_t fgw_std_devmap_eng = { + "std_devmap", + csch_c_call_script, + NULL, + on_load, + NULL /* on_unload */ +}; + + +const char csch_acts_quick_attr_devmap[] = "quick_attr_devmap(objptr)"; +const char csch_acth_quick_attr_devmap[] = "Quick Attribute Edit for devmap using the devmap library"; +fgw_error_t csch_act_quick_attr_devmap(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_design_t *hidlib = RND_ACT_DESIGN; + csch_sheet_t *sheet = (csch_sheet_t *)hidlib; + csch_cgrp_t *grp; + fgw_arg_t ares, args[4]; + int ret; + + QUICK_ATTR_GET_GRP(grp, "quick_attr_devmap"); + + args[1].type = FGW_STR; + args[1].val.cstr = "devmap"; + args[2].type = FGW_STR; + args[2].val.cstr = "sheet"; + args[3].type = FGW_STR; + args[3].val.cstr = "modal"; + + ret = rnd_actionv_bin(&sheet->hidlib, "librarydialog", &ares, 4, args); + if ((ret == 0) && ((ares.type & FGW_STR) == FGW_STR)) { + csch_source_arg_t *src; + char *path = ares.val.str, *sep = NULL; + + if ((path != NULL) && (*path != '\0')) + sep = strrchr(path, '/'); + if (sep != NULL) { + char *end = strrchr(sep+1, '.'); + if ((end != NULL) && (rnd_strcasecmp(end, ".devmap") == 0)) + *end = '\0'; + + src = csch_attrib_src_p("std_devmap", "manually picked from the devmap lib"); + csch_attr_modify_str(sheet, grp, -CSCH_ATP_USER_DEFAULT, "devmap", sep+1, src, 1); +/* rnd_trace("new devmap val: '%s'\n", sep+1);*/ + } + } + fgw_arg_free(&rnd_fgw, &ares); + + + RND_ACT_IRES(1); + return 0; +} + +static const char csch_acts_DevmaplibRehash[] = "DevmaplibRehash()"; +static const char csch_acth_DevmaplibRehash[] = "Rebuild the in-memory tree of devmaps"; +static fgw_error_t csch_act_DevmaplibRehash(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + csch_sheet_t *sheet = CSCH_ACT_SHEET; + csch_lib_master_t *master = csch_lib_get_master("devmap", 1); + + csch_lib_clear_sheet_lib(sheet, master->uid); + csch_lib_add_all(sheet, master, &std_devmap_conf.plugins.std_devmap.search_paths, 1); + rnd_event(&sheet->hidlib, CSCH_EVENT_LIBRARY_CHANGED, NULL); + RND_ACT_IRES(0); + return 0; +} + +static const char csch_acts_DevmaplibCleanLocal[] = "DevmaplibCleanLocal()"; +static const char csch_acth_DevmaplibCleanLocal[] = "Remove all local-lib devmaps from the current sheet; they are re-loaded from external libs into the local lib upon the next compilation. Useful to refresh local lib from disk."; +static fgw_error_t csch_act_DevmaplibCleanLocal(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + csch_sheet_t *sheet = CSCH_ACT_SHEET; + long cnt = 0, n, i; + csch_lib_root_t *libroot; + csch_lib_master_t *master = csch_lib_get_master("devmap", 0); + csch_cgrp_t *root_grp; + + libroot = sheet->local_libs.array[master->uid]; + for(n = 0; n < libroot->roots.used; n++) { + csch_lib_t *root = libroot->roots.array[n]; + if (strcmp(root->name, "") == 0) { + for(i = root->children.used-1; i >= 0; i--) { + csch_lib_t *le = root->children.array[i]; + csch_lib_remove(le); + + cnt++; + } + break; + } + } + + /* remove from indirect */ + root_grp = csch_loclib_get_root(sheet, devmaster, NULL, 0, NULL); + if (root_grp != NULL) + csch_cgrp_clear(root_grp); + + rnd_message(RND_MSG_INFO, "Removed %ld devmap(s) from the local lib of the sheet\n", cnt); + + rnd_event(&sheet->hidlib, CSCH_EVENT_LIBRARY_CHANGED, NULL); + RND_ACT_IRES(0); + return 0; +} + + +static void devmap_sheet_postload_ev(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + csch_sheet_t *sheet = (csch_sheet_t *)hidlib; + csch_lib_add_all(sheet, devmaster, &std_devmap_conf.plugins.std_devmap.search_paths, 0); + csch_lib_add_local(sheet, devmaster); +} + +#include "quick_attr_portmap.c" + +static rnd_action_t devmap_action_list[] = { + {"quick_attr_devmap", csch_act_quick_attr_devmap, csch_acth_quick_attr_devmap, csch_acts_quick_attr_devmap}, + {"quick_attr_portmap", csch_act_quick_attr_portmap, csch_acth_quick_attr_portmap, csch_acts_quick_attr_portmap}, + {"DevmaplibRehash", csch_act_DevmaplibRehash, csch_acth_DevmaplibRehash, csch_acts_DevmaplibRehash}, + {"DevmaplibCleanLocal", csch_act_DevmaplibCleanLocal, csch_acth_DevmaplibCleanLocal, csch_acts_DevmaplibCleanLocal} +}; + +/*** p4 ***/ + + +static void devmap_p4_project_init(csch_p4cfg_t *p4, csch_project_t *prj) +{ + /* initialize view-local cache */ + anymap_ctx_t *ctx = calloc(sizeof(anymap_ctx_t), 1); + ctx->name = ctx->attr_key = "devmap"; + ctx->eng_src_name = "std_devmap"; + ctx->be = &be_devmap_lht; + ctx->sheet_init = devmap_sheet_init; + ldch_init(&ctx->maps); + ctx->maps.load_name_to_real_name = devmap_lib_lookup; + ctx->low_parser = ldch_lht_reg_low_parser(&ctx->maps); + ctx->high_parser = ldch_reg_high_parser(&ctx->maps, "devmap"); + ctx->high_parser->parse = devmap_parse; + ctx->high_parser->free_payload = devmap_free_payload; + + csch_p4_set_by_project(p4, prj, ctx); +} + +static void devmap_p4_project_uninit(csch_p4cfg_t *p4, csch_project_t *prj) +{ + anymap_ctx_t *ctx = csch_p4_get_by_project(p4, prj); + ldch_uninit(&ctx->maps); + vtp0_uninit(&ctx->ssyms); + free(ctx); +} + + +/*** plugin ***/ + +int pplg_check_ver_std_devmap(int ver_needed) { return 0; } + +void pplg_uninit_std_devmap(void) +{ + rnd_event_unbind_allcookie(devmap_cookie); + rnd_remove_actions_by_cookie(devmap_cookie); + rnd_conf_plug_unreg("plugins/std_devmap/", std_devmap_conf_internal, devmap_cookie); + csch_p4_unreg_plugin(&p4_devmap); +} + +int pplg_init_std_devmap(void) +{ + RND_API_CHK_VER; + + fgw_eng_reg(&fgw_std_devmap_eng); + + RND_REGISTER_ACTIONS(devmap_action_list, devmap_cookie); + + devmaster = csch_lib_get_master("devmap", 1); + be_devmap_lht.name = "std_devmap"; + be_devmap_lht.realpath = devmap_lht_realpath; + be_devmap_lht.map = devmap_lht_map; + be_devmap_lht.map_local = devmap_lht_map_local; + be_devmap_lht.load = devmap_lht_load; + be_devmap_lht.preview_text = devmap_lht_preview_text; + be_devmap_lht.free = anymap_lht_free; + be_devmap_lht.loc_refresh_from_ext = devmap_loc_refresh_from_ext; + be_devmap_lht.loc_list = devmap_loc_list; + + + csch_lib_backend_reg(devmaster, &be_devmap_lht); + + rnd_event_bind(CSCH_EVENT_SHEET_POSTLOAD, devmap_sheet_postload_ev, NULL, devmap_cookie); + + rnd_conf_plug_reg(std_devmap_conf, std_devmap_conf_internal, devmap_cookie); +#define conf_reg(field,isarray,type_name,cpath,cname,desc,flags) \ + rnd_conf_reg_field(std_devmap_conf, field,isarray,type_name,cpath,cname,desc,flags); +#include "std_devmap_conf_fields.h" + + p4_devmap.project_init = devmap_p4_project_init; + p4_devmap.project_uninit = devmap_p4_project_uninit; + + csch_p4_reg_plugin(&p4_devmap); + + return 0; +} + Index: tags/1.0.5/src/plugins/std_devmap/std_devmap.conf =================================================================== --- tags/1.0.5/src/plugins/std_devmap/std_devmap.conf (nonexistent) +++ tags/1.0.5/src/plugins/std_devmap/std_devmap.conf (revision 10414) @@ -0,0 +1,14 @@ +li:pcb-rnd-conf-v1 { + ha:append { + ha:plugins { + ha:std_devmap { + li:search_paths = { + ?../../library/devmap + ?$(rc.path.design)/devmap + ?~/.sch-rnd/devmap/ + $(rc.path.share)/devmap + } + } + } + } +} Index: tags/1.0.5/src/plugins/std_devmap/std_devmap.pup =================================================================== --- tags/1.0.5/src/plugins/std_devmap/std_devmap.pup (nonexistent) +++ tags/1.0.5/src/plugins/std_devmap/std_devmap.pup (revision 10414) @@ -0,0 +1,8 @@ +$class engine +$short standard device mapper +$long Handles slotting, device mapping and port mapping +$state works +$package (core) +default buildin +dep lib_anymap +autoload 1 Index: tags/1.0.5/src/plugins/std_devmap/std_devmap_conf.h =================================================================== --- tags/1.0.5/src/plugins/std_devmap/std_devmap_conf.h (nonexistent) +++ tags/1.0.5/src/plugins/std_devmap/std_devmap_conf.h (revision 10414) @@ -0,0 +1,14 @@ +#ifndef SCH_RND_STD_DEVMAP_CONF_H +#define SCH_RND_STD_DEVMAP_CONF_H + +#include + +typedef struct { + const struct { + const struct { + RND_CFT_LIST search_paths; /* ordered list of paths that are each recursively searched for devmap files */ + } std_devmap; + } plugins; +} conf_std_devmap_t; + +#endif Index: tags/1.0.5/src/plugins/std_forge/Makefile =================================================================== --- tags/1.0.5/src/plugins/std_forge/Makefile (nonexistent) +++ tags/1.0.5/src/plugins/std_forge/Makefile (revision 10414) @@ -0,0 +1,2 @@ +all: + cd ../../sch-rnd && make mod_std_forge Index: tags/1.0.5/src/plugins/std_forge/Plug.tmpasm =================================================================== --- tags/1.0.5/src/plugins/std_forge/Plug.tmpasm (nonexistent) +++ tags/1.0.5/src/plugins/std_forge/Plug.tmpasm (revision 10414) @@ -0,0 +1,14 @@ +put /local/rnd/mod {std_forge} +put /local/rnd/mod/OBJS [@ + $(PLUGDIR)/std_forge/std_forge.o + $(PLUGDIR)/std_forge/cond_gram.o + $(PLUGDIR)/std_forge/dlg_test_bench.o +@] + +put /local/rnd/mod/BYACCIC {$(PLUGDIR)/std_forge/cond_gram} + +switch /local/module/std_forge/controls + case {buildin} include /local/csch/tmpasm/buildin; end; + case {plugin} include /local/csch/tmpasm/plugin; end; + case {disable} include /local/csch/tmpasm/disable; end; +end Index: tags/1.0.5/src/plugins/std_forge/cond.h =================================================================== --- tags/1.0.5/src/plugins/std_forge/cond.h (nonexistent) +++ tags/1.0.5/src/plugins/std_forge/cond.h (revision 10414) @@ -0,0 +1,27 @@ +#ifndef STD_FORGE_COND_H +#define STD_FORGE_COND_H +#include +#include +#include + +typedef struct { + gds_t strs; + vtl0_t prg; + unsigned in_quote:1; + unsigned error:1; + const char *var_val[2]; + csch_abstract_t *abst; + csch_project_t *prj; +} forgecond_ctx_t; + +int forgecond_parse_str(forgecond_ctx_t *ctx, const char *str); +void forgecond_dump(FILE *f, forgecond_ctx_t *ctx); +long forgecond_exec(forgecond_ctx_t *ctx, vtl0_t *stack); +void forgecond_uninit(forgecond_ctx_t *ctx); + + +/* Provided by the caller: */ +extern const char *forgecond_var_resolve_cb(forgecond_ctx_t *ctx, const char *name1, const char *name2); +extern void forgecond_error_cb(forgecond_ctx_t *ctx, const char *s); + +#endif Index: tags/1.0.5/src/plugins/std_forge/cond_gram.c =================================================================== --- tags/1.0.5/src/plugins/std_forge/cond_gram.c (nonexistent) +++ tags/1.0.5/src/plugins/std_forge/cond_gram.c (revision 10414) @@ -0,0 +1,821 @@ + +#ifdef YY_QUERY_API_VER +#define YY_BYACCIC +#define YY_API_MAJOR 1 +#define YY_API_MINOR 0 +#endif /*YY_QUERY_API_VER*/ + +#define forgecond_EMPTY (-1) +#define forgecond_clearin (forgecond_chr = forgecond_EMPTY) +#define forgecond_errok (forgecond_errflag = 0) +#define forgecond_RECOVERING() (forgecond_errflag != 0) +#define forgecond_ENOMEM (-2) +#define forgecond_EOF 0 +#line 16 "../plugins/std_forge/cond_gram.c" +#include "../plugins/std_forge/cond_gram.h" +static const forgecond_int_t forgecond_lhs[] = { -1, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, + 6, 5, 5, +}; +static const forgecond_int_t forgecond_len[] = { 2, + 1, 3, 4, 4, 4, 4, 4, 3, 3, 4, + 3, 3, 3, 3, 3, 3, 3, 4, 4, 2, + 2, 1, 1, 2, 1, 2, 2, 1, 3, 1, + 0, 4, 2, +}; +static const forgecond_int_t forgecond_defred[] = { 0, + 23, 25, 0, 0, 0, 0, 0, 0, 0, 0, + 30, 0, 20, 21, 0, 33, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 24, 27, + 26, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, + 8, 0, 0, 0, 32, 0, 0, 5, 10, 7, + 6, 3, 4, +}; +static const forgecond_int_t forgecond_dgoto[] = { 7, + 8, 9, 10, 11, 12, 17, +}; +static const forgecond_int_t forgecond_sindex[] = { -7, + 0, 0, -7, -7, -7, -10, 0, 158, -226, -41, + 0, -22, 0, 0, 132, 0, -224, -33, -30, -7, + -7, -7, -7, -7, -29, -24, -20, -17, 0, 0, + 0, -224, -21, -16, 0, -28, -7, 234, -7, 260, + 267, 267, 76, 76, 76, -7, -7, -7, 0, -7, + 0, -228, -32, -32, 0, 234, 260, 0, 0, 0, + 0, 0, 0, +}; +static const forgecond_int_t forgecond_rindex[] = { 0, + 0, 0, 0, 0, 0, -205, 0, 55, 9, 35, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 18, 0, 74, + 19, 43, 87, 107, 119, 0, 0, 0, 0, 0, + 0, 61, 0, 0, 0, 22, 75, 0, 0, 0, + 0, 0, 0, +}; +static const forgecond_int_t forgecond_gindex[] = { 0, + 241, 0, 4, 0, -5, 0, +}; +#define forgecond_TABLESIZE 329 +static const forgecond_int_t forgecond_table[] = { 4, + 6, 6, 4, 6, 32, 55, 5, 39, 22, 5, + 34, 3, 4, 6, 3, 4, 6, 17, 11, 5, + 36, 19, 5, 16, 3, 4, 6, 3, 30, 31, + 29, 46, 5, 2, 28, 52, 47, 3, 33, 53, + 48, 22, 12, 50, 54, 22, 22, 62, 63, 22, + 22, 22, 31, 22, 1, 22, 11, 0, 17, 11, + 29, 11, 19, 11, 0, 0, 0, 28, 22, 22, + 22, 28, 28, 16, 18, 28, 28, 28, 0, 28, + 12, 28, 0, 12, 0, 12, 13, 12, 0, 0, + 37, 0, 0, 29, 28, 28, 28, 29, 29, 0, + 0, 29, 29, 29, 0, 29, 14, 29, 26, 0, + 0, 16, 18, 0, 16, 18, 0, 0, 15, 0, + 29, 29, 29, 13, 13, 0, 0, 13, 13, 13, + 0, 13, 22, 13, 0, 27, 25, 28, 0, 0, + 0, 17, 11, 14, 14, 19, 0, 14, 14, 14, + 0, 14, 0, 14, 0, 15, 15, 0, 28, 15, + 15, 15, 0, 15, 26, 15, 12, 0, 24, 19, + 0, 0, 35, 22, 20, 0, 21, 0, 23, 0, + 0, 0, 0, 0, 29, 0, 0, 0, 0, 0, + 26, 27, 25, 28, 24, 19, 0, 16, 18, 22, + 20, 0, 21, 0, 23, 0, 0, 0, 0, 0, + 13, 0, 0, 0, 0, 30, 31, 27, 25, 28, + 0, 0, 0, 1, 2, 2, 1, 2, 30, 31, + 14, 0, 0, 0, 0, 0, 1, 2, 0, 1, + 2, 0, 15, 13, 14, 15, 0, 0, 0, 1, + 2, 0, 0, 0, 0, 18, 0, 0, 38, 40, + 41, 42, 43, 44, 45, 0, 26, 49, 51, 0, + 24, 19, 0, 0, 0, 22, 20, 56, 21, 57, + 23, 18, 0, 0, 0, 0, 58, 59, 60, 0, + 61, 0, 26, 27, 25, 28, 24, 0, 0, 26, + 0, 22, 20, 24, 21, 0, 23, 0, 22, 0, + 0, 0, 0, 23, 0, 0, 0, 0, 0, 27, + 25, 28, 0, 0, 0, 0, 27, 25, 28, +}; +static const forgecond_int_t forgecond_check[] = { 33, + 34, 34, 33, 34, 46, 34, 40, 38, 0, 40, + 33, 45, 33, 34, 45, 33, 34, 0, 0, 40, + 17, 0, 40, 34, 45, 33, 34, 45, 257, 258, + 257, 61, 40, 258, 0, 32, 61, 45, 61, 61, + 61, 33, 0, 61, 61, 37, 38, 53, 54, 41, + 42, 43, 258, 45, 0, 47, 38, -1, 41, 41, + 0, 43, 41, 45, -1, -1, -1, 33, 60, 61, + 62, 37, 38, 0, 0, 41, 42, 43, -1, 45, + 38, 47, -1, 41, -1, 43, 0, 45, -1, -1, + 124, -1, -1, 33, 60, 61, 62, 37, 38, -1, + -1, 41, 42, 43, -1, 45, 0, 47, 33, -1, + -1, 38, 38, -1, 41, 41, -1, -1, 0, -1, + 60, 61, 62, 37, 38, -1, -1, 41, 42, 43, + -1, 45, 124, 47, -1, 60, 61, 62, -1, -1, + -1, 124, 124, 37, 38, 124, -1, 41, 42, 43, + -1, 45, -1, 47, -1, 37, 38, -1, 124, 41, + 42, 43, -1, 45, 33, 47, 124, -1, 37, 38, + -1, -1, 41, 42, 43, -1, 45, -1, 47, -1, + -1, -1, -1, -1, 124, -1, -1, -1, -1, -1, + 33, 60, 61, 62, 37, 38, -1, 124, 124, 42, + 43, -1, 45, -1, 47, -1, -1, -1, -1, -1, + 124, -1, -1, -1, -1, 257, 258, 60, 61, 62, + -1, -1, -1, 257, 258, 258, 257, 258, 257, 258, + 124, -1, -1, -1, -1, -1, 257, 258, -1, 257, + 258, -1, 124, 3, 4, 5, -1, -1, -1, 257, + 258, -1, -1, -1, -1, 124, -1, -1, 18, 19, + 20, 21, 22, 23, 24, -1, 33, 27, 28, -1, + 37, 38, -1, -1, -1, 42, 43, 37, 45, 39, + 47, 124, -1, -1, -1, -1, 46, 47, 48, -1, + 50, -1, 33, 60, 61, 62, 37, -1, -1, 33, + -1, 42, 43, 37, 45, -1, 47, -1, 42, -1, + -1, -1, -1, 47, -1, -1, -1, -1, -1, 60, + 61, 62, -1, -1, -1, -1, 60, 61, 62, +}; +#define forgecond_FINAL 7 +#define forgecond_MAXTOKEN 260 +#define forgecond_UNDFTOKEN 269 +#define forgecond_TRANSLATE(a) ((a) > forgecond_MAXTOKEN ? forgecond_UNDFTOKEN : (a)) +#if forgecond_DEBUG +static const char *const forgecond_name[] = { + +"end-of-file",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +"'!'","'\"'",0,0,"'%'","'&'",0,"'('","')'","'*'","'+'",0,"'-'","'.'","'/'",0,0, +0,0,0,0,0,0,0,0,0,0,"'<'","'='","'>'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +"'|'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"DIGIT","LETTER","UMINUS","UNOT",0,0,0,0,0,0,0,0, +"illegal-symbol", +}; +static const char *const forgecond_rule[] = { +"$accept : cond", +"cond : expr", +"expr : '(' expr ')'", +"expr : str '=' '=' str", +"expr : str '!' '=' str", +"expr : expr '=' '=' expr", +"expr : expr '>' '=' expr", +"expr : expr '<' '=' expr", +"expr : expr '>' expr", +"expr : expr '<' expr", +"expr : expr '!' '=' expr", +"expr : expr '+' expr", +"expr : expr '-' expr", +"expr : expr '*' expr", +"expr : expr '/' expr", +"expr : expr '%' expr", +"expr : expr '&' expr", +"expr : expr '|' expr", +"expr : expr '&' '&' expr", +"expr : expr '|' '|' expr", +"expr : '-' expr", +"expr : '!' expr", +"expr : number", +"number : DIGIT", +"number : number DIGIT", +"id : LETTER", +"id : id LETTER", +"id : id DIGIT", +"var : id", +"var : id '.' id", +"str : var", +"$$1 :", +"str : '\"' $$1 id '\"'", +"str : '\"' '\"'", + +}; +#endif + +#line 151 "../plugins/std_forge/cond_gram.y" + /* start of programs */ + +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - standard cschem attributes + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust Fund in 2023) + * + * This program is free software licensed under the GPL, see the top of + * the file cond_gram.y. + */ + +static int lex(forgecond_ctx_t *ctx, forgecond_STYPE *yylval, const char **inp) +{ + int c; + + if (ctx->in_quote) { + c = **inp; + (*inp)++; + if (c == '\\') { + c = **inp; + (*inp)++; + } + else if (c == '\"') + return c; + yylval->l = c; + return LETTER; + } + + do { + c = **inp; + (*inp)++; + } while(isspace(c)); /* skip space */ + + if (c == '\0') + return forgecond_EOF; + + /* c is now nonblank */ + if (islower(c) || (c == '_')) { + yylval->l = c; + return LETTER; + } + if (isdigit(c)) { + yylval->l = c - '0'; + return DIGIT; + } + return c; +} + +void forgecond_dump(FILE *f, forgecond_ctx_t *ctx) +{ + long n, len; + + fprintf(f, "prg:\n"); + for(n = 0; n < ctx->prg.used; n++) { + char s[4]; + long l, l1, l2; + + switch(ctx->prg.array[n]) { + case FGC_NUM: fprintf(f, " NUM: %ld\n", ctx->prg.array[++n]); break; + case FGC_STR: fprintf(f, " STR: [%ld]\n", ctx->prg.array[++n]); break; + case FGC_VAR1: fprintf(f, " VAR1: [%ld]\n", ctx->prg.array[++n]); break; + case FGC_VAR2: + l1 = ctx->prg.array[++n]; + l2 = ctx->prg.array[++n]; + fprintf(f, " VAR2: [%ld] [%ld]\n", l1, l2); break; + default: + l = ctx->prg.array[n]; + s[0] = (l >> 16) & 0x0ff; + s[1] = (l >> 8) & 0x0ff; + s[2] = l & 0x0ff; + s[3] = '\0'; + fprintf(f, " %s\n", s); + break; + } + } + + fprintf(f, "strings:\n"); + for(n = 0; n < ctx->strs.used; n += len) { + len = strlen(ctx->strs.array+n)+1; + fprintf(f, " [%ld] '%s'\n", n, ctx->strs.array+n); + } +} + +static long pop_(forgecond_ctx_t *ctx, vtl0_t *stack) +{ + if (stack->used > 0) + return (long)stack->array[--stack->used]; + forgecond_error_cb(ctx, "forgecond: stack underflow (internal error)\n"); + return 0; +} + +static const char *get_str(forgecond_ctx_t *ctx, long idx, int allow_strval) +{ + if ((allow_strval) && (idx < 0)) { + if (idx == STR_VAL_NULL) + return NULL; + idx = idx - STR_VAL_BASE; + if ((idx >= 0) && (idx < sizeof(ctx->var_val)/sizeof(ctx->var_val[0]))) { + const char *res = ctx->var_val[idx]; + ctx->var_val[idx] = NULL; + return res; + } + forgecond_error_cb(ctx, "forgecond: invalid str val address (internal error)\n"); + return NULL; + } + + if ((idx < 0) || (idx >= ctx->strs.used)) { + forgecond_error_cb(ctx, "forgecond: invalid string literal address (internal error)\n"); + return NULL; + } + return ctx->strs.array + idx; + +} + +static const char *pop_str_(forgecond_ctx_t *ctx, vtl0_t *stack) +{ + return get_str(ctx, pop_(ctx, stack), 1); +} + +#define push(val) vtl0_append(stack, val) +#define pop() pop_(ctx, stack) +#define pop_str() pop_str_(ctx, stack) + +static void push_var_val(forgecond_ctx_t *ctx, vtl0_t *stack, long name_idx2, long name_idx1) +{ + int n; + const char *name1 = (name_idx1 >= 0) ? get_str(ctx, name_idx1, 0) : NULL; + const char *name2 = (name_idx2 >= 0) ? get_str(ctx, name_idx2, 0) : NULL; + const char *res = forgecond_var_resolve_cb(ctx, name2, name1); + + if (res == NULL) { + push(STR_VAL_NULL); + return; + } + + for(n = 0; n < sizeof(ctx->var_val)/sizeof(ctx->var_val[0]); n++) { + if (ctx->var_val[n] == NULL) { + ctx->var_val[n] = res; + push(STR_VAL_BASE+n); + return; + } + } + + forgecond_error_cb(ctx, "forgecond: no slot for str val (internal error)\n"); + push(STR_VAL_NULL); + return; +} + + + +static int safe_strcmp(const char *a, const char *b) +{ + if ((a == NULL) || (b == NULL)) return -1; /* an invalid string never equals to anyting */ + return strcmp(a, b); +} + +long forgecond_exec(forgecond_ctx_t *ctx, vtl0_t *stack) +{ + long n, a, b; + const char *sa, *sb; + + stack->used = 0; + for(n = 0; n < ctx->prg.used; n++) { + switch(ctx->prg.array[n]) { + + /* push immediate */ + case FGC_VAR2: + a = ctx->prg.array[++n]; + b = ctx->prg.array[++n]; + push_var_val(ctx, stack, a, b); + break; + /* fall-thru to push two string indices */ + case FGC_VAR1: + push_var_val(ctx, stack, ctx->prg.array[++n], -1); + break; + + case FGC_NUM: + case FGC_STR: + push(ctx->prg.array[++n]); + break; + + case FGC_ADD: push(pop() + pop()); break; + case FGC_SUB: a = pop(); b = pop(); push(b - a); break; + case FGC_MUL: push(pop() * pop()); break; + case FGC_DIV: a = pop(); b = pop(); push(b / a); break; + case FGC_MOD: a = pop(); b = pop(); push(b % a); break; + case FGC_EQ: push(pop() == pop()); break; + case FGC_NEQ: push(pop() != pop()); break; + case FGC_GT: a = pop(); b = pop(); push(b > a); break; + case FGC_LT: a = pop(); b = pop(); push(b < a); break; + case FGC_GTEQ: a = pop(); b = pop(); push(b >= a); break; + case FGC_LTEQ: a = pop(); b = pop(); push(b <= a); break; + case FGC_BIN_AND: push(pop() & pop()); break; + case FGC_BIN_OR: push(pop() | pop()); break; + case FGC_LOG_AND: push(pop() && pop()); break; + case FGC_LOG_OR: push(pop() || pop()); break; + case FGC_NEG: push(-pop()); break; + case FGC_NOT: push(!pop()); break; + + case FGC_STR_EQ: sa = pop_str(); sb = pop_str(); push(safe_strcmp(sa, sb) == 0); break; + case FGC_STR_NEQ: sa = pop_str(); sb = pop_str(); push(safe_strcmp(sa, sb) != 0); break; + } + } + + return pop(); +} + +int forgecond_parse_str(forgecond_ctx_t *ctx, const char *str) +{ + forgecond_res_t res; + forgecond_yyctx_t yyctx; + + ctx->strs.used = 0; + ctx->prg.used = 0; + ctx->in_quote = 0; + memset(&ctx->var_val, 0, sizeof(ctx->var_val)); + + if (str == NULL) + return -1; + + if (forgecond_parse_init(&yyctx) != 0) + return -1; + + do { + forgecond_STYPE lval; + int tok = lex(ctx, &lval, &str); + res = forgecond_parse(&yyctx, ctx, tok, &lval); + } while(res == forgecond_RES_NEXT); + + return (res == forgecond_RES_DONE) ? 0 : -1; +} + +void forgecond_error(forgecond_ctx_t *ctx, forgecond_STYPE tok, const char *s) +{ + forgecond_error_cb(ctx, s); +} + +void forgecond_uninit(forgecond_ctx_t *ctx) +{ + gds_uninit(&ctx->strs); + vtl0_uninit(&ctx->prg); +} +#line 447 "../plugins/std_forge/cond_gram.c" + +#if forgecond_DEBUG +#include /* needed for printf */ +#endif + +#include /* needed for malloc, etc */ +#include /* needed for memset */ + +/* allocate initial stack or double stack size, up to yyctx->stack_max_depth */ +static int forgecond_growstack(forgecond_yyctx_t *yyctx, forgecond_STACKDATA *data) +{ + int i; + unsigned newsize; + forgecond_int_t *newss; + forgecond_STYPE *newvs; + + if ((newsize = data->stacksize) == 0) + newsize = forgecond_INITSTACKSIZE; + else if (newsize >= yyctx->stack_max_depth) + return forgecond_ENOMEM; + else if ((newsize *= 2) > yyctx->stack_max_depth) + newsize = yyctx->stack_max_depth; + + i = (int)(data->s_mark - data->s_base); + newss = (forgecond_int_t *) realloc(data->s_base, newsize * sizeof(*newss)); + if (newss == 0) + return forgecond_ENOMEM; + + data->s_base = newss; + data->s_mark = newss + i; + + newvs = (forgecond_STYPE *) realloc(data->l_base, newsize * sizeof(*newvs)); + if (newvs == 0) + return forgecond_ENOMEM; + + data->l_base = newvs; + data->l_mark = newvs + i; + + data->stacksize = newsize; + data->s_last = data->s_base + newsize - 1; + return 0; +} + +static void forgecond_freestack(forgecond_STACKDATA *data) +{ + free(data->s_base); + free(data->l_base); + memset(data, 0, sizeof(*data)); +} + +#define forgecond_ABORT goto yyabort +#define forgecond_REJECT goto yyabort +#define forgecond_ACCEPT goto yyaccept +#define forgecond_ERROR goto yyerrlab + +int forgecond_parse_init(forgecond_yyctx_t *yyctx) +{ +#if forgecond_DEBUG + const char *yys; + + if ((yys = getenv("forgecond_DEBUG")) != 0) { + yyctx->yyn = *yys; + if (yyctx->yyn >= '0' && yyctx->yyn <= '9') + yyctx->debug = yyctx->yyn - '0'; + } +#endif + + memset(&yyctx->val, 0, sizeof(yyctx->val)); + memset(&yyctx->lval, 0, sizeof(yyctx->lval)); + + yyctx->yym = 0; + yyctx->yyn = 0; + yyctx->nerrs = 0; + yyctx->errflag = 0; + yyctx->chr = forgecond_EMPTY; + yyctx->state = 0; + + memset(&yyctx->stack, 0, sizeof(yyctx->stack)); + + yyctx->stack_max_depth = forgecond_INITSTACKSIZE > 10000 ? forgecond_INITSTACKSIZE : 10000; + if (yyctx->stack.s_base == NULL && forgecond_growstack(yyctx, &yyctx->stack) == forgecond_ENOMEM) + return -1; + yyctx->stack.s_mark = yyctx->stack.s_base; + yyctx->stack.l_mark = yyctx->stack.l_base; + yyctx->state = 0; + *yyctx->stack.s_mark = 0; + yyctx->jump = 0; + return 0; +} + + +#define forgecond_GETCHAR(labidx) \ +do { \ + if (used) { yyctx->jump = labidx; return forgecond_RES_NEXT; } \ + getchar_ ## labidx:; yyctx->chr = tok; yyctx->lval = *lval; used = 1; \ +} while(0) + +forgecond_res_t forgecond_parse(forgecond_yyctx_t *yyctx, forgecond_ctx_t *ctx, int tok, forgecond_STYPE *lval) +{ + int used = 0; +#if forgecond_DEBUG + const char *yys; +#endif + +yyloop:; + if (yyctx->jump == 1) { yyctx->jump = 0; goto getchar_1; } + if (yyctx->jump == 2) { yyctx->jump = 0; goto getchar_2; } + + if ((yyctx->yyn = forgecond_defred[yyctx->state]) != 0) + goto yyreduce; + if (yyctx->chr < 0) { + forgecond_GETCHAR(1); + if (yyctx->chr < 0) + yyctx->chr = forgecond_EOF; +#if forgecond_DEBUG + if (yyctx->debug) { + if ((yys = forgecond_name[forgecond_TRANSLATE(yyctx->chr)]) == NULL) + yys = forgecond_name[forgecond_UNDFTOKEN]; + printf("yyctx->debug: state %d, reading %d (%s)\n", yyctx->state, yyctx->chr, yys); + } +#endif + } + if (((yyctx->yyn = forgecond_sindex[yyctx->state]) != 0) && (yyctx->yyn += yyctx->chr) >= 0 && yyctx->yyn <= forgecond_TABLESIZE && forgecond_check[yyctx->yyn] == (forgecond_int_t) yyctx->chr) { +#if forgecond_DEBUG + if (yyctx->debug) + printf("yyctx->debug: state %d, shifting to state %d\n", yyctx->state, forgecond_table[yyctx->yyn]); +#endif + if (yyctx->stack.s_mark >= yyctx->stack.s_last && forgecond_growstack(yyctx, &yyctx->stack) == forgecond_ENOMEM) + goto yyoverflow; + yyctx->state = forgecond_table[yyctx->yyn]; + *++yyctx->stack.s_mark = forgecond_table[yyctx->yyn]; + *++yyctx->stack.l_mark = yyctx->lval; + yyctx->chr = forgecond_EMPTY; + if (yyctx->errflag > 0) + --yyctx->errflag; + goto yyloop; + } + if (((yyctx->yyn = forgecond_rindex[yyctx->state]) != 0) && (yyctx->yyn += yyctx->chr) >= 0 && yyctx->yyn <= forgecond_TABLESIZE && forgecond_check[yyctx->yyn] == (forgecond_int_t) yyctx->chr) { + yyctx->yyn = forgecond_table[yyctx->yyn]; + goto yyreduce; + } + if (yyctx->errflag != 0) + goto yyinrecovery; + + forgecond_error(ctx, yyctx->lval, "syntax error"); + + goto yyerrlab; /* redundant goto avoids 'unused label' warning */ +yyerrlab: + ++yyctx->nerrs; + +yyinrecovery: + if (yyctx->errflag < 3) { + yyctx->errflag = 3; + for(;;) { + if (((yyctx->yyn = forgecond_sindex[*yyctx->stack.s_mark]) != 0) && (yyctx->yyn += forgecond_ERRCODE) >= 0 && yyctx->yyn <= forgecond_TABLESIZE && forgecond_check[yyctx->yyn] == (forgecond_int_t) forgecond_ERRCODE) { +#if forgecond_DEBUG + if (yyctx->debug) + printf("yyctx->debug: state %d, error recovery shifting to state %d\n", *yyctx->stack.s_mark, forgecond_table[yyctx->yyn]); +#endif + if (yyctx->stack.s_mark >= yyctx->stack.s_last && forgecond_growstack(yyctx, &yyctx->stack) == forgecond_ENOMEM) + goto yyoverflow; + yyctx->state = forgecond_table[yyctx->yyn]; + *++yyctx->stack.s_mark = forgecond_table[yyctx->yyn]; + *++yyctx->stack.l_mark = yyctx->lval; + goto yyloop; + } + else { +#if forgecond_DEBUG + if (yyctx->debug) + printf("yyctx->debug: error recovery discarding state %d\n", *yyctx->stack.s_mark); +#endif + if (yyctx->stack.s_mark <= yyctx->stack.s_base) + goto yyabort; + --yyctx->stack.s_mark; + --yyctx->stack.l_mark; + } + } + } + else { + if (yyctx->chr == forgecond_EOF) + goto yyabort; +#if forgecond_DEBUG + if (yyctx->debug) { + if ((yys = forgecond_name[forgecond_TRANSLATE(yyctx->chr)]) == NULL) + yys = forgecond_name[forgecond_UNDFTOKEN]; + printf("yyctx->debug: state %d, error recovery discards token %d (%s)\n", yyctx->state, yyctx->chr, yys); + } +#endif + yyctx->chr = forgecond_EMPTY; + goto yyloop; + } + +yyreduce: +#if forgecond_DEBUG + if (yyctx->debug) + printf("yyctx->debug: state %d, reducing by rule %d (%s)\n", yyctx->state, yyctx->yyn, forgecond_rule[yyctx->yyn]); +#endif + yyctx->yym = forgecond_len[yyctx->yyn]; + if (yyctx->yym > 0) + yyctx->val = yyctx->stack.l_mark[1 - yyctx->yym]; + else + memset(&yyctx->val, 0, sizeof yyctx->val); + + switch (yyctx->yyn) { +case 2: +#line 105 "../plugins/std_forge/cond_gram.y" + { /* nothing to generate */ } +break; +case 3: +#line 106 "../plugins/std_forge/cond_gram.y" + { append(ctx, FGC_STR_EQ); } +break; +case 4: +#line 107 "../plugins/std_forge/cond_gram.y" + { append(ctx, FGC_STR_NEQ); } +break; +case 5: +#line 108 "../plugins/std_forge/cond_gram.y" + { append(ctx, FGC_EQ); } +break; +case 6: +#line 109 "../plugins/std_forge/cond_gram.y" + { append(ctx, FGC_GTEQ); } +break; +case 7: +#line 110 "../plugins/std_forge/cond_gram.y" + { append(ctx, FGC_LTEQ); } +break; +case 8: +#line 111 "../plugins/std_forge/cond_gram.y" + { append(ctx, FGC_GT); } +break; +case 9: +#line 112 "../plugins/std_forge/cond_gram.y" + { append(ctx, FGC_LT); } +break; +case 10: +#line 113 "../plugins/std_forge/cond_gram.y" + { append(ctx, FGC_NEQ); } +break; +case 11: +#line 114 "../plugins/std_forge/cond_gram.y" + { append(ctx, FGC_ADD); } +break; +case 12: +#line 115 "../plugins/std_forge/cond_gram.y" + { append(ctx, FGC_SUB); } +break; +case 13: +#line 116 "../plugins/std_forge/cond_gram.y" + { append(ctx, FGC_MUL); } +break; +case 14: +#line 117 "../plugins/std_forge/cond_gram.y" + { append(ctx, FGC_DIV); } +break; +case 15: +#line 118 "../plugins/std_forge/cond_gram.y" + { append(ctx, FGC_MOD); } +break; +case 16: +#line 119 "../plugins/std_forge/cond_gram.y" + { append(ctx, FGC_BIN_AND); } +break; +case 17: +#line 120 "../plugins/std_forge/cond_gram.y" + { append(ctx, FGC_BIN_OR); } +break; +case 18: +#line 121 "../plugins/std_forge/cond_gram.y" + { append(ctx, FGC_LOG_AND); } +break; +case 19: +#line 122 "../plugins/std_forge/cond_gram.y" + { append(ctx, FGC_LOG_OR); } +break; +case 20: +#line 123 "../plugins/std_forge/cond_gram.y" + { append(ctx, FGC_NEG); } +break; +case 21: +#line 124 "../plugins/std_forge/cond_gram.y" + { append(ctx, FGC_NOT); } +break; +case 22: +#line 125 "../plugins/std_forge/cond_gram.y" + { append(ctx, FGC_NUM); append(ctx, yyctx->stack.l_mark[0].l); } +break; +case 23: +#line 129 "../plugins/std_forge/cond_gram.y" + { yyctx->val.l = yyctx->stack.l_mark[0].l; } +break; +case 24: +#line 130 "../plugins/std_forge/cond_gram.y" + { yyctx->val.l = 10 * yyctx->stack.l_mark[-1].l + yyctx->stack.l_mark[0].l; } +break; +case 25: +#line 134 "../plugins/std_forge/cond_gram.y" + { if (ctx->strs.used != 0) gds_append(&ctx->strs, '\0'); yyctx->val.l = ctx->strs.used; gds_append(&ctx->strs, yyctx->stack.l_mark[0].l); } +break; +case 26: +#line 135 "../plugins/std_forge/cond_gram.y" + { yyctx->val.l = yyctx->stack.l_mark[-1].l; gds_append(&ctx->strs, yyctx->stack.l_mark[0].l); } +break; +case 27: +#line 136 "../plugins/std_forge/cond_gram.y" + { yyctx->val.l = yyctx->stack.l_mark[-1].l; gds_append(&ctx->strs, yyctx->stack.l_mark[0].l + '0'); } +break; +case 28: +#line 140 "../plugins/std_forge/cond_gram.y" + { append(ctx, FGC_VAR1); append(ctx, yyctx->stack.l_mark[0].l); } +break; +case 29: +#line 141 "../plugins/std_forge/cond_gram.y" + { append(ctx, FGC_VAR2); append(ctx, yyctx->stack.l_mark[-2].l); append(ctx, yyctx->stack.l_mark[0].l); } +break; +case 30: +#line 145 "../plugins/std_forge/cond_gram.y" + { yyctx->val.l = yyctx->stack.l_mark[0].l; } +break; +case 31: +#line 146 "../plugins/std_forge/cond_gram.y" + { ctx->in_quote = 1; } +break; +case 32: +#line 147 "../plugins/std_forge/cond_gram.y" + { ctx->in_quote = 0; append(ctx, FGC_STR); append(ctx, yyctx->stack.l_mark[-1].l); } +break; +case 33: +#line 148 "../plugins/std_forge/cond_gram.y" + { append(ctx, FGC_STR); append(ctx, ctx->strs.used); gds_append(&ctx->strs, '\0'); } +break; +#line 780 "../plugins/std_forge/cond_gram.c" + } + yyctx->stack.s_mark -= yyctx->yym; + yyctx->state = *yyctx->stack.s_mark; + yyctx->stack.l_mark -= yyctx->yym; + yyctx->yym = forgecond_lhs[yyctx->yyn]; + if (yyctx->state == 0 && yyctx->yym == 0) { +#if forgecond_DEBUG + if (yyctx->debug) + printf("yyctx->debug: after reduction, shifting from state 0 to state %d\n", forgecond_FINAL); +#endif + yyctx->state = forgecond_FINAL; + *++yyctx->stack.s_mark = forgecond_FINAL; + *++yyctx->stack.l_mark = yyctx->val; + if (yyctx->chr < 0) { + forgecond_GETCHAR(2); + if (yyctx->chr < 0) + yyctx->chr = forgecond_EOF; +#if forgecond_DEBUG + if (yyctx->debug) { + if ((yys = forgecond_name[forgecond_TRANSLATE(yyctx->chr)]) == NULL) + yys = forgecond_name[forgecond_UNDFTOKEN]; + printf("yyctx->debug: state %d, reading %d (%s)\n", forgecond_FINAL, yyctx->chr, yys); + } +#endif + } + if (yyctx->chr == forgecond_EOF) + goto yyaccept; + goto yyloop; + } + if (((yyctx->yyn = forgecond_gindex[yyctx->yym]) != 0) && (yyctx->yyn += yyctx->state) >= 0 && yyctx->yyn <= forgecond_TABLESIZE && forgecond_check[yyctx->yyn] == (forgecond_int_t) yyctx->state) + yyctx->state = forgecond_table[yyctx->yyn]; + else + yyctx->state = forgecond_dgoto[yyctx->yym]; +#if forgecond_DEBUG + if (yyctx->debug) + printf("yyctx->debug: after reduction, shifting from state %d to state %d\n", *yyctx->stack.s_mark, yyctx->state); +#endif + if (yyctx->stack.s_mark >= yyctx->stack.s_last && forgecond_growstack(yyctx, &yyctx->stack) == forgecond_ENOMEM) + goto yyoverflow; + *++yyctx->stack.s_mark = (forgecond_int_t) yyctx->state; + *++yyctx->stack.l_mark = yyctx->val; + goto yyloop; + +yyoverflow: + forgecond_error(ctx, yyctx->lval, "yacc stack overflow"); + +yyabort: + forgecond_freestack(&yyctx->stack); + return forgecond_RES_ABORT; + +yyaccept: + forgecond_freestack(&yyctx->stack); + return forgecond_RES_DONE; +} Index: tags/1.0.5/src/plugins/std_forge/cond_gram.h =================================================================== --- tags/1.0.5/src/plugins/std_forge/cond_gram.h (nonexistent) +++ tags/1.0.5/src/plugins/std_forge/cond_gram.h (revision 10414) @@ -0,0 +1,136 @@ +#ifndef _forgecond__defines_h_ +#define _forgecond__defines_h_ + +typedef short forgecond_int_t; +#define forgecond_chr yyctx->chr +#define forgecond_val yyctx->val +#define forgecond_lval yyctx->lval +#define forgecond_stack yyctx->stack +#define forgecond_debug yyctx->debug +#define forgecond_nerrs yyctx->nerrs +#define forgecond_errflag yyctx->errflag +#define forgecond_state yyctx->state +#define forgecond_yyn yyctx->yyn +#define forgecond_yym yyctx->yym +#define forgecond_jump yyctx->jump +#line 4 "../plugins/std_forge/cond_gram.y" + +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - standard cschem attributes + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust Fund in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include +#include +#include "cond.h" + +#define STR_VAL_NULL -1000 +#define STR_VAL_BASE -100 + +#define INST(a, b, c) ((((long)a) << 16) | (((long)b) << 8) | ((long)c)) + +typedef enum { + FGC_ABORT = 0, + FGC_ADD = INST('A', 'D', 'D'), + FGC_SUB = INST('S', 'U', 'B'), + FGC_MUL = INST('M', 'U', 'L'), + FGC_DIV = INST('D', 'I', 'V'), + FGC_MOD = INST('M', 'O', 'D'), + FGC_STR_EQ = INST('S', 'E', 'Q'), + FGC_STR_NEQ = INST('S', 'N', 'Q'), + FGC_EQ = INST('E', 'Q', 0), + FGC_NEQ = INST('N', 'E', 'Q'), + FGC_GT = INST('G', 'T', 0), + FGC_LT = INST('L', 'T', 0), + FGC_GTEQ = INST('G', 'T', 'E'), + FGC_LTEQ = INST('L', 'T', 'E'), + FGC_BIN_AND = INST('&', 0, 0), + FGC_BIN_OR = INST('|', 0, 0), + FGC_LOG_AND = INST('&', '&', 0), + FGC_LOG_OR = INST('|', '|', 0), + FGC_NEG = INST('N', 'E', 'G'), + FGC_NOT = INST('N', 'O', 'T'), + FGC_VAR1 = INST('V', 'R', '1'), + FGC_VAR2 = INST('V', 'R', '2'), + FGC_NUM = INST('N', 'U', 'M'), + FGC_STR = INST('S', 'T', 'R') /* string literal */ +} forgecond_inst_t; + +static void append(forgecond_ctx_t *ctx, long cod) { vtl0_append(&ctx->prg, cod); } + +#line 85 "../plugins/std_forge/cond_gram.y" +typedef union forgecond_tokunion_u +{ + long l; +} forgecond_tokunion_t; +typedef forgecond_tokunion_t forgecond_STYPE; + + +#define DIGIT 257 +#define LETTER 258 +#define UMINUS 259 +#define UNOT 260 +#define forgecond_ERRCODE 256 + +#ifndef forgecond_INITSTACKSIZE +#define forgecond_INITSTACKSIZE 200 +#endif + +typedef struct { + unsigned stacksize; + forgecond_int_t *s_base; + forgecond_int_t *s_mark; + forgecond_int_t *s_last; + forgecond_STYPE *l_base; + forgecond_STYPE *l_mark; +#if forgecond_DEBUG + int debug; +#endif +} forgecond_STACKDATA; + +typedef struct { + int errflag; + int chr; + forgecond_STYPE val; + forgecond_STYPE lval; + int nerrs; + int yym, yyn, state; + int jump; + int stack_max_depth; + int debug; + + /* variables for the parser stack */ + forgecond_STACKDATA stack; +} forgecond_yyctx_t; + +typedef enum { forgecond_RES_NEXT, forgecond_RES_DONE, forgecond_RES_ABORT } forgecond_res_t; + +extern int forgecond_parse_init(forgecond_yyctx_t *yyctx); +extern forgecond_res_t forgecond_parse(forgecond_yyctx_t *yyctx, forgecond_ctx_t *ctx, int tok, forgecond_STYPE *lval); +extern void forgecond_error(forgecond_ctx_t *ctx, forgecond_STYPE tok, const char *msg); + + +#endif /* _forgecond__defines_h_ */ Index: tags/1.0.5/src/plugins/std_forge/cond_gram.y =================================================================== --- tags/1.0.5/src/plugins/std_forge/cond_gram.y (nonexistent) +++ tags/1.0.5/src/plugins/std_forge/cond_gram.y (revision 10414) @@ -0,0 +1,395 @@ +%prefix forgecond_% + +%{ + +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - standard cschem attributes + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust Fund in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include +#include +#include "cond.h" + +#define STR_VAL_NULL -1000 +#define STR_VAL_BASE -100 + +#define INST(a, b, c) ((((long)a) << 16) | (((long)b) << 8) | ((long)c)) + +typedef enum { + FGC_ABORT = 0, + FGC_ADD = INST('A', 'D', 'D'), + FGC_SUB = INST('S', 'U', 'B'), + FGC_MUL = INST('M', 'U', 'L'), + FGC_DIV = INST('D', 'I', 'V'), + FGC_MOD = INST('M', 'O', 'D'), + FGC_STR_EQ = INST('S', 'E', 'Q'), + FGC_STR_NEQ = INST('S', 'N', 'Q'), + FGC_EQ = INST('E', 'Q', 0), + FGC_NEQ = INST('N', 'E', 'Q'), + FGC_GT = INST('G', 'T', 0), + FGC_LT = INST('L', 'T', 0), + FGC_GTEQ = INST('G', 'T', 'E'), + FGC_LTEQ = INST('L', 'T', 'E'), + FGC_BIN_AND = INST('&', 0, 0), + FGC_BIN_OR = INST('|', 0, 0), + FGC_LOG_AND = INST('&', '&', 0), + FGC_LOG_OR = INST('|', '|', 0), + FGC_NEG = INST('N', 'E', 'G'), + FGC_NOT = INST('N', 'O', 'T'), + FGC_VAR1 = INST('V', 'R', '1'), + FGC_VAR2 = INST('V', 'R', '2'), + FGC_NUM = INST('N', 'U', 'M'), + FGC_STR = INST('S', 'T', 'R') /* string literal */ +} forgecond_inst_t; + +static void append(forgecond_ctx_t *ctx, long cod) { vtl0_append(&ctx->prg, cod); } + +%} + +%start cond + +%token DIGIT LETTER + +%left '|' +%left '&' +%left '+' '-' +%left '*' '/' '%' +%left '=' '!' '<' '>' +%left UMINUS /* supplies precedence for unary minus */ +%left UNOT /* supplies precedence for unary not */ + +%union +{ + long l; +} + +%type LETTER +%type DIGIT +%type expr +%type number +%type id +%type var +%type str + +%% /* beginning of rules section */ + +cond: + expr + ; + +expr: + '(' expr ')' { /* nothing to generate */ } + | str '=' '=' str { append(ctx, FGC_STR_EQ); } + | str '!' '=' str { append(ctx, FGC_STR_NEQ); } + | expr '=' '=' expr { append(ctx, FGC_EQ); } + | expr '>' '=' expr { append(ctx, FGC_GTEQ); } + | expr '<' '=' expr { append(ctx, FGC_LTEQ); } + | expr '>' expr { append(ctx, FGC_GT); } + | expr '<' expr { append(ctx, FGC_LT); } + | expr '!' '=' expr { append(ctx, FGC_NEQ); } + | expr '+' expr { append(ctx, FGC_ADD); } + | expr '-' expr { append(ctx, FGC_SUB); } + | expr '*' expr { append(ctx, FGC_MUL); } + | expr '/' expr { append(ctx, FGC_DIV); } + | expr '%' expr { append(ctx, FGC_MOD); } + | expr '&' expr { append(ctx, FGC_BIN_AND); } + | expr '|' expr { append(ctx, FGC_BIN_OR); } + | expr '&' '&' expr { append(ctx, FGC_LOG_AND); } + | expr '|' '|' expr { append(ctx, FGC_LOG_OR); } + | '-' expr %prec UMINUS { append(ctx, FGC_NEG); } + | '!' expr %prec UNOT { append(ctx, FGC_NOT); } + | number { append(ctx, FGC_NUM); append(ctx, $1); } + ; + +number: + DIGIT { $$ = $1; } + | number DIGIT { $$ = 10 * $1 + $2; } + ; + +id: + LETTER { if (ctx->strs.used != 0) gds_append(&ctx->strs, '\0'); $$ = ctx->strs.used; gds_append(&ctx->strs, $1); } + | id LETTER { $$ = $1; gds_append(&ctx->strs, $2); } + | id DIGIT { $$ = $1; gds_append(&ctx->strs, $2 + '0'); } + ; + +var: + id { append(ctx, FGC_VAR1); append(ctx, $1); } + | id '.' id { append(ctx, FGC_VAR2); append(ctx, $1); append(ctx, $3); } + ; + +str: + var { $$ = $1; } + | '"' { ctx->in_quote = 1; } + id '"' { ctx->in_quote = 0; append(ctx, FGC_STR); append(ctx, $3); } + | '"' '"' { append(ctx, FGC_STR); append(ctx, ctx->strs.used); gds_append(&ctx->strs, '\0'); } + ; + +%% /* start of programs */ + +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - standard cschem attributes + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust Fund in 2023) + * + * This program is free software licensed under the GPL, see the top of + * the file cond_gram.y. + */ + +static int lex(forgecond_ctx_t *ctx, forgecond_STYPE *yylval, const char **inp) +{ + int c; + + if (ctx->in_quote) { + c = **inp; + (*inp)++; + if (c == '\\') { + c = **inp; + (*inp)++; + } + else if (c == '\"') + return c; + yylval->l = c; + return LETTER; + } + + do { + c = **inp; + (*inp)++; + } while(isspace(c)); /* skip space */ + + if (c == '\0') + return forgecond_EOF; + + /* c is now nonblank */ + if (islower(c) || (c == '_')) { + yylval->l = c; + return LETTER; + } + if (isdigit(c)) { + yylval->l = c - '0'; + return DIGIT; + } + return c; +} + +void forgecond_dump(FILE *f, forgecond_ctx_t *ctx) +{ + long n, len; + + fprintf(f, "prg:\n"); + for(n = 0; n < ctx->prg.used; n++) { + char s[4]; + long l, l1, l2; + + switch(ctx->prg.array[n]) { + case FGC_NUM: fprintf(f, " NUM: %ld\n", ctx->prg.array[++n]); break; + case FGC_STR: fprintf(f, " STR: [%ld]\n", ctx->prg.array[++n]); break; + case FGC_VAR1: fprintf(f, " VAR1: [%ld]\n", ctx->prg.array[++n]); break; + case FGC_VAR2: + l1 = ctx->prg.array[++n]; + l2 = ctx->prg.array[++n]; + fprintf(f, " VAR2: [%ld] [%ld]\n", l1, l2); break; + default: + l = ctx->prg.array[n]; + s[0] = (l >> 16) & 0x0ff; + s[1] = (l >> 8) & 0x0ff; + s[2] = l & 0x0ff; + s[3] = '\0'; + fprintf(f, " %s\n", s); + break; + } + } + + fprintf(f, "strings:\n"); + for(n = 0; n < ctx->strs.used; n += len) { + len = strlen(ctx->strs.array+n)+1; + fprintf(f, " [%ld] '%s'\n", n, ctx->strs.array+n); + } +} + +static long pop_(forgecond_ctx_t *ctx, vtl0_t *stack) +{ + if (stack->used > 0) + return (long)stack->array[--stack->used]; + forgecond_error_cb(ctx, "forgecond: stack underflow (internal error)\n"); + return 0; +} + +static const char *get_str(forgecond_ctx_t *ctx, long idx, int allow_strval) +{ + if ((allow_strval) && (idx < 0)) { + if (idx == STR_VAL_NULL) + return NULL; + idx = idx - STR_VAL_BASE; + if ((idx >= 0) && (idx < sizeof(ctx->var_val)/sizeof(ctx->var_val[0]))) { + const char *res = ctx->var_val[idx]; + ctx->var_val[idx] = NULL; + return res; + } + forgecond_error_cb(ctx, "forgecond: invalid str val address (internal error)\n"); + return NULL; + } + + if ((idx < 0) || (idx >= ctx->strs.used)) { + forgecond_error_cb(ctx, "forgecond: invalid string literal address (internal error)\n"); + return NULL; + } + return ctx->strs.array + idx; + +} + +static const char *pop_str_(forgecond_ctx_t *ctx, vtl0_t *stack) +{ + return get_str(ctx, pop_(ctx, stack), 1); +} + +#define push(val) vtl0_append(stack, val) +#define pop() pop_(ctx, stack) +#define pop_str() pop_str_(ctx, stack) + +static void push_var_val(forgecond_ctx_t *ctx, vtl0_t *stack, long name_idx2, long name_idx1) +{ + int n; + const char *name1 = (name_idx1 >= 0) ? get_str(ctx, name_idx1, 0) : NULL; + const char *name2 = (name_idx2 >= 0) ? get_str(ctx, name_idx2, 0) : NULL; + const char *res = forgecond_var_resolve_cb(ctx, name2, name1); + + if (res == NULL) { + push(STR_VAL_NULL); + return; + } + + for(n = 0; n < sizeof(ctx->var_val)/sizeof(ctx->var_val[0]); n++) { + if (ctx->var_val[n] == NULL) { + ctx->var_val[n] = res; + push(STR_VAL_BASE+n); + return; + } + } + + forgecond_error_cb(ctx, "forgecond: no slot for str val (internal error)\n"); + push(STR_VAL_NULL); + return; +} + + + +static int safe_strcmp(const char *a, const char *b) +{ + if ((a == NULL) || (b == NULL)) return -1; /* an invalid string never equals to anyting */ + return strcmp(a, b); +} + +long forgecond_exec(forgecond_ctx_t *ctx, vtl0_t *stack) +{ + long n, a, b; + const char *sa, *sb; + + stack->used = 0; + for(n = 0; n < ctx->prg.used; n++) { + switch(ctx->prg.array[n]) { + + /* push immediate */ + case FGC_VAR2: + a = ctx->prg.array[++n]; + b = ctx->prg.array[++n]; + push_var_val(ctx, stack, a, b); + break; + /* fall-thru to push two string indices */ + case FGC_VAR1: + push_var_val(ctx, stack, ctx->prg.array[++n], -1); + break; + + case FGC_NUM: + case FGC_STR: + push(ctx->prg.array[++n]); + break; + + case FGC_ADD: push(pop() + pop()); break; + case FGC_SUB: a = pop(); b = pop(); push(b - a); break; + case FGC_MUL: push(pop() * pop()); break; + case FGC_DIV: a = pop(); b = pop(); push(b / a); break; + case FGC_MOD: a = pop(); b = pop(); push(b % a); break; + case FGC_EQ: push(pop() == pop()); break; + case FGC_NEQ: push(pop() != pop()); break; + case FGC_GT: a = pop(); b = pop(); push(b > a); break; + case FGC_LT: a = pop(); b = pop(); push(b < a); break; + case FGC_GTEQ: a = pop(); b = pop(); push(b >= a); break; + case FGC_LTEQ: a = pop(); b = pop(); push(b <= a); break; + case FGC_BIN_AND: push(pop() & pop()); break; + case FGC_BIN_OR: push(pop() | pop()); break; + case FGC_LOG_AND: push(pop() && pop()); break; + case FGC_LOG_OR: push(pop() || pop()); break; + case FGC_NEG: push(-pop()); break; + case FGC_NOT: push(!pop()); break; + + case FGC_STR_EQ: sa = pop_str(); sb = pop_str(); push(safe_strcmp(sa, sb) == 0); break; + case FGC_STR_NEQ: sa = pop_str(); sb = pop_str(); push(safe_strcmp(sa, sb) != 0); break; + } + } + + return pop(); +} + +int forgecond_parse_str(forgecond_ctx_t *ctx, const char *str) +{ + forgecond_res_t res; + forgecond_yyctx_t yyctx; + + ctx->strs.used = 0; + ctx->prg.used = 0; + ctx->in_quote = 0; + memset(&ctx->var_val, 0, sizeof(ctx->var_val)); + + if (str == NULL) + return -1; + + if (forgecond_parse_init(&yyctx) != 0) + return -1; + + do { + forgecond_STYPE lval; + int tok = lex(ctx, &lval, &str); + res = forgecond_parse(&yyctx, ctx, tok, &lval); + } while(res == forgecond_RES_NEXT); + + return (res == forgecond_RES_DONE) ? 0 : -1; +} + +void forgecond_error(forgecond_ctx_t *ctx, forgecond_STYPE tok, const char *s) +{ + forgecond_error_cb(ctx, s); +} + +void forgecond_uninit(forgecond_ctx_t *ctx) +{ + gds_uninit(&ctx->strs); + vtl0_uninit(&ctx->prg); +} Index: tags/1.0.5/src/plugins/std_forge/dlg_test_bench.c =================================================================== --- tags/1.0.5/src/plugins/std_forge/dlg_test_bench.c (nonexistent) +++ tags/1.0.5/src/plugins/std_forge/dlg_test_bench.c (revision 10414) @@ -0,0 +1,655 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - standard cschem forge + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/* stance configuration dialog */ + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +/* This doesn't make a plugin dep as only inlines and macros and structs are used */ +#include +#define RND_TIMED_CHG_TIMEOUT conf_core.editor.edit_time +#include + +#include +#include +#include + +#include + +#include "std_forge.h" + +/*** test benches ***/ + +typedef struct { + csch_sheet_t *sheet; + csch_oidpath_t idp; + long wchk[1]; /* over-allocated for num_benches */ +} test_bench_obj_t; + +typedef struct { + long wtoggle; + char *name; /* strdup'd because the underlying stance.test_bench_values conf node value can be replaced any time */ +} test_bench_row_t; + +typedef struct test_bench_dlg_ctx_s { + RND_DAD_DECL_NOINIT(dlg) + long num_objs, num_benches; + test_bench_obj_t **obj; + unsigned modal:1; + + /* timed update */ + unsigned inhibit_pend:1; /* don't start the timer on the same dialog for our own mods */ + rnd_timed_chg_t pend; + + gdl_elem_t link; + test_bench_row_t row[1]; /* over-allocated for num_benches */ +} test_bench_dlg_ctx_t; + +static gdl_list_t test_bench_dlgs; + +/* Returns 1 if dsg affects ctx, 0 otherwise */ +static int sheet_in_dlg(test_bench_dlg_ctx_t *ctx, rnd_design_t *dsg) +{ + long n; + for(n = 0; n < ctx->num_objs; n++) { + if (&ctx->obj[n]->sheet->hidlib == dsg) + return 1; + } + return 0; +} + +static const char *sym_name(csch_cgrp_t *obj) +{ + const char *name = NULL; + + if (obj != NULL) + name = csch_attrib_get_str(&obj->attr, "name"); + if (name == NULL) + name = "?"; + + return name; +} + +/* Look up bench name in the dialog and return corresponding row index or -1 */ +static int bench_name2idx(test_bench_dlg_ctx_t *ctx, const char *name) +{ + int n; + for(n = 0; n < ctx->num_benches; n++) { + const char *lab = ctx->row[n].name; + if (strcmp(lab, name) == 0) + return n; + } + return -1; +} + +static void test_bench_free(test_bench_dlg_ctx_t *ctx) +{ + long n; + + rnd_timed_chg_cancel(&ctx->pend); + + if (ctx->modal) + return; /* will be free'd once at the end, after run() */ + + for(n = 0; n < ctx->num_objs; n++) { + csch_oidpath_free(&ctx->obj[n]->idp); + free(ctx->obj[n]); + } + for(n = 0; n < ctx->num_benches; n++) + free(ctx->row[n].name); + + if (ctx->link.parent != NULL) + gdl_remove(&test_bench_dlgs, ctx, link); + + free(ctx); +} + +static void test_bench_dlg_close_cb(void *caller_data, rnd_hid_attr_ev_t ev) +{ + test_bench_free(caller_data); +} + +static void sch_rnd_test_bench_sch2dlg(test_bench_dlg_ctx_t *ctx) +{ + long n, m; + vts0_t rev = {0}; + gds_t st = {0}; + rnd_hid_attr_val_t hv; + + gds_enlarge(&st, ctx->num_benches+1); + + for(n = 0; n < ctx->num_objs; n++) { + csch_cgrp_t *obj = (csch_cgrp_t *)csch_oidpath_resolve(ctx->obj[n]->sheet, &ctx->obj[n]->idp); + csch_attrib_t *a; + + if (obj == NULL) { + for(m = 0; m < ctx->num_benches; m++) + rnd_gui->attr_dlg_widget_state(ctx->dlg_hid_ctx, ctx->obj[n]->wchk[m], 0); + continue; + } + + + memset(st.array, 0, ctx->num_benches); + a = csch_attrib_get(&obj->attr, "forge-if/test_bench"); + if ((a != NULL) && (a->val == NULL) && (a->arr.used > 1)) { + const char *expr = a->arr.array[0]; + int r = forge_condition_get_test_bench(&rev, "symbol", sym_name(obj), "test_bench", expr); + rnd_trace("obj update '%s' -> %d!\n", expr, r); + for(m = 0; m < rev.used; m += 3) { + int idx; + const char *var1 = rev.array[m], *var2 = rev.array[m+1], *val = rev.array[m+2]; + if ((strcmp(var1, "stance") == 0) && (strcmp(var2, "test_bench") == 0) && (val[0] != '\0')) { + idx = bench_name2idx(ctx, val); + rnd_trace("%s.%s != '%s' %d\n", var1, var2, val); + if (idx >= 0) + st.array[idx] = 1; + } + } + } + + for(m = 0; m < ctx->num_benches; m++) { + hv.lng = st.array[m]; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->obj[n]->wchk[m], &hv); + } + } + + vts0_uninit(&rev); + gds_uninit(&st); +} + +static void create_testbench_attrib_arr(csch_sheet_t *sheet, csch_cgrp_t *obj, const char *expr, const char *src_str) +{ + csch_source_arg_t *src = csch_attrib_src_p("std_forge", src_str); + + uundo_freeze_serial(&sheet->undo); + csch_attr_modify_str(sheet, obj, 250, "forge-if/test_bench", expr, src, 1); + csch_attr_modify_conv_to_arr(sheet, obj, "forge-if/test_bench", 1); + csch_attr_arr_modify_ins_before(sheet, obj, "forge-if/test_bench", 1, "sub,^.*$,yes,omit", 1); + csch_attr_arr_modify_ins_before(sheet, obj, "forge-if/test_bench", 1, "scalar,omit", 1); + uundo_unfreeze_serial(&sheet->undo); + uundo_inc_serial(&sheet->undo); +} + +static void test_bench_regen_obj(test_bench_dlg_ctx_t *ctx, int obj_idx) +{ + test_bench_obj_t *bobj = ctx->obj[obj_idx]; + csch_sheet_t *sheet = bobj->sheet; + csch_cgrp_t *obj = (csch_cgrp_t *)csch_oidpath_resolve(sheet, &bobj->idp); + gds_t tmp = {0}; + int n; + + if (obj == NULL) + return; + + for(n = 0; n < ctx->num_benches; n++) { + if (ctx->dlg[bobj->wchk[n]].val.lng) { + if (tmp.used == 0) + gds_append_str(&tmp, "(stance.test_bench != \"\")"); + gds_append_str(&tmp, " && (stance.test_bench != \""); + gds_append_str(&tmp, ctx->row[n].name); + gds_append_str(&tmp, "\")"); + } + } + + + rnd_trace(" tb expr: '%s'\n", tmp.array); + + if (tmp.used > 0) { + csch_attrib_t *a = csch_attrib_get(&obj->attr, "forge-if/test_bench"); + if ((a != NULL) && (a->val == NULL) && (a->arr.used > 1)) { + /* existing array attribute, edit first entry */ + csch_attr_arr_modify_str(sheet, obj, "forge-if/test_bench", 0, tmp.array, 1); + } + else + create_testbench_attrib_arr(sheet, obj, tmp.array, "test bench dialog"); + } + else + csch_attr_modify_del(sheet, obj, "forge-if/test_bench", 1); + + + gds_uninit(&tmp); +} + +/* abuse geo fields - for checkbox these are not used by the HID code */ +#define OBJ_IDX geo_width +#define BENCH_IDX geo_height + +static void test_bench_chkbox_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *achkbox) +{ + test_bench_dlg_ctx_t *ctx = caller_data; + long wchkbox = achkbox - ctx->dlg; + int obj_idx = ctx->dlg[wchkbox].OBJ_IDX; + int bench_idx = ctx->dlg[wchkbox].BENCH_IDX; + int val = achkbox->val.lng; + + rnd_trace("clicked obj %d bench %d set to %d\n", obj_idx, bench_idx, val); + + ctx->inhibit_pend = 1; + test_bench_regen_obj(ctx, obj_idx); + ctx->inhibit_pend = 0; +} + +static void test_bench_row_toggle_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *abutton) +{ + test_bench_dlg_ctx_t *ctx = caller_data; + long wbutton = abutton - ctx->dlg; + int bench_idx = ctx->dlg[wbutton].BENCH_IDX; + rnd_hid_attribute_t *achk1 = ctx->dlg + ctx->obj[0]->wchk[bench_idx]; /* first checkbox in the row */ + int n, val = !achk1->val.lng; + rnd_hid_attr_val_t hv; + csch_sheet_t *sheet = ctx->obj[0]->sheet; + + uundo_freeze_serial(&sheet->undo); + hv.lng = val; + for(n = 0; n < ctx->num_objs; n++) { + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->obj[n]->wchk[bench_idx], &hv); + test_bench_regen_obj(ctx, n); + } + uundo_unfreeze_serial(&sheet->undo); + uundo_inc_serial(&sheet->undo); +} + +static void timed_update_cb(void *uctx) +{ + test_bench_dlg_ctx_t *ctx = uctx; + sch_rnd_test_bench_sch2dlg(ctx); +} + +static int sch_rnd_test_bench_dlg(const vtp0_t *objs, int modal) +{ + test_bench_dlg_ctx_t *ctx; + rnd_hid_dad_buttons_t clbtn[] = {{"Close", 0}, {NULL, 0}}; + rnd_conf_listitem_t *item_li; + const char *item_str; + int idx; + long n, i, numo, numb; + + numb = rnd_conflist_length(&conf_core.stance.test_bench_values); + if (numb < 1) { + rnd_message(RND_MSG_ERROR, "Please define stance.test_bench values first\nHint: file menu, project, project stances\n"); + return -1; + } + + for(n = numo = 0; n < objs->used; n++) { + csch_cgrp_t *g = objs->array[n]; + if (!csch_obj_is_grp(&g->hdr)) continue; + if (g->role != CSCH_ROLE_SYMBOL) continue; + numo++; + } + + if (numo == 0) { + rnd_message(RND_MSG_ERROR, "No symbols included in target objects.\n"); + return -1; + } + + ctx = calloc(sizeof(test_bench_dlg_ctx_t) + sizeof(test_bench_row_t)*numb, 1); + ctx->num_benches = numb; + ctx->num_objs = numo; + ctx->obj = malloc(sizeof(test_bench_obj_t *) * ctx->num_objs); + rnd_timed_chg_init(&ctx->pend, timed_update_cb, ctx); + + gdl_append(&test_bench_dlgs, ctx, link); + + for(n = 0; n < ctx->num_objs; n++) { + ctx->obj[n] = calloc(sizeof(test_bench_obj_t) + sizeof(long) * ctx->num_benches, 1); + } + + for(n = numo = 0; n < objs->used; n++) { + csch_cgrp_t *g = objs->array[n]; + if (!csch_obj_is_grp(&g->hdr)) continue; + if (g->role != CSCH_ROLE_SYMBOL) continue; + ctx->obj[numo]->sheet = g->hdr.sheet; + csch_oidpath_from_obj(&ctx->obj[numo]->idp, &g->hdr); + numo++; + } + + + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + + RND_DAD_BEGIN_TABLE(ctx->dlg, ctx->num_objs+2); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL | RND_HATF_SCROLL); + + /* header row */ + RND_DAD_LABEL(ctx->dlg, ""); + for(n = 0; n < ctx->num_objs; n++) { + csch_cgrp_t *grp = (csch_cgrp_t *)csch_oidpath_resolve(ctx->obj[n]->sheet, &ctx->obj[n]->idp); + RND_DAD_LABEL(ctx->dlg, sym_name(grp)); + } + RND_DAD_LABEL(ctx->dlg, ""); + + /* data rows */ + rnd_conf_loop_list_str(&conf_core.stance.test_bench_values, item_li, item_str, idx) { + RND_DAD_LABEL(ctx->dlg, item_str); + ctx->row[idx].name = rnd_strdup(item_str); + for(n = 0; n < ctx->num_objs; n++) { + RND_DAD_BOOL(ctx->dlg); + ctx->obj[n]->wchk[idx] = i = RND_DAD_CURRENT(ctx->dlg); + ctx->dlg[i].OBJ_IDX = n; + ctx->dlg[i].BENCH_IDX = idx; + RND_DAD_CHANGE_CB(ctx->dlg, test_bench_chkbox_cb); + } + if (ctx->num_objs > 1) { + RND_DAD_BUTTON(ctx->dlg, "Tgl!"); + RND_DAD_HELP(ctx->dlg, "Toggle all in row: set them all on or all off"); + ctx->row[idx].wtoggle = i = RND_DAD_CURRENT(ctx->dlg); + ctx->dlg[i].BENCH_IDX = idx; + RND_DAD_CHANGE_CB(ctx->dlg, test_bench_row_toggle_cb); + } + else + RND_DAD_LABEL(ctx->dlg, ""); + } + + RND_DAD_END(ctx->dlg); + + RND_DAD_LABEL(ctx->dlg, "A cell marked means the given symbol (column)"); + RND_DAD_LABEL(ctx->dlg, "is included in the given test bench (row)."); + + RND_DAD_BUTTON_CLOSES(ctx->dlg, clbtn); + RND_DAD_END(ctx->dlg); + + RND_DAD_DEFSIZE(ctx->dlg, 600, 300); + RND_DAD_NEW("TestBenchesDialog", ctx->dlg, "Test benches quick edit", ctx, modal, test_bench_dlg_close_cb); /* type=local */ + + sch_rnd_test_bench_sch2dlg(ctx); + + if (modal) { + ctx->modal = 1; + RND_DAD_RUN(ctx->dlg); + ctx->modal = 0; /* permit free() */ + test_bench_free(ctx); + } + + return 0; +} + +/* Returns 0 on success and loads lst with objs */ +static int get_objlist(csch_sheet_t *sheet, const char *cmd, vtp0_t *lst, const char *actname, const char *prompt) +{ + if (rnd_strncasecmp(cmd, "object", 6) == 0) { + if (cmd[6] == ':') { + csch_chdr_t *obj; + csch_oidpath_t idp = {0}; + + if (csch_oidpath_parse(&idp, cmd+7) != 0) { + rnd_message(RND_MSG_ERROR, "%s(): Failed to convert object ID: '%s'\n", actname, cmd+7); + return FGW_ERR_ARG_CONV; + } + obj = csch_oidpath_resolve(sheet, &idp); + csch_oidpath_free(&idp); + vtp0_append(lst, obj); + } + else { + csch_chdr_t *obj; + rnd_coord_t x, y; + + rnd_hid_get_coords(prompt, &x, &y, 0); + obj = sch_rnd_search_first_gui_inspect(sheet, sch_rnd_crosshair_x, sch_rnd_crosshair_y); + if (obj == NULL) + return 0; + vtp0_append(lst, obj); + } + + } + else if (rnd_strcasecmp(cmd, "selected") == 0) { + csch_search_all_selected(sheet, NULL, lst, 1); + } + else { + rnd_message(RND_MSG_ERROR, "%s() invalid first argument\n", actname); + return -1; + } + return 0; +} + +const char csch_acts_TestBenchDialog[] = "TestBenchDialog(object[:oidpath]|selected)"; +const char csch_acth_TestBenchDialog[] = "Open the test bench selector for the current object or for selected objects.\n"; +fgw_error_t csch_act_TestBenchDialog(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_design_t *hidlib = RND_ACT_DESIGN; + csch_sheet_t *sheet = (csch_sheet_t *)hidlib; + const char *cmd; + vtp0_t lst = {0}; + + RND_ACT_CONVARG(1, FGW_STR, TestBenchDialog, cmd = argv[1].val.str); + + if (get_objlist(sheet, cmd, &lst, "TestBenchDialog", "Test bench edit dialog: select object") != 0) + return FGW_ERR_ARG_CONV; + + sch_rnd_test_bench_dlg(&lst, 0); + vtp0_uninit(&lst); + return 0; +} + +const char csch_acts_quick_attr_forge__if__test_bench[] = "quick_attr_forge__if__test_bench(objptr)"; +const char csch_acth_quick_attr_forge__if__test_bench[] = "Quick Attribute Edit for core data model's symbol connect attribute (attribute based symbol terminal to network connection table)"; +fgw_error_t csch_act_quick_attr_forge__if__test_bench(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + vtp0_t lst = {0}; + csch_cgrp_t *grp; + + QUICK_ATTR_GET_GRP(grp, "quick_attr_forge__if__test_bench"); + + vtp0_append(&lst, grp); + sch_rnd_test_bench_dlg(&lst, 1); + + vtp0_uninit(&lst); + RND_ACT_IRES(1); /* refresh the attribute editor */ + return 0; +} + +static void test_bench_modify(csch_sheet_t *sheet, csch_cgrp_t *grp, int del, const char *benchname, gds_t *tmp) +{ + int has = 0; + vts0_t rev = {0}; + csch_attrib_t *a; + int m; + + tmp->used = 0; + + if (!csch_obj_is_grp(&grp->hdr)) + return; + + a = csch_attrib_get(&grp->attr, "forge-if/test_bench"); + if ((a != NULL) && (a->val == NULL) && (a->arr.used > 1)) { + const char *expr = a->arr.array[0]; + forge_condition_get_test_bench(&rev, "symbol", sym_name(grp), "test_bench", expr); + for(m = 0; m < rev.used; m += 3) { + const char *var1 = rev.array[m], *var2 = rev.array[m+1], *val = rev.array[m+2]; + if ((strcmp(var1, "stance") == 0) && (strcmp(var2, "test_bench") == 0) && (strcmp(val, benchname) == 0)) { + has = 1; + break; + } + } + } + + /* we do not need to do anything if object already has it the way the user wants */ + if (del && !has) goto quit; + if (!del && has) goto quit; + + if (del) { + int copied = 0; + + gds_append_str(tmp, "(stance.test_bench != \"\")"); + + for(m = 0; m < rev.used; m += 3) { + const char *var1 = rev.array[m], *var2 = rev.array[m+1], *val = rev.array[m+2]; + + if ((strcmp(var1, "stance") == 0) && (strcmp(var2, "test_bench") == 0) && (strcmp(val, benchname) == 0)) + continue; + + if (*val == '\0') + continue; + + gds_append_str(tmp, " && (stance.test_bench != \""); + gds_append_str(tmp, val); + gds_append_str(tmp, "\")"); + copied++; + } + + /* remove attr if expression became empty */ + if (copied == 0) { + csch_attr_modify_del(sheet, grp, "forge-if/test_bench", 1); + goto quit; + } + } + else { /* add */ + if ((a == NULL) || (a->val != NULL) || (a->arr.used <= 1)) { + /* create from scratch */ + gds_append_str(tmp, "(stance.test_bench != \"\")"); + gds_append_str(tmp, " && (stance.test_bench != \""); + gds_append_str(tmp, benchname); + gds_append_str(tmp, "\")"); + } + else { + /* extend existing */ + const char *expr = a->arr.array[0]; + gds_append_str(tmp, expr); + gds_append_str(tmp, " && (stance.test_bench != \""); + gds_append_str(tmp, benchname); + gds_append_str(tmp, "\")"); + } + } + create_testbench_attrib_arr(sheet, grp, tmp->array, "TestBenchModify() action"); + + quit:; + vts0_uninit(&rev); +} + +const char csch_acts_TestBenchModify[] = "TestBenchModify(object[:oidpath]|selected, add|del, testbench_name)"; +const char csch_acth_TestBenchModify[] = "Modify test bench affiliation of object(s), adding or deleting test benches in which the given objects are participating.\n"; +fgw_error_t csch_act_TestBenchModify(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_design_t *hidlib = RND_ACT_DESIGN; + csch_sheet_t *sheet = (csch_sheet_t *)hidlib; + const char *cmd, *how, *bench; + vtp0_t lst = {0}; + gds_t tmp = {0}; + long n; + int del; + + RND_ACT_CONVARG(1, FGW_STR, TestBenchModify, cmd = argv[1].val.str); + RND_ACT_CONVARG(2, FGW_STR, TestBenchModify, how = argv[2].val.str); + RND_ACT_CONVARG(3, FGW_STR, TestBenchModify, bench = argv[3].val.str); + + if (rnd_strcasecmp(how, "del") == 0) { + del = 1; + } + else if (rnd_strcasecmp(how, "add") == 0) { + del = 0; + } + else { + rnd_message(RND_MSG_ERROR, "Invalid second argument in TestBenchModify()\n"); + return FGW_ERR_ARG_CONV; + } + + if (get_objlist(sheet, cmd, &lst, "TestBenchModify", "Test bench edit dialog: select object") != 0) + return FGW_ERR_ARG_CONV; + + for(n = 0; n < lst.used; n++) + test_bench_modify(sheet, lst.array[n], del, bench, &tmp); + + gds_uninit(&tmp); + vtp0_uninit(&lst); + return 0; +} + +/*** Common ***/ + +/* trigger gui update if any the test_bench_values stance conf changes */ +static void test_bench_change_post(rnd_conf_native_t *cfg, int arr_idx, void *user_data) +{ +/* rnd_design_t *curr = rnd_multi_get_current();*/ +} + +static void test_bench_preunload(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + test_bench_dlg_ctx_t *ctx, *next; + for(ctx = gdl_first(&test_bench_dlgs); ctx != NULL; ctx = next) { + next = gdl_next(&test_bench_dlgs, ctx); + if (sheet_in_dlg(ctx, hidlib)) { + rnd_dad_retovr_t retovr = {0}; + gdl_remove(&test_bench_dlgs, ctx, link); + rnd_hid_dad_close(ctx->dlg_hid_ctx, &retovr, 0); + } + } +} + +static void test_bench_onchg(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + test_bench_dlg_ctx_t *ctx; + for(ctx = gdl_first(&test_bench_dlgs); ctx != NULL; ctx = gdl_next(&test_bench_dlgs, ctx)) + if (!ctx->inhibit_pend && sheet_in_dlg(ctx, hidlib)) + rnd_timed_chg_schedule(&ctx->pend); +} + +static rnd_conf_hid_id_t test_bench_hid_id; +static const char cookie[] = "test bench gui"; +void csch_dlg_test_bench_init(void) +{ + static rnd_conf_hid_callbacks_t cb; + rnd_conf_native_t *cn = rnd_conf_get_field("stance/test_bench_values"); + + rnd_event_bind(CSCH_EVENT_SHEET_PREUNLOAD, test_bench_preunload, NULL, cookie); + rnd_event_bind(CSCH_EVENT_SHEET_EDITED, test_bench_onchg, NULL, cookie); + + /* get a global conf change callback */ + cb.val_change_post = test_bench_change_post; + test_bench_hid_id = rnd_conf_hid_reg(cookie, &cb); + + if (cn != NULL) { + memset(&cb, 0, sizeof(rnd_conf_hid_callbacks_t)); + cb.val_change_post = test_bench_change_post; + rnd_conf_hid_set_cb(cn, test_bench_hid_id, &cb); + } +} + +void csch_dlg_test_bench_uninit(void) +{ + rnd_event_unbind_allcookie(cookie); + rnd_conf_hid_unreg(cookie); +} Index: tags/1.0.5/src/plugins/std_forge/dlg_test_bench.h =================================================================== --- tags/1.0.5/src/plugins/std_forge/dlg_test_bench.h (nonexistent) +++ tags/1.0.5/src/plugins/std_forge/dlg_test_bench.h (revision 10414) @@ -0,0 +1,14 @@ +void csch_dlg_test_bench_init(void); +void csch_dlg_test_bench_uninit(void); + +extern const char csch_acts_TestBenchDialog[]; +extern const char csch_acth_TestBenchDialog[]; +fgw_error_t csch_act_TestBenchDialog(fgw_arg_t *res, int argc, fgw_arg_t *argv); + +extern const char csch_acts_quick_attr_forge__if__test_bench[]; +extern const char csch_acth_quick_attr_forge__if__test_bench[]; +fgw_error_t csch_act_quick_attr_forge__if__test_bench(fgw_arg_t *res, int argc, fgw_arg_t *argv); + +extern const char csch_acts_TestBenchModify[]; +extern const char csch_acth_TestBenchModify[]; +fgw_error_t csch_act_TestBenchModify(fgw_arg_t *res, int argc, fgw_arg_t *argv); Index: tags/1.0.5/src/plugins/std_forge/std_forge.c =================================================================== --- tags/1.0.5/src/plugins/std_forge/std_forge.c (nonexistent) +++ tags/1.0.5/src/plugins/std_forge/std_forge.c (revision 10414) @@ -0,0 +1,587 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - standard cschem forge + * Copyright (C) 2022, 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "cond.h" +#include "cond_gram.h" +#include "dlg_test_bench.h" +#include "std_forge.h" + +#if 0 +typedef struct { +} std_forge_ctx_t; /* per view data */ +#endif + +static const char std_forge_cookie[] = "std_forge"; +static gds_t stmp = {0}; +static htsp_t cond_cache; /* key: condition expression source; val: precompiled forgecond_ctx_t */ +static vtl0_t cond_stack; + +/* skip matches protected with \, also interpret \\ */ +static char *strchr_prot(char *s, char chr) +{ + for(; *s != '\0'; s++) { + if (*s == '\\') + s++; + else if (*s == chr) + return s; + } + return NULL; +} + +static char *shift(char *last, csch_ahdr_t *aobj, const char *args) +{ + char *next; + + if (last == NULL) + return NULL; + + next = strchr_prot(last, ','); + if (next == NULL) { + rnd_message(RND_MSG_ERROR, "Syntax error in #%ld's forge: too few arguments in %s\n", aobj->aid, args); + return NULL; + } + *next = '\0'; + return next+1; +} + +/* execute regex subst to payload in dst; realloc dst as needed */ +static void forge_sub_exec(re_se_t *re, char **dst, char *payload, int global) +{ + char *res; + re_se_subst(re, &res, *dst, payload, !global); + free(*dst); + *dst = rnd_strdup(res); +} + +static int forge_sub(csch_ahdr_t *aobj, const char *args, int prio, int global, int isattr, const char *srctxt) +{ + csch_attrib_t *a; + char *pat, *target, *key; + re_se_t *re; + + stmp.used = 0; + gds_append_str(&stmp, args); + pat = stmp.array; + + target = shift(pat, aobj, args); + key = shift(target, aobj, args); + if (key == NULL) + return -1; + + a = csch_attrib_get(&aobj->attr, key); + if (a == NULL) { + rnd_message(RND_MSG_ERROR, "Error in regex sub in #%ld's forge: attribute %s does not exist\n", aobj->aid, key); + return -1; + } + + if (isattr) { + csch_attrib_t *ra; + + ra = csch_attrib_get(&aobj->attr, target); + if (ra != NULL) { + if (ra->val == NULL) { + rnd_message(RND_MSG_ERROR, "Error in regex [g]suba in #%ld's forge: referee %s is not scalar\n", aobj->aid, target); + return -1; + } + else + target = ra->val; + } + else + target = ""; + } + + if (prio > a->prio) { + csch_source_arg_t *src = csch_attrib_src_pa(aobj, srctxt, "forge", "inst: *sub*"); + csch_attrib_append_src(a, prio, src, 1); + csch_attr_src_free(src); + return 0; + } + + re = re_se_comp(pat); + if (re == NULL) { + rnd_message(RND_MSG_ERROR, "Error in regex sub in #%ld's forge: invalid regex '%s'\n", aobj->aid, pat); + return -1; + } + + if (a->val == NULL) { + long n; + for(n = 0; n < a->arr.used; n++) + forge_sub_exec(re, &a->arr.array[n], target, global); + } + else + forge_sub_exec(re, &a->val, target, global); + + re_se_free(re); + + { + csch_source_arg_t *src = csch_attrib_src_pa(aobj, srctxt, "forge", "inst: *sub*"); + csch_attrib_append_src(a, prio, src, 0); + csch_attr_src_free(src); + } + return 0; +} + +static int forge_delete(csch_ahdr_t *aobj, const char *args, int prio, const char *srctxt) +{ + csch_source_arg_t *src = csch_attrib_src_pa(aobj, srctxt, "forge", "inst: delete"); + csch_attrib_del(&aobj->attr, prio, args, src); + return 0; +} + +static int forge_create(csch_ahdr_t *aobj, const char *args, int prio, int isarr, const char *srctxt) +{ + csch_attrib_t *a = csch_attrib_get(&aobj->attr, args); + + if (a != NULL) { + if ((a->val != NULL) && isarr) { + rnd_message(RND_MSG_ERROR, "Error in 'array' in #%ld's forge: attribute %s is a scalar\n", aobj->aid, args); + return -1; + } + if ((a->arr.used > 0) && !isarr) { + rnd_message(RND_MSG_ERROR, "Error in 'scalar' in #%ld's forge: attribute %s is an array\n", aobj->aid, args); + return -1; + } + return 0; + } + else { + csch_source_arg_t *src = csch_attrib_src_pa(aobj, srctxt, "forge", isarr ? "inst: array" : "inst: scalar"); + csch_attrib_set(&aobj->attr, prio, args, isarr ? NULL : "", src, NULL); + } + + return 0; +} + +static void prep_app_arr(csch_attrib_t *dst, const char *str, int where) +{ + char *s = rnd_strdup(str); + if (where < 0) + vts0_insert_len(&dst->arr, 0, &s, 1); + else + vts0_append(&dst->arr, s); +} + +/* where: 0 is overwrite, -1 is prepend, +1 is append */ +static int forge_copy(csch_ahdr_t *aobj, const char *args, int prio, int where, const char *srctxt) +{ + csch_attrib_t *dst, *src; + char *dstn, *srcn; + long n; + + stmp.used = 0; + gds_append_str(&stmp, args); + + dstn = stmp.array; + srcn = shift(dstn, aobj, args); + if (srcn == NULL) + return -1; + + dst = csch_attrib_get(&aobj->attr, dstn); + if (dst == NULL) { + rnd_message(RND_MSG_ERROR, "Error in copy/append/prepend in #%ld's forge: destination attribute %s does not exist\n", aobj->aid, dstn); + return -1; + } + src = csch_attrib_get(&aobj->attr, srcn); + if (src == NULL) { + rnd_message(RND_MSG_ERROR, "Error in copy/append/prepend in #%ld's forge: source attribute %s does not exist\n", aobj->aid, srcn); + return -1; + } + + + if (prio > dst->prio) { + csch_source_arg_t *src = csch_attrib_src_pa(aobj, srctxt, "forge", "inst: prepend/append/copy"); + csch_attrib_append_src(dst, prio, src, 1); + csch_attr_src_free(src); + return 0; + } + + switch(where) { + case 0: /* copy */ + if ((src->val == NULL) != (dst->val == NULL)) { + rnd_message(RND_MSG_ERROR, "Error in copy/append/prepend in #%ld's forge: type of src and dst (%s and %s) does not match\n", aobj->aid, srcn, dstn); + return -1; + } + if (src->val == NULL) { + /* free dst array */ + for(n = 0; n < dst->arr.used; n++) { + free(dst->arr.array[n]); + dst->arr.array[n] = NULL; + } + dst->arr.used = 0; + + /* copy array */ + for(n = 0; n < src->arr.used; n++) + vts0_append(&dst->arr, src->arr.array[n]); + } + else { + free(dst->val); + dst->val = rnd_strdup(src->val); + } + break; + + case +1: + case -1: + if (dst->val == NULL) { + /* dst is an array */ + if (src->val == NULL) { + for(n = 0; n < src->arr.used; n++) + prep_app_arr(dst, src->arr.array[n], where); + } + else + prep_app_arr(dst, src->val, where); + } + else { + char *combined; + + /* plain string prepend/append */ + if (src->val == NULL) { + rnd_message(RND_MSG_ERROR, "Error in copy/append/prepend in #%ld's forge: can't combine array into scalar (%s into %s)\n", aobj->aid, srcn, dstn); + return -1; + } + if (where == -1) + combined = rnd_concat(src->val, dst->val, NULL); + else + combined = rnd_concat(dst->val, src->val, NULL); + free(dst->val); + dst->val = combined; + } + } + + { + csch_source_arg_t *src = csch_attrib_src_pa(aobj, srctxt, "forge", "inst: prepend/append/copy"); + csch_attrib_append_src(dst, prio, src, 0); + csch_attr_src_free(src); + } + + return 0; +} + +static int forge_exec(csch_ahdr_t *aobj, const char *inst, int prio, const char *srctxt) +{ + while(isspace(*inst)) inst++; + +/* rnd_trace(" %s\n", inst);*/ + + switch(*inst) { + case 'a': + if (strncmp(inst+1, "rray,", 5) == 0) return forge_create(aobj, inst+6, prio, 1, srctxt); + if (strncmp(inst+1, "ppend,", 6) == 0) return forge_copy(aobj, inst+7, prio, +1, srctxt); + break; + case 'c': + if (strncmp(inst+1, "opy,", 4) == 0) return forge_copy(aobj, inst+5, prio, 0, srctxt); + break; + case 'd': + if (strncmp(inst+1, "elete,", 6) == 0) return forge_delete(aobj, inst+7, prio, srctxt); + break; + case 'g': + if (strncmp(inst+1, "sub,", 4) == 0) return forge_sub(aobj, inst+5, prio, 1, 0, srctxt); + if (strncmp(inst+1, "suba,", 5) == 0) return forge_sub(aobj, inst+6, prio, 1, 1, srctxt); + break; + case 'p': + if (strncmp(inst+1, "repend,", 7) == 0) return forge_copy(aobj, inst+8, prio, -1, srctxt); + break; + case 's': + if (strncmp(inst+1, "ub,", 3) == 0) return forge_sub(aobj, inst+4, prio, 0, 0, srctxt); + if (strncmp(inst+1, "uba,", 4) == 0) return forge_sub(aobj, inst+5, prio, 0, 1, srctxt); + if (strncmp(inst+1, "calar,", 6) == 0) return forge_create(aobj, inst+7, prio, 0, srctxt); + break; + } + + rnd_message(RND_MSG_ERROR, "Syntax error in #%ld's forge: unknown instruction %s\n", aobj->aid, inst); + return -1; +} + +RND_INLINE const char *resolve_view(forgecond_ctx_t *ctx, const char *name) +{ + if ((ctx->abst == NULL) || (ctx->abst->prj == NULL)) + return NULL; + + return csch_view_get_prop(ctx->abst->prj, ctx->abst->view_id, name); +} + +const char *forgecond_var_resolve_cb(forgecond_ctx_t *ctx, const char *name1, const char *name2) +{ + if (name1 != NULL) { + switch(*name1) { + case 's': + if (strcmp(name1, "stance") == 0) return csch_stance_get(name2); + break; + case 'v': + if (strcmp(name1, "view") == 0) return resolve_view(ctx, name2); + break; + } + } + return NULL; +} + +void forgecond_error_cb(forgecond_ctx_t *ctx, const char *s) +{ + rnd_message(RND_MSG_ERROR, "std_forge condition: %s\n", s); +} + + + +static forgecond_ctx_t *forge_condition_get(const char *objtype, const char *objname, const char *condname, const char *condstr) +{ + forgecond_ctx_t *fc = htsp_get(&cond_cache, condstr); + + if (fc == NULL) { + fc = calloc(sizeof(forgecond_ctx_t), 1); + htsp_set(&cond_cache, rnd_strdup(condstr), fc); + if (forgecond_parse_str(fc, condstr) != 0) + fc->error = 1; + } + if (fc->error) { + rnd_message(RND_MSG_ERROR, "Failed to compile std_forge attribute condition: %s of %s %s:\n%s\n", condname, objtype, objname, condstr); + return NULL; + } + + return fc; +} + +static int forge_condition(const char *objtype, const char *objname, csch_ahdr_t *aobj, const char *condname, const char *condstr) +{ + forgecond_ctx_t *fc = forge_condition_get(objtype, objname, condname, condstr); + + if (fc == NULL) + return -1; + + fc->abst = aobj->abst; + return forgecond_exec(fc, &cond_stack); +} + +static int fc_test_bench_rev(vts0_t *dst, forgecond_ctx_t *fc, long *start) +{ + long istr, ivar1, ivar2; + + if (*start < 0) + return 0; + switch(fc->prg.array[*start]) { + case FGC_LOG_AND: +/*rnd_trace("[%ld] AND\n", *start);*/ + (*start)--; + if (fc_test_bench_rev(dst, fc, start) != 0) + return -1; + if (fc_test_bench_rev(dst, fc, start) != 0) + return -1; + return 0; + case FGC_STR_NEQ: +/*rnd_trace("[%ld] SNQ\n", *start);*/ + (*start)--; + istr = fc->prg.array[*start]; + (*start)--; + if (fc->prg.array[*start] != FGC_STR) + return -1; + (*start)--; + ivar2 = fc->prg.array[*start]; + (*start)--; + ivar1 = fc->prg.array[*start]; + (*start)--; + if (fc->prg.array[*start] != FGC_VAR2) + return -1; + (*start)--; +/*rnd_trace(" istr='%s' ivar1='%s' ivar2='%s'\n", fc->strs.array+istr, fc->strs.array+ivar1, fc->strs.array+ivar2);*/ + vts0_append(dst, fc->strs.array+ivar1); + vts0_append(dst, fc->strs.array+ivar2); + vts0_append(dst, fc->strs.array+istr); + return 0; + + } + + return -1; +} + + +int forge_condition_get_test_bench(vts0_t *dst, const char *objtype, const char *objname, const char *condname, const char *condstr) +{ + forgecond_ctx_t *fc = forge_condition_get(objtype, objname, condname, condstr); + long start = fc->prg.used-1; + + if (fc == NULL) + return -1; + + dst->used = 0; + return fc_test_bench_rev(dst, fc, &start); +} + + +static int forge_apply(const char *objtype, const char *objname, csch_ahdr_t *aobj, int prio) +{ + const csch_attrib_t *forge; + long n; + int r = 0; + htsp_entry_t *e; + + /* unconditional */ + forge = csch_attrib_get(&aobj->attr, "forge"); + if (forge != NULL) { + /* rnd_trace("--- FORGE in comp %s\n", comp->name);*/ + for(n = 0; (r == 0) && (n < forge->arr.used); n++) + r |= forge_exec(aobj, forge->arr.array[n], prio, "forge"); + } + + /* conditionals */ + for(e = htsp_first(&aobj->attr); (e != NULL) && (r == 0); e = htsp_next(&aobj->attr, e)) { + csch_attrib_t *a = e->value; + + if (a->deleted || (a->arr.used < 2) || (e->key[0] != 'f') || (strncmp(e->key, "forge-if/", 9) != 0)) + continue; + + /* execute */ + if (forge_condition(objtype, objname, aobj, e->key, a->arr.array[0])) { + for(n = 1; (r == 0) && (n < a->arr.used); n++) + r |= forge_exec(aobj, a->arr.array[n], prio, e->key); + } + } + + return r; +} + + +/*** hooks ***/ + +fgw_error_t std_forge_compile_comp0(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ +/* fgw_obj_t *obj = argv[0].val.argv0.func->obj;*/ +/* std_forge_ctx_t *ctx = obj->script_data; */ + csch_hook_call_ctx_t *cctx = argv[0].val.argv0.user_call_ctx; + csch_acomp_t *comp; + int prio = cctx->view_eng->eprio + CSCH_PRI_PLUGIN_NORMAL; + + CSCH_HOOK_CONVARG(1, FGW_AOBJ, std_forge_comp_update, comp = fgw_aobj(&argv[1])); + assert(comp->hdr.type == CSCH_ATYPE_COMP); + + res->type = FGW_INT; + res->val.nat_int = forge_apply("component", comp->name, &comp->hdr, prio); + return 0; +} + +fgw_error_t std_forge_compile_net(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ +/* fgw_obj_t *obj = argv[0].val.argv0.func->obj;*/ +/* std_forge_ctx_t *ctx = obj->script_data; */ + csch_hook_call_ctx_t *cctx = argv[0].val.argv0.user_call_ctx; + csch_anet_t *net; + int prio = cctx->view_eng->eprio + CSCH_PRI_PLUGIN_NORMAL; + + CSCH_HOOK_CONVARG(1, FGW_AOBJ, std_forge_comp_update, net = fgw_aobj(&argv[1])); + assert(net->hdr.type == CSCH_ATYPE_NET); + + res->type = FGW_INT; + res->val.nat_int = forge_apply("net", net->name, &net->hdr, prio); + return 0; +} + +static int on_load(fgw_obj_t *obj, const char *filename, const char *opts) +{ + fgw_func_reg(obj, "compile_component0", std_forge_compile_comp0); + fgw_func_reg(obj, "compile_net", std_forge_compile_net); + + /* initialize view-local cache */ + obj->script_data = /*calloc(sizeof(std_forge_ctx_t), 1)*/ NULL; + + return 0; +} + +static int on_unload(fgw_obj_t *obj) +{ +/* std_forge_ctx_t *ctx = obj->script_data; + free(ctx);*/ + return 0; +} + + +static const fgw_eng_t fgw_std_forge_eng = { + "std_forge", + csch_c_call_script, + NULL, + on_load, + on_unload +}; + +static rnd_action_t std_forge_action_list[] = { + {"TestBenchDialog", csch_act_TestBenchDialog, csch_acth_TestBenchDialog, csch_acts_TestBenchDialog}, + {"TestBenchModify", csch_act_TestBenchModify, csch_acth_TestBenchModify, csch_acts_TestBenchModify}, + {"quick_attr_forge__if__test_bench", csch_act_quick_attr_forge__if__test_bench, csch_acth_quick_attr_forge__if__test_bench, csch_acts_quick_attr_forge__if__test_bench} +}; + + +int pplg_check_ver_std_forge(int ver_needed) { return 0; } + +void pplg_uninit_std_forge(void) +{ + gds_uninit(&stmp); + csch_dlg_test_bench_uninit(); + vtl0_uninit(&cond_stack); + genht_uninit_deep(htsp, &cond_cache, { + forgecond_ctx_t *fc = htent->value; + free(htent->key); + forgecond_uninit(fc); + free(fc); + }); + rnd_remove_actions_by_cookie(std_forge_cookie); +} + +int pplg_init_std_forge(void) +{ + RND_API_CHK_VER; + fgw_eng_reg(&fgw_std_forge_eng); + htsp_init(&cond_cache, strhash, strkeyeq); + csch_dlg_test_bench_init(); + + RND_REGISTER_ACTIONS(std_forge_action_list, std_forge_cookie); + + return 0; +} + Index: tags/1.0.5/src/plugins/std_forge/std_forge.h =================================================================== --- tags/1.0.5/src/plugins/std_forge/std_forge.h (nonexistent) +++ tags/1.0.5/src/plugins/std_forge/std_forge.h (revision 10414) @@ -0,0 +1,9 @@ +#include + +/* reverse engineer a standard foormatted test bench conditonal. + The standard form is: (a.b != "") && (a.b != "foo") && (a.b != "bar") && ... + Result in dst is triplets of strings, "a", "b" and the literal it should + be equal to. Returns 0 on success. */ +int forge_condition_get_test_bench(vts0_t *dst, const char *objtype, const char *objname, const char *condname, const char *condstr); + + Index: tags/1.0.5/src/plugins/std_forge/std_forge.pup =================================================================== --- tags/1.0.5/src/plugins/std_forge/std_forge.pup (nonexistent) +++ tags/1.0.5/src/plugins/std_forge/std_forge.pup (revision 10414) @@ -0,0 +1,7 @@ +$class engine +$short standard cschem attr forge +$long Handles: attribute forging +$state works +$package (core) +default buildin +autoload 1 Index: tags/1.0.5/src/plugins/std_tools/Makefile =================================================================== --- tags/1.0.5/src/plugins/std_tools/Makefile (nonexistent) +++ tags/1.0.5/src/plugins/std_tools/Makefile (revision 10414) @@ -0,0 +1,2 @@ +all: + cd ../../sch-rnd && make mod_std_tools Index: tags/1.0.5/src/plugins/std_tools/Plug.tmpasm =================================================================== --- tags/1.0.5/src/plugins/std_tools/Plug.tmpasm (nonexistent) +++ tags/1.0.5/src/plugins/std_tools/Plug.tmpasm (revision 10414) @@ -0,0 +1,10 @@ +put /local/rnd/mod {std_tools} +put /local/rnd/mod/OBJS [@ + $(PLUGDIR)/std_tools/std_tools.o +@] + +switch /local/module/std_tools/controls + case {buildin} include /local/csch/tmpasm/buildin; end; + case {plugin} include /local/csch/tmpasm/plugin; end; + case {disable} include /local/csch/tmpasm/disable; end; +end Index: tags/1.0.5/src/plugins/std_tools/line_common.c =================================================================== --- tags/1.0.5/src/plugins/std_tools/line_common.c (nonexistent) +++ tags/1.0.5/src/plugins/std_tools/line_common.c (revision 10414) @@ -0,0 +1,234 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - standard tools + * Copyright (C) 2020 Tibor 'Igor2' Palinkas + * (copied from camv-rnd by the author) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include +#include +#include +#include +#include +#include "sch-rnd/crosshair.h" +#include "sch-rnd/conf_core.h" +#include +#include +#include +#include + +typedef enum { + CSCH_TOOL_LINEDIR_ALL = 0, + CSCH_TOOL_LINEDIR_HV, + CSCH_TOOL_LINEDIR_VH +} csch_tool_line_dir_t; + +typedef struct { + /* config */ + csch_tool_line_dir_t dir; + unsigned dir_temp_inv:1; + csch_cpen_t *stroke; + const char *stroke_name; + + /* statates */ + csch_coord_t x1, y1, x2, y2; /* in cschem coords, not in screen coords */ + int clicked; /* 0 means waiting for x1,y1, 1 means waiting for x2,y2 */ +} csch_tool_line_t; + +csch_tool_line_t csch_tool_line; + + + + +/* returns whether the line is finished */ +static int line_release(rnd_design_t *hl) +{ + switch(csch_tool_line.clicked) { + case 0: + csch_tool_line.x1 = csch_tool_line.x2 = P2C(sch_rnd_crosshair_x); + csch_tool_line.y1 = csch_tool_line.y2 = P2C(sch_rnd_crosshair_y); + csch_tool_line.clicked = 1; + return 0; + case 1: + csch_tool_line.x2 = P2C(sch_rnd_crosshair_x); + csch_tool_line.y2 = P2C(sch_rnd_crosshair_y); + return 1; + } + return 0; +} + +static int line_is_zero_len(void) +{ + if (!csch_tool_line.clicked) return 0; + if (csch_tool_line.x1 != csch_tool_line.x2) return 0; + if (csch_tool_line.y1 != csch_tool_line.y2) return 0; + return 1; +} + +/* called after a line is created; stops or continues drawing, depending on + the config */ +static void line_continue(rnd_design_t *hl) +{ + if (conf_core.editor.line_cont) { + csch_tool_line.x1 = csch_tool_line.x2; + csch_tool_line.y1 = csch_tool_line.y2; + } + else + csch_tool_line.clicked = 0; +} + + +static void line_adjust_attached_objects(rnd_design_t *hl) +{ + if (csch_tool_line.clicked == 1) { + csch_coord_t chx = P2C(sch_rnd_crosshair_x), chy = P2C(sch_rnd_crosshair_y); + if ((csch_tool_line.dir == CSCH_TOOL_LINEDIR_ALL) && rnd_gui->control_is_pressed(rnd_gui)) { + double rad = atan2(chy - csch_tool_line.y1, chy - csch_tool_line.x1); + double deg = rad * RND_RAD_TO_DEG; + double len = rnd_distance(chx, chy, csch_tool_line.x1, csch_tool_line.y1); + deg = rnd_round(deg/15.0) * 15.0; + rad = deg / RND_RAD_TO_DEG; + csch_tool_line.x2 = csch_tool_line.x1 + cos(rad) * len; + csch_tool_line.y2 = csch_tool_line.y1 + sin(rad) * len; + } + else { + csch_tool_line.dir_temp_inv = rnd_gui->shift_is_pressed(rnd_gui); + csch_tool_line.x2 = chx; + csch_tool_line.y2 = chy; + } + } +} + +/* returns 1 if the segment is valid; idx is 0 or 1 */ +static int line_get_seg(rnd_design_t *hl, int idx, csch_coord_t *x1, csch_coord_t *y1, csch_coord_t *x2, csch_coord_t *y2) +{ + csch_tool_line_dir_t tmpdir = csch_tool_line.dir; + if ((tmpdir == CSCH_TOOL_LINEDIR_HV) || (tmpdir == CSCH_TOOL_LINEDIR_VH)) { + int refr = !!conf_core.editor.line_refraction; + if (csch_tool_line.dir_temp_inv) + refr = !refr; + if (refr) { + if (tmpdir == CSCH_TOOL_LINEDIR_HV) tmpdir = CSCH_TOOL_LINEDIR_VH; + else tmpdir = CSCH_TOOL_LINEDIR_HV; + } + } + + switch(tmpdir) { + case CSCH_TOOL_LINEDIR_ALL: + if (idx == 0) { + *x1 = csch_tool_line.x1; *y1 = csch_tool_line.y1; + *x2 = csch_tool_line.x2; *y2 = csch_tool_line.y2; + return 1; + } + return 0; + case CSCH_TOOL_LINEDIR_HV: + if (idx == 0) { + *x1 = csch_tool_line.x1; *y1 = csch_tool_line.y1; + *x2 = csch_tool_line.x2; *y2 = csch_tool_line.y1; + } + else { + *x1 = csch_tool_line.x2; *y1 = csch_tool_line.y1; + *x2 = csch_tool_line.x2; *y2 = csch_tool_line.y2; + } + return 1; + case CSCH_TOOL_LINEDIR_VH: + if (idx == 0) { + *x1 = csch_tool_line.x1; *y1 = csch_tool_line.y1; + *x2 = csch_tool_line.x1; *y2 = csch_tool_line.y2; + } + else { + *x1 = csch_tool_line.x1; *y1 = csch_tool_line.y2; + *x2 = csch_tool_line.x2; *y2 = csch_tool_line.y2; + } + return 1; + } + return 0; +} + +static void line_draw_attached(rnd_design_t *hl, csch_cgrp_t *parent) +{ + csch_coord_t x1, y1, x2, y2; + rnd_coord_t ps = (csch_tool_line.stroke == NULL) ? C2P(1000) : C2P(csch_tool_line.stroke->size); + + rnd_hid_set_line_cap(sch_rnd_crosshair_gc, rnd_cap_round); + rnd_hid_set_line_width(sch_rnd_crosshair_gc, ps); + + switch(csch_tool_line.clicked) { + case 0: +/*rnd_printf("%mm %mm\n", sch_rnd_crosshair_x, sch_rnd_crosshair_y);*/ + rnd_render->draw_line(sch_rnd_crosshair_gc, sch_rnd_crosshair_x, sch_rnd_crosshair_y, sch_rnd_crosshair_x, sch_rnd_crosshair_y); + break; + case 1: + if (line_get_seg(hl, 0, &x1, &y1, &x2, &y2)) + rnd_render->draw_line(sch_rnd_crosshair_gc, C2P(x1), C2P(y1), C2P(x2), C2P(y2)); + if (line_get_seg(hl, 1, &x1, &y1, &x2, &y2)) + rnd_render->draw_line(sch_rnd_crosshair_gc, C2P(x1), C2P(y1), C2P(x2), C2P(y2)); + break; + } +} + +static void line_init(void) +{ + csch_tool_line.clicked = 0; +} + +static void line_uninit(void) +{ + csch_tool_line.clicked = 0; +} + +static void line_create_all(rnd_design_t *hl, csch_cgrp_t *parent, int wirenet) +{ + csch_sheet_t *sheet = (csch_sheet_t *)hl; + int n, chg = 0; + + for(n = 0; n < 2; n++) { + csch_coord_t x1, y1, x2, y2; + if (line_get_seg(hl, n, &x1, &y1, &x2, &y2)) { + if ((x1 == x2) && (y1 == y2)) + continue; + if (!wirenet) { + csch_line_t *line = (csch_line_t *)csch_op_create(sheet, parent, CSCH_CTYPE_LINE); + + if (line == NULL) { + rnd_message(RND_MSG_ERROR, "Failed to create line object\n"); + return; + } + + line->spec.p1.x = x1; line->spec.p1.y = y1; + line->spec.p2.x = x2; line->spec.p2.y = y2; + + line->hdr.stroke_name = csch_comm_str(sheet, csch_tool_line.stroke_name, 1); + csch_line_update(sheet, line, 1); + chg++; + } + else { + csch_wirenet_draw(sheet, csch_comm_str(sheet, csch_tool_line.stroke_name, 1), x1, y1, x2, y2); + chg++; + } + } + } + + if (chg) + csch_sheet_set_changed(sheet, 1); +} Index: tags/1.0.5/src/plugins/std_tools/std_tools.c =================================================================== --- tags/1.0.5/src/plugins/std_tools/std_tools.c (nonexistent) +++ tags/1.0.5/src/plugins/std_tools/std_tools.c (revision 10414) @@ -0,0 +1,92 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - standard tools + * Copyright (C) 2020,2022 Tibor 'Igor2' Palinkas + * (copied from camv-rnd by the author) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include + +#include + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +static const char std_tools_cookie[] = "std_tools"; + +#include "line_common.c" +#include "tool_circle.c" +#include "tool_rect.c" +#include "tool_wirenet.c" +#include "tool_line.c" +#include "tool_arrow.c" +#include "tool_remove.c" +#include "tool_rotate.c" +#include "tool_movecopy.c" +#include "tool_polyedit.c" +#include "tool_text.c" +#include "tool_lock.c" +#include "tool_mirror.c" +#include "tool_buffer.c" + + +int pplg_check_ver_std_tools(int ver_needed) { return 0; } + +void pplg_uninit_std_tools(void) +{ +} + +int pplg_init_std_tools(void) +{ + RND_API_CHK_VER; + + rnd_tool_reg(&sch_rnd_tool_arrow, std_tools_cookie); + rnd_tool_reg(&sch_rnd_tool_circle, std_tools_cookie); + rnd_tool_reg(&sch_rnd_tool_line, std_tools_cookie); + rnd_tool_reg(&sch_rnd_tool_text, std_tools_cookie); + rnd_tool_reg(&sch_rnd_tool_rect, std_tools_cookie); + rnd_tool_reg(&sch_rnd_tool_wirenet, std_tools_cookie); + rnd_tool_reg(&sch_rnd_tool_remove, std_tools_cookie); + rnd_tool_reg(&sch_rnd_tool_buffer, std_tools_cookie); + rnd_tool_reg(&sch_rnd_tool_rotate, std_tools_cookie); + rnd_tool_reg(&sch_rnd_tool_lock, std_tools_cookie); + rnd_tool_reg(&sch_rnd_tool_xmirror, std_tools_cookie); + rnd_tool_reg(&sch_rnd_tool_ymirror, std_tools_cookie); + + rnd_tool_reg(&sch_rnd_tool_move, std_tools_cookie); + rnd_tool_reg(&sch_rnd_tool_copy, std_tools_cookie); + rnd_tool_reg(&sch_rnd_tool_polyedit, std_tools_cookie); + + return 0; +} Index: tags/1.0.5/src/plugins/std_tools/std_tools.pup =================================================================== --- tags/1.0.5/src/plugins/std_tools/std_tools.pup (nonexistent) +++ tags/1.0.5/src/plugins/std_tools/std_tools.pup (revision 10414) @@ -0,0 +1,7 @@ +$class feature +$short standard drawing tools +$long Tools for drawing standard cschem concrete primitives +$state works +$package (core) +default buildin +autoload 1 Index: tags/1.0.5/src/plugins/std_tools/tool_arrow.c =================================================================== --- tags/1.0.5/src/plugins/std_tools/tool_arrow.c (nonexistent) +++ tags/1.0.5/src/plugins/std_tools/tool_arrow.c (revision 10414) @@ -0,0 +1,168 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - arrow tool + * Copyright (C) 2020 Tibor 'Igor2' Palinkas + * (copied from camv-rnd by the author) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include "tool_movecopy.h" +#include "tool_polyedit.h" + +typedef struct { + csch_coord_t press_x, press_y, press_chx, press_chy; + int click; + double click_timeout; + csch_chdr_t *click_obj; +} tool_arrow_t; + +static tool_arrow_t arrow; + +static int arrow_is_drag_n_drop() +{ + return (arrow.click_obj != NULL) && (rnd_dtime() > arrow.click_timeout); +} + +static void tool_arrow_init(void) +{ +} + +static void tool_arrow_uninit(void) +{ +} + +static void tool_arrow_press(rnd_design_t *hl) +{ + csch_sheet_t *sheet = (csch_sheet_t *)hl; + arrow.press_x = P2C(sch_rnd_crosshair_x); + arrow.press_y = P2C(sch_rnd_crosshair_y); + arrow.press_chx = sch_rnd_crosshair_x; + arrow.press_chy = sch_rnd_crosshair_y; + arrow.click = 1; + arrow.click_timeout = rnd_dtime() + ((double)conf_core.editor.click_time / 1000.0); + arrow.click_obj = sch_rnd_search_obj_at(sheet, arrow.press_x, arrow.press_y, sch_rnd_slop); +} + +static void tool_arrow_release(rnd_design_t *hl) +{ + if (arrow.click) { + csch_sheet_t *sheet = (csch_sheet_t *)hl; + csch_coord_t x = P2C(sch_rnd_crosshair_x), y = P2C(sch_rnd_crosshair_y); + + if ((arrow.press_x == x) && (arrow.press_y == y)) + sch_rnd_select_click(sheet, x, y); + else + sch_rnd_select_box(sheet, arrow.press_x, arrow.press_y, x, y); + + arrow.click = 0; + } +} + +static void tool_arrow_adjust_attached_objects(rnd_design_t *hl) +{ + if (!arrow.click) + return; + + + if (arrow_is_drag_n_drop()) { + const char *tool_name; + + /* detect drag&drop move of a polygon corner */ + if (arrow.click_obj->type == CSCH_CTYPE_POLY) { + csch_coord_t r = sch_rnd_slop/2+1; + long obj_idx[2], len; + + len = csch_poly_contour_objs_at((csch_cpoly_t *)arrow.click_obj, arrow.press_x, arrow.press_y, r, obj_idx); + if ((len == 2) && (tool_polyedit_press_at(hl, arrow.press_chx, arrow.press_chy, (csch_cpoly_t *)arrow.click_obj, obj_idx, 1) == 0)) { /* only on corner */ + rnd_tool_select_by_name(hl, "polyedit"); + arrow.click = 0; + return; /* passed on to poly edit */ + } + } + + /* fall back to any-object drag&drop move or copy */ + tool_name = rnd_gui->control_is_pressed(rnd_gui) ? "copy" : "move"; +/* rnd_trace("Drag&drop object; passing on to %s\n", tool_name);*/ + arrow.click = 0; + rnd_tool_select_by_name(hl, tool_name); + tool_movecopy_press_at(hl, arrow.press_chx, arrow.press_chy, arrow.click_obj, 1); + } +} + + +static void tool_arrow_draw_attached(rnd_design_t *hl) +{ + if (arrow.click) { + csch_coord_t x = P2C(sch_rnd_crosshair_x), y = P2C(sch_rnd_crosshair_y); + if ((arrow.press_x != x) || (arrow.press_y != y)) { + + rnd_hid_set_line_cap(sch_rnd_crosshair_gc, rnd_cap_round); + rnd_hid_set_line_width(sch_rnd_crosshair_gc, -1); + rnd_render->draw_rect(sch_rnd_crosshair_gc, arrow.press_chx, arrow.press_chy, sch_rnd_crosshair_x, sch_rnd_crosshair_y); + } + } +} + +/* XPM */ +static const char *arrow_icon[] = { +/* columns rows colors chars-per-pixel */ +"21 21 3 1", +" c #000000", +". c #6EA5D7", +"o c None", +/* pixels */ +"oo .. ooooooooooooooo", +"oo .... ooooooooooooo", +"ooo ...... oooooooooo", +"ooo ........ oooooooo", +"ooo ....... ooooooooo", +"oooo ..... oooooooooo", +"oooo ...... ooooooooo", +"ooooo .. ... oooooooo", +"ooooo . o ... ooooooo", +"oooooooooo ... oooooo", +"ooooooooooo .. oooooo", +"oooooooooooo ooooooo", +"ooooooooooooooooooooo", +"ooo ooo ooo ooo", +"oo o oo ooo oo ooo oo", +"oo o oo ooo oo ooo oo", +"o ooo o ooo ooo", +"o ooo o ooo oo ooo oo", +"o o ooo oo ooo oo", +"o ooo o ooo oo ooo oo", +"o ooo o ooo oo ooo oo" +}; + + +static rnd_tool_t sch_rnd_tool_arrow = { + "arrow", NULL, std_tools_cookie, 50, arrow_icon, RND_TOOL_CURSOR_NAMED("left_ptr"), 0, + tool_arrow_init, + tool_arrow_uninit, + tool_arrow_press, + tool_arrow_release, + tool_arrow_adjust_attached_objects, + tool_arrow_draw_attached, + NULL, /* undo */ + NULL, /* redo */ + NULL, /* escape */ +}; Index: tags/1.0.5/src/plugins/std_tools/tool_buffer.c =================================================================== --- tags/1.0.5/src/plugins/std_tools/tool_buffer.c (nonexistent) +++ tags/1.0.5/src/plugins/std_tools/tool_buffer.c (revision 10414) @@ -0,0 +1,113 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - buffer paste + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * (icons copied from pcb-rnd by the author) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include + +#include +#include + +#include + +#include +#include +#include +#include + + +static void buffer_init(void) +{ + TODO("check if buffer_number is in range and fix it if not"); +} + +static void buffer_uninit(void) +{ +} + +static void buffer_notify_mode(rnd_design_t *hl) +{ + csch_sheet_t *sheet = (csch_sheet_t *)hl; + + if (rnd_gui->shift_is_pressed(rnd_gui)) { + rnd_actionva(hl, "ReplaceSymbol", "object", "", NULL); + return; + } + + sch_rnd_buffer_paste(sheet, SCH_RND_PASTEBUFFER, P2C(sch_rnd_crosshair_x), P2C(sch_rnd_crosshair_y)); +} + +static void buffer_draw_attached(rnd_design_t *hl) +{ + csch_sheet_t *sheet = (csch_sheet_t *)hl; + + sch_rnd_xor_draw_buffer(sheet, SCH_RND_PASTEBUFFER, P2C(sch_rnd_crosshair_x), P2C(sch_rnd_crosshair_y), sch_rnd_crosshair_gc, 1, 0); +} + +/* XPM */ +static const char *buf_icon[] = { +/* columns rows colors chars-per-pixel */ +"21 21 3 1", +" c #000000", +". c #7A8584", +"o c None", +/* pixels */ +"oooooooo oo ooooooo", +"oooooo.. o o ..ooooo", +"oooooooo oooo ooooooo", +"oooooo.. oooo ..ooooo", +"oooooooo oooo ooooooo", +"oooooo.. oooo ..ooooo", +"oooooooo oooo ooooooo", +"oooooo.. oooo ..ooooo", +"oooooooo oooo ooooooo", +"oooooo.. oooo ..ooooo", +"oooooooo ooooooo", +"ooooooooooooooooooooo", +"oo oo ooo o o", +"ooo ooo o ooo o ooooo", +"ooo ooo o ooo o ooooo", +"ooo ooo o ooo o oo", +"ooo oo ooo o ooooo", +"ooo ooo o ooo o ooooo", +"ooo ooo o ooo o ooooo", +"oo ooo oo ooooo", +"ooooooooooooooooooooo" +}; + +rnd_tool_t sch_rnd_tool_buffer = { + "buffer", NULL, NULL, 100, buf_icon, RND_TOOL_CURSOR_NAMED("hand"), 0, + buffer_init, + buffer_uninit, + buffer_notify_mode, + NULL, /* release */ + NULL, /* adjust */ + buffer_draw_attached, + NULL, + NULL, + NULL, /* escape */ + + 0 +}; Index: tags/1.0.5/src/plugins/std_tools/tool_circle.c =================================================================== --- tags/1.0.5/src/plugins/std_tools/tool_circle.c (nonexistent) +++ tags/1.0.5/src/plugins/std_tools/tool_circle.c (revision 10414) @@ -0,0 +1,187 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - draw circle + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include + +typedef struct { + int clicked; + rnd_coord_t x, y, r; + csch_cpen_t *stroke; +} csch_tool_circle_t; + +static csch_tool_circle_t csch_tool_circle; + +static void tool_circle_init(void) +{ + csch_tool_circle.clicked = 0; + csch_tool_circle.r = 0; + csch_tool_circle.stroke = NULL; +} + +static void tool_circle_uninit(void) +{ +} + +static void tool_circle_press(rnd_design_t *hl) +{ +} + +static void tool_circle_release(rnd_design_t *hl) +{ + csch_sheet_t *sheet = (csch_sheet_t *)hl; + + if (csch_tool_circle.clicked) { + const char *stroke_name; + csch_arc_t *arc = (csch_arc_t *)csch_op_create(sheet, &sheet->direct, CSCH_CTYPE_ARC); + + if (arc == NULL) { + rnd_message(RND_MSG_ERROR, "Failed to create arc object\n"); + return; + } + + arc->spec.c.x = csch_tool_circle.x; + arc->spec.c.y = csch_tool_circle.y; + arc->spec.r = csch_tool_circle.r; + arc->spec.start = 0; + arc->spec.delta = 360 / RND_RAD_TO_DEG; + + csch_tool_circle.stroke = SCH_RND_DIRECT_PEN(sheet, tool_circle_stroke, &stroke_name); + + arc->hdr.stroke_name = csch_comm_str(sheet, stroke_name, 1); + csch_arc_update(sheet, arc, 1); + csch_sheet_set_changed(sheet, 1); + + csch_tool_circle.clicked = 0; + + } + else { + csch_tool_circle.clicked = 1; + csch_tool_circle.x = P2C(sch_rnd_crosshair_x); + csch_tool_circle.y = P2C(sch_rnd_crosshair_y); + } +} + +static void tool_circle_adjust_attached_objects(rnd_design_t *hl) +{ +} + + +static void tool_circle_draw_attached(rnd_design_t *hl) +{ + csch_sheet_t *sheet = (csch_sheet_t *)hl; + + if (csch_tool_circle.clicked) { + double dx, dy; + rnd_coord_t ps; + + if (csch_tool_circle.stroke == NULL) + csch_tool_circle.stroke = SCH_RND_DIRECT_PEN(sheet, tool_circle_stroke, NULL); + + ps = (csch_tool_circle.stroke == NULL) ? C2P(1000) : C2P(csch_tool_circle.stroke->size); + dx = csch_tool_circle.x - P2C(sch_rnd_crosshair_x); + dy = csch_tool_circle.y - P2C(sch_rnd_crosshair_y); + + csch_tool_circle.r = rnd_round(sqrt(dx*dx + dy * dy)); + + rnd_hid_set_line_cap(sch_rnd_crosshair_gc, rnd_cap_round); + rnd_hid_set_line_width(sch_rnd_crosshair_gc, -1); + + /* mark center */ + rnd_render->draw_line(sch_rnd_crosshair_gc, + C2P(csch_tool_circle.x - 200), C2P(csch_tool_circle.y), + C2P(csch_tool_circle.x + 200), C2P(csch_tool_circle.y)); + + rnd_render->draw_line(sch_rnd_crosshair_gc, + C2P(csch_tool_circle.x), C2P(csch_tool_circle.y - 200), + C2P(csch_tool_circle.x), C2P(csch_tool_circle.y + 200)); + + /* draw contour */ + rnd_hid_set_line_width(sch_rnd_crosshair_gc, ps); + + rnd_render->draw_arc(sch_rnd_crosshair_gc, + C2P(csch_tool_circle.x), C2P(csch_tool_circle.y), + C2P(csch_tool_circle.r), C2P(csch_tool_circle.r), + 0, 360); + } + +} + +static void tool_circle_escape(rnd_design_t *hl) +{ + if (!csch_tool_circle.clicked) + rnd_tool_select_by_name(hl, "arrow"); + else + rnd_tool_select_by_name(hl, "circle"); +} + + +/* XPM */ +static const char *circle_icon[] = { +/* columns rows colors chars-per-pixel */ +"21 21 4 1", +" c #000000", +". c #7A8584", +"X c #6EA5D7", +"O c None", +/* pixels */ +"OOOOOOOOO...OOOOOOOOO", +"OOOOOOO..OOO..OOOOOOO", +"OOOOOO.OOOOOOO.OOOOOO", +"OOOOOO.OOOOOOO.OOOOOO", +"OOOOO.OOOOxOOOO.OOOOO", +"OOOOO.OOOxxxOOO.OOOOO", +"OOOOO.OOOOxOOOO.OOOOO", +"OOOOOO.OOOOOOO.OOOOOO", +"OOOOOO.OOOOOOO.OOOOOO", +"OOOOOOO..OOO..OOOOOOO", +"OOOOOOOOO...OOOOOOOOO", +"OOOOOOOOOOOOOOOOOOOOO", +" O O OOO O", +" OOOOO OO OOO OO OOOO", +" OOOOO OO OOO OO OOOO", +" OOOOO OO OOO OO OOOO", +" OOOOO OO OOO OOOO", +" OOOOO OO OO OOO OOOO", +" OOOOO OO OOO OO OOOO", +" O O OOO OO O", +"OOOOOOOOOOOOOOOOOOOOO" +}; + + +static rnd_tool_t sch_rnd_tool_circle = { + "circle", NULL, std_tools_cookie, 100, circle_icon, RND_TOOL_CURSOR_NAMED("question_arrow"), 0, + tool_circle_init, + tool_circle_uninit, + tool_circle_press, + tool_circle_release, + tool_circle_adjust_attached_objects, + tool_circle_draw_attached, + NULL, /* undo */ + NULL, /* redo */ + tool_circle_escape +}; Index: tags/1.0.5/src/plugins/std_tools/tool_line.c =================================================================== --- tags/1.0.5/src/plugins/std_tools/tool_line.c (nonexistent) +++ tags/1.0.5/src/plugins/std_tools/tool_line.c (revision 10414) @@ -0,0 +1,130 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - line draw tool + * Copyright (C) 2020 Tibor 'Igor2' Palinkas + * (copied from camv-rnd by the author) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +static void tool_line_init(void) +{ + line_init(); + csch_tool_line.dir = CSCH_TOOL_LINEDIR_ALL; + csch_tool_line.stroke = NULL; + csch_tool_line.stroke_name = NULL; +} + +static void tool_line_uninit(void) +{ + line_uninit(); +} + +static void tool_line_press(rnd_design_t *hl) +{ +} + +static void tool_line_release(rnd_design_t *hl) +{ + if (line_release(hl)) { + csch_sheet_t *sheet = (csch_sheet_t *)hl; + + if (line_is_zero_len()) { + csch_tool_line.clicked = 0; + return; + } + + if (csch_tool_line.stroke == NULL) + csch_tool_line.stroke = SCH_RND_DIRECT_PEN(sheet, tool_line_stroke, &csch_tool_line.stroke_name); + line_create_all(hl, &sheet->direct, 0); + line_continue(hl); + } +} + +static void tool_line_adjust_attached_objects(rnd_design_t *hl) +{ + line_adjust_attached_objects(hl); +} + + +static void tool_line_draw_attached(rnd_design_t *hl) +{ + csch_sheet_t *sheet = (csch_sheet_t *)hl; + + if (csch_tool_line.stroke == NULL) + csch_tool_line.stroke = SCH_RND_DIRECT_PEN(sheet, tool_line_stroke, &csch_tool_line.stroke_name); + line_draw_attached(hl, &sheet->direct); +} + +static void tool_line_escape(rnd_design_t *hl) +{ + if (!csch_tool_line.clicked) + rnd_tool_select_by_name(hl, "arrow"); + else + rnd_tool_select_by_name(hl, "line"); +} + + +/* XPM */ +static const char *line_icon[] = { +/* columns rows colors chars-per-pixel */ +"21 21 4 1", +" c #000000", +". c #7A8584", +"X c #6EA5D7", +"O c None", +/* pixels */ +"OOOOOOOOOOOOOOOOOOOOO", +"OO...OOOOOOOOOOOOOOOO", +"O.OOO.OOOOOOOOOOOOOOO", +"O.OXXXOOOOOOOOOOOOOOO", +"O.OOO.XXXOOOOOOOOOOOO", +"OO...OOOOXXXOOOO...OO", +"OOOOOOOOOOOOXXX.OOO.O", +"OOOOOOOOOOOOOOOXXXO.O", +"OOOOOOOOOOOOOOO.OOO.O", +"OOOOOOOOOOOOOOOO...OO", +"OOOOOOOOOOOOOOOOOOOOO", +"OOOOOOOOOOOOOOOOOOOOO", +" OOOO O OOOO O O", +" OOOOO OO OOO O OOOO", +" OOOOO OO O OO O OOOO", +" OOOOO OO O OO O OOOO", +" OOOOO OO OO O O OO", +" OOOOO OO OO O O OOOO", +" OOOOO OO OOO O OOOO", +" O O OOOO O O", +"OOOOOOOOOOOOOOOOOOOOO" +}; + + +static rnd_tool_t sch_rnd_tool_line = { + "line", NULL, std_tools_cookie, 100, line_icon, RND_TOOL_CURSOR_NAMED("pencil"), 0, + tool_line_init, + tool_line_uninit, + tool_line_press, + tool_line_release, + tool_line_adjust_attached_objects, + tool_line_draw_attached, + NULL, /* undo */ + NULL, /* redo */ + tool_line_escape +}; Index: tags/1.0.5/src/plugins/std_tools/tool_lock.c =================================================================== --- tags/1.0.5/src/plugins/std_tools/tool_lock.c (nonexistent) +++ tags/1.0.5/src/plugins/std_tools/tool_lock.c (revision 10414) @@ -0,0 +1,118 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - lock tool + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * (icons copied from pcb-rnd by the author) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include + +#include + +#include +#include +#include +#include +#include + + +static void csch_tool_lock_notify_mode(rnd_design_t *hl) +{ + csch_sheet_t *sheet = (csch_sheet_t *)hl; + csch_rtree_box_t box; + csch_chdr_t *obj; + int itmp; + + box.x1 = P2C(sch_rnd_crosshair_x) - sch_rnd_slop; box.y1 = P2C(sch_rnd_crosshair_y) - sch_rnd_slop; + box.x2 = P2C(sch_rnd_crosshair_x) + sch_rnd_slop; box.y2 = P2C(sch_rnd_crosshair_y) + sch_rnd_slop; + + obj = csch_search_first_locked_gui(sheet, &box); + if (obj != NULL) { + itmp = 0; + csch_commprp_modify(sheet, obj, &itmp, NULL, 1); + return; + } + + obj = csch_search_first_gui(sheet, &box); + if (obj != NULL) { + itmp = 1; + csch_commprp_modify(sheet, obj, &itmp, NULL, 1); + return; + } +} + +/* XPM */ +static const char *lock_icon[] = { +/* columns rows colors chars-per-pixel */ +"21 21 2 1", +" c black", +"X c None", +/* pixels */ +"XXXXXXXX XXXXXXXX", +"XXXXXXX XXX XXXXXXX", +"XXXXXXX XXXXX XXXXXXX", +"XXXXXX XXXXX XXXXXX", +"XXXXXX XXXXXXX XXXXXX", +"XXXXXX XXXXXXX XXXXXX", +"XXXX XXXX", +"XXXX XXXXXXXXXXX XXXX", +"XXXX XXXX", +"XXXX XXXXXXXXXXX XXXX", +"XXXX XXXX", +"XXXX XXXXXXXXXXX XXXX", +"XXXX XXXX", +"XXXXXXXXXXXXXXXXXXXXX", +"XX XXXX XXX X XX XX", +"XX XXX XX X XXX XX XX", +"XX XXX XX X XXX X XXX", +"XX XXX XX X XXX XXXX", +"XX XXX XX X XXX X XXX", +"XX XXX XX X XXX XX XX", +"XX XX XXX X XX XX" +}; + +#define lockIcon_width 16 +#define lockIcon_height 16 +static unsigned char lockIcon_bits[] = { + 0x00, 0x00, 0xe0, 0x07, 0x30, 0x0c, 0x10, 0x08, 0x18, 0x18, 0x08, 0x10, + 0x08, 0x00, 0xfc, 0x3f, 0x04, 0x20, 0xfc, 0x3f, 0x04, 0x20, 0xfc, 0x3f, + 0x04, 0x20, 0xfc, 0x3f, 0x04, 0x20, 0xfc, 0x3f}; +#define lockMask_width 16 +#define lockMask_height 16 +static unsigned char lockMask_bits[] = { + 0xf0, 0x0f, 0xf0, 0x0f, 0xf8, 0x1f, 0x38, 0x1c, 0x1c, 0x3c, 0x1c, 0x38, + 0x1c, 0x30, 0xfe, 0x7f, 0xfe, 0x7f, 0xfe, 0x7f, 0xfe, 0x7f, 0xfe, 0x7f, + 0xfe, 0x7f, 0xfe, 0x7f, 0xfe, 0x7f, 0xfe, 0x7f}; + +rnd_tool_t sch_rnd_tool_lock = { + "lock", NULL, NULL, 100, lock_icon, RND_TOOL_CURSOR_XBM(lockIcon_bits, lockMask_bits), 0, + NULL, + NULL, + csch_tool_lock_notify_mode, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL /* escape */ +}; Index: tags/1.0.5/src/plugins/std_tools/tool_mirror.c =================================================================== --- tags/1.0.5/src/plugins/std_tools/tool_mirror.c (nonexistent) +++ tags/1.0.5/src/plugins/std_tools/tool_mirror.c (revision 10414) @@ -0,0 +1,147 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - mirror tool + * Copyright (C) 2022,2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022, Entrust in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include + +#include +#include +#include +#include +#include + + +static void csch_tool_mirror_notify_mode(rnd_design_t *hl, int mirx, int miry) +{ + csch_sheet_t *sheet = (csch_sheet_t *)hl; + csch_chdr_t *obj; + + obj = sch_rnd_search_obj_at(sheet, P2C(sch_rnd_crosshair_x), P2C(sch_rnd_crosshair_y), sch_rnd_slop); + if (obj != NULL) { + csch_mirror(sheet, obj, P2C(sch_rnd_crosshair_x), P2C(sch_rnd_crosshair_y), mirx, miry, 1); + return; + } +} + +static void csch_tool_xmirror_notify_mode(rnd_design_t *hl) +{ + csch_tool_mirror_notify_mode(hl, 1, 0); +} + +static void csch_tool_ymirror_notify_mode(rnd_design_t *hl) +{ + csch_tool_mirror_notify_mode(hl, 0, 1); +} + +/* XPM */ +static const char *xmirror_icon[] = { +/* columns rows colors chars-per-pixel */ +"21 21 3 1", +" c #000000", +". c #6EA5D7", +"o c None", +/* pixels */ +"ooooooooooooooooooooo", +"ooooooooooooooooooooo", +"oooooo oooo ooooooo", +"ooooo . oooo . oooooo", +"oooo .. .. ooooo", +"ooo ............ oooo", +"ooo ............ oooo", +"ooo .. .. ooooo", +"oooo . oooo . oooooo", +"ooooo oooo ooooooo", +"ooooooooooooooooooooo", +"ooooooooooooooooooooo", +"ooooooooooooooooooooo", +" ooo o ooo o o o", +" ooo o o oo oo oo o", +" o o oo oo oo o", +"o oo o o oo oo o", +"o oo ooo oo oo o oo", +" o o ooo oo oo oo o", +" ooo o ooo oo oo oo o", +" ooo o ooo o o oo o" +}; + +/* XPM */ +static const char *ymirror_icon[] = { +/* columns rows colors chars-per-pixel */ +"21 21 3 1", +" c #000000", +". c #6EA5D7", +"o c None", +/* pixels */ +"ooooooooo oooooooooo", +"oooooooo .. ooooooooo", +"ooooooo .... oooooooo", +"oooooo ...... ooooooo", +"oooooo .. ooooooo", +"oooooooo .. ooooooooo", +"oooooooo .. ooooooooo", +"oooooo .. ooooooo", +"oooooo ...... ooooooo", +"ooooooo .... oooooooo", +"oooooooo .. ooooooooo", +"ooooooooo oooooooooo", +"ooooooooooooooooooooo", +" ooo o ooo o o o", +" ooo o o oo oo oo o", +" o o oo oo oo o", +"o oo o o oo oo o", +"oo ooo ooo oo oo o oo", +"oo ooo ooo oo oo oo o", +"oo ooo ooo oo oo oo o", +"oo ooo ooo o o oo o" +}; + + +rnd_tool_t sch_rnd_tool_xmirror = { + "xmirror", NULL, NULL, 100, xmirror_icon, RND_TOOL_CURSOR_NAMED("iron_cross"), 0, + NULL, + NULL, + csch_tool_xmirror_notify_mode, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL /* escape */ +}; + +rnd_tool_t sch_rnd_tool_ymirror = { + "ymirror", NULL, NULL, 100, ymirror_icon, RND_TOOL_CURSOR_NAMED("iron_cross"), 0, + NULL, + NULL, + csch_tool_ymirror_notify_mode, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL /* escape */ +}; Index: tags/1.0.5/src/plugins/std_tools/tool_movecopy.c =================================================================== --- tags/1.0.5/src/plugins/std_tools/tool_movecopy.c (nonexistent) +++ tags/1.0.5/src/plugins/std_tools/tool_movecopy.c (revision 10414) @@ -0,0 +1,432 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - move or copy object + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include +#include +#include + +#include "tool_movecopy.h" + +typedef struct { + csch_coord_t press_x, press_y, press_chx, press_chy; + int click; + int copy; + int ret_arrow; + int endpoint; /* 1 or 2 for grabbing endpoint in move, 0 for non-endpoint */ + csch_chdr_t *click_obj; + vtp0_t click_list; + + htepu_t rubber; + unsigned rubber_inited:1; +} tool_movecopy_t; + +static tool_movecopy_t mvcp; + +static void rbm_reset_endpoints(void) +{ + if (!mvcp.rubber_inited) { + htepu_init(&mvcp.rubber, htepu_keyhash_xy, htepu_keyeq_xy); + mvcp.rubber_inited = 1; + } + else + htepu_clear(&mvcp.rubber); +} + +static int rbm_include_obj(void *ctx, csch_chdr_t *obj) +{ + /* ignore junctions */ + if (obj->type == CSCH_CTYPE_LINE) { + csch_line_t *line = (csch_line_t *)obj; + if ((line->inst.c.p1.x == line->inst.c.p2.x) && (line->inst.c.p1.y == line->inst.c.p2.y)) + return 0; + } + + return 1; +} + + +static int rbm_include_sel(void *ctx, csch_chdr_t *obj) +{ + if (!rbm_include_obj(ctx, obj)) + return 0; + + /* ignore selected objects - they are being moved, they shouldn't leave + endpoints behind to connect to */ + if (csch_chdr_is_selected(obj)) + return 0; + + return 1; +} + +static void rbm_grab_endpoints(csch_sheet_t *sheet, csch_chdr_t *obj, int omit_selected) +{ + if (obj->type != CSCH_CTYPE_LINE) + return; + + if (omit_selected) + csch_endpoint_list_connected(sheet, &mvcp.rubber, obj, rbm_include_sel, NULL); + else + csch_endpoint_list_connected(sheet, &mvcp.rubber, obj, rbm_include_obj, NULL); +} + +static void rbm_xor_draw(csch_sheet_t *sheet, csch_coord_t dx, csch_coord_t dy) +{ + htepu_entry_t *e; + if (!conf_core.editor.rubber_band_mode) + return; + + for(e = htepu_first(&mvcp.rubber); e != NULL; e = htepu_next(&mvcp.rubber, e)) { + if (conf_core.editor.rubber_band_ortho) { + rnd_render->draw_line(sch_rnd_crosshair_gc, C2P(e->key.x), C2P(e->key.y), C2P(e->key.x+dx), C2P(e->key.y)); + rnd_render->draw_line(sch_rnd_crosshair_gc, C2P(e->key.x+dx), C2P(e->key.y), C2P(e->key.x+dx), C2P(e->key.y+dy)); + } + else + rnd_render->draw_line(sch_rnd_crosshair_gc, C2P(e->key.x), C2P(e->key.y), C2P(e->key.x+dx), C2P(e->key.y+dy)); + } +} + +static void rbm_execute(csch_sheet_t *sheet, csch_coord_t dx, csch_coord_t dy) +{ + htepu_entry_t *e; + csch_cpen_t *pen; + + if (!conf_core.editor.rubber_band_mode) + return; + + pen = SCH_RND_DIRECT_PEN(sheet, tool_wire_stroke, NULL); + if (pen == NULL) + return; + + for(e = htepu_first(&mvcp.rubber); e != NULL; e = htepu_next(&mvcp.rubber, e)) { + csch_line_t *line; + + if (csch_obj_is_deleted(e->key.obj)) continue; + + if (conf_core.editor.rubber_band_ortho) { + line = csch_wirenet_draw_line_in(sheet, e->key.obj->parent, pen->name, e->key.x, e->key.y, e->key.x + dx, e->key.y); + csch_wirenet_recalc_obj_conn(sheet, &line->hdr); + csch_wirenet_recalc_merge(sheet, line, 1); /* must be the last; with overlap removal enabled this removes the stub in the |_ case converted into a |- case */ + + line = csch_wirenet_draw_line_in(sheet, e->key.obj->parent, pen->name, e->key.x + dx, e->key.y, e->key.x + dx, e->key.y + dy); + csch_wirenet_recalc_obj_conn(sheet, &line->hdr); + csch_wirenet_recalc_merge(sheet, line, 1); /* must be the last; with overlap removal enabled this removes the stub in the |_ case converted into a |- case */ + } + else { + line = csch_wirenet_draw_line_in(sheet, e->key.obj->parent, pen->name, e->key.x, e->key.y, e->key.x + dx, e->key.y + dy); + csch_wirenet_recalc_obj_conn(sheet, &line->hdr); + csch_wirenet_recalc_merge(sheet, line, 1); /* must be the last; with overlap removal enabled this removes the stub in the |_ case converted into a |- case */ + } + } +} + +static void tool_move_init(void) +{ + mvcp.copy = 0; +} + +static void tool_copy_init(void) +{ + mvcp.copy = 1; +} + +static void tool_movecopy_uninit(void) +{ +} + +/* for the passon from the arrow tool */ +static void tool_movecopy_press_at(rnd_design_t *hl, csch_coord_t x, csch_coord_t y, csch_chdr_t *obj, int ret_arrow) +{ + csch_sheet_t *sheet = (csch_sheet_t *)hl; + long v; + + mvcp.ret_arrow = ret_arrow; + mvcp.press_x = P2C(x); + mvcp.press_y = P2C(y); + mvcp.press_chx = x; + mvcp.press_chy = y; + rbm_reset_endpoints(); + + mvcp.click_list.used = 0; + mvcp.endpoint = 0; + v = csch_search_all_selected(sheet, &sheet->direct, &mvcp.click_list, 1); + + if (v == 0) { + mvcp.click_obj = obj; + if (mvcp.click_obj == NULL) + mvcp.click_obj = sch_rnd_search_obj_at(sheet, mvcp.press_x, mvcp.press_y, sch_rnd_slop); + if (mvcp.click_obj == NULL) { + mvcp.click = 0; + return; + } + + /* figure endpoint for move */ + if (!mvcp.copy) { + switch(mvcp.click_obj->type) { + case CSCH_CTYPE_LINE: + { + csch_line_t *l = (csch_line_t *)mvcp.click_obj; + if ((l->inst.c.p1.x == mvcp.press_x) && (l->inst.c.p1.y == mvcp.press_y)) mvcp.endpoint = 1; + else if ((l->inst.c.p2.x == mvcp.press_x) && (l->inst.c.p2.y == mvcp.press_y)) mvcp.endpoint = 2; + } + break; + default: + break; + } + } + + if (!mvcp.copy && (mvcp.endpoint == 0) && conf_core.editor.rubber_band_mode) + rbm_grab_endpoints(sheet, mvcp.click_obj, 0); + } + else { + mvcp.click_obj = NULL; + if (!mvcp.copy && conf_core.editor.rubber_band_mode) { + long n; + for(n = 0; n < mvcp.click_list.used; n++) + rbm_grab_endpoints(sheet, mvcp.click_list.array[n], 1); + } + } + + mvcp.click = 1; +} + +static void tool_movecopy_press(rnd_design_t *hl) +{ + tool_movecopy_press_at(hl, sch_rnd_crosshair_x, sch_rnd_crosshair_y, NULL, 0); +} + +static void move_endpoint(csch_sheet_t *sheet, csch_coord_t dx, csch_coord_t dy) +{ + switch(mvcp.click_obj->type) { + case CSCH_CTYPE_LINE: + { + csch_line_t *l = (csch_line_t *)mvcp.click_obj; + uundo_freeze_serial(&sheet->undo); + if (mvcp.endpoint == 1) + csch_line_modify(sheet, l, &dx, &dy, NULL, NULL, 1, 1, 1); + else if (mvcp.endpoint == 2) + csch_line_modify(sheet, l, NULL, NULL, &dx, &dy, 1, 1, 1); + uundo_unfreeze_serial(&sheet->undo); + uundo_inc_serial(&sheet->undo); + } + break; + default: break; + } + +} + +static void tool_movecopy_release(rnd_design_t *hl) +{ + csch_sheet_t *sheet = (csch_sheet_t *)hl; + long n; + + if (mvcp.click) { + csch_coord_t x = P2C(sch_rnd_crosshair_x), y = P2C(sch_rnd_crosshair_y); + csch_coord_t dx = x - mvcp.press_x, dy = y - mvcp.press_y; + + if (!mvcp.copy) { + if (!mvcp.endpoint) { + csch_cobj_redraw_freeze(sheet); + uundo_freeze_serial(&sheet->undo); + csch_wirenet_recalc_freeze(sheet); + + for(n = 0; n < mvcp.click_list.used; n++) { + csch_chdr_t *obj = mvcp.click_list.array[n]; + if (!csch_chdr_any_parent_selected(obj)) /* do not move anything with parent group selected because the parent grp is moved already */ + csch_move(sheet, obj, dx, dy, 1); + } + if (mvcp.click_obj != NULL) { + csch_move(sheet, mvcp.click_obj, dx, dy, 1); + if (mvcp.click_obj->type == CSCH_CTYPE_LINE) + csch_wirenet_recalc_merge(sheet, (csch_line_t *)mvcp.click_obj, 0); + } + for(n = 0; n < mvcp.click_list.used; n++) { /* revisit for merging line pieces */ + csch_chdr_t *obj = mvcp.click_list.array[n]; + if (!csch_chdr_any_parent_selected(obj)) /* do not move anything with parent group selected because the parent grp is moved already */ + if (obj->type == CSCH_CTYPE_LINE) + csch_wirenet_recalc_merge(sheet, (csch_line_t *)obj, 0); + } + + rbm_execute(sheet, dx, dy); + + csch_wirenet_recalc_unfreeze(sheet); + uundo_unfreeze_serial(&sheet->undo); + uundo_inc_serial(&sheet->undo); + csch_cobj_redraw_unfreeze(sheet); + } + else + move_endpoint(sheet, dx, dy); + } + else { + csch_cobj_redraw_freeze(sheet); + uundo_freeze_serial(&sheet->undo); + csch_wirenet_recalc_freeze(sheet); + for(n = 0; n < mvcp.click_list.used; n++) { + csch_chdr_t *obj = mvcp.click_list.array[n]; + if (!csch_chdr_any_parent_selected(obj)) /* do not copy anything with parent group selected because the parent grp is copied already */ + csch_copy(sheet, obj, dx, dy, 1); + } + if (mvcp.click_obj != NULL) + csch_copy(sheet, mvcp.click_obj, dx, dy, 1); + csch_wirenet_recalc_unfreeze(sheet); + uundo_unfreeze_serial(&sheet->undo); + uundo_inc_serial(&sheet->undo); + csch_cobj_redraw_unfreeze(sheet); + } + + + mvcp.click = 0; + } + if (mvcp.ret_arrow) + rnd_tool_select_by_name(hl, "arrow"); +} + +static void xor_draw_endpoint(csch_sheet_t *sheet, csch_coord_t dx, csch_coord_t dy) +{ + switch(mvcp.click_obj->type) { + case CSCH_CTYPE_LINE: + { + csch_line_t *l = (csch_line_t *)mvcp.click_obj; + if (mvcp.endpoint == 1) + rnd_render->draw_line(sch_rnd_crosshair_gc, C2P(l->inst.c.p1.x + dx), C2P(l->inst.c.p1.y + dy), C2P(l->inst.c.p2.x), C2P(l->inst.c.p2.y)); + else if (mvcp.endpoint == 2) + rnd_render->draw_line(sch_rnd_crosshair_gc, C2P(l->inst.c.p1.x), C2P(l->inst.c.p1.y), C2P(l->inst.c.p2.x + dx), C2P(l->inst.c.p2.y + dy)); + } + break; + default: break; + } +} + +static void tool_movecopy_draw_attached(rnd_design_t *hl) +{ + if (mvcp.click) { + csch_sheet_t *sheet = (csch_sheet_t *)hl; + csch_coord_t x = P2C(sch_rnd_crosshair_x), y = P2C(sch_rnd_crosshair_y); + csch_coord_t dx = x - mvcp.press_x, dy = y - mvcp.press_y; + + if (!mvcp.copy && mvcp.endpoint) { + xor_draw_endpoint(sheet, dx, dy); + } + else { + long n; + rbm_xor_draw(sheet, dx, dy); + for(n = 0; n < mvcp.click_list.used; n++) + sch_rnd_xor_draw_obj(sheet, mvcp.click_list.array[n], dx, dy, sch_rnd_crosshair_gc, 1, 0); + if (mvcp.click_obj != NULL) + sch_rnd_xor_draw_obj(sheet, mvcp.click_obj, dx, dy, sch_rnd_crosshair_gc, 1, 0); + } + } +} + +/* XPM */ +static const char *move_icon[] = { +/* columns rows colors chars-per-pixel */ +"21 21 3 1", +" c #000000", +". c #6EA5D7", +"o c None", +/* pixels */ +"ooooooooooooooooooooo", +"ooooooooooooooooooooo", +"oooooooooooo ooooooo", +"oooooooooooo . oooooo", +"ooo .. ooooo", +"ooo ............ oooo", +"ooo ............ oooo", +"ooo .. ooooo", +"oooooooooooo . oooooo", +"oooooooooooo ooooooo", +"ooooooooooooooooooooo", +"ooooooooooooooooooooo", +"ooooooooooooooooooooo", +"o ooo oo ooo ooo oo", +"o o o ooo oo ooo oo", +"o o ooo oo ooo oo", +"o o o o ooo oo ooo oo", +"o ooo o ooo oo ooo oo", +"o ooo o ooo ooo o ooo", +"o ooo o ooo ooo o ooo", +"o ooo oo oooo ooo" +}; + +/* XPM */ +static const char *copy_icon[] = { +/* columns rows colors chars-per-pixel */ +"21 21 3 1", +" c #000000", +". c #6EA5D7", +"o c None", +/* pixels */ +"ooooooooooooooooooooo", +"ooooooooooooooooooooo", +"oooooo oooooo oooo", +"oooooo . ooooo .. ooo", +"o .. ooo .. oo", +"o ........ o ...... o", +"o ........ o ...... o", +"o .. ooo .. oo", +"oooooo . ooooo .. ooo", +"oooooo oooooo ooo", +"ooooooooooooooooooooo", +"ooooooooooooooooooooo", +"ooooooooooooooooooooo", +"o o ooo ooo oo", +"o oooo ooo oo ooo oo", +"o ooooo ooo ooo o ooo", +"o ooooo oooo ooo", +"o ooooo oooooooo oooo", +"o ooooo oooooooo oooo", +"o ooooo oooooooo oooo", +"o o oooooooo oooo" +}; + + +static rnd_tool_t sch_rnd_tool_move = { + "move", NULL, std_tools_cookie, 50, move_icon, RND_TOOL_CURSOR_NAMED("left_ptr"), 0, + tool_move_init, + tool_movecopy_uninit, + tool_movecopy_press, + tool_movecopy_release, + NULL, /* adjust_attached_objects */ + tool_movecopy_draw_attached, + NULL, /* undo */ + NULL, /* redo */ + NULL, /* escape */ +}; + +static rnd_tool_t sch_rnd_tool_copy = { + "copy", NULL, std_tools_cookie, 50, copy_icon, RND_TOOL_CURSOR_NAMED("left_ptr"), 0, + tool_copy_init, + tool_movecopy_uninit, + tool_movecopy_press, + tool_movecopy_release, + NULL, /* adjust_attached_objects */ + tool_movecopy_draw_attached, + NULL, /* undo */ + NULL, /* redo */ + NULL, /* escape */ +}; Index: tags/1.0.5/src/plugins/std_tools/tool_movecopy.h =================================================================== --- tags/1.0.5/src/plugins/std_tools/tool_movecopy.h (nonexistent) +++ tags/1.0.5/src/plugins/std_tools/tool_movecopy.h (revision 10414) @@ -0,0 +1,6 @@ +#ifndef STD_TOOLS_MOVECOPY_H +#define STD_TOOLS_MOVECOPY_H + +static void tool_movecopy_press_at(rnd_design_t *hl, csch_coord_t x, csch_coord_t y, csch_chdr_t *obj, int ret_arrow); + +#endif \ No newline at end of file Index: tags/1.0.5/src/plugins/std_tools/tool_polyedit.c =================================================================== --- tags/1.0.5/src/plugins/std_tools/tool_polyedit.c (nonexistent) +++ tags/1.0.5/src/plugins/std_tools/tool_polyedit.c (revision 10414) @@ -0,0 +1,336 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - edit polygon points + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include +#include +#include + +#include "tool_polyedit.h" + +typedef struct { + csch_coord_t press_x, press_y, press_chx, press_chy; + int click, ret_arrow, ortho_valid; + csch_cpoly_t *poly; + long obj_idx[2]; + csch_chdr_t *obj[2]; +} tool_polyedit_t; + +static tool_polyedit_t pedit; + +/* extend the line between px;py and (already moved) x;y knowing the previous + point beyond px;py (which is ppx;ppy) */ +static void perp_extend(csch_coord_t ppx, csch_coord_t ppy, csch_coord_t *px, csch_coord_t *py, csch_coord_t x, csch_coord_t y, csch_coord_t dx, csch_coord_t dy) +{ + g2d_cline_t l1, l2; + g2d_vect_t ip; + g2d_offs_t offs[2]; + + l1.p1.x = ppx; l1.p1.y = ppy; + l1.p2.x = *px; l1.p2.y = *py; + + l2.p1.x = (*px) + dx; l2.p1.y = (*py) + dy; + l2.p2.x = x; l2.p2.y = y; + + /* calculate the intersection point, which is most probably not on any of the lines */ + g2d__iscp_cline_cline_o(&l1, &l2, NULL, offs, 1); + ip = g2d_cline_offs(&l1, offs[0]); + + *px = ip.x; + *py = ip.y; +} + + +RND_INLINE csch_line_t *get_mod_obj(csch_vtcoutline_t *cnt, long idx) +{ + if (idx < 0) idx += cnt->used; + else if (idx >= cnt->used) idx -= cnt->used; + return &cnt->array[idx].line; +} + +RND_INLINE int ortho_pt_move(csch_vtcoutline_t *cnt, csch_coord_t dx, csch_coord_t dy, int draw) +{ + csch_coord_t x, y; /* point being moved */ + csch_coord_t px, py, nx, ny; /* previous and next point */ + csch_coord_t ppx, ppy, nnx, nny; /* 2nd previous and next point */ + csch_line_t *obj = get_mod_obj(cnt, pedit.obj_idx[0]); /* object before x;y (2nd endpoint is x;y) */ + csch_line_t *pobj = get_mod_obj(cnt, pedit.obj_idx[0]-1); /* object before px;py (2nd endpoint is px;py) */ + csch_line_t *nobj = get_mod_obj(cnt, pedit.obj_idx[0]+1); /* object after x;y (1st endpoint is x;y) */ + csch_line_t *ppobj = get_mod_obj(cnt, pedit.obj_idx[0]-2); /* object before ppx;ppy (2nd endpoint is ppx;ppy) */ + csch_line_t *nnobj = get_mod_obj(cnt, pedit.obj_idx[0]+2); /* object after nx;ny (1st endpoint is nx;ny) */ + + if (obj->hdr.type != CSCH_CTYPE_LINE) return -1; + if (nobj->hdr.type != CSCH_CTYPE_LINE) return -1; + if (pobj->hdr.type != CSCH_CTYPE_LINE) return -1; + if (nnobj->hdr.type != CSCH_CTYPE_LINE) return -1; + if (ppobj->hdr.type != CSCH_CTYPE_LINE) return -1; + + x = obj->inst.c.p2.x + dx; y = obj->inst.c.p2.y + dy; + nx = nobj->inst.c.p2.x; ny = nobj->inst.c.p2.y; + nnx = nnobj->inst.c.p2.x; nny = nnobj->inst.c.p2.y; + px = pobj->inst.c.p2.x; py = pobj->inst.c.p2.y; + ppx = ppobj->inst.c.p2.x; ppy = ppobj->inst.c.p2.y; + + + perp_extend(ppx, ppy, &px, &py, x, y, dx, dy); + perp_extend(nnx, nny, &nx, &ny, x, y, dx, dy); + + if (draw) { + rnd_render->draw_line(sch_rnd_crosshair_gc, C2P(ppx), C2P(ppy), C2P(px), C2P(py)); + rnd_render->draw_line(sch_rnd_crosshair_gc, C2P(nnx), C2P(nny), C2P(nx), C2P(ny)); + + rnd_render->draw_line(sch_rnd_crosshair_gc, C2P(px), C2P(py), C2P(x), C2P(y)); + rnd_render->draw_line(sch_rnd_crosshair_gc, C2P(nx), C2P(ny), C2P(x), C2P(y)); + } + else { + nobj->spec.p2.x = nx; nobj->spec.p2.y = ny; + nnobj->spec.p1.x = nx; nnobj->spec.p1.y = ny; + + pobj->spec.p2.x = px; pobj->spec.p2.y = py; + obj->spec.p1.x = px; obj->spec.p1.y = py; + + obj->spec.p2.x = x; obj->spec.p2.y = y; + nobj->spec.p1.x = x; nobj->spec.p1.y = y; + } + + return 0; +} + +RND_INLINE void polyedit_draw_pt_anydir(csch_coord_t dx, csch_coord_t dy) +{ + csch_line_t *l1 = (csch_line_t *)pedit.obj[0]; + csch_line_t *l2 = (csch_line_t *)pedit.obj[1]; + + /* TODO: this assumes two lines */ + rnd_render->draw_line(sch_rnd_crosshair_gc, C2P(l1->inst.c.p1.x), C2P(l1->inst.c.p1.y), C2P(l1->inst.c.p2.x + dx), C2P(l1->inst.c.p2.y + dy)); + rnd_render->draw_line(sch_rnd_crosshair_gc, C2P(l2->inst.c.p2.x), C2P(l2->inst.c.p2.y), C2P(l2->inst.c.p1.x + dx), C2P(l2->inst.c.p1.y + dy)); +} + +RND_INLINE void polyedit_draw_pt_ortho(csch_coord_t dx, csch_coord_t dy) +{ + if (ortho_pt_move(&pedit.poly->outline, dx, dy, 1) != 0) { + polyedit_draw_pt_anydir(dx, dy); /* fall back */ + pedit.ortho_valid = 0; + } + else + pedit.ortho_valid = 1; +} + +RND_INLINE void polyedit_exec_pt_anydir(csch_sheet_t *sheet, csch_coord_t dx, csch_coord_t dy) +{ + csch_line_t *l1, *l2; + csch_vtcoutline_t *cnt; + void *cookie; + + /* TODO: this assumes two lines */ + cnt = csch_cpoly_modify_geo_begin(sheet, pedit.poly, &cookie, 1); + l1 = &cnt->array[pedit.obj_idx[0]].line; + l2 = &cnt->array[pedit.obj_idx[1]].line; + l1->spec.p2.x += dx; l1->spec.p2.y += dy; + l2->spec.p1.x += dx; l2->spec.p1.y += dy; + csch_cpoly_modify_geo_end(sheet, pedit.poly, &cookie); +} + +RND_INLINE void polyedit_exec_pt_ortho(csch_sheet_t *sheet, csch_coord_t dx, csch_coord_t dy) +{ + if (pedit.ortho_valid) { + void *cookie; + csch_vtcoutline_t *cnt = csch_cpoly_modify_geo_begin(sheet, pedit.poly, &cookie, 1); + ortho_pt_move(cnt, dx, dy, 0); + csch_cpoly_modify_geo_end(sheet, pedit.poly, &cookie); + } + else + polyedit_exec_pt_anydir(sheet, dx, dy); +} + + +static void tool_polyedit_init(void) +{ +} + +static void tool_polyedit_uninit(void) +{ +} + +/* for the passon from the arrow tool; returns 0 if accepted */ +static int tool_polyedit_press_at(rnd_design_t *hl, csch_coord_t x, csch_coord_t y, csch_cpoly_t *poly, long obj_idx[2], int ret_arrow) +{ + csch_sheet_t *sheet = (csch_sheet_t *)hl; + long v; + int n; + vtp0_t tmp = {0}; + + if (poly == NULL) return -1; + if (obj_idx[0] < 0) return -1; + if (obj_idx[1] < 0) return -1; /* for now accept only corner moves */ + + for(n = 0; n < 2; n++) { + if (obj_idx[n] >= 0) { + if (obj_idx[n] >= poly->outline.used) + return -1; /* invalid object */ + pedit.obj[n] = &poly->outline.array[obj_idx[n]].hdr; + + if (pedit.obj[n]->type != CSCH_CTYPE_LINE) return -1; /* accept line-line only for now */ + } + else + pedit.obj[n] = NULL; + } + + /* refuse if there's selection (move selected) */ + v = csch_search_all_selected(sheet, &sheet->direct, &tmp, 1); + if (v != 0) { + vtp0_uninit(&tmp); + return -1; + } + + pedit.ret_arrow = ret_arrow; + pedit.press_x = P2C(x); + pedit.press_y = P2C(y); + pedit.press_chx = x; + pedit.press_chy = y; + pedit.poly = poly; + pedit.click = 1; + pedit.obj_idx[0] = obj_idx[0]; + pedit.obj_idx[1] = obj_idx[1]; + +rnd_trace("polyedit!\n"); + return 0; /* accept */ +} + +static void tool_polyedit_press(rnd_design_t *hl) +{ + csch_sheet_t *sheet = (csch_sheet_t *)hl; + csch_coord_t x, y, r = sch_rnd_slop/2+1; + long obj_idx[2], len; + csch_chdr_t *obj; + csch_rtree_box_t query; + + x = P2C(sch_rnd_crosshair_x); y = P2C(sch_rnd_crosshair_y); + query.x1 = x - r; query.y1 = y - r; + query.x2 = x + r; query.y2 = y + r; + obj = csch_search_first_mask(sheet, &query, CSCH_CMASK_POLY); + if (obj == NULL) + return; + + len = csch_poly_contour_objs_at((csch_cpoly_t *)obj, x, y, r, obj_idx); + if (len == 2) + tool_polyedit_press_at(hl, sch_rnd_crosshair_x, sch_rnd_crosshair_y, (csch_cpoly_t *)obj, obj_idx, 0); +} + +static void tool_polyedit_release(rnd_design_t *hl) +{ + csch_sheet_t *sheet = (csch_sheet_t *)hl; + + if (pedit.click) { + csch_coord_t r = sch_rnd_slop/2+1; + csch_coord_t x = P2C(sch_rnd_crosshair_x), y = P2C(sch_rnd_crosshair_y); + csch_coord_t dx = x - pedit.press_x, dy = y - pedit.press_y; + long obj_idx[2]; + int len; + + if ((dx == 0) && (dy == 0)) + goto skip; /* do not pollute the undo list */ + + len = csch_poly_contour_objs_at(pedit.poly, x, y, r, obj_idx); + if (len != 0) { + if ((len > 1) || !csch_poly_contour_obj_ends_at(pedit.poly, obj_idx[0], pedit.press_x, pedit.press_y)) { + rnd_message(RND_MSG_ERROR, "Polygon corner shall not overlap with the same polygon's edge or corner\n"); + goto skip; + } + /* else the new point is on a contour object that starts or ends on the corner we are moving so the resulting poly won't be invalid */ + } + + if (rnd_gui->control_is_pressed(rnd_gui)) + polyedit_exec_pt_ortho(sheet, dx, dy); + else + polyedit_exec_pt_anydir(sheet, dx, dy); + + skip:; + pedit.click = 0; + } + if (pedit.ret_arrow) + rnd_tool_select_by_name(hl, "arrow"); +} + +static void tool_polyedit_draw_attached(rnd_design_t *hl) +{ + if (pedit.click) { + /*csch_sheet_t *sheet = (csch_sheet_t *)hl;*/ + csch_coord_t x = P2C(sch_rnd_crosshair_x), y = P2C(sch_rnd_crosshair_y); + csch_coord_t dx = x - pedit.press_x, dy = y - pedit.press_y; + + if (rnd_gui->control_is_pressed(rnd_gui)) + polyedit_draw_pt_ortho(dx, dy); + else + polyedit_draw_pt_anydir(dx, dy); + + } +} + +/* XPM */ +static const char *polyedit_icon[] = { +/* columns rows colors chars-per-pixel */ +"21 21 3 1", +" c #000000", +". c #6EA5D7", +"o c None", +/* pixels */ +"ooooooooooooooooooooo", +"ooooooooooooooooooooo", +"ooooooo...........ooo", +"ooooooo. .ooo", +"oooooo. ...... ...ooo", +"ooooo. .ooo. .ooooooo", +"oooo. .oo. .ooooooooo", +"ooo. .o. .ooooooooooo", +"oo. . .oooooooooooooo", +"o. .ooooooooooooooooo", +"o...ooooooooooooooooo", +"ooooooooooooooooooooo", +"ooooooooooooooooooooo", +"o oo o oo", +"o ooo o oooooo oooo o", +"o ooo o oooooo oooo o", +"o oo ooo oooo o", +"o ooooo oooooo oooo o", +"o ooooo oooooo oooo o", +"o ooooo o oo", +"ooooooooooooooooooooo" +}; + + +static rnd_tool_t sch_rnd_tool_polyedit = { + "polyedit", NULL, std_tools_cookie, 50, polyedit_icon, RND_TOOL_CURSOR_NAMED("left_ptr"), 0, + tool_polyedit_init, + tool_polyedit_uninit, + tool_polyedit_press, + tool_polyedit_release, + NULL, /* adjust_attached_objects */ + tool_polyedit_draw_attached, + NULL, /* undo */ + NULL, /* redo */ + NULL, /* escape */ +}; + Index: tags/1.0.5/src/plugins/std_tools/tool_polyedit.h =================================================================== --- tags/1.0.5/src/plugins/std_tools/tool_polyedit.h (nonexistent) +++ tags/1.0.5/src/plugins/std_tools/tool_polyedit.h (revision 10414) @@ -0,0 +1,7 @@ +#ifndef STD_TOOLS_POLYEDIT_H +#define STD_TOOLS_POLYEDIT_H + +/* returns 0 if accepted */ +static int tool_polyedit_press_at(rnd_design_t *hl, csch_coord_t x, csch_coord_t y, csch_cpoly_t *poly, long obj_idx[2], int ret_arrow); + +#endif \ No newline at end of file Index: tags/1.0.5/src/plugins/std_tools/tool_rect.c =================================================================== --- tags/1.0.5/src/plugins/std_tools/tool_rect.c (nonexistent) +++ tags/1.0.5/src/plugins/std_tools/tool_rect.c (revision 10414) @@ -0,0 +1,194 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - draw rectangle + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include + +typedef struct { + int clicked; + rnd_coord_t x, y; + csch_cpen_t *stroke, *fill; +} csch_tool_rect_t; + +static csch_tool_rect_t csch_tool_rect; + +static void tool_rect_init(void) +{ + csch_tool_rect.clicked = 0; + csch_tool_rect.stroke = NULL; + csch_tool_rect.fill = NULL; +} + +static void tool_rect_uninit(void) +{ +} + +static void tool_rect_press(rnd_design_t *hl) +{ +} + +static void new_line(csch_sheet_t *sheet, csch_cpoly_t *poly, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) +{ + csch_coutline_t *dst = csch_vtcoutline_alloc_append(&poly->outline, 1); + csch_line_t *line = &dst->line; + line->hdr.type = CSCH_CTYPE_LINE; + line->spec.p1.x = x1; line->spec.p1.y = y1; + line->spec.p2.x = x2; line->spec.p2.y = y2; +} + +static void tool_rect_release(rnd_design_t *hl) +{ + csch_sheet_t *sheet = (csch_sheet_t *)hl; + + if (csch_tool_rect.clicked) { + const char *stroke_name, *fill_name; + csch_cpoly_t *poly = (csch_cpoly_t *)csch_op_create(sheet, &sheet->direct, CSCH_CTYPE_POLY); + rnd_coord_t x1, y1, x2, y2; + + if (poly == NULL) { + rnd_message(RND_MSG_ERROR, "Failed to create line object\n"); + return; + } + + csch_tool_rect.stroke = SCH_RND_DIRECT_PEN(sheet, tool_rect_stroke, &stroke_name); + csch_tool_rect.fill = SCH_RND_DIRECT_PEN(sheet, tool_rect_fill, &fill_name); + + x1 = csch_tool_rect.x; + y1 = csch_tool_rect.y; + x2 = P2C(sch_rnd_crosshair_x); + y2 = P2C(sch_rnd_crosshair_y); + + new_line(sheet, poly, x1, y1, x1, y2); + new_line(sheet, poly, x1, y2, x2, y2); + new_line(sheet, poly, x2, y2, x2, y1); + new_line(sheet, poly, x2, y1, x1, y1); + + poly->hdr.stroke_name = csch_comm_str(sheet, stroke_name, 1); + poly->has_stroke = conf_core.editor.style.tool_rect_has_stroke; + poly->hdr.fill_name = csch_comm_str(sheet, fill_name, 1); + poly->has_fill = conf_core.editor.style.tool_rect_has_fill; + + csch_poly_update(sheet, poly, 1); + csch_sheet_set_changed(sheet, 1); + + csch_tool_rect.clicked = 0; + } + else { + csch_tool_rect.clicked = 1; + csch_tool_rect.x = P2C(sch_rnd_crosshair_x); + csch_tool_rect.y = P2C(sch_rnd_crosshair_y); + } +} + +static void tool_rect_adjust_attached_objects(rnd_design_t *hl) +{ +} + + +static void tool_rect_draw_attached(rnd_design_t *hl) +{ + csch_sheet_t *sheet = (csch_sheet_t *)hl; + + if (csch_tool_rect.clicked) { + rnd_coord_t x1, y1, x2, y2, ps; + + if (csch_tool_rect.stroke == NULL) + csch_tool_rect.stroke = SCH_RND_DIRECT_PEN(sheet, tool_rect_stroke, NULL); + if (csch_tool_rect.fill == NULL) + csch_tool_rect.fill = SCH_RND_DIRECT_PEN(sheet, tool_rect_fill, NULL); + + ps = (csch_tool_rect.stroke == NULL) ? C2P(1000) : C2P(csch_tool_rect.stroke->size); + x1 = C2P(csch_tool_rect.x); + y1 = C2P(csch_tool_rect.y); + x2 = sch_rnd_crosshair_x; + y2 = sch_rnd_crosshair_y; + + rnd_hid_set_line_cap(sch_rnd_crosshair_gc, rnd_cap_round); + rnd_hid_set_line_width(sch_rnd_crosshair_gc, ps); + + /* draw contour */ + rnd_render->draw_line(sch_rnd_crosshair_gc, x1, y1, x2, y1); + rnd_render->draw_line(sch_rnd_crosshair_gc, x2, y1, x2, y2); + rnd_render->draw_line(sch_rnd_crosshair_gc, x2, y2, x1, y2); + rnd_render->draw_line(sch_rnd_crosshair_gc, x1, y2, x1, y1); + } +} + +static void tool_rect_escape(rnd_design_t *hl) +{ + if (!csch_tool_rect.clicked) + rnd_tool_select_by_name(hl, "arrow"); + else + rnd_tool_select_by_name(hl, "rect"); +} + + +/* XPM */ +static const char *rect_icon[] = { +/* columns rows colors chars-per-pixel */ +"21 21 4 1", +" c #000000", +". c #7A8584", +"X c #6EA5D7", +"O c None", +/* pixels */ +"OOOOOOOOOOOOOOOOOOOOO", +"OOO...............OOO", +"OOO.OOOOOOOOOOOOO.OOO", +"OOO.OOOOOOOOOOOOO.OOO", +"OOO.OOOOOOOOOOOOO.OOO", +"OOO.OOOOOOOOOOOOO.OOO", +"OOO.OOOOOOOOOOOOO.OOO", +"OOO.OOOOOOOOOOOOO.OOO", +"OOO.OOOOOOOOOOOOO.OOO", +"OOO.OOOOOOOOOOOOO.OOO", +"OOO...............OOO", +"OOOOOOOOOOOOOOOOOOOOO", +" OO O O ", +" OOO O OOOO OOOOOO OO", +" OOO O OOOO OOOOOO OO", +" OOO O OO OOOOOO OO", +" OO OOOO OOOOOO OO", +" OO OO OOOO OOOOOO OO", +" OOO O OOOO OOOOOO OO", +" OOO O O OOO OO", +"OOOOOOOOOOOOOOOOOOOOO" +}; + + +static rnd_tool_t sch_rnd_tool_rect = { + "rect", NULL, std_tools_cookie, 100, rect_icon, RND_TOOL_CURSOR_NAMED("ul_angle"), 0, + tool_rect_init, + tool_rect_uninit, + tool_rect_press, + tool_rect_release, + tool_rect_adjust_attached_objects, + tool_rect_draw_attached, + NULL, /* undo */ + NULL, /* redo */ + tool_rect_escape +}; Index: tags/1.0.5/src/plugins/std_tools/tool_remove.c =================================================================== --- tags/1.0.5/src/plugins/std_tools/tool_remove.c (nonexistent) +++ tags/1.0.5/src/plugins/std_tools/tool_remove.c (revision 10414) @@ -0,0 +1,79 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - remove object + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * (copied from pcb-rnd by the author) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + + + +void sch_rnd_tool_remove_notify_mode(rnd_design_t *hl) +{ + csch_sheet_t *sheet = (csch_sheet_t *)hl; + + sch_rnd_op_remove_xy(sheet, P2C(sch_rnd_crosshair_x), P2C(sch_rnd_crosshair_y)); +} + +/* XPM */ +static const char *remove_icon[] = { +/* columns rows colors chars-per-pixel */ +"21 21 3 1", +" c black", +". c gray100", +"X c None", +/* pixels */ +"XXX XXXXXXXXXXXX XXXX", +"XXXX XXX XXX XXXXX", +"XXXXX X X XXXXXX", +"XXXXXX XX XX XXXXXXX", +"XXXXX XX XX XXXXXX", +"XXXXX XXXXXX", +"XXXXXX XXXXXXX", +"XXXXXXX XX XXXXXXXX", +"XXXXXXX XX XXXXXXXXX", +"XXXXXX X XX XXXXXXXX", +"XXXX XX X XXXXXX", +"XX XXXXX XXXX XXXX", +"XXXXXXXXXXXXXXXXXXXXX", +"XX XX X XXXXX", +"XXX XXX X XXXXX XXXXX", +"XXX XXX X XXXXX XXXXX", +"XXX XXX X XXXXX XXXXX", +"XXX XXX X XX XXXXX", +"XXX XXX X XXXXX XXXXX", +"XXX XXX X XXXXX XXXXX", +"XX XX X X" +}; + + +static rnd_tool_t sch_rnd_tool_remove = { + "remove", NULL, std_tools_cookie, 100, remove_icon, RND_TOOL_CURSOR_NAMED("pirate"), 0, + NULL, + NULL, + sch_rnd_tool_remove_notify_mode, + NULL, + NULL, + NULL, + NULL, + NULL +}; Index: tags/1.0.5/src/plugins/std_tools/tool_rotate.c =================================================================== --- tags/1.0.5/src/plugins/std_tools/tool_rotate.c (nonexistent) +++ tags/1.0.5/src/plugins/std_tools/tool_rotate.c (revision 10414) @@ -0,0 +1,103 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - rotate object + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * (icons copied from pcb-rnd by the author) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include + +#include +#include +#include +#include +#include + + +void csch_tool_rotate_notify_mode(rnd_design_t *hl) +{ + csch_sheet_t *sheet = (csch_sheet_t *)hl; + + sch_rnd_op_rotate90_xy(sheet, P2C(sch_rnd_crosshair_x), P2C(sch_rnd_crosshair_y), + rnd_gui->shift_is_pressed(rnd_gui) ? 3 : 1); + csch_sheet_set_changed(sheet, 1); +} + +/* XPM */ +static const char *rot_icon[] = { +/* columns rows colors chars-per-pixel */ +"21 21 4 1", +" c black", +". c #6EA5D7", +"X c gray100", +"o c None", +/* pixels */ +"ooooooooooo.ooooooooo", +"oooooooooo..ooooooooo", +"ooooooooo....oooooooo", +"oooooooooo..o.ooooooo", +"ooooooooooo.oo.oooooo", +"oooooooooooooo.oooooo", +"oooooooooooooo.oooooo", +"oooooooooooooo.oooooo", +"oooooooooooooo.oooooo", +"ooooooooooooo.ooooooo", +"oooooooooooo.oooooooo", +"oooooooooo..ooooooooo", +"ooooooooooooooooooooo", +"ooo ooo oo o", +"ooo ooo o ooo ooo ooo", +"ooo ooo o ooo ooo ooo", +"ooo oo ooo ooo ooo", +"ooo ooo ooo ooo ooo", +"ooo o oo ooo ooo ooo", +"ooo oo o ooo ooo ooo", +"ooo ooo oo oooo ooo" +}; + +#define rotateIcon_width 16 +#define rotateIcon_height 16 +static unsigned char rotateIcon_bits[] = { + 0xf0, 0x03, 0xf8, 0x87, 0x0c, 0xcc, 0x06, 0xf8, 0x03, 0xb0, 0x01, 0x98, + 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x19, 0x80, 0x0d, 0xc0, + 0x1f, 0x60, 0x3b, 0x30, 0xe1, 0x3f, 0xc0, 0x0f}; + +#define rotateMask_width 16 +#define rotateMask_height 16 +static unsigned char rotateMask_bits[] = { + 0xf0, 0x03, 0xf8, 0x87, 0x0c, 0xcc, 0x06, 0xf8, 0x03, 0xf0, 0x01, 0xf8, + 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x1f, 0x80, 0x0f, 0xc0, + 0x1f, 0x60, 0x3b, 0x30, 0xe1, 0x3f, 0xc0, 0x0f}; + +rnd_tool_t sch_rnd_tool_rotate = { + "rotate", NULL, NULL, 100, rot_icon, RND_TOOL_CURSOR_XBM(rotateIcon_bits, rotateMask_bits), 0, + NULL, + NULL, + csch_tool_rotate_notify_mode, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* escape */ +}; Index: tags/1.0.5/src/plugins/std_tools/tool_text.c =================================================================== --- tags/1.0.5/src/plugins/std_tools/tool_text.c (nonexistent) +++ tags/1.0.5/src/plugins/std_tools/tool_text.c (revision 10414) @@ -0,0 +1,151 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - draw text object + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * (icons copied from pcb-rnd by the author) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include + +#include +#include +#include +#include +#include + +typedef struct { + csch_cpen_t *stroke; +} csch_tool_text_t; + +static csch_tool_text_t csch_tool_text; + +static void tool_text_init(void) +{ + csch_tool_text.stroke = NULL; +} + +void sch_tool_text_notify_mode(rnd_design_t *hl) +{ + csch_sheet_t *sheet = (csch_sheet_t *)hl; + char *new_str = rnd_hid_prompt_for(hl, "Enter text:", "", "text"); + + if ((new_str != NULL) && (*new_str != '\0')) { + const char *stroke_name; + csch_text_t *text = (csch_text_t *)csch_op_create(sheet, &sheet->direct, CSCH_CTYPE_TEXT); + + if (text == NULL) { + rnd_message(RND_MSG_ERROR, "Failed to create line object\n"); + return; + } + + text->spec1.x = P2C(sch_rnd_crosshair_x); + text->spec1.y = P2C(sch_rnd_crosshair_y); + text->text = new_str; + + csch_tool_text.stroke = SCH_RND_DIRECT_PEN(sheet, tool_text_stroke, &stroke_name); + + text->hdr.stroke_name = csch_comm_str(sheet, stroke_name, 1); + csch_text_update(sheet, text, 1); + csch_sheet_set_changed(sheet, 1); + /* do not free new_str: owner is text now */ + } +} + +void sch_tool_text_draw_attached(rnd_design_t *hl) +{ + csch_sheet_t *sheet = (csch_sheet_t *)hl; + rnd_coord_t x1, y1, x2, y2, d, h; + + if (csch_tool_text.stroke == NULL) + csch_tool_text.stroke = SCH_RND_DIRECT_PEN(sheet, tool_text_stroke, NULL); + + h = csch_tool_text.stroke->font_height; + if (h <= 0) + h = 1000; + + d = C2P(h); + x1 = sch_rnd_crosshair_x; + y1 = sch_rnd_crosshair_y; + x2 = x1 + d; + y2 = y1 + d; + + rnd_hid_set_line_cap(sch_rnd_crosshair_gc, rnd_cap_round); + rnd_hid_set_line_width(sch_rnd_crosshair_gc, -1); + + rnd_render->draw_line(sch_rnd_crosshair_gc, x1, y1, x2, y2); + rnd_render->draw_line(sch_rnd_crosshair_gc, x1, y2, x2, y1); + rnd_render->draw_line(sch_rnd_crosshair_gc, x1, y1, x2, y1); + rnd_render->draw_line(sch_rnd_crosshair_gc, x2, y1, x2, y2); + rnd_render->draw_line(sch_rnd_crosshair_gc, x2, y2, x1, y2); + rnd_render->draw_line(sch_rnd_crosshair_gc, x1, y2, x1, y1); + + /* baseline */ + rnd_render->draw_line(sch_rnd_crosshair_gc, x1 + d/8, y1 + d/4, x2 - d/8, y1 + d/4); +} + +/* XPM */ +static const char *text_icon[] = { +/* columns rows colors chars-per-pixel */ +"21 21 3 1", +" c #000000", +". c #6EA5D7", +"o c None", +/* pixels */ +"ooooooooooooooooooooo", +"ooooooooooooooooooooo", +"ooooooooooooooooooooo", +"oo.ooo.ooo.ooo.ooo.oo", +"o.o.o.o.o.o.o.o.o.o.o", +"oo.ooo.ooo.ooo.ooo.oo", +"ooooooooooooooooooooo", +"ooooooooooooooooooooo", +"ooooooooooooooooooooo", +"ooooooooooooooooooooo", +"ooooooooooooooooooooo", +"ooooooooooooooooooooo", +" o o ooo o ", +"oo ooo ooo ooo ooo oo", +"oo ooo oooo o oooo oo", +"oo ooo ooooo ooooo oo", +"oo ooo ooo o oooo oo", +"oo ooo ooo ooo ooo oo", +"oo ooo ooo ooo ooo oo", +"oo ooo o ooo ooo oo", +"ooooooooooooooooooooo" +}; + +rnd_tool_t sch_rnd_tool_text = { + "text", NULL, NULL, 100, text_icon, RND_TOOL_CURSOR_NAMED("xterm"), 0, + tool_text_init, + NULL, + sch_tool_text_notify_mode, + NULL, + NULL, + sch_tool_text_draw_attached, + NULL, + NULL, + NULL, /* escape */ + + 0 +}; + Index: tags/1.0.5/src/plugins/std_tools/tool_wirenet.c =================================================================== --- tags/1.0.5/src/plugins/std_tools/tool_wirenet.c (nonexistent) +++ tags/1.0.5/src/plugins/std_tools/tool_wirenet.c (revision 10414) @@ -0,0 +1,134 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - draw wirenets + * Copyright (C) 2020 Tibor 'Igor2' Palinkas + * (copied from camv-rnd by the author) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +static void tool_wirenet_init(void) +{ + line_init(); + csch_tool_line.dir = CSCH_TOOL_LINEDIR_HV; + csch_tool_line.stroke = NULL; + csch_tool_line.stroke_name = NULL; +} + +static void tool_wirenet_uninit(void) +{ + line_uninit(); +} + +static void tool_wirenet_press(rnd_design_t *hl) +{ +} + +static void tool_wirenet_release(rnd_design_t *hl) +{ + csch_sheet_t *sheet = (csch_sheet_t *)hl; + + if (sheet->is_symbol) { + rnd_message(RND_MSG_ERROR, "Can't draw wirenets in symbol edit mode\n"); + return; + } + + if (line_release(hl)) { + if (line_is_zero_len()) { + csch_tool_line.clicked = 0; + return; + } + + if (csch_tool_line.stroke == NULL) + csch_tool_line.stroke = SCH_RND_DIRECT_PEN(sheet, tool_wire_stroke, &csch_tool_line.stroke_name); + line_create_all(hl, &sheet->direct, 1); + line_continue(hl); + } +} + +static void tool_wirenet_adjust_attached_objects(rnd_design_t *hl) +{ + line_adjust_attached_objects(hl); +} + + +static void tool_wirenet_draw_attached(rnd_design_t *hl) +{ + csch_sheet_t *sheet = (csch_sheet_t *)hl; + if (csch_tool_line.stroke == NULL) + csch_tool_line.stroke = SCH_RND_DIRECT_PEN(sheet, tool_wire_stroke, &csch_tool_line.stroke_name); + line_draw_attached(hl, &sheet->direct); +} + +static void tool_wirenet_escape(rnd_design_t *hl) +{ + if (!csch_tool_line.clicked) + rnd_tool_select_by_name(hl, "arrow"); + else + rnd_tool_select_by_name(hl, "wirenet"); +} + + +/* XPM */ +static const char *wire_icon[] = { +/* columns rows colors chars-per-pixel */ +"21 21 4 1", +" c #000000", +". c #7A8584", +"X c #6EA5D7", +"O c None", +/* pixels */ +"OOOOOOOOOOOOOOOOOOOOO", +"OO...OOOOOOOOOOOOOOOO", +"O.....OOOOOOOOOOOOOOO", +"O..XXXXXXXXXXXXXXXOOO", +"O.....OOOOOOOOOOOXOOO", +"OO...OOOOOOOOOOO.X.OO", +"OOOOOOOOOOOOOOO..X..O", +"OOOOOOOOOOOOOOO..X..O", +"OOOOOOOOOOOOOOO.....O", +"OOOOOOOOOOOOOOOO...OO", +"OOOOOOOOOOOOOOOOOOOOO", +"OOOOOOOOOOOOOOOOOOOOO", +" OOO O O OOO O", +" OOO OO OO OO OO OOOO", +" O O OO OO OO OO OOOO", +" O O OO OO OO OO OOOO", +" O O OO OO OOO OO", +"O OOO OO OO OO OOOO", +"O OOO OO OO OO OOOO", +"O OO O OO OO O", +"OOOOOOOOOOOOOOOOOOOOO" +}; + + +static rnd_tool_t sch_rnd_tool_wirenet = { + "wirenet", NULL, std_tools_cookie, 100, wire_icon, RND_TOOL_CURSOR_NAMED("pencil"), 0, + tool_wirenet_init, + tool_wirenet_uninit, + tool_wirenet_press, + tool_wirenet_release, + tool_wirenet_adjust_attached_objects, + tool_wirenet_draw_attached, + NULL, /* undo */ + NULL, /* redo */ + tool_wirenet_escape +}; Index: tags/1.0.5/src/plugins/symlib_fs/Makefile =================================================================== --- tags/1.0.5/src/plugins/symlib_fs/Makefile (nonexistent) +++ tags/1.0.5/src/plugins/symlib_fs/Makefile (revision 10414) @@ -0,0 +1,2 @@ +all: + cd ../../sch-rnd && make mod_symlib_fs Index: tags/1.0.5/src/plugins/symlib_fs/Plug.tmpasm =================================================================== --- tags/1.0.5/src/plugins/symlib_fs/Plug.tmpasm (nonexistent) +++ tags/1.0.5/src/plugins/symlib_fs/Plug.tmpasm (revision 10414) @@ -0,0 +1,10 @@ +put /local/rnd/mod {symlib_fs} +put /local/rnd/mod/OBJS [@ + $(PLUGDIR)/symlib_fs/symlib_fs.o +@] + +switch /local/module/symlib_fs/controls + case {buildin} include /local/csch/tmpasm/buildin; end; + case {plugin} include /local/csch/tmpasm/plugin; end; + case {disable} include /local/csch/tmpasm/disable; end; +end Index: tags/1.0.5/src/plugins/symlib_fs/symlib_fs.c =================================================================== --- tags/1.0.5/src/plugins/symlib_fs/symlib_fs.c (nonexistent) +++ tags/1.0.5/src/plugins/symlib_fs/symlib_fs.c (revision 10414) @@ -0,0 +1,183 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - symbol library from the file system + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +static csch_lib_backend_t be_symlib_fs; + +static char *symlib_fs_realpath(rnd_design_t *hl, const char *root) +{ + /* accept only non-prefixed paths */ + if (strchr(root, '@') != NULL) + return NULL; + + return csch_lib_fs_realpath(hl, root); +} + +csch_lib_type_t symlib_fs_file_type(rnd_design_t *hl, const char *fn) +{ + char head[2] = {0, 0}; + FILE *f; + int res; + + f = rnd_fopen(hl, fn, "r"); + if (f == NULL) + return CSCH_SLIB_invalid; + fread(head, 2, 1, f); + if ((head[0] == '#') && (head[1] == '!')) { + fclose(f); + return CSCH_SLIB_PARAMETRIC; + } + + res = csch_test_parse_file(hl, f, fn, CSCH_IOTYP_GROUP); + fclose(f); + + if (res > 0) + return CSCH_SLIB_STATIC; + return CSCH_SLIB_invalid; +} + +static int symlib_fs_map(rnd_design_t *hl, csch_lib_t *root_dir) +{ + gds_t tmp = {0}; + gds_append_str(&tmp, root_dir->realpath); + csch_lib_fs_map(hl, &be_symlib_fs, root_dir, &tmp, symlib_fs_file_type); + gds_uninit(&tmp); + return 0; +} + +static int run_parametric(rnd_design_t *hl, const char *cmd, const char *params, const char *ofn) +{ + gds_t cmdl = {0}; + int res; + + gds_append_str(&cmdl, cmd); + gds_append(&cmdl, ' '); + if (params != NULL) + gds_append_str(&cmdl, params); + gds_append_str(&cmdl, " > "); + gds_append_str(&cmdl, ofn); + + res = rnd_system(hl, cmdl.array); + + /* rnd_trace("parametric: '%s' is %d\n", cmdl.array, res); */ + + gds_uninit(&cmdl); + return res; +} + +static int symlib_fs_load(csch_sheet_t *sheet, void *dst_, csch_lib_t *src, const char *params) +{ + csch_sheet_t *dst = dst_; + csch_cgrp_t *grp = NULL; + + switch(src->type) { + case CSCH_SLIB_PARAMETRIC: + { + char *tmp; + int rv; + + tmp = rnd_tempfile_name_new("symlib_fs_p"); + if (tmp == NULL) { + rnd_message(RND_MSG_ERROR, "symlib_fs_load(parametric): failed to create temp file\n"); + return -1; + } + + rv = run_parametric(&sheet->hidlib, src->realpath, params, tmp); + if (rv == 0) { + grp = csch_load_grp(dst, tmp, NULL); + if (grp != NULL) { + /* do not let the system remember the temp file name, put back the real file name */ + free(grp->file_name); + grp->file_name = rnd_strdup(src->realpath); + } + } + else + rnd_message(RND_MSG_ERROR, "symlib_fs_load(parametric): '%s' returned error %d\n", src->realpath, rv); + rnd_tempfile_unlink(tmp); + } + break; + case CSCH_SLIB_STATIC: + grp = csch_load_grp(dst, src->realpath, NULL); + break; + + case CSCH_SLIB_invalid: + case CSCH_SLIB_DIR: + return -1; + } + + if (grp == NULL) + return -1; + + grp->sym_prefer_loclib = 1; + csch_cgrp_render_all(dst, &dst->direct); + csch_cobj_update(dst, &dst->direct.hdr, 1); + + return 0; +} + +static void symlib_fs_free(csch_lib_t *src) +{ +} + + +int pplg_check_ver_symlib_fs(int ver_needed) { return 0; } + +void pplg_uninit_symlib_fs(void) +{ + +} + +int pplg_init_symlib_fs(void) +{ + RND_API_CHK_VER; + + be_symlib_fs.name = "symlib_fs"; + be_symlib_fs.realpath = symlib_fs_realpath; + be_symlib_fs.map = symlib_fs_map; + be_symlib_fs.load = symlib_fs_load; /* loads a group into dst sheet */ + be_symlib_fs.free = symlib_fs_free; + + csch_lib_backend_reg(csch_lib_get_master("symbol", 1), &be_symlib_fs); + + return 0; +} + Index: tags/1.0.5/src/plugins/symlib_fs/symlib_fs.pup =================================================================== --- tags/1.0.5/src/plugins/symlib_fs/symlib_fs.pup (nonexistent) +++ tags/1.0.5/src/plugins/symlib_fs/symlib_fs.pup (revision 10414) @@ -0,0 +1,7 @@ +$class symlib +$short file system symbols +$long access symbol libraries stored on the local file system +$state works +$package (core) +default buildin +autoload 1 Index: tags/1.0.5/src/plugins/symlib_local/Makefile =================================================================== --- tags/1.0.5/src/plugins/symlib_local/Makefile (nonexistent) +++ tags/1.0.5/src/plugins/symlib_local/Makefile (revision 10414) @@ -0,0 +1,2 @@ +all: + cd ../../sch-rnd && make mod_symlib_local Index: tags/1.0.5/src/plugins/symlib_local/Plug.tmpasm =================================================================== --- tags/1.0.5/src/plugins/symlib_local/Plug.tmpasm (nonexistent) +++ tags/1.0.5/src/plugins/symlib_local/Plug.tmpasm (revision 10414) @@ -0,0 +1,10 @@ +put /local/rnd/mod {symlib_local} +put /local/rnd/mod/OBJS [@ + $(PLUGDIR)/symlib_local/symlib_local.o +@] + +switch /local/module/symlib_local/controls + case {buildin} include /local/csch/tmpasm/buildin; end; + case {plugin} include /local/csch/tmpasm/plugin; end; + case {disable} include /local/csch/tmpasm/disable; end; +end Index: tags/1.0.5/src/plugins/symlib_local/loc_acts.c =================================================================== --- tags/1.0.5/src/plugins/symlib_local/loc_acts.c (nonexistent) +++ tags/1.0.5/src/plugins/symlib_local/loc_acts.c (revision 10414) @@ -0,0 +1,167 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - sheet-local symbol library + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/* symbol local-lib specific actions */ + +extern csch_chdr_t *csch_obj_clicked; + +static int sym_loc_lib_to_grp(csch_chdr_t *obj) +{ + csch_cgrp_t *grp = (csch_cgrp_t *)obj; + + if (obj->type == CSCH_CTYPE_GRP) { + rnd_message(RND_MSG_ERROR, "SymLocLib: togrp: target object is already a group\n"); + return -1; + } + if (obj->type != CSCH_CTYPE_GRP_REF) { + rnd_message(RND_MSG_ERROR, "SymLocLib: togrp: target object must be a group reference\n"); + return -1; + } + if (grp->role != CSCH_ROLE_SYMBOL) { + rnd_message(RND_MSG_ERROR, "SymLocLib: togrp: target object is not a symbol\n"); + return -1; + } + + csch_grp_ref_embed(grp); + + return 0; +} + +static int sym_loc_lib_to_ref(csch_chdr_t *obj) +{ + csch_cgrp_t *grp = (csch_cgrp_t *)obj; + csch_sheet_t *sheet = obj->sheet; + + if (obj->type == CSCH_CTYPE_GRP_REF) { + rnd_message(RND_MSG_ERROR, "SymLocLib: toref: target object is already a group ref\n"); + return -1; + } + if (obj->type != CSCH_CTYPE_GRP) { + rnd_message(RND_MSG_ERROR, "SymLocLib: toref: target object must be a group\n"); + return -1; + } + + uundo_freeze_serial(&sheet->undo); + + /* replace grp with a grpref */ + local_paste_place(sheet, &grp); + csch_op_inserted(sheet, grp->hdr.parent, &grp->hdr); + csch_op_remove(sheet, obj); + + uundo_unfreeze_serial(&sheet->undo); + uundo_inc_serial(&sheet->undo); + + + return -1; +} + +static int doit_selected(csch_cgrp_t *root, int (*doit)(csch_chdr_t *obj)) +{ + int res = 0; + htip_entry_t *e; + + if ((root->role == CSCH_ROLE_SYMBOL) && root->hdr.selected) + res |= doit(&root->hdr); + + for(e = htip_first(&root->id2obj); e != NULL; e = htip_next(&root->id2obj, e)) { + csch_cgrp_t *g = e->value; + if (csch_obj_is_grp(&g->hdr)) + res |= doit_selected(g, doit); + } + + return res; +} + +const char csch_acts_SymLocLib[] = "SymLocLib(object[:idpath]|selected, [toref|togrp])\n"; +const char csch_acth_SymLocLib[] = "Convert between \"embedded\" symbols (full copy) and local lib symbol references"; +fgw_error_t csch_act_SymLocLib(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_design_t *hl = RND_ACT_DESIGN; + csch_sheet_t *sheet = (csch_sheet_t *)hl; + csch_chdr_t *obj; + const char *scope, *cmd; + int selected = 0, quiet = 0; + int (*doit)(csch_chdr_t *obj); + int r = 0; + + RND_ACT_MAY_CONVARG(1, FGW_STR, SymLocLib, scope = argv[1].val.str); + RND_ACT_MAY_CONVARG(2, FGW_STR, SymLocLib, cmd = argv[2].val.str); + + if (strcmp(cmd, "togrp") == 0) + doit = sym_loc_lib_to_grp; + else if (strcmp(cmd, "toref") == 0) + doit = sym_loc_lib_to_ref; + else { + rnd_message(RND_MSG_ERROR, "SymLocLib: invalid command '%s'\n", cmd); + return FGW_ERR_ARG_CONV; + } + + if (strncmp(scope, "object", 6) == 0) { + csch_oidpath_t idp = {0}; + + if (scope[6] == ':') { + if (csch_oidpath_parse(&idp, scope+7) != 0) { + if (!quiet) + rnd_message(RND_MSG_ERROR, "Failed to convert object ID path: '%s'\n", scope+7); + return FGW_ERR_ARG_CONV; + } + obj = csch_oidpath_resolve(sheet, &idp); + csch_oidpath_free(&idp); + if (obj == NULL) { + if (!quiet) + rnd_message(RND_MSG_ERROR, "No object by idpath %s\n", scope+7); + return FGW_ERR_ARG_CONV; + } + } + else { + obj = csch_obj_clicked; + if (obj == NULL) { + if (!quiet) + rnd_message(RND_MSG_ERROR, "No object under the cursor\n"); + return FGW_ERR_ARG_CONV; + } + } + } + else if (strcmp(scope, "selected") == 0) { + selected = 1; + } + + if (obj != NULL) + r |= doit(obj); + + if (selected) + r |= doit_selected(&sheet->direct, doit); + + RND_ACT_IRES(0); + return 0; +} + +static rnd_action_t symlib_local_action_list[] = { + {"SymLocLib", csch_act_SymLocLib, csch_acth_SymLocLib, csch_acts_SymLocLib} +}; + Index: tags/1.0.5/src/plugins/symlib_local/loc_ops.c =================================================================== --- tags/1.0.5/src/plugins/symlib_local/loc_ops.c (nonexistent) +++ tags/1.0.5/src/plugins/symlib_local/loc_ops.c (revision 10414) @@ -0,0 +1,307 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - sheet-local symbol library + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/* Backend local-lib operations */ + +static csch_cgrp_t *loc_get(csch_sheet_t *sheet, csch_lib_t *src, csch_lib_t **root_dir_out) +{ + long locgrp_oid = src->backend_data.lng[0]; + csch_source_arg_t *srca; + csch_cgrp_t *symlib; + csch_lib_t *root_dir; + + srca = csch_attrib_src_p("symlib_local", NULL); + if (csch_loclib_get_roots(&root_dir, &symlib, loclib_master, sheet, srca, 0, NULL) != 0) + return NULL; + + if (root_dir_out != NULL) + *root_dir_out = root_dir; + + return htip_get(&symlib->id2obj, locgrp_oid); +} + +static long loc_list_recurse(csch_cgrp_t *grp, csch_cgrp_t *loc, vtp0_t *res) +{ + long sum = 0; + htip_entry_t *e; + + if ((grp->hdr.type == CSCH_CTYPE_GRP_REF) && (grp->data.ref.grp == loc)) { + vtp0_append(res, grp); + return 1; + } + + for(e = htip_first(&grp->id2obj); e != NULL; e = htip_next(&grp->id2obj, e)) { + csch_cgrp_t *child = e->value; + if (csch_obj_is_grp(&child->hdr)) + sum += loc_list_recurse(child, loc, res); + } + return sum; +} + + +static int symlib_local_loc_list(csch_sheet_t *sheet, csch_lib_t *src) +{ + long cnt; + vtp0_t arr = {0}; + csch_cgrp_t *loc; + + loc = loc_get(sheet, src, NULL); + if (loc == NULL) + return -1; + + cnt = loc_list_recurse(&sheet->direct, loc, &arr); + rnd_message(RND_MSG_INFO, "Found %ld references to local lib entry %s\n", cnt, loc->loclib_name); + + if (cnt > 0) { + fgw_arg_t args[4], ares; + + args[1].type = FGW_STR; args[1].val.str = "objarr"; + fgw_ptr_reg(&rnd_fgw, &args[2], CSCH_PTR_DOMAIN_COBJ_ARR, FGW_PTR | FGW_STRUCT, &arr); + rnd_actionv_bin(&sheet->hidlib, "TreeDialog", &ares, 3, args); + fgw_ptr_unreg(&rnd_fgw, &args[2], CSCH_PTR_DOMAIN_COBJ_ARR); + vtp0_uninit(&arr); + } + + return 0; +} + +static long loc_del_recurse(csch_cgrp_t *grp, csch_cgrp_t *loc) +{ + long sum = 0; + htip_entry_t *e; + + if ((grp->hdr.type == CSCH_CTYPE_GRP_REF) && (grp->data.ref.grp == loc)) { + csch_grp_ref_embed(grp); + return 1; + } + + for(e = htip_first(&grp->id2obj); e != NULL; e = htip_next(&grp->id2obj, e)) { + csch_cgrp_t *child = e->value; + if (csch_obj_is_grp(&child->hdr)) + sum += loc_del_recurse(child, loc); + } + return sum; +} + + +static int symlib_local_loc_del(csch_sheet_t *sheet, csch_lib_t *src) +{ + long cnt; + csch_cgrp_t *loc; + + loc = loc_get(sheet, src, NULL); + if (loc == NULL) + return -1; + + cnt = loc_del_recurse(&sheet->direct, loc); + rnd_message(RND_MSG_INFO, "Embedded %ld symbols whole removing local lib entry %s\n", cnt, loc->loclib_name); + + csch_cnc_remove(sheet, &loc->hdr); + csch_lib_remove(src); + + rnd_event(&sheet->hidlib, CSCH_EVENT_LIBRARY_CHANGED, NULL); + + return 0; +} + +static const char *loc_ext_path_split(const char *path) +{ + const char *fn = strrchr(path, '/'); + if (fn != NULL) + fn++; + else + fn = path; + + return fn; +} + +static void loc_find_ext(vtp0_t *res, csch_lib_t *libent, const char *name) +{ + if (libent->type == CSCH_SLIB_DIR) { + long n; + for(n = 0; n < libent->children.used; n++) + loc_find_ext(res, (csch_lib_t *)libent->children.array[n], name); + } + else { + const char *lpath, *lfn; + + lpath = libent->name; + lfn = loc_ext_path_split(lpath); + + if (strcmp(lfn, name) == 0) { +/* rnd_trace("found %s %s %s\n", name, lpath, libent->realpath);*/ + vtp0_append(res, libent); + } + } +} + +static csch_cgrp_t *first_grp(const csch_cgrp_t *src) +{ + htip_entry_t *e; + for(e = htip_first(&src->id2obj); e != NULL; e = htip_next(&src->id2obj, e)) { + csch_cgrp_t *obj = e->value; + if (csch_obj_is_grp(&obj->hdr)) + return obj; + } + return NULL; +} + +/* Make sure only floaters are grp-ref-transformed; remove non-floaters + from the child_xform list and warn */ +static void loc_validate_xforms(csch_cgrp_t *grpref) +{ + long n; + + for(n = 0; n < grpref->data.ref.child_xform.used; n++) { + csch_child_xform_t *cx = grpref->data.ref.child_xform.array[n]; + if (cx != NULL) { + csch_chdr_t *child = csch_oidpath_resolve_in(grpref->data.ref.grp, &cx->path); + if (!child->floater) { + const char *aname = csch_attrib_get_str(&grpref->attr, "name"); + rnd_message(RND_MSG_WARNING, "removing group ref transformation in %s:\nin the new symbol child object is not a floater\n", aname); + vtp0_remove(&grpref->data.ref.child_xform, n, 1); + n--; + } + } + } +} + +static void loc_replace_cached_refs(csch_cgrp_t *grp, csch_cgrp_t *old_grp, csch_cgrp_t *new_grp) +{ + htip_entry_t *e; + + if (grp->hdr.type == CSCH_CTYPE_GRP_REF) { + if (grp->data.ref.grp == old_grp) { + grp->data.ref.grp = new_grp; + loc_validate_xforms(grp); + } + } + + for(e = htip_first(&grp->id2obj); e != NULL; e = htip_next(&grp->id2obj, e)) + if (csch_obj_is_grp(e->value)) + loc_replace_cached_refs(e->value, old_grp, new_grp); +} + +static void loc_replace(csch_sheet_t *sheet, csch_cgrp_t *old_grp, csch_lib_t *old_lib, csch_lib_t *new_lib) +{ + csch_sheet_t tmp = {0}; + csch_cgrp_t *new_grp = NULL; + int r; + + csch_sheet_init(&tmp, NULL); + r = csch_lib_load(sheet, &tmp, new_lib, NULL); + if (r == 0) + new_grp = first_grp(&tmp.direct); + if (new_grp != NULL) { + new_grp->hdr.oid = old_grp->hdr.oid; /* preserve OID so grp_refs don't break */ + + csch_lib_remove(old_lib); /* remove from lib hash first, this depends on existing grp... */ + csch_cnc_remove(sheet, &old_grp->hdr); /* ... now it's safe to get rid of the old grp */ + + new_grp = local_insert(sheet, new_grp, 0); + + rnd_event(&sheet->hidlib, CSCH_EVENT_LIBRARY_CHANGED, NULL); + loc_replace_cached_refs(&sheet->direct, old_grp, new_grp); + csch_cgrp_render_all(sheet, &sheet->direct); + if (rnd_gui != NULL) + rnd_gui->invalidate_all(rnd_gui); + } + else + rnd_message(RND_MSG_ERROR, "Failed to load group object from external library\n"); + + csch_sheet_uninit(&tmp); +} + +static int symlib_local_loc_refresh_from_ext(csch_sheet_t *sheet, csch_lib_t *src) +{ + long n; + csch_cgrp_t *loc; + csch_lib_t *root_dir; + vtp0_t cand = {0}; + char *name, *sep; + csch_lib_root_t *libroot; + + loc = loc_get(sheet, src, &root_dir); + if (loc == NULL) + return -1; + + libroot = sheet->libs.array[loclib_master->uid]; + + name = rnd_strdup(src->name); + sep = strrchr(name, '.'); + if (sep != NULL) + *sep = '\0'; + + rnd_trace("search %s\n", name); + for(n = 0; n < libroot->roots.used; n++) { + csch_lib_t *root = libroot->roots.array[n]; + if ((root != root_dir) && (root != NULL)) + loc_find_ext(&cand, root, name); + } + + switch(cand.used) { + case 0: + rnd_message(RND_MSG_ERROR, "No such symbol found in external libs: '%s'\n", name); + break; + default: /* more than one candidates */ + TODO("offer picking one (we are currently using the first only)"); + rnd_message(RND_MSG_WARNING, "More than one candidates for '%s' in libs.\nUsing the first one.\n", name); + case 1: + loc_replace(sheet, loc, src, cand.array[0]); + } + + vtp0_uninit(&cand); + free(name); + rnd_event(&sheet->hidlib, CSCH_EVENT_LIBRARY_CHANGED, NULL); + return 0; +} + + +static int symlib_local_loc_edit(csch_sheet_t *sheet, csch_lib_t *src) +{ + csch_cgrp_t *loc; + fgw_arg_t args[2], ares; + gds_t tmp = {0}; + csch_oidpath_t oidp = {0}; + + loc = loc_get(sheet, src, NULL); + if (loc == NULL) + return -1; + + /* build object:oidpath for first arg of AttributeDialog() */ + csch_oidpath_from_obj(&oidp, &loc->hdr); + gds_append_str(&tmp, "object:"); + csch_oidpath_to_str_append(&tmp, &oidp); + csch_oidpath_free(&oidp); + + /* call AttributeDialog */ + args[1].type = FGW_STR | FGW_DYN; args[1].val.str = tmp.array; + rnd_actionv_bin(&sheet->hidlib, "AttributeDialog", &ares, 2, args); + + return 0; +} Index: tags/1.0.5/src/plugins/symlib_local/symlib_local.c =================================================================== --- tags/1.0.5/src/plugins/symlib_local/symlib_local.c (nonexistent) +++ tags/1.0.5/src/plugins/symlib_local/symlib_local.c (revision 10414) @@ -0,0 +1,530 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - sheet-local symbol library + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + + +#include + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +static csch_lib_backend_t be_symlib_local; +static csch_lib_master_t *loclib_master; + +static const char symlib_local_cookie[] = "symlib_local"; + +static unsigned ll_hash(const void *obj) { return csch_cobj_hash((void *)obj); } +static int ll_keyeq(const void *obj1, const void *obj2) { return csch_cobj_keyeq((void *)obj1, (void *)obj2); } +static unsigned ll_hashna(const void *obj) { return csch_cobj_hash_((void *)obj, CSCH_HIGN_FLOATER_GEO | CSCH_HIGN_GRP_ATTRIB | CSCH_HIGN_GRP_PLACEMENT); } +static int ll_keyeqna(const void *obj1, const void *obj2) { return csch_cobj_keyeq_((void *)obj1, (void *)obj2, CSCH_HIGN_FLOATER_GEO | CSCH_HIGN_GRP_ATTRIB | CSCH_HIGN_GRP_PLACEMENT); } + +/* hash: a htpi_t, keyed with indirect symlib groups are stored in the + indirect/purpose=symbol group's backend_data->ptr[0]; [1] is the version + without attribute matching. Also remember our local root group in ptr[2]. +*/ +static void symlib_local_sheet_init(rnd_design_t *hl, csch_lib_t *root_dir, const csch_cgrp_t *symlib) +{ + root_dir->backend_data.ptr[0] = htpi_alloc(ll_hash, ll_keyeq); + root_dir->backend_data.ptr[1] = htpi_alloc(ll_hashna, ll_keyeqna); + root_dir->backend_data.ptr[2] = (void *)symlib; +} + +static void symlib_local_sheet_uninit(csch_lib_t *root_dir) +{ + csch_cgrp_t *symlib = root_dir->backend_data.ptr[2]; + + if (symlib == NULL) return; + + htpi_free(root_dir->backend_data.ptr[0]); + htpi_free(root_dir->backend_data.ptr[1]); + root_dir->backend_data.ptr[0] = NULL; + root_dir->backend_data.ptr[1] = NULL; + root_dir->backend_data.ptr[2] = NULL; +} + +/* Insert grp into the local lib cache (assuming it's already in the indirect + group's symlib group). Returns 0 on success, 1 on non-fatal error */ +static int symlib_local_insert_sym(csch_lib_t *root_dir, htpi_t *sh, htpi_t *shna, csch_cgrp_t *grp) +{ + int res = 0; + const char *gname = NULL; + csch_lib_t *newent; + char tmp[64]; + gds_t nm = {0}; + + if (grp->loclib_name != NULL) { + const char *end = strrchr(grp->loclib_name, '/'); + gname = end == NULL ? grp->loclib_name : end+1; + } + if (gname == NULL) + gname = csch_attrib_get_str(&grp->attr, "name"); + if (gname != NULL) + gds_append_str(&nm, gname); + sprintf(tmp, ".%d", grp->hdr.oid); + gds_append_str(&nm, tmp); + + if (htpi_has(sh, grp)) { + rnd_message(RND_MSG_WARNING, "Redundant local lib symbol '%s'\n", nm.array); + res = 1; + } + else { + htpi_set(sh, grp, 0); + htpi_set(shna, grp, 0); + } + + newent = csch_lib_alloc_append(&be_symlib_local, root_dir, nm.array, CSCH_SLIB_STATIC); + newent->backend_data.lng[0] = grp->hdr.oid; + /* do not free nm: name ownership passed on to newent */ + + return res; +} + +static int symlib_local_map_local_(rnd_design_t *hl, csch_lib_t *root_dir, csch_cgrp_t *symlib) +{ + htip_entry_t *e; + htpi_t *sh = root_dir->backend_data.ptr[0]; + htpi_t *shna = root_dir->backend_data.ptr[1]; + + for(e = htip_first(&symlib->id2obj); e != NULL; e = htip_next(&symlib->id2obj, e)) { + csch_cgrp_t *grp = e->value; + if ((grp->hdr.type == CSCH_CTYPE_GRP) && (grp->role == CSCH_ROLE_SYMBOL)) + symlib_local_insert_sym(root_dir, sh, shna, grp); + } + return 0; +} + +static int symlib_local_map_local(rnd_design_t *hl, csch_lib_t *root_dir, const csch_cgrp_t *indirect) +{ + csch_cgrp_t *grp = csch_loclib_get_root((csch_sheet_t *)hl, loclib_master, NULL, 0, NULL); + if (grp != NULL) { + symlib_local_sheet_init(hl, root_dir, grp); + symlib_local_map_local_(hl, root_dir, grp); + } + return 0; +} + +static int symlib_local_load(csch_sheet_t *sheet, void *dst, csch_lib_t *src_lib, const char *params) +{ + long oid; + csch_sheet_t *dst_sheet = dst; + csch_cgrp_t *sym, *src_grp, *symlib = src_lib->parent->backend_data.ptr[2]; + + + if ((params != NULL) || (symlib == NULL)) + return -1; + + oid = src_lib->backend_data.lng[0]; + src_grp = htip_get(&symlib->id2obj, oid); + if (src_grp == NULL) + return -1; + + sym = csch_cgrp_dup(dst_sheet, &dst_sheet->direct, src_grp, 0); + sym->sym_prefer_loclib = 1; + csch_cgrp_render_all(dst_sheet, &dst_sheet->direct); + csch_cobj_update(dst_sheet, &dst_sheet->direct.hdr, 1); + csch_text_invalidate_all_grp(sym, 0); /* let the draw code recalculate text objects, with proper fallback to sheet's pens */ + + return 0; +} + +static void symlib_local_free(csch_lib_t *src) +{ + csch_lib_t *root_dir = src->parent; + + if (root_dir != NULL) { + htpi_t *sh, *shna; + csch_cgrp_t *symlib, *grp; + long oid; + + sh = root_dir->backend_data.ptr[0]; + shna = root_dir->backend_data.ptr[1]; + symlib = root_dir->backend_data.ptr[2]; + + oid = src->backend_data.lng[0]; + grp = htip_get(&symlib->id2obj, oid); + if (grp == NULL) + return; + + if (sh != NULL) + htpi_pop(sh, grp); + if (shna != NULL) + htpi_pop(shna, grp); + } + else + symlib_local_sheet_uninit(src); /* src is a root dir */ +} + +/* We have *grp already placed on the sheet; move it to indirect; this happens + if some other plugin already handled the event and decided to place the + group */ +static void local_paste_already_placed(csch_sheet_t *sheet, csch_chdr_t **grp) +{ + /* no other plugin handles this event at the moment */ + rnd_message(RND_MSG_ERROR, "symlib_local local_paste_already_placed() not yet implemented\nPlease report this bug!\n"); +} + +/* Copy src as a new group in the local lib and return the new group's pointer */ +static csch_cgrp_t *loclib_create_entry(csch_sheet_t *sheet, csch_lib_t *root_dir, htpi_t *sh, htpi_t *shna, csch_cgrp_t *symlib, csch_cgrp_t *src) +{ + csch_cgrp_t *loc_lib_sym; + + loc_lib_sym = csch_cgrp_dup(sheet, symlib, src, 1); + if (loc_lib_sym == NULL) + loc_lib_sym = csch_cgrp_dup(sheet, symlib, src, 0); /* don't insist on keeping the original ID too hard */ + + if (loc_lib_sym != NULL) { + loc_lib_sym->x = 0; + loc_lib_sym->y = 0; + loc_lib_sym->spec_rot = 0; + loc_lib_sym->mirx = 0; + loc_lib_sym->miry = 0; + loc_lib_sym->sym_prefer_loclib = 0; + if (src->file_name != NULL) + loc_lib_sym->loclib_name = rnd_strdup(src->file_name); + symlib_local_insert_sym(root_dir, sh, shna, loc_lib_sym); + rnd_event(&sheet->hidlib, CSCH_EVENT_LIBRARY_CHANGED, NULL); + } + else + rnd_message(RND_MSG_ERROR, "Failed to create a copy of symbol in the local library\n(falling back to embedded copy)\n"); + + return loc_lib_sym; +} + +/* Take loc_lib_sym and create a group ref within dst (normally sheet->direct), + copying src's transformations */ +static csch_cgrp_t *loclib_create_ref(csch_sheet_t *sheet, csch_cgrp_t *dst, csch_cgrp_t *loc_lib_sym, csch_cgrp_t *src) +{ + csch_cgrp_t *new_grp = csch_cgrp_ref_alloc(sheet, dst, csch_oid_new(sheet, dst)); + + if (new_grp == NULL) { + rnd_message(RND_MSG_ERROR, "Failed to alocate group reference to place local library symbol\n(falling back to embedded copy)\n"); + return NULL; + } + + new_grp->x = src->x; + new_grp->y = src->y; + new_grp->spec_rot = src->spec_rot; + new_grp->mirx = src->mirx; + new_grp->miry = src->miry; + new_grp->data.ref.grp = loc_lib_sym; + + csch_sheet_set_changed(sheet, 1); + + return new_grp; +} + +/* insert grp in indirect */ +static csch_cgrp_t *local_insert(csch_sheet_t *sheet, csch_cgrp_t *grp, int strict) +{ + csch_source_arg_t *src; + csch_cgrp_t *symlib, *loc; + csch_lib_t *root_dir; + htpi_t *sh, *shna; + htpi_entry_t *e; + int alloced = 0; + + src = csch_attrib_src_p("symlib_local", NULL); + if (csch_loclib_get_roots(&root_dir, &symlib, loclib_master, sheet, src, 1, &alloced) != 0) + return NULL; + + if (alloced) { + symlib_local_sheet_init(&sheet->hidlib, root_dir, symlib); + symlib_local_map_local_(&sheet->hidlib, root_dir, symlib); + } + + sh = root_dir->backend_data.ptr[0]; + shna = root_dir->backend_data.ptr[1]; + + if (sh == NULL) { /* local lib is not yet created */ + symlib_local_sheet_init(&sheet->hidlib, root_dir, symlib); + sh = root_dir->backend_data.ptr[0]; + assert(sh != NULL); + } + + /* check for direct match: the very same symbol already in lib */ + e = htpi_getentry(strict ? sh : shna, grp); +/* rnd_trace("*** loclib: root=%p sh=%p e=%p\n", root_dir, sh, e);*/ + + if (0) { /* hash debug: take a sheet with exactly 1 local lib entry and place it */ + htpi_entry_t *e = htpi_first(sh); + csch_chdr_t *l = e->key, *obj = &grp->hdr; + long lh, gh; + int eq; + + rnd_trace("---- h l ----\n"); + lh = csch_cobj_hash_(l, CSCH_HIGN_FLOATER_GEO | CSCH_HIGN_GRP_ATTRIB | CSCH_HIGN_GRP_PLACEMENT); + rnd_trace("---- h g ----\n"); + gh = csch_cobj_hash_(obj, CSCH_HIGN_FLOATER_GEO | CSCH_HIGN_GRP_ATTRIB | CSCH_HIGN_GRP_PLACEMENT); + rnd_trace("---- eq ----\n"); + eq = csch_cobj_keyeq_(l, obj, CSCH_HIGN_FLOATER_GEO | CSCH_HIGN_GRP_ATTRIB | CSCH_HIGN_GRP_PLACEMENT); + rnd_trace("l=%p lh=%ld gh=%ld -> %d\n", l, lh, gh, eq); + } + + if (e == NULL) + loc = loclib_create_entry(sheet, root_dir, sh, shna, symlib, grp); + else + loc = e->key; + + return loc; +} + +static void copy_std_sym_attribs(csch_cgrp_t *dst, csch_cgrp_t *src, csch_cgrp_t *loc) +{ + const char *tmp; + csch_source_arg_t *src_none; + htsp_entry_t *e; + + /* always copy name, it should be unique */ + tmp = csch_attrib_get_str(&src->attr, "name"); + src_none = csch_attrib_src_c(NULL, 0, 0, NULL); + csch_attrib_set(&dst->attr, CSCH_ATP_USER_DEFAULT, "name", tmp, src_none, NULL); + + /* always copy role, we shouldn't depend on the lib */ + tmp = csch_attrib_get_str(&src->attr, "role"); + src_none = csch_attrib_src_c(NULL, 0, 0, NULL); + csch_attrib_set(&dst->attr, CSCH_ATP_USER_DEFAULT, "role", tmp, src_none, NULL); + + /* copy any attribute of src to dst that's not coming from or differs from loc */ + for(e = htsp_first(&src->attr); e; e = htsp_next(&src->attr, e)) { + csch_attrib_t *asrc = e->value; + csch_attrib_t *aloc = csch_attrib_get(&loc->attr, e->key); + csch_attrib_t *adst = csch_attrib_get(&dst->attr, e->key); + + if (adst != NULL) continue; /* already present in dst, don't overwrite */ + + if ((aloc == NULL) || !csch_attrib_eq_(aloc, asrc)) { + csch_attrib_t *anew = csch_attrib_dup(asrc); + htsp_set(&dst->attr, anew->key, anew); + } + } +} + + +/* insert *grp in indirect, place ref on the sheet */ +static void local_paste_place(csch_sheet_t *sheet, csch_cgrp_t **grp) +{ + csch_cgrp_t *loc = local_insert(sheet, *grp, 0); + + if (loc != NULL) { + csch_cgrp_t *new_ref = loclib_create_ref(sheet, &sheet->direct, loc, *grp); + if (new_ref != NULL) { + copy_std_sym_attribs(new_ref, *grp, loc); + csch_cgrp_ref_render(sheet, new_ref); + *grp = new_ref; + } + } +} + +/* Perform a "place a ref from local lib" when pasting a symbol from the buffer */ +static void symlib_local_paste(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + csch_sheet_t *sheet = (csch_sheet_t *)hidlib; + csch_chdr_t **obj = argv[1].d.p; + + + if (argv[1].type != RND_EVARG_PTR) { + rnd_message(RND_MSG_ERROR, "symlib_local_paste() wrong first arg\n"); + return; + } + + /* when placing a symbol group, take over normal placement and create a + group ref instead */ + if ((*obj)->type == CSCH_CTYPE_GRP) { + csch_cgrp_t *grp = (csch_cgrp_t *)*obj; + + if (!conf_core.editor.paste_to_local_lib) + return; + + if ((grp->role == CSCH_ROLE_SYMBOL) && (grp->sym_prefer_loclib)) { + if (grp->hdr.sheet == sheet) + local_paste_already_placed(sheet, obj); + else + local_paste_place(sheet, (csch_cgrp_t **)obj); + } + } + else if ((*obj)->type == CSCH_CTYPE_GRP_REF) { + csch_cgrp_t *src = (csch_cgrp_t *)*obj, *bsymlib, *loc, *newgr; + const char *purp; + + /* Doc: trunk/doc/developer/symbol_loclib_paste.txt */ + +/* rnd_trace("-- symlib_local_paste\n");*/ + if ((src->data.ref.grp == NULL) && (csch_cgrp_ref_text2ptr(src->hdr.sheet, src) != 0)) { +/* rnd_trace(" Failed to resolve group ref\n");*/ + return; + } + bsymlib = src->data.ref.grp->hdr.parent; + purp = csch_attrib_get_str(&bsymlib->attr, "purpose"); + if ((purp == NULL) || (strcmp(purp, "symbol") != 0)) { +/* rnd_trace(" not a symlib grp_ref\n");*/ + return; + } + + loc = local_insert(sheet, src->data.ref.grp, 1); + if (loc == NULL) { + rnd_message(RND_MSG_ERROR, "Failed to paste symbol prototype in loclib of the sheet\n"); + return; + } + +/* rnd_trace(" place as loclib grp_ref %p\n", loc);*/ + newgr = (csch_cgrp_t *)csch_cobj_dup(sheet, &sheet->direct, &src->hdr, 0, 0); + if (newgr != NULL) { + free(newgr->data.ref.ref_str); + newgr->data.ref.ref_str = NULL; + newgr->data.ref.grp = loc; + *obj = &newgr->hdr; + } + else + rnd_message(RND_MSG_ERROR, "Failed to paste loclib symbol grp_ref on the sheet\n"); + } +} + + +/* Perform a "copy to buffer" on local lib refs: need to include the referenced + group from local lib into buffer's indirect so the buffer is self-contained */ +static void symlib_local_copy(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + csch_chdr_t **obj = argv[1].d.p; + csch_cgrp_t *src, *symlib, *newg, *newr, *bsymlib; + csch_sheet_t *buffer = argv[2].d.p, *sheet = (csch_sheet_t *)hidlib; + const char *purp; + int alloced; + +/* Doc: trunk/doc/developer/symbol_loclib_paste.txt */ + + if ((argv[1].type != RND_EVARG_PTR) || (argv[2].type != RND_EVARG_PTR)) { + rnd_message(RND_MSG_ERROR, "symlib_local_copy() wrong argument types\n"); + return; + } + +/* rnd_trace("--- symlib_local_copy()\n");*/ + + /* veryify source and ignore anything that's not a loclib ref */ + src = (csch_cgrp_t *)(*obj); + + if (src->hdr.type != CSCH_CTYPE_GRP_REF) { +/* rnd_trace(" not a group ref\n");*/ + return; + } + + if (src->data.ref.grp == NULL) { + if (csch_cgrp_ref_text2ptr(sheet, src) != 0) { +/* rnd_trace(" can't resolve referee so can't decide if it's a loclib ref\n");*/ + return; + } + } + + symlib = src->data.ref.grp->hdr.parent; + purp = csch_attrib_get_str(&symlib->attr, "purpose"); + if ((purp == NULL) || (strcmp(purp, "symbol") != 0)) { +/* rnd_trace(" not a loclib reference\n");*/ + return; + } + +/* rnd_trace(" took over copy\n");*/ + { + csch_source_arg_t *src = csch_attrib_src_p("symlib_local", NULL); + bsymlib = csch_loclib_get_root(buffer, loclib_master, src, 1, &alloced); + } + + /* check if we already have it in buffer's loclib */ + newr = (csch_cgrp_t *)htip_get(&bsymlib->id2obj, src->data.ref.grp->hdr.oid); + if (newr == NULL) + newr = (csch_cgrp_t *)csch_cobj_dup(buffer, bsymlib, &src->data.ref.grp->hdr, 1, 0); + newg = (csch_cgrp_t *)csch_cobj_dup(buffer, &buffer->direct, &src->hdr, 0, 0); + *obj = &newg->hdr; + + /* break original pointer ref pointing into sheet by converting ref back to + text. Whenever needed it will be resolved within the buffer */ + newg->data.ref.grp = newr; + csch_cgrp_ref_ptr2text(buffer, newg); +} + +#include "loc_ops.c" +#include "loc_acts.c" + +static void symlib_local_sheet_postload_ev(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + csch_sheet_t *sheet = (csch_sheet_t *)hidlib; + csch_lib_add_local(sheet, loclib_master); +} + + +int pplg_check_ver_symlib_local(int ver_needed) { return 0; } + +void pplg_uninit_symlib_local(void) +{ + rnd_event_unbind_allcookie(symlib_local_cookie); + rnd_remove_actions_by_cookie(symlib_local_cookie); +} + +int pplg_init_symlib_local(void) +{ + RND_API_CHK_VER; + + RND_REGISTER_ACTIONS(symlib_local_action_list, symlib_local_cookie); + + be_symlib_local.name = "symlib_local"; + be_symlib_local.map_local = symlib_local_map_local; + be_symlib_local.load = symlib_local_load; + be_symlib_local.free = symlib_local_free; + be_symlib_local.loc_list = symlib_local_loc_list; + be_symlib_local.loc_del = symlib_local_loc_del; + be_symlib_local.loc_refresh_from_ext = symlib_local_loc_refresh_from_ext; + be_symlib_local.loc_edit = symlib_local_loc_edit; + + loclib_master = csch_lib_get_master("symbol", 1); + csch_lib_backend_reg(loclib_master, &be_symlib_local); + + rnd_event_bind(CSCH_EVENT_BUFFER_PASTE_CUSTOM, symlib_local_paste, NULL, symlib_local_cookie); + rnd_event_bind(CSCH_EVENT_BUFFER_COPY_CUSTOM, symlib_local_copy, NULL, symlib_local_cookie); + rnd_event_bind(CSCH_EVENT_SHEET_POSTLOAD, symlib_local_sheet_postload_ev, NULL, symlib_local_cookie); + + return 0; +} + Index: tags/1.0.5/src/plugins/symlib_local/symlib_local.pup =================================================================== --- tags/1.0.5/src/plugins/symlib_local/symlib_local.pup (nonexistent) +++ tags/1.0.5/src/plugins/symlib_local/symlib_local.pup (revision 10414) @@ -0,0 +1,7 @@ +$class symlib +$short sheet local symbols +$long access symbol library stored within the sheet +$state works +$package (core) +default buildin +autoload 1 Index: tags/1.0.5/src/plugins/target_none/Makefile =================================================================== --- tags/1.0.5/src/plugins/target_none/Makefile (nonexistent) +++ tags/1.0.5/src/plugins/target_none/Makefile (revision 10414) @@ -0,0 +1,2 @@ +all: + cd ../../sch-rnd && make mod_target_none Index: tags/1.0.5/src/plugins/target_none/Plug.tmpasm =================================================================== --- tags/1.0.5/src/plugins/target_none/Plug.tmpasm (nonexistent) +++ tags/1.0.5/src/plugins/target_none/Plug.tmpasm (revision 10414) @@ -0,0 +1,10 @@ +put /local/rnd/mod {target_none} +put /local/rnd/mod/OBJS [@ + $(PLUGDIR)/target_none/target_none.o +@] + +switch /local/module/target_none/controls + case {buildin} include /local/csch/tmpasm/buildin; end; + case {plugin} include /local/csch/tmpasm/plugin; end; + case {disable} include /local/csch/tmpasm/disable; end; +end Index: tags/1.0.5/src/plugins/target_none/target_none.c =================================================================== --- tags/1.0.5/src/plugins/target_none/target_none.c (nonexistent) +++ tags/1.0.5/src/plugins/target_none/target_none.c (revision 10414) @@ -0,0 +1,90 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - dummy target + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +/*** hooks ***/ + +fgw_error_t target_none_compile_port(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + fgw_obj_t *obj = argv[0].val.argv0.func->obj; + csch_view_eng_t *eng = obj->script_data; + csch_aport_t *port; + + CSCH_HOOK_CONVARG(1, FGW_AOBJ, std_cschem_comp_update, port = fgw_aobj(&argv[1])); + assert(port->hdr.type == CSCH_ATYPE_PORT); + + if (port->name != NULL) { + csch_source_arg_t *src = csch_attrib_src_p("target_none", NULL); + csch_attrib_set(&port->hdr.attr, eng->eprio + CSCH_PRI_PLUGIN_NORMAL, "display/name", port->name, src, NULL); + } + + return 0; +} + +static int on_load(fgw_obj_t *obj, const char *filename, const char *opts) +{ + fgw_func_reg(obj, "compile_port", target_none_compile_port); + obj->script_data = obj->script_user_call_ctx; /* save eng ptr */ + return 0; +} + +static const fgw_eng_t fgw_target_none_eng = { + "target_none", + csch_c_call_script, + NULL, + on_load, + NULL, /* on_unload */ +}; + +int pplg_check_ver_target_none(int ver_needed) { return 0; } + +void pplg_uninit_target_none(void) +{ +} + +int pplg_init_target_none(void) +{ + RND_API_CHK_VER; + + fgw_eng_reg(&fgw_target_none_eng); + return 0; +} + Index: tags/1.0.5/src/plugins/target_none/target_none.pup =================================================================== --- tags/1.0.5/src/plugins/target_none/target_none.pup (nonexistent) +++ tags/1.0.5/src/plugins/target_none/target_none.pup (revision 10414) @@ -0,0 +1,7 @@ +$class engine +$short dummy attr. xform +$long Display original names +$state works +$package (core) +default buildin +autoload 1 Index: tags/1.0.5/src/plugins/target_pcb/Makefile =================================================================== --- tags/1.0.5/src/plugins/target_pcb/Makefile (nonexistent) +++ tags/1.0.5/src/plugins/target_pcb/Makefile (revision 10414) @@ -0,0 +1,2 @@ +all: + cd ../../sch-rnd && make mod_target_pcb Index: tags/1.0.5/src/plugins/target_pcb/Plug.tmpasm =================================================================== --- tags/1.0.5/src/plugins/target_pcb/Plug.tmpasm (nonexistent) +++ tags/1.0.5/src/plugins/target_pcb/Plug.tmpasm (revision 10414) @@ -0,0 +1,14 @@ +put /local/rnd/mod {target_pcb} +put /local/rnd/mod/OBJS [@ + $(PLUGDIR)/target_pcb/target_pcb.o +@] + +put /local/rnd/mod/CONFFILE {target_pcb.conf} +put /local/rnd/mod/CONF {$(PLUGDIR)/target_pcb/target_pcb_conf.h} +put /local/rnd/mod/CONFVAR {target_pcb_conf_internal} + +switch /local/module/target_pcb/controls + case {buildin} include /local/csch/tmpasm/buildin; end; + case {plugin} include /local/csch/tmpasm/plugin; end; + case {disable} include /local/csch/tmpasm/disable; end; +end Index: tags/1.0.5/src/plugins/target_pcb/target_pcb.c =================================================================== --- tags/1.0.5/src/plugins/target_pcb/target_pcb.c (nonexistent) +++ tags/1.0.5/src/plugins/target_pcb/target_pcb.c (revision 10414) @@ -0,0 +1,228 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - attr. transf. for PCB workflow + * Copyright (C) 2022, 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022 and Entrust in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "target_pcb_conf.h" +#include "conf_internal.c" + +conf_target_pcb_t target_pcb_conf; + +static const char cookie[] = "target_pcb"; + +typedef struct target_pcb_ctx_s { + csch_view_eng_t *eng; + sch_trgt_ctx_t trgt; +} target_pcb_ctx_t; + +/*** hooks ***/ + +fgw_error_t target_pcb_compile_port(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ +/* csch_hook_call_ctx_t *cctx = argv[0].val.argv0.user_call_ctx;*/ + fgw_obj_t *obj = argv[0].val.argv0.func->obj; + target_pcb_ctx_t *ctx = obj->script_data; + csch_view_eng_t *eng = ctx->eng; + csch_aport_t *port; + const char *pinnum; + csch_source_arg_t *src; + + + CSCH_HOOK_CONVARG(1, FGW_AOBJ, std_cschem_comp_update, port = fgw_aobj(&argv[1])); + assert(port->hdr.type == CSCH_ATYPE_PORT); + + pinnum = csch_attrib_get_str(&port->hdr.attr, "pcb/pinnum"); + if (pinnum != NULL) + src = csch_attrib_src_pa(&port->hdr, "pcb/pinnum", "target_pcb", NULL); + + if (pinnum == NULL) { + pinnum = csch_attrib_get_str(&port->hdr.attr, "pinnum"); + if (pinnum != NULL) + src = csch_attrib_src_pa(&port->hdr, "pinnum", "target_pcb", NULL); + } + if (pinnum == NULL) { + pinnum = port->name; + if (pinnum != NULL) + src = csch_attrib_src_p("target_pcb", "fallback on port name"); + } + + if (pinnum != NULL) + csch_attrib_set(&port->hdr.attr, eng->eprio + CSCH_PRI_PLUGIN_NORMAL, "display/name", pinnum, src, NULL); + + return 0; +} + +fgw_error_t target_pcb_compile_component0(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + fgw_obj_t *obj = argv[0].val.argv0.func->obj; + target_pcb_ctx_t *ctx = obj->script_data; + csch_view_eng_t *eng = ctx->eng; + csch_acomp_t *comp; + + CSCH_HOOK_CONVARG(1, FGW_AOBJ, std_cschem_comp_update, comp = fgw_aobj(&argv[1])); + assert(comp->hdr.type == CSCH_ATYPE_COMP); + + sch_trgt_copy_alt_attrib(&comp->hdr, eng->eprio + CSCH_PRI_PLUGIN_NORMAL, "target_pcb", "display/dnp", "pcb/dnp", "dnp", NULL); + sch_trgt_copy_alt_attrib(&comp->hdr, eng->eprio + CSCH_PRI_PLUGIN_NORMAL, "target_pcb", "display/omit", "pcb/omit", "omit", NULL); + + return 0; +} + +fgw_error_t target_pcb_compile_component1(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + fgw_obj_t *obj = argv[0].val.argv0.func->obj; + target_pcb_ctx_t *ctx = obj->script_data; +/* csch_view_eng_t *eng = ctx->eng;*/ + csch_acomp_t *comp; + + CSCH_HOOK_CONVARG(1, FGW_AOBJ, std_cschem_comp_update, comp = fgw_aobj(&argv[1])); + assert(comp->hdr.type == CSCH_ATYPE_COMP); + + sch_trgt_export_attrs(&ctx->trgt, &comp->hdr); + + return 0; +} + +static void target_pcb_gen_nettags(target_pcb_ctx_t *ctx, csch_abstract_t *abst) +{ + htsp_entry_t *e; + csch_view_eng_t *eng = ctx->eng; + + for(e = htsp_first(&abst->nets); e != NULL; e = htsp_next(&abst->nets, e)) { + csch_anet_t *net = e->value; + + sch_trgt_copy_alt_attrib(&net->hdr, eng->eprio + CSCH_PRI_PLUGIN_NORMAL, "target_pcb", "display/omit", "pcb/omit", "omit", NULL); + sch_trgt_export_attrs(&ctx->trgt, &net->hdr); + } +} + + +fgw_error_t target_pcb_compile_project_before(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ +/* csch_hook_call_ctx_t *cctx = argv[0].val.argv0.user_call_ctx;*/ + fgw_obj_t *obj = argv[0].val.argv0.func->obj; + target_pcb_ctx_t *ctx = obj->script_data; + + sch_trgt_ctx_init(&ctx->trgt, + &target_pcb_conf.plugins.target_pcb.attr_export.whitelist, + &target_pcb_conf.plugins.target_pcb.attr_export.blacklist, + target_pcb_conf.plugins.target_pcb.attr_export.flow_prefix, + target_pcb_conf.plugins.target_pcb.attr_export.sw_prefix); + + + return 0; +} + +fgw_error_t target_pcb_compile_project_after(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ +/* csch_hook_call_ctx_t *cctx = argv[0].val.argv0.user_call_ctx;*/ + fgw_obj_t *obj = argv[0].val.argv0.func->obj; + target_pcb_ctx_t *ctx = obj->script_data; + csch_abstract_t *abst; +/* csch_project_t *prj;*/ + + CSCH_HOOK_CONVARG(1, FGW_STRUCT|FGW_PTR, std_cschem_comp_update, abst = argv[1].val.ptr_void); +/* CSCH_HOOK_CONVARG(2, FGW_STRUCT|FGW_PTR, std_cschem_comp_update, prj = argv[2].val.ptr_void);*/ + + target_pcb_gen_nettags(ctx, abst); + + sch_trgt_ctx_uninit(&ctx->trgt); + return 0; +} + + +static int on_load(fgw_obj_t *obj, const char *filename, const char *opts) +{ + target_pcb_ctx_t *ctx = calloc(sizeof(target_pcb_ctx_t), 1); + + fgw_func_reg(obj, "compile_port", target_pcb_compile_port); + fgw_func_reg(obj, "compile_component0", target_pcb_compile_component0); + fgw_func_reg(obj, "compile_component1", target_pcb_compile_component1); + fgw_func_reg(obj, "compile_project_before", target_pcb_compile_project_before); + fgw_func_reg(obj, "compile_project_after", target_pcb_compile_project_after); + + obj->script_data = ctx; + ctx->eng = obj->script_user_call_ctx; /* save eng ptr */ + return 0; +} + +static int on_unload(fgw_obj_t *obj) +{ + target_pcb_ctx_t *ctx = obj->script_data; + sch_trgt_ctx_uninit(&ctx->trgt); + free(ctx); + return 0; +} + + +static const fgw_eng_t fgw_target_pcb_eng = { + "target_pcb", + csch_c_call_script, + NULL, + on_load, + on_unload +}; + +int pplg_check_ver_target_pcb(int ver_needed) { return 0; } + +void pplg_uninit_target_pcb(void) +{ + rnd_conf_plug_unreg("plugins/target_pcb/", target_pcb_conf_internal, cookie); +} + +int pplg_init_target_pcb(void) +{ + RND_API_CHK_VER; + + fgw_eng_reg(&fgw_target_pcb_eng); + + rnd_conf_plug_reg(target_pcb_conf, target_pcb_conf_internal, cookie); +#define conf_reg(field,isarray,type_name,cpath,cname,desc,flags) \ + rnd_conf_reg_field(target_pcb_conf, field,isarray,type_name,cpath,cname,desc,flags); +#include "target_pcb_conf_fields.h" + + return 0; +} + Index: tags/1.0.5/src/plugins/target_pcb/target_pcb.conf =================================================================== --- tags/1.0.5/src/plugins/target_pcb/target_pcb.conf (nonexistent) +++ tags/1.0.5/src/plugins/target_pcb/target_pcb.conf (revision 10414) @@ -0,0 +1,12 @@ +li:pcb-rnd-conf-v1 { + ha:overwrite { + ha:plugins { + ha:target_pcb { + ha:attr_export { + flow_prefix=pcb + li:whitelist={display/dnp->dnp; tolerance; color} + } + } + } + } +} Index: tags/1.0.5/src/plugins/target_pcb/target_pcb.pup =================================================================== --- tags/1.0.5/src/plugins/target_pcb/target_pcb.pup (nonexistent) +++ tags/1.0.5/src/plugins/target_pcb/target_pcb.pup (revision 10414) @@ -0,0 +1,8 @@ +$class engine +$short attr. xform for PCB workflow +$long Attribute transformations for the PCB workflow +$state works +$package (core) +default buildin +dep lib_target +autoload 1 Index: tags/1.0.5/src/plugins/target_pcb/target_pcb_conf.h =================================================================== --- tags/1.0.5/src/plugins/target_pcb/target_pcb_conf.h (nonexistent) +++ tags/1.0.5/src/plugins/target_pcb/target_pcb_conf.h (revision 10414) @@ -0,0 +1,21 @@ +#ifndef SCH_RND_TARGET_PCB_CONF_H +#define SCH_RND_TARGET_PCB_CONF_H + +#include + +typedef struct { + const struct { + const struct { + const struct { + RND_CFT_STRING flow_prefix; /* attributes starting with this prefix and a colon are exported (because of workflow considerations) */ + RND_CFT_STRING sw_prefix; /* attributes starting with this prefix and a colon are exported (because of mathcing target software) */ + RND_CFT_LIST whitelist; /* list attribute keys to be copied to export; when in form of key1->key2, rename key1 to key2 on export */ + RND_CFT_LIST blacklist; /* do not export these attributes even if other rules would permit exporting them */ + } attr_export; + } target_pcb; + } plugins; +} conf_target_pcb_t; + +extern conf_target_pcb_t target_pcb_conf; + +#endif Index: tags/1.0.5/src/plugins/target_spice/Makefile =================================================================== --- tags/1.0.5/src/plugins/target_spice/Makefile (nonexistent) +++ tags/1.0.5/src/plugins/target_spice/Makefile (revision 10414) @@ -0,0 +1,2 @@ +all: + cd ../../sch-rnd && make mod_target_spice Index: tags/1.0.5/src/plugins/target_spice/Plug.tmpasm =================================================================== --- tags/1.0.5/src/plugins/target_spice/Plug.tmpasm (nonexistent) +++ tags/1.0.5/src/plugins/target_spice/Plug.tmpasm (revision 10414) @@ -0,0 +1,15 @@ +put /local/rnd/mod {target_spice} +put /local/rnd/mod/OBJS [@ + $(PLUGDIR)/target_spice/htcp.o + $(PLUGDIR)/target_spice/target_spice.o +@] + +put /local/rnd/mod/CONFFILE {target_spice.conf} +put /local/rnd/mod/CONF {$(PLUGDIR)/target_spice/target_spice_conf.h} +put /local/rnd/mod/CONFVAR {target_spice_conf_internal} + +switch /local/module/target_spice/controls + case {buildin} include /local/csch/tmpasm/buildin; end; + case {plugin} include /local/csch/tmpasm/plugin; end; + case {disable} include /local/csch/tmpasm/disable; end; +end Index: tags/1.0.5/src/plugins/target_spice/htcp.c =================================================================== --- tags/1.0.5/src/plugins/target_spice/htcp.c (nonexistent) +++ tags/1.0.5/src/plugins/target_spice/htcp.c (revision 10414) @@ -0,0 +1,18 @@ +#include "htcp.h" +#define HT(x) htcp_ ## x +static htcp_value_t invalid; +#define HT_INVALID_VALUE invalid +#include +#include + +int htcp_keyeq(htcp_key_t a, htcp_key_t b) +{ + return (strcmp(a.orig_comp_name, b.orig_comp_name) == 0) && (a.pinnum == b.pinnum); +} + +unsigned int htcp_keyhash(htcp_key_t a) +{ + return strhash(a.orig_comp_name) ^ longhash(a.pinnum); +} + +#undef HT Index: tags/1.0.5/src/plugins/target_spice/htcp.h =================================================================== --- tags/1.0.5/src/plugins/target_spice/htcp.h (nonexistent) +++ tags/1.0.5/src/plugins/target_spice/htcp.h (revision 10414) @@ -0,0 +1,22 @@ +#ifndef GENHT_HTCP_H +#define GENHT_HTCP_H + +#include + +typedef struct { + const char *orig_comp_name; /* points into an attribute value */ + long pinnum; +} htcp_key_t; + +typedef struct { + vtp0_t ports; +} htcp_value_t; + +#define HT(x) htcp_ ## x +#include +#undef HT + +int htcp_keyeq(htcp_key_t a, htcp_key_t b); +unsigned int htcp_keyhash(htcp_key_t a); + +#endif Index: tags/1.0.5/src/plugins/target_spice/libs.c =================================================================== --- tags/1.0.5/src/plugins/target_spice/libs.c (nonexistent) +++ tags/1.0.5/src/plugins/target_spice/libs.c (revision 10414) @@ -0,0 +1,255 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - spice target + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/*** spice model library handling ***/ + +static char *spicelib_lib_lookup(ldch_ctx_t *ctx, const char *load_name, ldch_low_parser_t *low, ldch_high_parser_t *high, void *low_call_ctx, void *high_call_ctx) +{ +/* csch_hook_call_ctx_t *cctx = high_call_ctx; for cctx->project */ +/* fgw_obj_t *obj = ctx->user_data;*/ + csch_lib_t *le; + + /* if full path is known */ + if (strchr(load_name, '/') != NULL) + return rnd_strdup(load_name); + + TODO("we shouldn't search master, only sheet's devmap libs, but the" + "abstract model doesn't have sheets"); + le = csch_lib_search_master(spicelibmaster, load_name, CSCH_SLIB_STATIC); + if (le == NULL) { + char *load_name2 = rnd_concat(load_name, ".mod", NULL); + le = csch_lib_search_master(spicelibmaster, load_name2, CSCH_SLIB_STATIC); + free(load_name2); + } + if (le == NULL) { + char *load_name2 = rnd_concat(load_name, ".prm", NULL); + le = csch_lib_search_master(spicelibmaster, load_name2, CSCH_SLIB_STATIC); + free(load_name2); + } +/* rnd_trace("spicelib lookup: %s -> %p\n", load_name, le);*/ + + return le == NULL ? NULL : rnd_strdup(le->realpath); +} + +/* effectively a test-parse */ +csch_lib_type_t spicelib_mod_file_type(rnd_design_t *hl, const char *fn) +{ + FILE *f; + int n; + csch_lib_type_t res = CSCH_SLIB_invalid; + + f = rnd_fopen(hl, fn, "r"); + if (f == NULL) + return res; + + for(n = 0; n < 64; n++) { + char *s, line[1024]; + s = fgets(line, sizeof(line), f); + if (s == NULL) break; + if ((strstr(s, ".model") != NULL) || (strstr(s, ".MODEL") != NULL)) { + res = CSCH_SLIB_STATIC; + break; + } + } + fclose(f); + return res; +} + + +static char *spicelib_mod_realpath(rnd_design_t *hl, const char *root) +{ + /* accept only non-prefixed paths for now */ + if (strchr(root, '@') != NULL) + return NULL; + + return csch_lib_fs_realpath(hl, root); +} + +static int spicelib_mod_map(rnd_design_t *hl, csch_lib_t *root_dir) +{ + gds_t tmp = {0}; + gds_append_str(&tmp, root_dir->realpath); + csch_lib_fs_map(hl, &be_spicelib_mod, root_dir, &tmp, spicelib_mod_file_type); + gds_uninit(&tmp); + return 0; +} + + + +/* Load (and cache-parse) a spicelib from the external libs */ +static const char *spicelib_get_extlib(spicelib_ctx_t *ctx, const char *spicelib_name, csch_hook_call_ctx_t *cctx, int save_in_local, csch_project_t *for_project) +{ + ldch_data_t *data; + spicelib_t *spicelib; + gds_t *res; + long n; + + data = ldch_load_(&ctx->spicelibs, spicelib_name, ctx->low_parser, ctx->high_parser, NULL, cctx); + if (data == NULL) + return NULL; + + spicelib = (spicelib_t *)&data->payload; + res = spicelib->text; + + if (save_in_local) { +/* rnd_trace("spicelib: inserting %s in local libs:\n", spicelib_name);*/ + if (for_project != NULL) { + for(n = 0; n < for_project->hdr.designs.used; n++) { + csch_sheet_t *sheet = for_project->hdr.designs.array[n]; + spicelib_set_in_loclib(sheet, spicelib_name, res); + } + } + else { + for(n = 0; n < ctx->ssyms.used; n++) { + csch_cgrp_t *sym = ctx->ssyms.array[n]; +/* rnd_trace(" %s\n", sym->hdr.sheet->hidlib.fullpath);*/ + rnd_message(RND_MSG_INFO, "spicelib: inserting %s in local lib of %s\n", spicelib_name, sym->hdr.sheet->hidlib.fullpath); + spicelib_set_in_loclib(sym->hdr.sheet, spicelib_name, res); + } + } + } + + return res == NULL ? NULL : res->array; +} + +/* Look up and return component attributes for the component's spicelib name: + - first look in the local lib; if present, load from there + - if not, look in the library and import into the local lib + - return NULL if both fail +*/ +static const char *spicelib_get_from_any_lib_for_comp(spicelib_ctx_t *ctx, csch_acomp_t *comp, csch_attrib_t *adm, void *ucallctx) +{ + csch_cgrp_t *res_sym = NULL; + const char *spicelib_name, *res = NULL, *loc_dm; + long n; + + if ((adm == NULL) || (adm->deleted)) return NULL; + spicelib_name = adm->val; + + if (spicelib_name == NULL) { + rnd_message(RND_MSG_ERROR, "spice/model attribute should be a string in component %s\n", comp->name); + return NULL; + } + + if (*spicelib_name == '\0') /* empty value is okay, it means no spicelib */ + return NULL; + + /* figure which symbol(s) have this spicelib */ + ctx->ssyms.used = 0; + for(n = 0; n < comp->hdr.srcs.used; n++) { + csch_cgrp_t *sym = comp->hdr.srcs.array[n]; + const char *cdmn; + + if (sym == NULL) + continue; + + cdmn = csch_attrib_get_str(&sym->attr, "spice/model"); +/*rnd_trace("spicelib: comp: %s spicelib: %s sym's: '%s'\n", comp->name, spicelib_name, cdmn);*/ + if ((cdmn == NULL) || (strcmp(cdmn, spicelib_name) != 0)) + continue; + + vtp0_append(&ctx->ssyms, sym); + } + + if (ctx->ssyms.used == 0) { + rnd_message(RND_MSG_ERROR, "Spicelib internal error in component %s: no source symbol has the right spicelib attribute\n", comp->name); + return NULL; + } + + /* if there are more than one, compare the relevant ones and remember the first */ + for(n = 0; n < ctx->ssyms.used; n++) { + csch_cgrp_t *sym = ctx->ssyms.array[n]; + + loc_dm = spicelib_get_from_loclib(sym->hdr.sheet, spicelib_name); + if (res != NULL) { + if (rnd_strcasecmp(res, loc_dm) != 0) { + rnd_message(RND_MSG_ERROR, "Spicelib local lib sync error sheet %s and %s has different copy of spicelib %s\nPlease sync your local libs before compiling!\n", sym->hdr.sheet->hidlib.fullpath, res_sym->hdr.sheet->hidlib.fullpath, spicelib_name); + return NULL; + } + } + else { + res = loc_dm; + if (res != NULL) + res_sym = sym; + } + } + + if (res != NULL) { +/* rnd_trace("spicelib: served %s from local lib of sheet %s\n", spicelib_name, res_sym->hdr.sheet->hidlib.fullpath);*/ + return res; + } + +/* rnd_trace("spicelib: %s is not in our local libs\n", spicelib_name);*/ + res = spicelib_get_extlib(ctx, spicelib_name, ucallctx, 1, NULL); + if (res == NULL) { + rnd_message(RND_MSG_ERROR, "Spicelib %s not found in the library for component %s\n", spicelib_name, comp->name); + return NULL; + } + + return res; +} + +static const char *spicelib_get_from_any_lib_for_project(spicelib_ctx_t *ctx, csch_project_t *prj, const char *model_name, void *ucallctx) +{ + const char *res = NULL; + csch_sheet_t *res_sheet = NULL; + long n; + + /* if there are more than one, compare the relevant ones and remember the first */ + for(n = 0; n < prj->hdr.designs.used; n++) { + csch_sheet_t *sheet = prj->hdr.designs.array[n]; + const char *loc_dm; + + loc_dm = spicelib_get_from_loclib(sheet, model_name); + if (res != NULL) { + if (rnd_strcasecmp(res, loc_dm) != 0) { + rnd_message(RND_MSG_ERROR, "Spicelib local lib sync error sheet %s and %s has different copy of spicelib %s\nPlease sync your local libs before compiling!\n", sheet->hidlib.fullpath, res_sheet->hidlib.fullpath, model_name); + return NULL; + } + } + else { + res = loc_dm; + if (res != NULL) + res_sheet = sheet; + } + } + + if (res != NULL) { +/* rnd_trace("spicelib: served %s from local lib of sheet %s\n", model_name, res_sheet->hidlib.fullpath);*/ + return res; + } + +/* rnd_trace("spicelib: %s is not in our local libs\n", model_name);*/ + res = spicelib_get_extlib(ctx, model_name, ucallctx, 1, prj); + if (res == NULL) { + rnd_message(RND_MSG_ERROR, "Spicelib %s not found in the library (search scope: project)\n", model_name); + return NULL; + } + + return res; +} Index: tags/1.0.5/src/plugins/target_spice/loclib.c =================================================================== --- tags/1.0.5/src/plugins/target_spice/loclib.c (nonexistent) +++ tags/1.0.5/src/plugins/target_spice/loclib.c (revision 10414) @@ -0,0 +1,257 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - spice target + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/*** local lib support ***/ + +static void spicelib_local_ins(htsp_t *map, csch_lib_t *root_dir, csch_cgrp_t *grp) +{ + csch_lib_t *newent; + + htsp_set(map, grp->loclib_name, grp); + + newent = csch_lib_alloc_append(&be_spicelib_mod, root_dir, rnd_strdup(grp->loclib_name), CSCH_SLIB_STATIC); + newent->backend_data.lng[0] = grp->hdr.oid; +} + +/* hash: a htsi_t, keyed with indirect spicelib groups are stored in the + indirect/purpose=spicelib group's backend_data->ptr[0]; this is used + for quick lookup of spicelib_name -> grp; key is grp->loclib_name (not + alloced/free'd for the hash table). backend_data->ptr[0] points + to the indirect/purpose=spicelib grp */ +static void spicelib_sheet_init_(rnd_design_t *hl, csch_lib_t *root_dir, const csch_cgrp_t *spicelib_root) +{ + if (root_dir->backend_data.ptr[0] == NULL) { + htip_entry_t *e; + htsp_t *map; + + map = root_dir->backend_data.ptr[0] = htsp_alloc(strhash, strkeyeq); + root_dir->backend_data.ptr[1] = (void *)spicelib_root; + + for(e = htip_first(&spicelib_root->id2obj); e != NULL; e = htip_next(&spicelib_root->id2obj, e)) { + csch_cgrp_t *grp = e->value; + if (grp->hdr.type == CSCH_CTYPE_GRP) + spicelib_local_ins(map, root_dir, grp); + } + } +} + +static int spicelib_mod_map_local(rnd_design_t *hl, csch_lib_t *root_dir, const csch_cgrp_t *indirect) +{ + csch_sheet_t *sheet = (csch_sheet_t *)hl; + const csch_cgrp_t *root_grp; + + /* do not automatically create a local spicelib dir (we are at opening a sheet) */ + root_grp = csch_loclib_get_root(sheet, spicelibmaster, NULL, 0, NULL); + if (root_grp != NULL) + spicelib_sheet_init_(hl, root_dir, root_grp); + + return 0; +} + +static void spicelib_sheet_init(csch_sheet_t *sheet, csch_lib_t **root_dir_out, int alloc) +{ + csch_lib_t *root_dir = NULL; + int alloced; + csch_cgrp_t *root_grp; + csch_source_arg_t *src; + + src = csch_attrib_src_p("spicelib", NULL); + if (csch_loclib_get_roots(&root_dir, &root_grp, spicelibmaster, sheet, src, alloc, &alloced) == 0) + spicelib_sheet_init_(&sheet->hidlib, root_dir, root_grp); + + if (root_dir_out != NULL) + *root_dir_out = root_dir; +} + +static void spicelib_sheet_uninit(csch_lib_t *root_dir) +{ + csch_cgrp_t *symlib = root_dir->backend_data.ptr[1]; + + if (symlib == NULL) return; + + htsp_free(root_dir->backend_data.ptr[0]); + + root_dir->backend_data.ptr[0] = NULL; + root_dir->backend_data.ptr[1] = NULL; +} + +static int spicelib_mod_load(csch_sheet_t *sheet, void *dst_, csch_lib_t *src, const char *params) +{ + /* real loading happens through spicelib_lib_lookup(); this is called from the + lib window (will be needed for the preview) */ + return -1; +} + +static void spicelib_mod_free(csch_lib_t *src) +{ + csch_lib_t *root_dir = src->parent; + if (root_dir != NULL) { + htsp_t *map = root_dir->backend_data.ptr[0]; + if (map != NULL) + htsp_pop(map, src->name); + } + else + spicelib_sheet_uninit(src); /* src is a root dir */ +} + + +static const char *spicelib_get_from_loclib(csch_sheet_t *sheet, const char *spicelib_name) +{ + csch_lib_t *root_dir; + csch_cgrp_t *gd; + htsp_t *map; + + spicelib_sheet_init(sheet, &root_dir, 0); + + if ((root_dir == NULL) || (root_dir->backend_data.ptr[0] == NULL)) + return NULL; + + map = root_dir->backend_data.ptr[0]; + + gd = htsp_get(map, spicelib_name); +/*rnd_trace("*** get: map=%p '%s' -> %p\n", map, spicelib_name, gd);*/ + if (gd == NULL) + return NULL; + + return csch_attrib_get_str(&gd->attr, "spice/model_card"); +} + +static void spicelib_set_attr_in_loclib(csch_sheet_t *sheet, csch_cgrp_t *dst, gds_t *dma) +{ + csch_source_arg_t *src = csch_attrib_src_p("spicelib", "external lib"); + + csch_attrib_set(&dst->attr, CSCH_ATP_USER_DEFAULT, "spice/model_card", dma->array, src, NULL); + csch_sheet_set_changed(sheet, 1); +} + +void spicelib_set_in_loclib(csch_sheet_t *sheet, const char *spicelib_name, gds_t *dma) +{ + csch_lib_t *root_dir; + csch_cgrp_t *spicelib_root; + htsp_t *map; + csch_cgrp_t *gd; + + spicelib_sheet_init(sheet, &root_dir, 1); + + map = root_dir->backend_data.ptr[0]; + spicelib_root = root_dir->backend_data.ptr[1]; + + if ((map == NULL) || (spicelib_root == NULL)) { + rnd_message(RND_MSG_ERROR, "Failed to create spicelib local lib root for sheet %s\nNot building a local lib, sheet is not portable.\n", sheet->hidlib.loadname); + return; + } + + gd = csch_cgrp_alloc(sheet, spicelib_root, csch_oid_new(sheet, spicelib_root)); + if (gd == NULL) { + rnd_message(RND_MSG_ERROR, "Failed to create spicelib local lib entry for %s in sheet %s\nNot building a local lib, sheet is not portable.\n", spicelib_name, sheet->hidlib.loadname); + return; + } + + + gd->loclib_name = rnd_strdup(spicelib_name); + spicelib_set_attr_in_loclib(sheet, gd, dma); + + spicelib_local_ins(map, root_dir, gd); + rnd_event(&sheet->hidlib, CSCH_EVENT_LIBRARY_CHANGED, NULL); + +/*rnd_trace("*** set: map=%p '%s' -> %p\n", map, gd->loclib_name, gd);*/ + + +} + + +static int spicelib_loc_refresh_from_ext(csch_sheet_t *sheet, csch_lib_t *src) +{ + csch_lib_t *root_dir = src->parent; + htsp_t *map; + ldch_data_t *data; + csch_hook_call_ctx_t cctx = {0}; + csch_cgrp_t *old; + spicelib_t *spicelib; + + map = root_dir->backend_data.ptr[0]; + old = htsp_get(map, src->name); + if (old == NULL) { + rnd_message(RND_MSG_ERROR, "spicelib loclib internal error: can't find spicelib '%s'\n", src->name); + return -1; + } + + /* check if it is loadable from the external lib */ + data = ldch_load_(&global_spicelib_ctx->spicelibs, src->name, global_spicelib_ctx->low_parser, global_spicelib_ctx->high_parser, NULL, &cctx); + if (data == NULL) { + rnd_message(RND_MSG_ERROR, "Can't find spicelib '%s' in the external spicelib lib\n", src->name); + return -1; + } + + spicelib = (spicelib_t *)&data->payload; + spicelib_set_attr_in_loclib(sheet, old, spicelib->text); + return 0; +} + + +static long loc_list_recurse(csch_cgrp_t *grp, const char *spicelib_name, vtp0_t *res) +{ + long sum = 0; + htip_entry_t *e; + const char *spiceliba; + + spiceliba = csch_attrib_get_str(&grp->attr, "spicelib"); + if ((spiceliba != NULL) && (strcmp(spiceliba, spicelib_name) == 0)) { + vtp0_append(res, grp); + sum++; + } + + for(e = htip_first(&grp->id2obj); e != NULL; e = htip_next(&grp->id2obj, e)) { + csch_cgrp_t *child = e->value; + if (csch_obj_is_grp(&child->hdr)) + sum += loc_list_recurse(child, spicelib_name, res); + } + return sum; +} + + +static int spicelib_loc_list(csch_sheet_t *sheet, csch_lib_t *src) +{ + long cnt; + vtp0_t arr = {0}; + + cnt = loc_list_recurse(&sheet->direct, src->name, &arr); + rnd_message(RND_MSG_INFO, "Found %ld references to spicelib %s\n", cnt, src->name); + + if (cnt > 0) { + fgw_arg_t args[4], ares; + + args[1].type = FGW_STR; args[1].val.str = "objarr"; + fgw_ptr_reg(&rnd_fgw, &args[2], CSCH_PTR_DOMAIN_COBJ_ARR, FGW_PTR | FGW_STRUCT, &arr); + rnd_actionv_bin(&sheet->hidlib, "TreeDialog", &ares, 3, args); + fgw_ptr_unreg(&rnd_fgw, &args[2], CSCH_PTR_DOMAIN_COBJ_ARR); + vtp0_uninit(&arr); + } + + return 0; +} Index: tags/1.0.5/src/plugins/target_spice/mod_parse.c =================================================================== --- tags/1.0.5/src/plugins/target_spice/mod_parse.c (nonexistent) +++ tags/1.0.5/src/plugins/target_spice/mod_parse.c (revision 10414) @@ -0,0 +1,102 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - spice target + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/*** spice module parser ***/ + +static void parse_error(void *ectx, lht_node_t *n, const char *msg) +{ + rnd_message(RND_MSG_ERROR, "spicelib: parse error '%s' near %ld:%ld\n", msg, n->line, n->col); +} + +static ldch_data_t *spicelib_parse(ldch_high_parser_t *parser, void *call_ctx, ldch_file_t *file) +{ + gds_t *low = (gds_t *)&file->low_payload; + ldch_data_t *data = NULL; + spicelib_t *spicelib; + + data = ldch_data_alloc(file, parser, sizeof(spicelib_t)); + spicelib = (spicelib_t *)&data->payload; + spicelib->text = low; + return data; +} + +static void spicelib_free_payload(ldch_data_t *data) +{ + spicelib_t *spicelib = (spicelib_t *)&data->payload; + gds_uninit(spicelib->text); +} + + +/* called when the file is first loaded; should allocate (ldch_file_t *) */ +static ldch_file_t *ldspice_parse_alloc(ldch_low_parser_t *parser, void *call_ctx, const char *fn) +{ + return ldch_file_alloc(parser->ctx, parser, sizeof(gds_t)); +} + +/* called after parse_alloc() on initial load or after free_payload() on reload */ +static int ldspice_parse(ldch_low_parser_t *parser, void *call_ctx, ldch_file_t *file, const char *fn) +{ + FILE *f; + gds_t *payload = (gds_t *)&file->low_payload; + + f = rnd_fopen(NULL, fn, "r"); + if (f == NULL) + return -1; + + for(;;) { + char tmp[4096]; + size_t len; + + len = fread(tmp, 1, sizeof(tmp), f); + if (len <= 0) + break; + + gds_append_len(payload, tmp, len); + } + + fclose(f); + return 0; +} + +/* should free the in-memory document/parse-tree; a call to parse() may follow when reloading */ +static void ldspice_free_payload(ldch_low_parser_t *low, ldch_file_t *file) +{ + gds_t *payload = (gds_t *)&file->low_payload; + gds_uninit(payload); +} + +static ldch_low_parser_t *spicelib_reg_low_parser(ldch_ctx_t *ctx) +{ + ldch_low_parser_t *p = ldch_reg_low_parser(ctx, "spice"); + + p->parse_alloc = ldspice_parse_alloc; + p->parse = ldspice_parse; + p->free_payload = ldspice_free_payload; + + return p; +} Index: tags/1.0.5/src/plugins/target_spice/preview.c =================================================================== --- tags/1.0.5/src/plugins/target_spice/preview.c (nonexistent) +++ tags/1.0.5/src/plugins/target_spice/preview.c (revision 10414) @@ -0,0 +1,48 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - spice target + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +static char *spicelib_mod_preview_text(csch_sheet_t *sheet, csch_lib_t *src, const char *parametric) +{ + const char *mod; + long oid = src->backend_data.lng[0]; + + if (oid == 0) { + /* external lib */ + csch_hook_call_ctx_t cctx = {0}; + + cctx.project = (csch_project_t *)sheet->hidlib.project; + mod = spicelib_get_extlib(global_spicelib_ctx, src->realpath, &cctx, 0, NULL); + } + else { + /* local lib */ + mod = spicelib_get_from_loclib(sheet, src->name); + } + + return rnd_strdup(mod == NULL ? "" : mod); +} + Index: tags/1.0.5/src/plugins/target_spice/target_spice.c =================================================================== --- tags/1.0.5/src/plugins/target_spice/target_spice.c (nonexistent) +++ tags/1.0.5/src/plugins/target_spice/target_spice.c (revision 10414) @@ -0,0 +1,898 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - spice target + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "htcp.h" +#include "target_spice_conf.h" +#include "conf_internal.c" + +static conf_target_spice_t target_spice_conf; + +typedef struct { + ldch_ctx_t spicelibs; + csch_view_eng_t *eng; + ldch_low_parser_t *low_parser; + ldch_high_parser_t *high_parser; + vtp0_t ssyms; + htcp_t shared_ports; /* key is comp-term, value is a vtp0_t of ports in different slots */ + htsp_t bridged_ports; /* ports that need brindging; key is bridge model name (assuming vector bridges), value is vtp0_t of (csch_aport_t *) */ + unsigned compiling:1; +} spicelib_ctx_t; /* per view data */ + +typedef struct spicelib_s { + gds_t *text; +} spicelib_t; + +static spicelib_ctx_t *global_spicelib_ctx = NULL; + +static const char cookie[] = "target_spice"; +static const char spicelib_cookie[] = "target_spice/spicelib"; +static csch_lib_backend_t be_spicelib_mod; +static csch_lib_master_t *spicelibmaster; + +const char csch_acts_quick_attr_spice__model[] = "quick_attr_spice__model(objptr)"; +const char csch_acth_quick_attr_spice__model[] = "Quick Attribute Edit for spice/model using the devmap library"; +fgw_error_t csch_act_quick_attr_spice__model(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_design_t *hidlib = RND_ACT_DESIGN; + csch_sheet_t *sheet = (csch_sheet_t *)hidlib; + csch_cgrp_t *grp; + fgw_arg_t ares, args[4]; + int ret; + + QUICK_ATTR_GET_GRP(grp, "quick_attr_spice__model"); + + args[1].type = FGW_STR; + args[1].val.cstr = "spicelib"; + args[2].type = FGW_STR; + args[2].val.cstr = "sheet"; + args[3].type = FGW_STR; + args[3].val.cstr = "modal"; + + ret = rnd_actionv_bin(&sheet->hidlib, "librarydialog", &ares, 4, args); + if ((ret == 0) && ((ares.type & FGW_STR) == FGW_STR)) { + csch_source_arg_t *src; + char *path = ares.val.str, *sep = NULL; + + if ((path != NULL) && (*path != '\0')) + sep = strrchr(path, '/'); + if (sep != NULL) { + char *end = strrchr(sep+1, '.'); + if ((end != NULL) && ((rnd_strcasecmp(end, ".prm") == 0) || (rnd_strcasecmp(end, ".mod") == 0))) + *end = '\0'; + + src = csch_attrib_src_p("tagret_spice", "manually picked from the model lib"); + csch_attr_modify_str(sheet, grp, -CSCH_ATP_USER_DEFAULT, "spice/model", sep+1, src, 1); +/* rnd_trace("new devmap val: '%s'\n", sep+1);*/ + } + } + fgw_arg_free(&rnd_fgw, &ares); + + + RND_ACT_IRES(1); + return 0; +} + +static void spicelib_sheet_postload_ev(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + csch_sheet_t *sheet = (csch_sheet_t *)hidlib; + csch_lib_add_all(sheet, spicelibmaster, &target_spice_conf.plugins.target_spice.search_paths, 0); + csch_lib_add_local(sheet, spicelibmaster); +} + +#include "mod_parse.c" +#include "loclib.c" +#include "libs.c" +#include "preview.c" + + +/*** hooks ***/ + +#define SLOTSEP "__" + +/* Return the slot value of a symbol */ +static const char *get_slot(csch_cgrp_t *sym) +{ + const char *slot = csch_attrib_get_str(&sym->attr, "-slot"); + + if (slot == NULL) + slot = csch_attrib_get_str(&sym->attr, "slot"); + return slot; +} + +/* Return the slot value of a component (looking back at source symbols) */ +static const char *get_aslot(csch_acomp_t *comp) +{ + long n; + + for(n = 0; n < comp->hdr.srcs.used; n++) { + csch_cgrp_t *sym = comp->hdr.srcs.array[n]; + if (csch_obj_is_grp(&sym->hdr)) { + const char *slot = get_slot(sym); + if (slot != NULL) + return slot; + } + } + + return NULL; +} + + +fgw_error_t target_spice_sym2comp(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + csch_cgrp_t *sym; + const char *sname, *slot; + csch_hier_path_t *hpath; + gds_t tmp; + + CSCH_HOOK_CONVARG(1, FGW_STR, target_spice_sym2comp, sname = argv[1].val.cstr); + CSCH_HOOK_CONVARG(2, FGW_COBJ, target_spice_sym2comp, sym = fgw_cobj(&argv[2])); + CSCH_HOOK_CONVARG(3, FGW_HPATH, target_spice_sym2comp, hpath = fgw_hpath(&argv[3])); + + slot = get_slot(sym); + if (slot == NULL) + return 0; + + /* output port name is slot/input port name */ + gds_init(&tmp); + if (hpath->prefix.used > 0) { + gds_append(&tmp, sname[0]); + gds_append_len(&tmp, hpath->prefix.array, hpath->prefix.used); + } + gds_append_str(&tmp, sname); + gds_append_str(&tmp, SLOTSEP); + gds_append_str(&tmp, slot); + gds_append(&tmp, '\n'); + gds_append_str(&tmp, sname); + gds_append_str(&tmp, SLOTSEP); + gds_append_str(&tmp, slot); + res->type = FGW_STR | FGW_DYN; + res->val.str = tmp.array; + return 0; + +} + + +fgw_error_t target_spice_compile_port(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ +/* csch_hook_call_ctx_t *cctx = argv[0].val.argv0.user_call_ctx;*/ + fgw_obj_t *obj = argv[0].val.argv0.func->obj; + spicelib_ctx_t *ctx = obj->script_data; + csch_view_eng_t *eng = ctx->eng; + csch_aport_t *port; + const char *pinnum, *bridgemod; + csch_source_arg_t *src; + + + CSCH_HOOK_CONVARG(1, FGW_AOBJ, std_cschem_comp_update, port = fgw_aobj(&argv[1])); + assert(port->hdr.type == CSCH_ATYPE_PORT); + + /* remember bridged ports, per bridge model type */ + bridgemod = csch_attrib_get_str(&port->hdr.attr, "spice/bridge/model"); + if (bridgemod != NULL) { + htsp_entry_t *e = htsp_getentry(&ctx->bridged_ports, bridgemod); + vtp0_t *plist; + + if (e == NULL) { + plist = calloc(sizeof(vtp0_t), 1); + htsp_set(&ctx->bridged_ports, (char *)bridgemod, (void *)plist); + } + else + plist = e->value; + vtp0_append(plist, port); + } + + /* figure pin number */ + pinnum = csch_attrib_get_str(&port->hdr.attr, "spice/pinnum"); + if (pinnum != NULL) + src = csch_attrib_src_pa(&port->hdr, "spice/pinnum", "target_spice", NULL); + + if (pinnum == NULL) { + pinnum = csch_attrib_get_str(&port->hdr.attr, "pinnum"); + if (pinnum != NULL) + src = csch_attrib_src_pa(&port->hdr, "pinnum", "target_spice", NULL); + } + if (pinnum == NULL) { + pinnum = port->name; + if (pinnum != NULL) + src = csch_attrib_src_p("target_spice", "fallback on port name"); + } + + /* Calculate final name */ + if (pinnum != NULL) + csch_attrib_set(&port->hdr.attr, eng->eprio + CSCH_PRI_PLUGIN_NORMAL, "display/name", pinnum, src, NULL); + + /* remember shared ports */ + if (pinnum != NULL) { + const char *shared = csch_attrib_get_str(&port->hdr.attr, "spice/shared"); + if (shared != NULL) { + htcp_key_t shkey; + htcp_entry_t *e; + + shkey.orig_comp_name = csch_attrib_get_str(&port->parent->hdr.attr, "name"); + if (shkey.orig_comp_name != NULL) { + shkey.pinnum = strtol(pinnum, NULL, 10); + + e = htcp_getentry(&ctx->shared_ports, shkey); + if (e == NULL) { + htcp_value_t tmp = {0}; + htcp_set(&ctx->shared_ports, shkey, tmp); + e = htcp_getentry(&ctx->shared_ports, shkey); + } + vtp0_append(&e->value.ports, port); + } + } + } + + return 0; +} + +/* Returns whether model_card's first model is a subckt */ +static int model_is_subckt(const char *model_card, const char *model_name) +{ + const char *curr, *next; + for(curr = model_card; curr != NULL; curr = next) { + next = strchr(curr, '\n'); + if (next != NULL) + next++; + while(isspace(*curr)) curr++; + if (rnd_strncasecmp(curr, ".subckt", 7) == 0) + return 1; + if (rnd_strncasecmp(curr, ".model", 6) == 0) + return 0; + } + return 0; +} + +/* Create a component for a reusable (lib) model card */ +static csch_acomp_t *make_acomp_for_model_card(spicelib_ctx_t *ctx, csch_acomp_t *comp, const char *modcompname, const char *model_name, const char *model_card, int *is_subckt_out, int set_uname) +{ + csch_source_arg_t *src; + char *freeme = NULL; + const char *existing; + csch_acomp_t *modcomp; + + if (modcompname == NULL) + modcompname = freeme = rnd_concat("_spice_model_card_", model_name, NULL); + + modcomp = csch_acomp_get(comp->hdr.abst, modcompname); + if (modcomp == NULL) + modcomp = csch_acomp_new(comp->hdr.abst, comp->hdr.abst->hroot, CSCH_ASCOPE_GLOBAL, modcompname, modcompname); + if (modcomp == NULL) + return NULL; + + if (set_uname) { + char *uname = rnd_concat("schrnd_", modcompname, NULL); + src = csch_attrib_src_p("target_spice", "model card copied from lib"); + csch_attrib_set(&comp->hdr.attr, 0, "spice/model_card_uname", uname, src, NULL); + free(uname); + } + + existing = csch_attrib_get_str(&modcomp->hdr.attr, "spice/model_card"); + if (existing != NULL) { + const char *s_is_subckt = csch_attrib_get_str(&modcomp->hdr.attr, "spice/model_is_subckt"); + if (strcmp(existing, model_card) != 0) + rnd_message(RND_MSG_ERROR, "target spice: internal error: model card mismatch for %s\n", comp->name); + *is_subckt_out = ((s_is_subckt != NULL) && (s_is_subckt[0] == '1')); + } + else { + src = csch_attrib_src_p("target_spice", "model card copied from lib"); + csch_attrib_set(&modcomp->hdr.attr, 0, "spice/model_card", model_card, src, NULL); + + *is_subckt_out = model_is_subckt(model_card, model_name); + src = csch_attrib_src_p("target_spice", "parsed from model card"); + csch_attrib_set(&modcomp->hdr.attr, 0, "spice/model_is_subckt", ((*is_subckt_out) ? "1" : "0"), src, NULL); + } + free(freeme); + return modcomp; +} + +fgw_error_t target_spice_compile_component0(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + fgw_obj_t *obj = argv[0].val.argv0.func->obj; + spicelib_ctx_t *ctx = obj->script_data; + csch_view_eng_t *eng = ctx->eng; + csch_acomp_t *comp; + + CSCH_HOOK_CONVARG(1, FGW_AOBJ, std_cschem_comp_update, comp = fgw_aobj(&argv[1])); + + sch_trgt_copy_alt_attrib(&comp->hdr, eng->eprio + CSCH_PRI_PLUGIN_NORMAL, "target_spice", "display/omit", "spice/omit", "omit", NULL); + return 0; +} + + +fgw_error_t target_spice_compile_component1(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ +/* csch_hook_call_ctx_t *cctx = argv[0].val.argv0.user_call_ctx;*/ + fgw_obj_t *obj = argv[0].val.argv0.func->obj; + spicelib_ctx_t *ctx = obj->script_data; + csch_view_eng_t *eng = ctx->eng; + csch_acomp_t *comp; + const char *prefix, *name, *slot; + csch_attrib_t *portmap, *amodel; + char *tmp; + csch_source_arg_t *src; + const char *model_card, *shprefix; + int is_subckt = 0; + gds_t hprefix = {0}; + + + CSCH_HOOK_CONVARG(1, FGW_AOBJ, std_cschem_comp_update, comp = fgw_aobj(&argv[1])); + assert(comp->hdr.type == CSCH_ATYPE_COMP); + + + model_card = csch_attrib_get_str(&comp->hdr.attr, "spice/model_card"); + if (model_card != NULL) { + char *uname = rnd_concat("schrnd_", comp->name, NULL); + + src = csch_attrib_src_p("target_spice", "model card copied from symbol"); + csch_attrib_set(&comp->hdr.attr, 0, "spice/model_card_uname", uname, src, NULL); + free(uname); + } + else { + amodel = csch_attrib_get(&comp->hdr.attr, "spice/model"); + if (amodel != NULL) { + const char *model_name = (amodel->val == NULL ? "" : amodel->val); + const char *model_card; + model_card = spicelib_get_from_any_lib_for_comp(ctx, comp, amodel, obj); + if (model_card != NULL) + make_acomp_for_model_card(ctx, comp, NULL, model_name, model_card, &is_subckt, 1); + else + rnd_message(RND_MSG_ERROR, "Can't find spicelib model card %s for component %s\n", model_name, comp->name); + } + } + + + /* this component1() runs before ports are compiled for the component, so + it is safe to set up the portmap here */ + portmap = csch_attrib_get(&comp->hdr.attr, "spice/portmap"); + if (portmap != NULL) { + /* rnd_trace("spice pm: %s\n", comp->name);*/ + src = csch_attrib_src_p("target_spice", "acquired from spice/portmap"); + csch_compile_attribute(&comp->hdr, "portmap", portmap, src, "component", comp->name, 0, 1, NULL); + } + + + /* Set 'X' prefix for subcircuit models on normal engine prio; lets the + user both override and fallback it with different prios (250 and 31050) */ + if (is_subckt) { + prefix = "X"; + src = csch_attrib_src_p("target_spice", "model is a subcircuit"); + csch_attrib_set(&comp->hdr.attr, eng->eprio + CSCH_PRI_PLUGIN_NORMAL, "spice/prefix", "X", src, NULL); + } + + prefix = csch_attrib_get_str(&comp->hdr.attr, "spice/prefix"); + if (prefix == NULL) + return 0; + + name = csch_attrib_get_str(&comp->hdr.attr, "display/name"); + if (name == NULL) + name = csch_attrib_get_str(&comp->hdr.attr, "name"); + if (name == NULL) + name = comp->name; + + /* do not prefix if no need to */ + if (*name == *prefix) + return 0; + +/* rnd_trace("spice rename: name='%s' prefix='%s'\n", name, prefix);*/ + + /* compute hierarchic prefix */ + if (comp->hlev->parent != NULL) { + csch_hier_build_path(&hprefix, comp->hlev); + shprefix = hprefix.array; + } + else + shprefix =""; + + src = csch_attrib_src_p("target_spice", "instance prefix from spice/prefix"); + slot = get_aslot(comp); + if (slot != NULL) + tmp = rnd_concat(prefix, "_", shprefix, name, SLOTSEP, slot, NULL); + else + tmp = rnd_concat(prefix, "_", shprefix, name, NULL); + + csch_attrib_set(&comp->hdr.attr, eng->eprio + CSCH_PRI_PLUGIN_NORMAL, "display/name", tmp, src, NULL); + gds_uninit(&hprefix); + free(tmp); + + return 0; +} + +fgw_error_t target_spice_compile_project_before(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ +/* csch_hook_call_ctx_t *cctx = argv[0].val.argv0.user_call_ctx;*/ + fgw_obj_t *obj = argv[0].val.argv0.func->obj; + spicelib_ctx_t *ctx = obj->script_data; + + assert(!ctx->compiling); /* we are not reentrant */ + ctx->compiling = 1; + htcp_init(&ctx->shared_ports, htcp_keyhash, htcp_keyeq); + htsp_init(&ctx->bridged_ports, strhash, strkeyeq); + return 0; +} + +#define MAXSC (1L<<30) +#define SCORE(x) (MAXSC-1000L+x) + +static void elect_net_zero(spicelib_ctx_t *ctx, csch_abstract_t *abst) +{ + csch_view_eng_t *eng = ctx->eng; + csch_source_arg_t *src; + csch_anet_t *best = NULL; + long score = 0; /* higher value is more preferred */ + htsp_entry_t *e; + int warn = 1; + + for(e = htsp_first(&abst->nets); e != NULL; e = htsp_next(&abst->nets, e)) { + csch_anet_t *net = e->value; + const char *attr = csch_attrib_get_str(&net->hdr.attr, "spice/gnd"); + if (attr != NULL) { + if (score < MAXSC) { + score = MAXSC; + best = net; + warn = 0; + /* keep on searching to find redundant spice/gnd attrs */ + } + else + rnd_message(RND_MSG_ERROR, "Multiple nets are marked with spice/gnd: %s and %s\n", best->name, net->name); + } + else { + if ((score < SCORE(100)) && (rnd_strcasecmp(net->name, "gnd") == 0)) { + score = SCORE(100); + best = net; + warn = 0; + } + else if ((SCORE(score) < 90) && ((strstr(net->name, "gnd") != NULL) || (strstr(net->name, "GND") != NULL))) { + score = SCORE(90); + best = net; + } + else if (net->conns.used > score) { + /* if name doesn't elect a gnd net, go for the largest net */ + score = net->conns.used; + best = net; + } + } + } + + if (score >= MAXSC) + return; /* do not set attribute if we got one already */ + + if (best == NULL) { + rnd_message(RND_MSG_ERROR, "Failed to elect gnd net (node 0). Spice needs at least 2 nets, one being the gnd.\n"); + return; + } + + if (warn) + rnd_message(RND_MSG_WARNING, "Spice needs a ground net, also known as node 0.\nIt's best to select it by setting spice/gnd attribute on a net.\nThere was no such net, my best bet for gnd is net %s\n", best->name); + + src = csch_attrib_src_p("target_spice", "elected gnd (node 0) net"); + csch_attrib_set(&best->hdr.attr, eng->eprio + CSCH_PRI_PLUGIN_NORMAL, "spice/gnd", "elected", src, NULL); +} + +#undef MAXSC +#undef SCORE + +static void shared_port_connect(spicelib_ctx_t *ctx, csch_abstract_t *abst) +{ + htcp_entry_t *e; + + /* find all shared ports among components and copy their connections */ + for(e = htcp_first(&ctx->shared_ports); e != NULL; e = htcp_next(&ctx->shared_ports, e)) { + long n; + csch_anet_t *net = NULL; + + /* find the net that's connected */ + for(n = 0; n < e->value.ports.used; n++) { + csch_aport_t *port = e->value.ports.array[n]; + if (port->conn.net != NULL) { + net = port->conn.net; + break; + } + } + + /* if there's a net, connect any unconnected ports there and warn for ports connected elsewhere */ + if (net != NULL) { + for(n = 0; n < e->value.ports.used; n++) { + csch_aport_t *port = e->value.ports.array[n]; + if ((port->conn.net == NULL) || (port->conn.net != net)) { + if (csch_compile_connect_net_to(&net, &port->hdr, 1) != 0) + rnd_message(RND_MSG_ERROR, "target_spice: shared port %s-%s failed to connect to %s\n", port->parent->name, port->name, net->name); + } + } + } + + vtp0_uninit(&e->value.ports); + } + + htcp_uninit(&ctx->shared_ports); +} + +/* Create a model card and a component instance for a bridge; return + the bridge component or NULL on error. Also set *is_subckt depending + on model type (1=subckt, 0=model) */ +static csch_acomp_t *make_bridge_comp(spicelib_ctx_t *ctx, csch_abstract_t *abst, csch_project_t *prj, const char *model_name, const char *brname, int *is_subckt, int multi) +{ + csch_view_eng_t *eng = ctx->eng; + csch_source_arg_t *src; + csch_acomp_t *br; + void *obj = NULL; + const char *model_card = spicelib_get_from_any_lib_for_project(ctx, prj, model_name, obj); + + if (model_card != NULL) { + const char *compname; + csch_acomp_t dummy = {0}; + + dummy.hdr.abst = abst; + dummy.name = "(auto-bridge)"; + + compname = multi ? brname : model_name; + br = make_acomp_for_model_card(ctx, &dummy, compname, model_card, model_card, is_subckt, 0); + } + else { + rnd_message(RND_MSG_ERROR, "Can't find spicelib model card %s for auto-bridge\n", model_name); + return NULL; + } + + src = csch_attrib_src_p("target_spice", "automatic bridge (port attrib)"); + csch_attrib_set(&br->hdr.attr, eng->eprio + CSCH_PRI_PLUGIN_NORMAL, "display/name", brname, src, NULL); + + src = csch_attrib_src_p("target_spice", "automatic bridge (port attrib)"); + csch_attrib_set(&br->hdr.attr, eng->eprio + CSCH_PRI_PLUGIN_NORMAL, "spice/model_card_uname", model_name, src, NULL); + + return br; +} + +/* Return model basename and figure default model direction */ +static const char *bridge_model_suffix(const char *model_name, int *straight_by_model) +{ + const char *end = strrchr(model_name, '/'); + if (end == NULL) + end = model_name; + + /* reverse order of pins in dac by default, assuming bridging is done + on the digital side */ + if ((strstr(model_name, "dac") != NULL) || (strstr(model_name, "DAC") != NULL)) + *straight_by_model = 0; + else + *straight_by_model = 1; + + return end; +} + +static void bridge_insert(spicelib_ctx_t *ctx, csch_abstract_t *abst, csch_aport_t *port, csch_acomp_t *br, const char *pn1, const char *pn2, const char *modelsuff, long puid, int straight_by_model, gds_t *tmp) +{ + csch_source_arg_t *src; + csch_view_eng_t *eng = ctx->eng; + + csch_anet_t *new_net, *old_net; + csch_aport_t *brp_in, *brp_out; + char *netname, pname[128]; + int straight; + + /* create a new net (to be in between the bridge and the port) */ + tmp->used = 0; + rnd_append_printf(tmp, "br_%s_%ld", modelsuff, puid); + netname = tmp->array; + new_net = csch_anet_new(abst, NULL, CSCH_ASCOPE_GLOBAL, netname, netname, 1); + +/*rnd_trace(" net: '%s' %p\n", netname, new_net);*/ + old_net = port->conn.net; + csch_compile_disconnect(&port->hdr); + csch_compile_connect_net_to(&new_net, &port->hdr, 1); + + sprintf(pname, "s1p%ld", puid); + brp_in = csch_aport_get(abst, br, pname, 1); + src = csch_attrib_src_p("target_spice", "automatic bridge (port attrib)"); + csch_attrib_set(&brp_in->hdr.attr, eng->eprio + CSCH_PRI_PLUGIN_NORMAL, "display/name", pn1, src, NULL); + + sprintf(pname, "s2p%ld", puid); + brp_out = csch_aport_get(abst, br, pname, 1); + src = csch_attrib_src_p("target_spice", "automatic bridge (port attrib)"); + csch_attrib_set(&brp_out->hdr.attr, eng->eprio + CSCH_PRI_PLUGIN_NORMAL, "display/name", pn2, src, NULL); + + /* detect ordering - use the one suggested by the model's name but let + the user override it. */ + { + const char *dir = csch_attrib_get_str(&port->hdr.attr, "spice/bridge/dir"); + + straight = straight_by_model; + if (dir != NULL) { + int err = 0; + switch(dir[0]) { + case 'n': case 'N': + switch(dir[1]) { + case '1': straight = 1; break; /* n1p2 */ + case '2': straight = 0; break; /* n2p1 */ + default: err = 1; + } + break; + case 'p': case 'P': + switch(dir[1]) { + case '1': straight = 0; break; /* p1n2 */ + case '2': straight = 1; break; /* p2n1 */ + default: err = 1; + } + break; + default: + err = 1; + } + if (err) + rnd_message(RND_MSG_ERROR, "Invalid spice/bridge/dir on component %s port %s: '%s'; should be n1p2 or p1n2\n", port->parent->name, port->name, dir); + } + } + + /* hook up an input and and output port of the bridge */ + if (straight) { /* net -> bridge[1] -> bridge[2] -> port */ + csch_compile_connect_net_to(&new_net, &brp_out->hdr, 1); + csch_compile_connect_net_to(&old_net, &brp_in->hdr, 1); + } + else { /* net -> bridge[2] -> bridge[1] -> port */ + csch_compile_connect_net_to(&new_net, &brp_in->hdr, 1); + csch_compile_connect_net_to(&old_net, &brp_out->hdr, 1); + } +} + + +/* Insert a vector bridge between ports and their nets (disconnecting the ports); + create one bridge component per bridge type, use vector ports */ +static void install_vector_bridges(spicelib_ctx_t *ctx, csch_abstract_t *abst, csch_project_t *prj) +{ + htsp_entry_t *e; + gds_t tmp = {0}; + + for(e = htsp_first(&ctx->bridged_ports); e != NULL; e = htsp_next(&ctx->bridged_ports, e)) { + csch_acomp_t *br; + vtp0_t *plist = e->value; + int is_subckt = 0, straight_by_model = 1; + long n; + const char *model_name = e->key, *end, *brname; + +/* rnd_trace("BRIDGED: %s has %d ports\n", model_name, plist->used);*/ + + end = bridge_model_suffix(model_name, &straight_by_model); + + tmp.used = 0; + rnd_append_printf(&tmp, "A_sch_rnd_br_%s", end); + brname = tmp.array; + + br = make_bridge_comp(ctx, abst, prj, model_name, brname, &is_subckt, 0); + if (br == NULL) + continue; + + for(n = 0; n < plist->used; n++) + bridge_insert(ctx, abst, plist->array[n], br, "[1]", "[2]", end, n, straight_by_model, &tmp); + + vtp0_uninit(plist); + free(plist); + e->value = NULL; + } + htsp_uninit(&ctx->bridged_ports); + gds_uninit(&tmp); +} + +/* Insert a scalar bridge between ports and their nets (disconnecting the ports); + create one bridge component per port */ +static void install_scalar_bridges(spicelib_ctx_t *ctx, csch_abstract_t *abst, csch_project_t *prj) +{ + htsp_entry_t *e; + gds_t tmp = {0}; + unsigned long bruid = 0; + + for(e = htsp_first(&ctx->bridged_ports); e != NULL; e = htsp_next(&ctx->bridged_ports, e)) { + csch_acomp_t *br; + vtp0_t *plist = e->value; + int is_subckt = 0, straight_by_model = 1; + long n; + const char *model_name = e->key, *end, *brname; + +/* rnd_trace("BRIDGED: %s has %d ports\n", model_name, plist->used);*/ + + end = bridge_model_suffix(model_name, &straight_by_model); + + + for(n = 0; n < plist->used; n++) { + tmp.used = 0; + rnd_append_printf(&tmp, "A_sch_rnd_br_%ld", bruid++); + brname = tmp.array; + + br = make_bridge_comp(ctx, abst, prj, model_name, brname, &is_subckt, 1); + if (br == NULL) { + continue; + } + + bridge_insert(ctx, abst, plist->array[n], br, "1", "2", end, n, straight_by_model, &tmp); + } + + vtp0_uninit(plist); + free(plist); + e->value = NULL; + } + htsp_uninit(&ctx->bridged_ports); + gds_uninit(&tmp); + +} + +static void target_spice_gen_net_omits(spicelib_ctx_t *ctx, csch_abstract_t *abst) +{ + htsp_entry_t *e; + csch_view_eng_t *eng = ctx->eng; + + for(e = htsp_first(&abst->nets); e != NULL; e = htsp_next(&abst->nets, e)) { + csch_anet_t *net = e->value; + + sch_trgt_copy_alt_attrib(&net->hdr, eng->eprio + CSCH_PRI_PLUGIN_NORMAL, "target_spice", "display/omit", "spice/omit", "omit", NULL); + } +} + + +fgw_error_t target_spice_compile_project_after(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ +/* csch_hook_call_ctx_t *cctx = argv[0].val.argv0.user_call_ctx;*/ + fgw_obj_t *obj = argv[0].val.argv0.func->obj; + spicelib_ctx_t *ctx = obj->script_data; + csch_abstract_t *abst; + csch_project_t *prj; + + CSCH_HOOK_CONVARG(1, FGW_STRUCT|FGW_PTR, std_cschem_comp_update, abst = argv[1].val.ptr_void); + CSCH_HOOK_CONVARG(2, FGW_STRUCT|FGW_PTR, std_cschem_comp_update, prj = argv[2].val.ptr_void); + + shared_port_connect(ctx, abst); + switch(*target_spice_conf.plugins.target_spice.bridges) { + case 'v': case 'V': install_vector_bridges(ctx, abst, prj); break; + case 's': case 'S': install_scalar_bridges(ctx, abst, prj); break; + default: /* no bridges inserted */ ; + } + elect_net_zero(ctx, abst); + target_spice_gen_net_omits(ctx, abst); + + ctx->compiling = 0; + + return 0; +} + +static int on_load(fgw_obj_t *obj, const char *filename, const char *opts) +{ + spicelib_ctx_t *ctx; + + fgw_func_reg(obj, "symbol_name_to_component_name", target_spice_sym2comp); + fgw_func_reg(obj, "compile_port", target_spice_compile_port); + fgw_func_reg(obj, "compile_component0", target_spice_compile_component0); + fgw_func_reg(obj, "compile_component1", target_spice_compile_component1); + fgw_func_reg(obj, "compile_project_before", target_spice_compile_project_before); + fgw_func_reg(obj, "compile_project_after", target_spice_compile_project_after); + + + /* initialize view-local cache */ + obj->script_data = ctx = calloc(sizeof(spicelib_ctx_t), 1); + ldch_init(&ctx->spicelibs); + ctx->eng = obj->script_user_call_ctx; + ctx->spicelibs.load_name_to_real_name = spicelib_lib_lookup; + ctx->spicelibs.user_data = obj; + ctx->low_parser = spicelib_reg_low_parser(&ctx->spicelibs); + ctx->high_parser = ldch_reg_high_parser(&ctx->spicelibs, "spicelib"); + ctx->high_parser->parse = spicelib_parse; + ctx->high_parser->free_payload = spicelib_free_payload; + + if (global_spicelib_ctx == NULL) + global_spicelib_ctx = ctx; + + + return 0; +} + +static int on_unload(fgw_obj_t *obj) +{ + spicelib_ctx_t *ctx = obj->script_data; + ldch_uninit(&ctx->spicelibs); + free(ctx); + return 0; +} + +static const fgw_eng_t fgw_target_spice_eng = { + "target_spice", + csch_c_call_script, + NULL, + on_load, + on_unload +}; + +static rnd_action_t spicelib_action_list[] = { + {"quick_attr_spice__model", csch_act_quick_attr_spice__model, csch_acth_quick_attr_spice__model, csch_acts_quick_attr_spice__model} +}; + +int pplg_check_ver_target_spice(int ver_needed) { return 0; } + +void pplg_uninit_target_spice(void) +{ + rnd_conf_plug_unreg("plugins/target_spice/", target_spice_conf_internal, cookie); + rnd_event_unbind_allcookie(spicelib_cookie); + rnd_remove_actions_by_cookie(spicelib_cookie); +} + +int pplg_init_target_spice(void) +{ + RND_API_CHK_VER; + + spicelibmaster = csch_lib_get_master("spicelib", 1); + be_spicelib_mod.name = "spicelib"; + be_spicelib_mod.realpath = spicelib_mod_realpath; + be_spicelib_mod.map = spicelib_mod_map; + be_spicelib_mod.map_local = spicelib_mod_map_local; + be_spicelib_mod.load = spicelib_mod_load; + be_spicelib_mod.preview_text = spicelib_mod_preview_text; + be_spicelib_mod.free = spicelib_mod_free; + be_spicelib_mod.loc_refresh_from_ext = spicelib_loc_refresh_from_ext; + be_spicelib_mod.loc_list = spicelib_loc_list; + + csch_lib_backend_reg(spicelibmaster, &be_spicelib_mod); + + rnd_event_bind(CSCH_EVENT_SHEET_POSTLOAD, spicelib_sheet_postload_ev, NULL, spicelib_cookie); + + fgw_eng_reg(&fgw_target_spice_eng); + + RND_REGISTER_ACTIONS(spicelib_action_list, spicelib_cookie); + + rnd_conf_plug_reg(target_spice_conf, target_spice_conf_internal, cookie); +#define conf_reg(field,isarray,type_name,cpath,cname,desc,flags) \ + rnd_conf_reg_field(target_spice_conf, field,isarray,type_name,cpath,cname,desc,flags); +#include "target_spice_conf_fields.h" + + return 0; +} + Index: tags/1.0.5/src/plugins/target_spice/target_spice.conf =================================================================== --- tags/1.0.5/src/plugins/target_spice/target_spice.conf (nonexistent) +++ tags/1.0.5/src/plugins/target_spice/target_spice.conf (revision 10414) @@ -0,0 +1,15 @@ +li:pcb-rnd-conf-v1 { + ha:append { + ha:plugins { + ha:target_spice { + bridges = vector; # default for ngspice + li:search_paths = { + ?../../library/spice + ?$(rc.path.design)/spice + ?~/.sch-rnd/spice/ + $(rc.path.share)/spice + } + } + } + } +} Index: tags/1.0.5/src/plugins/target_spice/target_spice.pup =================================================================== --- tags/1.0.5/src/plugins/target_spice/target_spice.pup (nonexistent) +++ tags/1.0.5/src/plugins/target_spice/target_spice.pup (revision 10414) @@ -0,0 +1,8 @@ +$class engine +$short attr. xform for SPICE workflow +$long Attribute transformations for the SPICE workflow +$state works +$package (core) +default buildin +dep lib_target +autoload 1 Index: tags/1.0.5/src/plugins/target_spice/target_spice_conf.h =================================================================== --- tags/1.0.5/src/plugins/target_spice/target_spice_conf.h (nonexistent) +++ tags/1.0.5/src/plugins/target_spice/target_spice_conf.h (revision 10414) @@ -0,0 +1,15 @@ +#ifndef SCH_RND_TARGET_SPICE_CONF_H +#define SCH_RND_TARGET_SPICE_CONF_H + +#include + +typedef struct { + const struct { + const struct { + RND_CFT_STRING bridges; /* what kind of bdiges to install when a port has spice/bridge/model set; one of: none, vector, scalar */ + RND_CFT_LIST search_paths; /* ordered list of paths that are each recursively searched for spice module files */ + } target_spice; + } plugins; +} conf_target_spice_t; + +#endif Index: tags/1.0.5/src/sch-rnd/Makefile.dep =================================================================== --- tags/1.0.5/src/sch-rnd/Makefile.dep (nonexistent) +++ tags/1.0.5/src/sch-rnd/Makefile.dep (revision 10414) @@ -0,0 +1,1468 @@ +### Generated file, do not edit, run make dep ### + +../plugins/act_draw/act_draw.o: ../plugins/act_draw/act_draw.c \ + ../libcschem/config.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/cnc_arc.h ../libcschem/cnc_line.h ../libcschem/cnc_text.h \ + ../libcschem/cnc_text_dyn.h ../libcschem/cnc_grp.h \ + ../libcschem/util_wirenet.h ../libcschem/operation.h \ + ../libcschem/concrete.h ../libcschem/actions_csch.h +../plugins/act_read/act_read.o: ../plugins/act_read/act_read.c \ + ../libcschem/config.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../plugins/act_read/keywords_sphash.h ../plugins/act_read/act_idpath.c \ + ../plugins/act_read/act_search.c ../sch-rnd/search.h ../sch-rnd/draw.h \ + ../sch-rnd/crosshair.h ../plugins/act_read/act_rtree.c +../plugins/act_read/keywords_sphash.o: \ + ../plugins/act_read/keywords_sphash.c +../plugins/backann/auto_ba.o: ../plugins/backann/auto_ba.c \ + ../libcschem/config.h ../libcschem/abstract.h \ + ../libcschem/common_types.h ../libcschem/attrib.h ../libcschem/TODO.h \ + ../libcschem/concrete.h ../libcschem/rtree.h ../libcschem/oidpath.h \ + ../libcschem/vtoid.h ../../src_3rd/libuundo/uundo.h \ + ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/project.h ../libcschem/engine.h ../libcschem/cnc_conn.h \ + ../libcschem/vtoidpath.h ../libcschem/intersect.h \ + ../libcschem/util_abst.h ../libcschem/util_wirenet.h \ + ../libcschem/cnc_line.h ../../src_3rd/gengeo2d/cline.h \ + ../../src_3rd/gengeo2d/vect.h ../../src_3rd/gengeo2d/box.h \ + ../plugins/backann/backann.h ../plugins/backann/auto_ba.h +../plugins/backann/backann.o: ../plugins/backann/backann.c \ + ../libcschem/config.h ../libcschem/event.h ../libcschem/search.h \ + ../libcschem/concrete.h ../libcschem/common_types.h ../libcschem/rtree.h \ + ../libcschem/attrib.h ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/util_grp.h ../libcschem/cnc_text.h \ + ../libcschem/cnc_text_dyn.h ../libcschem/cnc_text.h \ + ../plugins/backann/backann.h ../plugins/backann/check_ba.h \ + ../plugins/backann/auto_ba.h ../plugins/backann/dlg_ba.c \ + ../libcschem/actions_csch.h ../libcschem/project.h ../libcschem/engine.h \ + ../libcschem/abstract.h ../libcschem/TODO.h ../libcschem/operation.h \ + ../libcschem/concrete.h ../libcschem/util_wirenet.h \ + ../libcschem/cnc_line.h ../plugins/backann/parse_backann.c \ + ../plugins/backann/parse_bap.c ../plugins/backann/bap_sphash.h \ + ../plugins/backann/parse_tedax.c ../plugins/lib_tedax/parse.h +../plugins/backann/bap_sphash.o: ../plugins/backann/bap_sphash.c +../plugins/backann/check_ba.o: ../plugins/backann/check_ba.c \ + ../libcschem/config.h ../libcschem/abstract.h \ + ../libcschem/common_types.h ../libcschem/attrib.h ../libcschem/TODO.h \ + ../libcschem/project.h ../libcschem/concrete.h ../libcschem/rtree.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/engine.h ../plugins/backann/backann.h \ + ../plugins/backann/check_ba.h +../plugins/construct/construct.o: ../plugins/construct/construct.c \ + ../libcschem/config.h ../libcschem/search.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/util_grp.h ../libcschem/cnc_text.h \ + ../libcschem/cnc_text_dyn.h ../libcschem/cnc_text.h \ + ../sch-rnd/funchash_core.h ../sch-rnd/funchash_core_list.h \ + ../sch-rnd/draw.h ../plugins/construct/breakup.c ../libcschem/cnc_grp.h \ + ../libcschem/cnc_poly.h ../libcschem/vtcoutline.h ../libcschem/cnc_arc.h \ + ../libcschem/cnc_line.h ../libcschem/cnc_any_obj.h \ + ../libcschem/concrete.h ../libcschem/operation.h \ + ../plugins/construct/conv_grp.c ../sch-rnd/crosshair.h \ + ../plugins/construct/conv_poly.c +../plugins/diag/diag.o: ../plugins/diag/diag.c ../libcschem/config.h \ + ../libcschem/event.h ../libcschem/undo.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../sch-rnd/font.h ../libcschem/cnc_text.h ../libcschem/concrete.h \ + ../libcschem/cnc_text_dyn.h +../plugins/export_abst/export_abst.o: \ + ../plugins/export_abst/export_abst.c ../libcschem/config.h \ + ../libcschem/plug_io.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/abstract.h ../libcschem/TODO.h ../libcschem/util_export.h \ + ../libcschem/project.h ../libcschem/engine.h \ + ../plugins/export_abst/hid_impl.c ../sch-rnd/export.h ../sch-rnd/draw.h +../plugins/export_bom/export_bom.o: ../plugins/export_bom/export_bom.c \ + ../libcschem/config.h ../libcschem/plug_io.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/abstract.h ../libcschem/TODO.h ../libcschem/util_export.h \ + ../libcschem/project.h ../libcschem/engine.h \ + ../plugins/export_bom/bom_conf.h ../plugins/export_bom/conf_internal.c \ + ../../src_3rd/rnd_inclib/lib_bom/lib_bom.h \ + ../plugins/export_bom/hid_impl.c ../sch-rnd/export.h ../sch-rnd/draw.h \ + ../../src_3rd/rnd_inclib/lib_bom/lib_bom.c \ + ../plugins/export_bom/bom_conf_fields.h +../plugins/export_lpr/lpr.o: ../plugins/export_lpr/lpr.c \ + ../libcschem/config.h ../plugins/export_lpr/../export_ps/export_ps.h +../plugins/export_png/export_png.o: ../plugins/export_png/export_png.c \ + ../libcschem/config.h ../libcschem/util_export.h ../libcschem/project.h \ + ../libcschem/common_types.h ../libcschem/concrete.h ../libcschem/rtree.h \ + ../libcschem/attrib.h ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/engine.h ../libcschem/abstract.h ../libcschem/TODO.h \ + ../sch-rnd/draw.h ../sch-rnd/export.h +../plugins/export_ps/eps.o: ../plugins/export_ps/eps.c \ + ../libcschem/config.h ../libcschem/util_export.h ../libcschem/project.h \ + ../libcschem/common_types.h ../libcschem/concrete.h ../libcschem/rtree.h \ + ../libcschem/attrib.h ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/engine.h ../libcschem/abstract.h ../libcschem/TODO.h \ + ../sch-rnd/draw.h ../sch-rnd/export.h ../plugins/export_ps/export_ps.h +../plugins/export_ps/export_ps.o: ../plugins/export_ps/export_ps.c \ + ../libcschem/config.h ../plugins/export_ps/export_ps.h +../plugins/export_ps/ps.o: ../plugins/export_ps/ps.c \ + ../libcschem/config.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/util_export.h ../libcschem/project.h ../libcschem/engine.h \ + ../libcschem/abstract.h ../libcschem/TODO.h ../sch-rnd/draw.h \ + ../sch-rnd/export.h ../plugins/export_ps/export_ps.h +../plugins/export_spice/export_spice.o: \ + ../plugins/export_spice/export_spice.c ../libcschem/config.h \ + ../libcschem/plug_io.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/abstract.h ../libcschem/TODO.h \ + ../plugins/lib_netlist_exp/lib_netlist_exp.h \ + ../plugins/export_spice/hid_impl.c ../libcschem/project.h \ + ../libcschem/engine.h ../libcschem/util_export.h ../sch-rnd/export.h \ + ../sch-rnd/draw.h +../plugins/export_svg/export_svg.o: ../plugins/export_svg/export_svg.c \ + ../libcschem/config.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/util_export.h ../libcschem/project.h ../libcschem/engine.h \ + ../libcschem/abstract.h ../libcschem/TODO.h ../sch-rnd/draw.h \ + ../sch-rnd/export.h +../plugins/export_tedax/export_tedax.o: \ + ../plugins/export_tedax/export_tedax.c ../libcschem/config.h \ + ../libcschem/plug_io.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/abstract.h ../libcschem/TODO.h \ + ../plugins/lib_netlist_exp/lib_netlist_exp.h \ + ../plugins/export_tedax/hid_impl.c ../libcschem/project.h \ + ../libcschem/engine.h ../libcschem/util_export.h ../sch-rnd/export.h \ + ../sch-rnd/draw.h +../plugins/export_tedax_footprint/export_tedax_footprint.o: \ + ../plugins/export_tedax_footprint/export_tedax_footprint.c \ + ../libcschem/config.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/util_export.h ../libcschem/project.h ../libcschem/engine.h \ + ../libcschem/abstract.h ../libcschem/TODO.h ../sch-rnd/draw.h \ + ../sch-rnd/export.h +../plugins/funcmap/funcmap.o: ../plugins/funcmap/funcmap.c \ + ../../src_3rd/load_cache/load_cache.h ../libcschem/config.h \ + ../libcschem/abstract.h ../libcschem/common_types.h \ + ../libcschem/attrib.h ../libcschem/TODO.h ../libcschem/concrete.h \ + ../libcschem/rtree.h ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/cnc_grp.h ../libcschem/engine.h ../libcschem/actions_csch.h \ + ../libcschem/libcschem.h ../libcschem/util_lib_fs.h \ + ../libcschem/config.h ../libcschem/plug_library.h \ + ../libcschem/util_loclib.h ../libcschem/project.h \ + ../libcschem/project_p4.h ../libcschem/event.h ../libcschem/util_parse.h \ + ../plugins/sch_dialogs/quick_attr_util.h \ + ../plugins/lib_anymap/lib_anymap.h ../plugins/funcmap/funcmap_conf.h \ + ../plugins/funcmap/conf_internal.c ../plugins/funcmap/parse.c \ + ../plugins/funcmap/loclib.c ../plugins/funcmap/libs.c \ + ../plugins/funcmap/preview.c ../plugins/funcmap/fmparse.c \ + ../plugins/funcmap/compiler.c ../plugins/funcmap/dlg_funcmap.c \ + ../sch-rnd/funchash_core.h ../sch-rnd/funchash_core_list.h \ + ../sch-rnd/crosshair.h ../sch-rnd/search.h ../sch-rnd/draw.h \ + ../plugins/funcmap/fmdrc.c ../libcschem/drc.h \ + ../plugins/funcmap/funcmap_conf_fields.h +../plugins/gui/act.o: ../plugins/gui/act.c ../libcschem/config.h \ + ../libcschem/concrete.h ../libcschem/common_types.h ../libcschem/rtree.h \ + ../libcschem/attrib.h ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../sch-rnd/select.h ../plugins/gui/act.h +../plugins/gui/layersel.o: ../plugins/gui/layersel.c \ + ../libcschem/config.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../sch-rnd/draw.h ../plugins/gui/layersel.h +../plugins/gui/sch_rnd_gui.o: ../plugins/gui/sch_rnd_gui.c \ + ../libcschem/config.h ../libcschem/search.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/event.h ../libcschem/plug_io.h ../libcschem/abstract.h \ + ../libcschem/TODO.h ../sch-rnd/draw.h ../sch-rnd/search.h \ + ../sch-rnd/funchash_core.h ../sch-rnd/funchash_core_list.h \ + ../sch-rnd/multi.h ../sch-rnd/sheet.h ../sch-rnd/export.h \ + ../plugins/gui/layersel.h ../plugins/gui/sheetsel.h ../plugins/gui/act.h \ + ../plugins/gui/status.h ../plugins/gui/infobar.c ../sch-rnd/conf_core.h \ + ../plugins/gui/title.c ../plugins/gui/edit_act.c \ + ../libcschem/operation.h ../libcschem/concrete.h \ + ../libcschem/actions_csch.h ../sch-rnd/crosshair.h ../sch-rnd/buffer.h \ + ../sch-rnd/select.h +../plugins/gui/sheetsel.o: ../plugins/gui/sheetsel.c \ + ../libcschem/config.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/project.h ../libcschem/engine.h ../libcschem/abstract.h \ + ../libcschem/TODO.h ../libcschem/util_project.h ../sch-rnd/multi.h \ + ../plugins/gui/sheetsel.h +../plugins/gui/status.o: ../plugins/gui/status.c ../libcschem/config.h \ + ../libcschem/project.h ../libcschem/common_types.h \ + ../libcschem/concrete.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/engine.h ../libcschem/abstract.h ../libcschem/TODO.h \ + ../sch-rnd/conf_core.h ../sch-rnd/crosshair.h ../sch-rnd/draw.h \ + ../sch-rnd/buffer.h ../sch-rnd/multi.h ../plugins/gui/autocomp.c +../plugins/hlibrary_fs/hlibrary_fs.o: \ + ../plugins/hlibrary_fs/hlibrary_fs.c ../libcschem/config.h \ + ../libcschem/plug_io.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/abstract.h ../libcschem/TODO.h ../libcschem/plug_library.h \ + ../libcschem/util_lib_fs.h ../libcschem/config.h ../libcschem/cnc_grp.h \ + ../libcschem/cnc_any_obj.h ../libcschem/concrete.h +../plugins/io_altium/altium_kw_sphash.o: \ + ../plugins/io_altium/altium_kw_sphash.c +../plugins/io_altium/io_altium.o: ../plugins/io_altium/io_altium.c \ + ../libcschem/config.h ../libcschem/plug_io.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/abstract.h ../libcschem/TODO.h ../plugins/io_altium/read.h \ + ../plugins/io_altium/io_altium_conf.h \ + ../plugins/io_altium/conf_internal.c \ + ../plugins/io_altium/io_altium_conf_fields.h +../plugins/io_altium/pcbdoc_ascii.o: ../plugins/io_altium/pcbdoc_ascii.c \ + ../libcschem/config.h ../plugins/io_altium/pcbdoc_ascii.h \ + ../libcschem/plug_io.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/abstract.h ../libcschem/TODO.h \ + ../plugins/io_altium/altium_kw_sphash.h \ + ../plugins/lib_alien/read_helper.h ../plugins/lib_alien/read_postproc.h \ + ../plugins/io_altium/schdoc.c ../libcschem/cnc_grp.h \ + ../libcschem/cnc_grp_child.h ../libcschem/cnc_any_obj.h \ + ../libcschem/concrete.h ../libcschem/rotate.h \ + ../../src_3rd/gengeo2d/xform.h ../../src_3rd/gengeo2d/vect.h \ + ../libcschem/cnc_line.h ../libcschem/cnc_text.h \ + ../libcschem/cnc_text_dyn.h ../libcschem/cnc_poly.h \ + ../libcschem/vtcoutline.h ../libcschem/cnc_arc.h ../libcschem/cnc_pen.h \ + ../libcschem/operation.h ../libcschem/util_wirenet.h \ + ../plugins/io_altium/io_altium_conf.h ../plugins/io_altium/schdoc.h +../plugins/io_altium/read.o: ../plugins/io_altium/read.c \ + ../libcschem/config.h ../../src_3rd/libucdf/ucdf.h \ + ../plugins/io_altium/pcbdoc_ascii.h ../libcschem/plug_io.h \ + ../libcschem/concrete.h ../libcschem/common_types.h ../libcschem/rtree.h \ + ../libcschem/attrib.h ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/abstract.h ../libcschem/TODO.h \ + ../plugins/io_altium/altium_kw_sphash.h \ + ../plugins/lib_alien/read_helper.h ../plugins/lib_alien/read_postproc.h \ + ../plugins/io_altium/schdoc.h ../plugins/io_altium/read.h \ + ../plugins/io_altium/binlen2txt.c ../plugins/io_altium/binlen2txt.h +../plugins/io_geda/io_geda.o: ../plugins/io_geda/io_geda.c \ + ../libcschem/config.h ../libcschem/plug_io.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/abstract.h ../libcschem/TODO.h ../plugins/io_geda/read.h \ + ../plugins/io_geda/io_geda_conf.h ../plugins/io_geda/conf_internal.c \ + ../plugins/io_geda/io_geda_conf_fields.h +../plugins/io_geda/read.o: ../plugins/io_geda/read.c \ + ../libcschem/config.h ../libcschem/cnc_pen.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/cnc_grp.h ../libcschem/cnc_line.h ../libcschem/cnc_poly.h \ + ../libcschem/vtcoutline.h ../libcschem/cnc_arc.h ../libcschem/cnc_text.h \ + ../libcschem/cnc_text_dyn.h ../libcschem/cnc_conn.h \ + ../libcschem/vtoidpath.h ../libcschem/cnc_any_obj.h \ + ../libcschem/concrete.h ../libcschem/operation.h ../libcschem/project.h \ + ../libcschem/engine.h ../libcschem/abstract.h ../libcschem/TODO.h \ + ../libcschem/util_parse.h ../../src_3rd/load_cache/load_cache.h \ + ../sch-rnd/buffer.h ../plugins/lib_alien/read_helper.h \ + ../plugins/lib_alien/read_postproc.h ../plugins/io_geda/io_geda_conf.h \ + ../plugins/io_geda/read.h ../libcschem/plug_io.h \ + ../plugins/io_geda/read_postproc.c +../plugins/io_lihata/io_lihata.o: ../plugins/io_lihata/io_lihata.c \ + ../libcschem/config.h ../libcschem/plug_io.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/abstract.h ../libcschem/TODO.h ../plugins/io_lihata/read.h \ + ../plugins/io_lihata/write.h +../plugins/io_lihata/read.o: ../plugins/io_lihata/read.c \ + ../libcschem/config.h ../libcschem/cnc_pen.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/cnc_grp.h ../libcschem/cnc_grp_child.h \ + ../libcschem/cnc_any_obj.h ../libcschem/concrete.h ../libcschem/rotate.h \ + ../../src_3rd/gengeo2d/xform.h ../../src_3rd/gengeo2d/vect.h \ + ../libcschem/cnc_line.h ../libcschem/cnc_poly.h \ + ../libcschem/vtcoutline.h ../libcschem/cnc_arc.h ../libcschem/cnc_text.h \ + ../libcschem/cnc_text_dyn.h ../libcschem/cnc_conn.h \ + ../libcschem/vtoidpath.h ../libcschem/project.h ../libcschem/engine.h \ + ../libcschem/abstract.h ../libcschem/TODO.h ../libcschem/util_parse.h \ + ../../src_3rd/load_cache/load_cache.h ../sch-rnd/util_sheet.h \ + ../plugins/io_lihata/read.h ../libcschem/plug_io.h +../plugins/io_lihata/write.o: ../plugins/io_lihata/write.c \ + ../libcschem/config.h ../libcschem/cnc_pen.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/cnc_grp.h ../libcschem/cnc_grp_child.h \ + ../libcschem/cnc_any_obj.h ../libcschem/concrete.h ../libcschem/rotate.h \ + ../../src_3rd/gengeo2d/xform.h ../../src_3rd/gengeo2d/vect.h \ + ../libcschem/cnc_line.h ../libcschem/cnc_arc.h ../libcschem/cnc_poly.h \ + ../libcschem/vtcoutline.h ../libcschem/cnc_text.h \ + ../libcschem/cnc_text_dyn.h ../libcschem/cnc_conn.h \ + ../libcschem/vtoidpath.h ../libcschem/cnc_bitmap.h \ + ../libcschem/project.h ../libcschem/engine.h ../libcschem/abstract.h \ + ../libcschem/TODO.h ../plugins/io_lihata/write.h +../plugins/io_ngrp_fawk/io_ngrp_fawk.o: \ + ../plugins/io_ngrp_fawk/io_ngrp_fawk.c ../libcschem/config.h \ + ../libcschem/plug_io.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/abstract.h ../libcschem/TODO.h ../libcschem/non_graphical.h \ + ../libcschem/hierarchy.h ../plugins/io_ngrp_fawk/read.h +../plugins/io_ngrp_fawk/read.o: ../plugins/io_ngrp_fawk/read.c \ + ../libcschem/config.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/non_graphical.h ../libcschem/hierarchy.h \ + ../libcschem/abstract.h ../libcschem/TODO.h \ + ../plugins/lib_ngrp/lib_ngrp.h ../plugins/io_ngrp_fawk/read.h \ + ../libcschem/plug_io.h +../plugins/io_ngrp_tedax/io_ngrp_tedax.o: \ + ../plugins/io_ngrp_tedax/io_ngrp_tedax.c ../libcschem/config.h \ + ../libcschem/plug_io.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/abstract.h ../libcschem/TODO.h ../libcschem/non_graphical.h \ + ../libcschem/hierarchy.h ../plugins/io_ngrp_tedax/read.h +../plugins/io_ngrp_tedax/read.o: ../plugins/io_ngrp_tedax/read.c \ + ../libcschem/config.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/non_graphical.h ../libcschem/hierarchy.h \ + ../libcschem/abstract.h ../libcschem/TODO.h ../libcschem/event.h \ + ../plugins/lib_ngrp/lib_ngrp.h ../plugins/lib_tedax/parse.h \ + ../plugins/io_ngrp_tedax/read.h ../libcschem/plug_io.h +../plugins/io_orcad/io_orcad.o: ../plugins/io_orcad/io_orcad.c \ + ../libcschem/config.h ../libcschem/plug_io.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/abstract.h ../libcschem/TODO.h ../plugins/io_orcad/read.h \ + ../plugins/io_orcad/io_orcad_conf.h ../plugins/io_orcad/conf_internal.c \ + ../plugins/io_orcad/io_orcad_conf_fields.h +../plugins/io_orcad/read.o: ../plugins/io_orcad/read.c \ + ../libcschem/config.h ../libcschem/cnc_grp.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/cnc_text.h ../libcschem/cnc_text_dyn.h \ + ../libcschem/cnc_line.h ../libcschem/cnc_any_obj.h \ + ../libcschem/concrete.h ../libcschem/operation.h \ + ../plugins/lib_alien/read_helper.h ../plugins/lib_alien/read_postproc.h \ + ../plugins/io_orcad/read.h ../libcschem/plug_io.h \ + ../libcschem/abstract.h ../libcschem/TODO.h \ + ../plugins/io_orcad/read_parse.h ../plugins/io_orcad/read_fio.h \ + ../../src_3rd/libucdf/ucdf.h ../plugins/io_orcad/io_orcad_conf.h +../plugins/io_orcad/read_cache.o: ../plugins/io_orcad/read_cache.c \ + ../plugins/io_orcad/read_fio.h ../plugins/io_orcad/read.h \ + ../libcschem/plug_io.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/config.h ../libcschem/rtree.h \ + ../libcschem/attrib.h ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/abstract.h ../libcschem/TODO.h ../../src_3rd/libucdf/ucdf.h \ + ../plugins/lib_alien/read_helper.h ../plugins/io_orcad/read_common.h \ + ../plugins/io_orcad/read_parse.h +../plugins/io_orcad/read_common.o: ../plugins/io_orcad/read_common.c \ + ../plugins/io_orcad/read_fio.h ../plugins/io_orcad/read.h \ + ../libcschem/plug_io.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/config.h ../libcschem/rtree.h \ + ../libcschem/attrib.h ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/abstract.h ../libcschem/TODO.h ../../src_3rd/libucdf/ucdf.h \ + ../plugins/lib_alien/read_helper.h ../plugins/io_orcad/read_common.h \ + ../plugins/io_orcad/read_parse.h +../plugins/io_orcad/read_dump.o: ../plugins/io_orcad/read_dump.c \ + ../plugins/io_orcad/read_fio.h ../plugins/io_orcad/read.h \ + ../libcschem/plug_io.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/config.h ../libcschem/rtree.h \ + ../libcschem/attrib.h ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/abstract.h ../libcschem/TODO.h ../../src_3rd/libucdf/ucdf.h \ + ../plugins/lib_alien/read_helper.h ../plugins/io_orcad/read_common.h \ + ../plugins/io_orcad/read_parse.h +../plugins/io_orcad/read_fio.o: ../plugins/io_orcad/read_fio.c \ + ../plugins/io_orcad/read_fio.h ../plugins/io_orcad/read.h \ + ../libcschem/plug_io.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/config.h ../libcschem/rtree.h \ + ../libcschem/attrib.h ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/abstract.h ../libcschem/TODO.h ../../src_3rd/libucdf/ucdf.h \ + ../plugins/lib_alien/read_helper.h +../plugins/io_orcad/read_free.o: ../plugins/io_orcad/read_free.c \ + ../plugins/io_orcad/read_fio.h ../plugins/io_orcad/read.h \ + ../libcschem/plug_io.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/config.h ../libcschem/rtree.h \ + ../libcschem/attrib.h ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/abstract.h ../libcschem/TODO.h ../../src_3rd/libucdf/ucdf.h \ + ../plugins/lib_alien/read_helper.h ../plugins/io_orcad/read_common.h \ + ../plugins/io_orcad/read_parse.h +../plugins/io_orcad/read_library.o: ../plugins/io_orcad/read_library.c \ + ../plugins/io_orcad/read_fio.h ../plugins/io_orcad/read.h \ + ../libcschem/plug_io.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/config.h ../libcschem/rtree.h \ + ../libcschem/attrib.h ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/abstract.h ../libcschem/TODO.h ../../src_3rd/libucdf/ucdf.h \ + ../plugins/lib_alien/read_helper.h ../plugins/io_orcad/read_common.h \ + ../plugins/io_orcad/read_parse.h +../plugins/io_orcad/read_page.o: ../plugins/io_orcad/read_page.c \ + ../plugins/io_orcad/read_fio.h ../plugins/io_orcad/read.h \ + ../libcschem/plug_io.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/config.h ../libcschem/rtree.h \ + ../libcschem/attrib.h ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/abstract.h ../libcschem/TODO.h ../../src_3rd/libucdf/ucdf.h \ + ../plugins/lib_alien/read_helper.h ../plugins/io_orcad/read_common.h \ + ../plugins/io_orcad/read_parse.h +../plugins/io_orcad/read_prim.o: ../plugins/io_orcad/read_prim.c \ + ../plugins/io_orcad/read_fio.h ../plugins/io_orcad/read.h \ + ../libcschem/plug_io.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/config.h ../libcschem/rtree.h \ + ../libcschem/attrib.h ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/abstract.h ../libcschem/TODO.h ../../src_3rd/libucdf/ucdf.h \ + ../plugins/lib_alien/read_helper.h ../plugins/io_orcad/read_common.h \ + ../plugins/io_orcad/read_parse.h +../plugins/io_tinycad/io_tinycad.o: ../plugins/io_tinycad/io_tinycad.c \ + ../libcschem/config.h ../libcschem/plug_io.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/abstract.h ../libcschem/TODO.h ../plugins/io_tinycad/read.h \ + ../plugins/io_tinycad/io_tinycad_conf.h \ + ../plugins/io_tinycad/conf_internal.c \ + ../plugins/io_tinycad/io_tinycad_conf_fields.h +../plugins/io_tinycad/read.o: ../plugins/io_tinycad/read.c \ + ../libcschem/config.h ../libcschem/cnc_grp.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/cnc_grp_child.h ../libcschem/cnc_any_obj.h \ + ../libcschem/concrete.h ../libcschem/rotate.h \ + ../../src_3rd/gengeo2d/xform.h ../../src_3rd/gengeo2d/vect.h \ + ../libcschem/cnc_line.h ../libcschem/cnc_text.h \ + ../libcschem/cnc_text_dyn.h ../libcschem/cnc_poly.h \ + ../libcschem/vtcoutline.h ../libcschem/cnc_arc.h ../libcschem/cnc_pen.h \ + ../libcschem/operation.h ../libcschem/util_loclib.h \ + ../libcschem/plug_library.h ../plugins/lib_alien/read_helper.h \ + ../plugins/lib_alien/read_postproc.h \ + ../plugins/io_tinycad/io_tinycad_conf.h ../plugins/io_tinycad/read.h \ + ../libcschem/plug_io.h ../libcschem/abstract.h ../libcschem/TODO.h \ + ../libcschem/cnc_obj.h ../libcschem/event.h ../libcschem/attrib.h \ + ../libcschem/cnc_pen.h ../libcschem/cnc_text.h +../plugins/lib_alien/lib_alien.o: ../plugins/lib_alien/lib_alien.c \ + ../libcschem/config.h +../plugins/lib_alien/read_helper.o: ../plugins/lib_alien/read_helper.c \ + ../libcschem/config.h ../libcschem/libcschem.h \ + ../../src_3rd/libminuid/libminuid.h ../libcschem/util_wirenet.h \ + ../libcschem/cnc_line.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/cnc_grp.h ../libcschem/cnc_arc.h ../libcschem/cnc_text.h \ + ../libcschem/cnc_text_dyn.h ../libcschem/cnc_poly.h \ + ../libcschem/vtcoutline.h ../libcschem/cnc_any_obj.h \ + ../libcschem/concrete.h ../libcschem/cnc_conn.h ../libcschem/vtoidpath.h \ + ../libcschem/operation.h ../libcschem/project.h ../libcschem/engine.h \ + ../libcschem/abstract.h ../libcschem/TODO.h ../sch-rnd/style.h \ + ../sch-rnd/sheet.h ../sch-rnd/util_sheet.h ../plugins/query/query.h \ + ../plugins/query/fields_sphash.h ../plugins/query/query_access.h \ + ../plugins/query/query.h ../plugins/query/query_exec.h \ + ../plugins/lib_alien/read_helper.h ../plugins/lib_alien/read_postproc.c +../plugins/lib_anymap/lib_anymap.o: ../plugins/lib_anymap/lib_anymap.c \ + ../libcschem/config.h ../libcschem/abstract.h \ + ../libcschem/common_types.h ../libcschem/attrib.h ../libcschem/TODO.h \ + ../libcschem/actions_csch.h ../libcschem/concrete.h ../libcschem/rtree.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/cnc_grp.h ../libcschem/engine.h \ + ../plugins/lib_anymap/lib_anymap.h ../../src_3rd/load_cache/load_cache.h \ + ../libcschem/plug_library.h ../libcschem/event.h \ + ../plugins/lib_anymap/loclib.c ../plugins/lib_anymap/libs.c \ + ../plugins/lib_anymap/preview.c +../plugins/lib_netlist_exp/lib_netlist_exp.o: \ + ../plugins/lib_netlist_exp/lib_netlist_exp.c ../libcschem/config.h \ + ../plugins/lib_netlist_exp/lib_netlist_exp.h ../libcschem/abstract.h \ + ../libcschem/common_types.h ../libcschem/attrib.h ../libcschem/TODO.h +../plugins/lib_ngrp/lib_ngrp.o: ../plugins/lib_ngrp/lib_ngrp.c \ + ../libcschem/config.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/non_graphical.h ../libcschem/hierarchy.h \ + ../libcschem/abstract.h ../libcschem/TODO.h ../libcschem/compile.h \ + ../libcschem/project.h ../libcschem/engine.h ../libcschem/cnc_obj.h \ + ../libcschem/event.h ../libcschem/attrib.h ../libcschem/cnc_pen.h \ + ../libcschem/cnc_text.h ../libcschem/cnc_text_dyn.h \ + ../libcschem/cnc_text.h ../sch-rnd/draw.h ../plugins/lib_ngrp/lib_ngrp.h +../plugins/lib_plot/lib_plot.o: ../plugins/lib_plot/lib_plot.c \ + ../libcschem/config.h +../plugins/lib_plot/plot_data.o: ../plugins/lib_plot/plot_data.c \ + ../plugins/lib_plot/plot_data.h +../plugins/lib_plot/plot_preview.o: ../plugins/lib_plot/plot_preview.c \ + ../plugins/lib_plot/plot_preview.h ../plugins/lib_plot/plot_data.h \ + ../sch-rnd/font.h ../libcschem/cnc_text.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/config.h ../libcschem/rtree.h \ + ../libcschem/attrib.h ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/cnc_text_dyn.h +../plugins/lib_target/lib_target.o: ../plugins/lib_target/lib_target.c \ + ../libcschem/config.h ../plugins/lib_target/lib_target.h \ + ../libcschem/abstract.h ../libcschem/common_types.h \ + ../libcschem/attrib.h ../libcschem/TODO.h +../plugins/lib_tedax/lib_tedax.o: ../plugins/lib_tedax/lib_tedax.c \ + ../libcschem/config.h ../plugins/lib_tedax/lib_tedax.h \ + ../plugins/lib_tedax/parse.c ../plugins/lib_tedax/parse.h +../plugins/lib_ucdf/lib_ucdf.o: ../plugins/lib_ucdf/lib_ucdf.c \ + ../libcschem/config.h +../plugins/place/place.o: ../plugins/place/place.c ../libcschem/config.h \ + ../libcschem/search.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/util_grp.h ../libcschem/cnc_text.h \ + ../libcschem/cnc_text_dyn.h ../libcschem/cnc_text.h \ + ../sch-rnd/funchash_core.h ../sch-rnd/funchash_core_list.h \ + ../sch-rnd/draw.h ../sch-rnd/crosshair.h ../plugins/place/attrib.c \ + ../libcschem/cnc_grp.h ../libcschem/cnc_pen.h ../libcschem/operation.h \ + ../libcschem/concrete.h ../sch-rnd/search.h ../plugins/place/terminal.c \ + ../libcschem/cnc_line.h +../plugins/propedit/propdlg.o: ../plugins/propedit/propdlg.c \ + ../libcschem/config.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/libcschem.h ../libcschem/event.h ../sch-rnd/dad.h \ + ../sch-rnd/draw.h ../plugins/propedit/props.h \ + ../plugins/propedit/propsel.h +../plugins/propedit/propedit.o: ../plugins/propedit/propedit.c \ + ../libcschem/config.h ../libcschem/search.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/util_grp.h ../libcschem/cnc_text.h \ + ../libcschem/cnc_text_dyn.h ../libcschem/cnc_text.h \ + ../libcschem/actions_csch.h ../sch-rnd/funchash_core.h \ + ../sch-rnd/funchash_core_list.h ../sch-rnd/crosshair.h \ + ../plugins/propedit/props.h ../plugins/propedit/propsel.h \ + ../plugins/propedit/propdlg.h +../plugins/propedit/props.o: ../plugins/propedit/props.c \ + ../libcschem/config.h ../plugins/propedit/props.h \ + ../libcschem/concrete.h ../libcschem/common_types.h ../libcschem/rtree.h \ + ../libcschem/attrib.h ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h +../plugins/propedit/propsel.o: ../plugins/propedit/propsel.c \ + ../libcschem/config.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/cnc_line.h ../libcschem/cnc_poly.h \ + ../libcschem/vtcoutline.h ../libcschem/cnc_arc.h ../libcschem/cnc_text.h \ + ../libcschem/cnc_text_dyn.h ../libcschem/cnc_bitmap.h \ + ../libcschem/cnc_grp.h ../libcschem/cnc_grp_child.h \ + ../libcschem/cnc_any_obj.h ../libcschem/concrete.h ../libcschem/rotate.h \ + ../../src_3rd/gengeo2d/xform.h ../../src_3rd/gengeo2d/vect.h \ + ../libcschem/cnc_obj.h ../libcschem/event.h ../libcschem/attrib.h \ + ../libcschem/cnc_pen.h ../libcschem/cnc_text.h ../libcschem/undo.h \ + ../sch-rnd/operation.h ../plugins/propedit/props.h \ + ../plugins/propedit/propsel.h +../plugins/query/dlg_search.o: ../plugins/query/dlg_search.c \ + ../libcschem/config.h ../plugins/query/query.h \ + ../plugins/query/fields_sphash.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../plugins/query/dlg_search_tab.h ../plugins/query/dlg_search_edit.c \ + ../sch-rnd/dad.h ../libcschem/libcschem.h +../plugins/query/fields_sphash.o: ../plugins/query/fields_sphash.c +../plugins/query/fnc.o: ../plugins/query/fnc.c ../libcschem/config.h \ + ../libcschem/concrete.h ../libcschem/common_types.h ../libcschem/rtree.h \ + ../libcschem/attrib.h ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../plugins/query/query_access.h ../plugins/query/query.h \ + ../plugins/query/fields_sphash.h ../plugins/query/query_exec.h \ + ../plugins/query/fnc_glue.c ../libcschem/cnc_text.h \ + ../libcschem/cnc_text_dyn.h ../plugins/query/fnc_list.c +../plugins/query/query.o: ../plugins/query/query.c ../libcschem/config.h \ + ../libcschem/event.h ../plugins/query/query.h \ + ../plugins/query/fields_sphash.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../plugins/query/query_l.h ../plugins/query/dlg_search.h +../plugins/query/query_access.o: ../plugins/query/query_access.c \ + ../libcschem/config.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/cnc_line.h ../libcschem/cnc_bitmap.h ../libcschem/cnc_arc.h \ + ../libcschem/cnc_pen.h ../libcschem/cnc_text.h \ + ../libcschem/cnc_text_dyn.h ../libcschem/cnc_poly.h \ + ../libcschem/vtcoutline.h ../libcschem/cnc_grp.h ../libcschem/cnc_conn.h \ + ../libcschem/vtoidpath.h ../libcschem/cnc_obj.h ../libcschem/event.h \ + ../libcschem/attrib.h ../libcschem/cnc_pen.h ../libcschem/cnc_text.h \ + ../plugins/query/query_access.h ../plugins/query/query.h \ + ../plugins/query/fields_sphash.h ../plugins/query/query_exec.h +../plugins/query/query_act.o: ../plugins/query/query_act.c \ + ../libcschem/config.h ../libcschem/actions_csch.h ../sch-rnd/conf_core.h \ + ../sch-rnd/buffer.h ../libcschem/concrete.h ../libcschem/common_types.h \ + ../libcschem/rtree.h ../libcschem/attrib.h ../libcschem/oidpath.h \ + ../libcschem/vtoid.h ../../src_3rd/libuundo/uundo.h \ + ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../plugins/query/query.h ../plugins/query/fields_sphash.h \ + ../plugins/query/query_y.h ../plugins/query/query_exec.h \ + ../plugins/query/query_access.h ../libcschem/cnc_any_obj.h \ + ../libcschem/concrete.h ../plugins/query/dlg_search.h +../plugins/query/query_exec.o: ../plugins/query/query_exec.c \ + ../libcschem/config.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../plugins/query/query.h ../plugins/query/fields_sphash.h \ + ../plugins/query/query_exec.h ../plugins/query/query_access.h \ + ../sch-rnd/buffer.h +../plugins/query/query_l.o: ../plugins/query/query_l.c \ + ../plugins/query/query.h ../plugins/query/fields_sphash.h \ + ../libcschem/concrete.h ../libcschem/common_types.h \ + ../libcschem/config.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../plugins/query/query_y.h ../libcschem/cnc_text.h \ + ../libcschem/cnc_text_dyn.h +../plugins/query/query_y.o: ../plugins/query/query_y.c \ + ../plugins/query/query.h ../plugins/query/fields_sphash.h \ + ../libcschem/concrete.h ../libcschem/common_types.h \ + ../libcschem/config.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../plugins/query/query_l.h +../plugins/renumber/renumber.o: ../plugins/renumber/renumber.c \ + ../libcschem/config.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/actions_csch.h ../libcschem/libcschem.h \ + ../sch-rnd/funchash_core.h ../sch-rnd/funchash_core_list.h \ + ../plugins/renumber/renumber_conf.h ../plugins/renumber/conf_internal.c \ + ../plugins/renumber/renumber_impl.c ../plugins/renumber/renumber_dlg.c \ + ../sch-rnd/build_run.h ../plugins/renumber/renumber_conf_fields.h +../plugins/sch_dialogs/abst_attr.o: ../plugins/sch_dialogs/abst_attr.c \ + ../libcschem/config.h ../libcschem/actions_csch.h \ + ../plugins/sch_dialogs/abst_attr.h ../libcschem/abstract.h \ + ../libcschem/common_types.h ../libcschem/attrib.h ../libcschem/TODO.h \ + ../libcschem/project.h ../libcschem/concrete.h ../libcschem/rtree.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/engine.h +../plugins/sch_dialogs/dlg_about.o: ../plugins/sch_dialogs/dlg_about.c \ + ../libcschem/config.h ../sch-rnd/build_run.h \ + ../plugins/sch_dialogs/dlg_about.h +../plugins/sch_dialogs/dlg_abstract.o: \ + ../plugins/sch_dialogs/dlg_abstract.c ../libcschem/config.h \ + ../libcschem/abstract.h ../libcschem/common_types.h \ + ../libcschem/attrib.h ../libcschem/TODO.h ../libcschem/project.h \ + ../libcschem/concrete.h ../libcschem/rtree.h ../libcschem/oidpath.h \ + ../libcschem/vtoid.h ../../src_3rd/libuundo/uundo.h \ + ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/engine.h ../libcschem/actions_csch.h \ + ../plugins/sch_dialogs/abst_attr.h +../plugins/sch_dialogs/dlg_attrib.o: ../plugins/sch_dialogs/dlg_attrib.c \ + ../libcschem/config.h ../libcschem/search.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/abstract.h ../libcschem/TODO.h ../libcschem/cnc_grp.h \ + ../libcschem/util_grp.h ../libcschem/cnc_text.h \ + ../libcschem/cnc_text_dyn.h ../libcschem/cnc_text.h ../sch-rnd/draw.h \ + ../sch-rnd/crosshair.h ../sch-rnd/search.h \ + ../plugins/sch_dialogs/abst_attr.h ../libcschem/project.h \ + ../libcschem/engine.h ../plugins/sch_dialogs/quick_attr.h \ + ../plugins/sch_dialogs/dlg_attrib.h +../plugins/sch_dialogs/dlg_cond.o: ../plugins/sch_dialogs/dlg_cond.c \ + ../libcschem/config.h ../libcschem/project.h ../libcschem/common_types.h \ + ../libcschem/concrete.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/engine.h ../libcschem/abstract.h ../libcschem/TODO.h \ + ../libcschem/event.h ../libcschem/actions_csch.h ../libcschem/search.h \ + ../sch-rnd/crosshair.h ../sch-rnd/draw.h ../sch-rnd/search.h \ + ../sch-rnd/funchash_core.h ../sch-rnd/funchash_core_list.h \ + ../plugins/sch_dialogs/quick_attr_util.h +../plugins/sch_dialogs/dlg_library.o: \ + ../plugins/sch_dialogs/dlg_library.c ../libcschem/config.h \ + ../libcschem/concrete.h ../libcschem/common_types.h ../libcschem/rtree.h \ + ../libcschem/attrib.h ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/cnc_any_obj.h ../libcschem/concrete.h \ + ../libcschem/operation.h ../libcschem/plug_library.h \ + ../libcschem/util_wirenet.h ../libcschem/cnc_line.h \ + ../sch-rnd/conf_core.h ../sch-rnd/draw.h ../sch-rnd/search.h \ + ../sch-rnd/buffer.h ../sch-rnd/funchash_core.h \ + ../sch-rnd/funchash_core_list.h ../plugins/sch_dialogs/adialogs_conf.h \ + ../plugins/sch_dialogs/../../../src_3rd/rnd_inclib/dialogs/dlg_library_param.h \ + ../plugins/sch_dialogs/../../../src_3rd/rnd_inclib/dialogs/dlg_library_param.c +../plugins/sch_dialogs/dlg_pen.o: ../plugins/sch_dialogs/dlg_pen.c \ + ../libcschem/config.h ../libcschem/search.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/cnc_loop.h ../libcschem/concrete.h ../libcschem/cnc_pen.h \ + ../libcschem/cnc_grp.h ../libcschem/cnc_any_obj.h \ + ../libcschem/operation.h ../libcschem/actions_csch.h ../sch-rnd/draw.h \ + ../sch-rnd/search.h ../sch-rnd/funchash_core.h \ + ../sch-rnd/funchash_core_list.h ../sch-rnd/crosshair.h ../sch-rnd/dad.h \ + ../libcschem/libcschem.h ../sch-rnd/conf_core.h +../plugins/sch_dialogs/dlg_pref_apptab.o: \ + ../plugins/sch_dialogs/dlg_pref_apptab.c ../libcschem/config.h \ + ../plugins/sch_dialogs/dlg_pref_general.c \ + ../plugins/sch_dialogs/dlg_pref_sheet.c ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../plugins/sch_dialogs/dlg_pen.h ../sch-rnd/conf_core.h \ + ../plugins/sch_dialogs/dlg_pref_lib.c \ + ../plugins/sch_dialogs/dlg_pref_color.c +../plugins/sch_dialogs/dlg_project.o: \ + ../plugins/sch_dialogs/dlg_project.c ../libcschem/config.h \ + ../libcschem/project.h ../libcschem/common_types.h \ + ../libcschem/concrete.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/engine.h ../libcschem/abstract.h ../libcschem/TODO.h +../plugins/sch_dialogs/dlg_stance.o: ../plugins/sch_dialogs/dlg_stance.c \ + ../libcschem/config.h ../libcschem/project.h ../libcschem/common_types.h \ + ../libcschem/concrete.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/engine.h ../libcschem/abstract.h ../libcschem/TODO.h \ + ../libcschem/event.h ../libcschem/actions_csch.h ../libcschem/search.h \ + ../sch-rnd/project.h ../sch-rnd/conf_core.h \ + ../plugins/sch_dialogs/dlg_stance.h +../plugins/sch_dialogs/dlg_text.o: ../plugins/sch_dialogs/dlg_text.c \ + ../libcschem/config.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/cnc_text.h ../libcschem/cnc_text_dyn.h \ + ../libcschem/cnc_grp_child.h ../libcschem/cnc_any_obj.h \ + ../libcschem/concrete.h ../libcschem/rotate.h \ + ../../src_3rd/gengeo2d/xform.h ../../src_3rd/gengeo2d/vect.h \ + ../libcschem/actions_csch.h ../sch-rnd/search.h ../sch-rnd/operation.h \ + ../sch-rnd/crosshair.h ../sch-rnd/draw.h ../sch-rnd/funchash_core.h \ + ../sch-rnd/funchash_core_list.h ../sch-rnd/conf_core.h +../plugins/sch_dialogs/dlg_tree.o: ../plugins/sch_dialogs/dlg_tree.c \ + ../libcschem/config.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/project.h ../libcschem/engine.h ../libcschem/abstract.h \ + ../libcschem/TODO.h ../libcschem/actions_csch.h \ + ../libcschem/cnc_any_obj.h ../libcschem/concrete.h \ + ../libcschem/cnc_conn.h ../libcschem/vtoidpath.h \ + ../libcschem/operation.h ../libcschem/util_wirenet.h \ + ../libcschem/cnc_line.h ../sch-rnd/draw.h ../sch-rnd/search.h \ + ../sch-rnd/funchash_core.h ../sch-rnd/funchash_core_list.h \ + ../sch-rnd/crosshair.h +../plugins/sch_dialogs/dlg_undo.o: ../plugins/sch_dialogs/dlg_undo.c \ + ../libcschem/config.h ../../src_3rd/libuundo/uundo.h \ + ../libcschem/event.h ../libcschem/concrete.h ../libcschem/common_types.h \ + ../libcschem/rtree.h ../libcschem/attrib.h ../libcschem/oidpath.h \ + ../libcschem/vtoid.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/undo.h ../libcschem/concrete.h +../plugins/sch_dialogs/dlg_view.o: ../plugins/sch_dialogs/dlg_view.c \ + ../libcschem/config.h ../libcschem/libcschem.h \ + ../../src_3rd/libminuid/libminuid.h ../libcschem/project.h \ + ../libcschem/common_types.h ../libcschem/concrete.h ../libcschem/rtree.h \ + ../libcschem/attrib.h ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/engine.h ../libcschem/abstract.h ../libcschem/TODO.h \ + ../sch-rnd/project.h ../plugins/sch_dialogs/dlg_view.h +../plugins/sch_dialogs/quick_attr.o: ../plugins/sch_dialogs/quick_attr.c \ + ../libcschem/config.h ../libcschem/actions_csch.h \ + ../plugins/sch_dialogs/dlg_attrib.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../plugins/sch_dialogs/quick_attr.h \ + ../plugins/sch_dialogs/quick_attr_util.h +../plugins/sch_dialogs/sch_dialogs.o: \ + ../plugins/sch_dialogs/sch_dialogs.c ../libcschem/config.h \ + ../libcschem/event.h ../plugins/sch_dialogs/dlg_attrib.h \ + ../libcschem/concrete.h ../libcschem/common_types.h ../libcschem/rtree.h \ + ../libcschem/attrib.h ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../plugins/sch_dialogs/dlg_about.h ../plugins/sch_dialogs/dlg_abstract.h \ + ../plugins/sch_dialogs/dlg_stance.h ../plugins/sch_dialogs/dlg_cond.h \ + ../plugins/sch_dialogs/dlg_undo.h ../plugins/sch_dialogs/dlg_pen.h \ + ../plugins/sch_dialogs/dlg_text.h ../libcschem/cnc_text.h \ + ../libcschem/cnc_text_dyn.h ../plugins/sch_dialogs/dlg_tree.h \ + ../plugins/sch_dialogs/dlg_library.h \ + ../plugins/sch_dialogs/dlg_infobar.c ../sch-rnd/sheet.h \ + ../libcschem/plug_io.h ../libcschem/abstract.h ../libcschem/TODO.h \ + ../plugins/sch_dialogs/dlg_view.h ../plugins/sch_dialogs/dlg_project.h \ + ../plugins/sch_dialogs/quick_attr.h \ + ../plugins/sch_dialogs/adialogs_conf.h \ + ../plugins/sch_dialogs/conf_internal.c \ + ../plugins/sch_dialogs/adialogs_conf_fields.h +../plugins/sim/actions.o: ../plugins/sim/actions.c ../libcschem/config.h \ + ../libcschem/abstract.h ../libcschem/common_types.h \ + ../libcschem/attrib.h ../libcschem/TODO.h ../libcschem/project.h \ + ../libcschem/concrete.h ../libcschem/rtree.h ../libcschem/oidpath.h \ + ../libcschem/vtoid.h ../../src_3rd/libuundo/uundo.h \ + ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/engine.h ../libcschem/event.h ../plugins/sim/sim.h \ + ../plugins/sim/sim_conf.h ../plugins/sim/util.h ../plugins/sim/sim.h \ + ../plugins/sim/actions.h +../plugins/sim/mods.o: ../plugins/sim/mods.c ../libcschem/config.h \ + ../libcschem/libcschem.h ../../src_3rd/libminuid/libminuid.h \ + ../libcschem/compile.h ../libcschem/abstract.h \ + ../libcschem/common_types.h ../libcschem/attrib.h ../libcschem/TODO.h \ + ../libcschem/concrete.h ../libcschem/rtree.h ../libcschem/oidpath.h \ + ../libcschem/vtoid.h ../../src_3rd/libuundo/uundo.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/project.h ../libcschem/engine.h ../plugins/sim/sim.h \ + ../plugins/sim/sim_conf.h ../plugins/sim/mods.h ../plugins/sim/sim.h +../plugins/sim/sim.o: ../plugins/sim/sim.c ../libcschem/config.h \ + ../libcschem/project.h ../libcschem/common_types.h \ + ../libcschem/concrete.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/engine.h ../libcschem/abstract.h ../libcschem/TODO.h \ + ../plugins/sim/sim.h ../plugins/sim/sim_conf.h ../plugins/sim/actions.h \ + ../plugins/sim/sim.h ../plugins/sim/conf_internal.c \ + ../plugins/sim/sim_conf_fields.h +../plugins/sim/sim_conf.o: ../plugins/sim/sim_conf.c \ + ../libcschem/config.h ../libcschem/project.h ../libcschem/common_types.h \ + ../libcschem/concrete.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/engine.h ../libcschem/abstract.h ../libcschem/TODO.h \ + ../sch-rnd/multi.h ../plugins/sim/sim.h ../plugins/sim/sim_conf.h +../plugins/sim/util.o: ../plugins/sim/util.c ../libcschem/config.h \ + ../libcschem/libcschem.h ../../src_3rd/libminuid/libminuid.h \ + ../sch-rnd/conf_core.h ../plugins/sim/sim_conf.h ../libcschem/project.h \ + ../libcschem/common_types.h ../libcschem/concrete.h ../libcschem/rtree.h \ + ../libcschem/attrib.h ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/engine.h ../libcschem/abstract.h ../libcschem/TODO.h \ + ../plugins/sim/util.h ../plugins/sim/sim.h +../plugins/sim_gui/sim_gui.o: ../plugins/sim_gui/sim_gui.c \ + ../libcschem/config.h ../libcschem/event.h \ + ../plugins/sim_gui/sim_setup_dlg.h ../libcschem/project.h \ + ../libcschem/common_types.h ../libcschem/concrete.h ../libcschem/rtree.h \ + ../libcschem/attrib.h ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/engine.h ../libcschem/abstract.h ../libcschem/TODO.h \ + ../plugins/sim_gui/plot_test.c ../plugins/lib_plot/plot_preview.h \ + ../plugins/lib_plot/plot_data.h ../plugins/sim_gui/sim_dlg.c \ + ../plugins/sim/sim_conf.h ../plugins/sim_gui/sim_setup_dlg.c \ + ../plugins/sim/actions.h ../plugins/sim/sim.h ../plugins/sim/util.h \ + ../plugins/sch_dialogs/dlg_stance.h ../plugins/sim_gui/sim_gui_conf.h \ + ../plugins/sim_gui/sim_mod_dlg.c ../plugins/sim_gui/sim_outcfg_dlg.c \ + ../plugins/sim_gui/conf_internal.c \ + ../plugins/sim_gui/sim_gui_conf_fields.h +../plugins/sim_ngspice/sim_ngspice.o: \ + ../plugins/sim_ngspice/sim_ngspice.c ../libcschem/config.h \ + ../libcschem/abstract.h ../libcschem/common_types.h \ + ../libcschem/attrib.h ../libcschem/TODO.h ../libcschem/engine.h \ + ../libcschem/project.h ../libcschem/concrete.h ../libcschem/rtree.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/actions_csch.h ../libcschem/libcschem.h \ + ../libcschem/util_compile.h ../plugins/sim/sim.h \ + ../plugins/sim/sim_conf.h ../plugins/sim/mods.h ../plugins/sim/util.h +../plugins/std_cschem/std_cschem.o: ../plugins/std_cschem/std_cschem.c \ + ../libcschem/config.h ../libcschem/abstract.h \ + ../libcschem/common_types.h ../libcschem/attrib.h ../libcschem/TODO.h \ + ../libcschem/concrete.h ../libcschem/rtree.h ../libcschem/oidpath.h \ + ../libcschem/vtoid.h ../../src_3rd/libuundo/uundo.h \ + ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/engine.h ../libcschem/actions_csch.h \ + ../libcschem/libcschem.h ../libcschem/util_compile.h \ + ../libcschem/hierarchy.h ../plugins/sch_dialogs/quick_attr_util.h \ + ../plugins/std_cschem/std_cschem_conf.h \ + ../plugins/std_cschem/conf_internal.c \ + ../plugins/std_cschem/quick_attr_connect.c \ + ../plugins/std_cschem/std_cschem_conf_fields.h +../plugins/std_devmap/std_devmap.o: ../plugins/std_devmap/std_devmap.c \ + ../../src_3rd/load_cache/load_cache.h ../libcschem/config.h \ + ../libcschem/abstract.h ../libcschem/common_types.h \ + ../libcschem/attrib.h ../libcschem/TODO.h ../libcschem/concrete.h \ + ../libcschem/rtree.h ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/cnc_grp.h ../libcschem/engine.h ../libcschem/actions_csch.h \ + ../libcschem/libcschem.h ../libcschem/util_lib_fs.h \ + ../libcschem/config.h ../libcschem/plug_library.h \ + ../libcschem/util_loclib.h ../libcschem/project.h \ + ../libcschem/project_p4.h ../libcschem/event.h ../libcschem/util_parse.h \ + ../libcschem/operation.h ../libcschem/concrete.h \ + ../libcschem/hierarchy.h ../plugins/sch_dialogs/quick_attr_util.h \ + ../plugins/lib_anymap/lib_anymap.h \ + ../plugins/std_devmap/std_devmap_conf.h \ + ../plugins/std_devmap/conf_internal.c ../plugins/std_devmap/parse.c \ + ../plugins/std_devmap/loclib.c ../plugins/std_devmap/libs.c \ + ../plugins/std_devmap/preview.c ../plugins/std_devmap/compiler.c \ + ../plugins/std_devmap/quick_attr_portmap.c \ + ../plugins/std_devmap/std_devmap_conf_fields.h +../plugins/std_forge/cond_gram.o: ../plugins/std_forge/cond_gram.c \ + ../plugins/std_forge/cond_gram.h ../plugins/std_forge/cond.h \ + ../libcschem/abstract.h ../libcschem/common_types.h \ + ../libcschem/config.h ../libcschem/attrib.h ../libcschem/TODO.h +../plugins/std_forge/dlg_test_bench.o: \ + ../plugins/std_forge/dlg_test_bench.c ../libcschem/config.h \ + ../libcschem/project.h ../libcschem/common_types.h \ + ../libcschem/concrete.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/engine.h ../libcschem/abstract.h ../libcschem/TODO.h \ + ../libcschem/event.h ../libcschem/actions_csch.h ../libcschem/search.h \ + ../sch-rnd/conf_core.h ../sch-rnd/crosshair.h ../sch-rnd/search.h \ + ../plugins/sch_dialogs/quick_attr_util.h \ + ../plugins/std_forge/std_forge.h +../plugins/std_forge/std_forge.o: ../plugins/std_forge/std_forge.c \ + ../libcschem/config.h ../libcschem/abstract.h \ + ../libcschem/common_types.h ../libcschem/attrib.h ../libcschem/TODO.h \ + ../libcschem/concrete.h ../libcschem/rtree.h ../libcschem/oidpath.h \ + ../libcschem/vtoid.h ../../src_3rd/libuundo/uundo.h \ + ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/engine.h ../libcschem/actions_csch.h \ + ../libcschem/libcschem.h ../libcschem/project.h \ + ../libcschem/util_compile.h ../plugins/std_forge/cond.h \ + ../plugins/std_forge/cond_gram.h ../plugins/std_forge/dlg_test_bench.h \ + ../plugins/std_forge/std_forge.h +../plugins/std_tools/std_tools.o: ../plugins/std_tools/std_tools.c \ + ../libcschem/config.h ../libcschem/search.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../sch-rnd/draw.h ../sch-rnd/draw_xor.h ../sch-rnd/style.h \ + ../sch-rnd/select.h ../sch-rnd/operation.h ../libcschem/cnc_text.h \ + ../libcschem/cnc_text_dyn.h ../sch-rnd/search.h \ + ../plugins/std_tools/line_common.c ../libcschem/cnc_line.h \ + ../libcschem/cnc_pen.h ../libcschem/operation.h ../libcschem/concrete.h \ + ../libcschem/util_wirenet.h ../sch-rnd/crosshair.h \ + ../sch-rnd/conf_core.h ../plugins/std_tools/tool_circle.c \ + ../libcschem/cnc_arc.h ../plugins/std_tools/tool_rect.c \ + ../libcschem/cnc_poly.h ../libcschem/vtcoutline.h \ + ../plugins/std_tools/tool_wirenet.c ../plugins/std_tools/tool_line.c \ + ../plugins/std_tools/tool_arrow.c ../plugins/std_tools/tool_movecopy.h \ + ../plugins/std_tools/tool_polyedit.h ../plugins/std_tools/tool_remove.c \ + ../plugins/std_tools/tool_rotate.c ../plugins/std_tools/tool_movecopy.c \ + ../libcschem/cnc_obj.h ../libcschem/event.h ../libcschem/attrib.h \ + ../libcschem/cnc_pen.h ../libcschem/cnc_text.h \ + ../libcschem/util_endpoint.h ../libcschem/htepu.h ../libcschem/config.h \ + ../plugins/std_tools/tool_polyedit.c ../../src_3rd/gengeo2d/cline.h \ + ../../src_3rd/gengeo2d/vect.h ../../src_3rd/gengeo2d/box.h \ + ../plugins/std_tools/tool_text.c ../plugins/std_tools/tool_lock.c \ + ../plugins/std_tools/tool_mirror.c ../plugins/std_tools/tool_buffer.c \ + ../sch-rnd/buffer.h +../plugins/symlib_fs/symlib_fs.o: ../plugins/symlib_fs/symlib_fs.c \ + ../libcschem/config.h ../libcschem/plug_io.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/abstract.h ../libcschem/TODO.h ../libcschem/plug_library.h \ + ../libcschem/util_lib_fs.h ../libcschem/config.h ../libcschem/cnc_grp.h \ + ../libcschem/cnc_any_obj.h ../libcschem/concrete.h +../plugins/symlib_local/symlib_local.o: \ + ../plugins/symlib_local/symlib_local.c ../libcschem/config.h \ + ../libcschem/concrete.h ../libcschem/common_types.h ../libcschem/rtree.h \ + ../libcschem/attrib.h ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/cnc_any_obj.h ../libcschem/concrete.h \ + ../libcschem/cnc_grp.h ../libcschem/cnc_grp_child.h \ + ../libcschem/rotate.h ../../src_3rd/gengeo2d/xform.h \ + ../../src_3rd/gengeo2d/vect.h ../libcschem/cnc_text.h \ + ../libcschem/cnc_text_dyn.h ../libcschem/plug_library.h \ + ../libcschem/event.h ../libcschem/util_loclib.h \ + ../libcschem/actions_csch.h ../libcschem/operation.h \ + ../libcschem/op_common.h ../libcschem/operation.h ../sch-rnd/conf_core.h \ + ../plugins/symlib_local/loc_ops.c ../plugins/symlib_local/loc_acts.c +../plugins/target_none/target_none.o: \ + ../plugins/target_none/target_none.c ../libcschem/config.h \ + ../libcschem/libcschem.h ../../src_3rd/libminuid/libminuid.h \ + ../libcschem/abstract.h ../libcschem/common_types.h \ + ../libcschem/attrib.h ../libcschem/TODO.h ../libcschem/engine.h \ + ../libcschem/actions_csch.h +../plugins/target_pcb/target_pcb.o: ../plugins/target_pcb/target_pcb.c \ + ../libcschem/config.h ../libcschem/libcschem.h \ + ../../src_3rd/libminuid/libminuid.h ../libcschem/abstract.h \ + ../libcschem/common_types.h ../libcschem/attrib.h ../libcschem/TODO.h \ + ../libcschem/engine.h ../libcschem/actions_csch.h \ + ../libcschem/util_compile.h ../plugins/lib_target/lib_target.h \ + ../plugins/target_pcb/target_pcb_conf.h \ + ../plugins/target_pcb/conf_internal.c \ + ../plugins/target_pcb/target_pcb_conf_fields.h +../plugins/target_spice/htcp.o: ../plugins/target_spice/htcp.c \ + ../plugins/target_spice/htcp.h ../libcschem/abstract.h \ + ../libcschem/common_types.h ../libcschem/config.h ../libcschem/attrib.h \ + ../libcschem/TODO.h +../plugins/target_spice/target_spice.o: \ + ../plugins/target_spice/target_spice.c ../libcschem/config.h \ + ../../src_3rd/load_cache/load_cache.h ../libcschem/libcschem.h \ + ../../src_3rd/libminuid/libminuid.h ../libcschem/abstract.h \ + ../libcschem/common_types.h ../libcschem/attrib.h ../libcschem/TODO.h \ + ../libcschem/compile.h ../libcschem/concrete.h ../libcschem/rtree.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/project.h ../libcschem/engine.h ../libcschem/cnc_grp.h \ + ../libcschem/event.h ../libcschem/actions_csch.h \ + ../libcschem/util_compile.h ../libcschem/util_loclib.h \ + ../libcschem/plug_library.h ../libcschem/util_lib_fs.h \ + ../libcschem/config.h ../libcschem/hierarchy.h \ + ../plugins/sch_dialogs/quick_attr_util.h \ + ../plugins/lib_target/lib_target.h ../plugins/target_spice/htcp.h \ + ../plugins/target_spice/target_spice_conf.h \ + ../plugins/target_spice/conf_internal.c \ + ../plugins/target_spice/mod_parse.c ../plugins/target_spice/loclib.c \ + ../plugins/target_spice/libs.c ../plugins/target_spice/preview.c \ + ../plugins/target_spice/target_spice_conf_fields.h +../../src_3rd/libucdf/ucdf.o: ../../src_3rd/libucdf/ucdf.c \ + ../../src_3rd/libucdf/ucdf.h +buffer.o: buffer.c ../libcschem/config.h ../libcschem/project.h \ + ../libcschem/common_types.h ../libcschem/concrete.h ../libcschem/rtree.h \ + ../libcschem/attrib.h ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/engine.h ../libcschem/abstract.h ../libcschem/TODO.h \ + ../libcschem/search.h ../libcschem/cnc_any_obj.h ../libcschem/concrete.h \ + ../libcschem/cnc_grp.h ../libcschem/cnc_text.h \ + ../libcschem/cnc_text_dyn.h ../libcschem/cnc_obj.h ../libcschem/event.h \ + ../libcschem/attrib.h ../libcschem/cnc_pen.h ../libcschem/cnc_text.h \ + ../libcschem/cnc_conn.h ../libcschem/vtoidpath.h \ + ../libcschem/operation.h ../libcschem/op_common.h \ + ../libcschem/operation.h ../libcschem/plug_io.h ../libcschem/event.h \ + ../libcschem/util_wirenet.h ../libcschem/cnc_line.h \ + ../libcschem/util_grp.h conf_core.h crosshair.h draw.h search.h \ + funchash_core.h funchash_core_list.h buffer.h +build_run.o: build_run.c ../libcschem/config.h conf_core.h build_run.h \ + emergency.h ../libcschem/concrete.h ../libcschem/common_types.h \ + ../libcschem/rtree.h ../libcschem/attrib.h ../libcschem/oidpath.h \ + ../libcschem/vtoid.h ../../src_3rd/libuundo/uundo.h \ + ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h +conf_core.o: conf_core.c config.h ../libcschem/config.h conf_core.h \ + conf_core_fields.h +conf_internal.o: conf_internal.c +crosshair.o: crosshair.c ../libcschem/config.h conf_core.h draw.h \ + ../libcschem/concrete.h ../libcschem/common_types.h ../libcschem/rtree.h \ + ../libcschem/attrib.h ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + crosshair.h +defsheet_internal.o: defsheet_internal.c +draw.o: draw.c ../libcschem/config.h ../libcschem/abstract.h \ + ../libcschem/common_types.h ../libcschem/attrib.h ../libcschem/TODO.h \ + ../libcschem/concrete.h ../libcschem/rtree.h ../libcschem/oidpath.h \ + ../libcschem/vtoid.h ../../src_3rd/libuundo/uundo.h \ + ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/cnc_grp.h ../libcschem/cnc_line.h ../libcschem/cnc_conn.h \ + ../libcschem/vtoidpath.h ../libcschem/cnc_poly.h \ + ../libcschem/vtcoutline.h ../libcschem/cnc_arc.h ../libcschem/cnc_text.h \ + ../libcschem/cnc_text_dyn.h ../libcschem/cnc_pen.h \ + ../libcschem/non_graphical.h ../libcschem/hierarchy.h \ + ../libcschem/util_wirenet.h ../libcschem/event.h ../libcschem/project.h \ + ../libcschem/engine.h ../../src_3rd/gengeo2d/xform.h \ + ../../src_3rd/gengeo2d/vect.h conf_core.h font.h draw.h search.h \ + draw_poly.c +draw_xor.o: draw_xor.c ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/config.h ../libcschem/rtree.h \ + ../libcschem/attrib.h ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/cnc_line.h ../libcschem/cnc_poly.h \ + ../libcschem/vtcoutline.h ../libcschem/cnc_arc.h ../libcschem/cnc_text.h \ + ../libcschem/cnc_text_dyn.h ../libcschem/cnc_pen.h draw.h draw_xor.h \ + font.h +emergency.o: emergency.c ../libcschem/config.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/plug_io.h ../libcschem/abstract.h ../libcschem/TODO.h \ + conf_core.h emergency.h +export.o: export.c ../libcschem/config.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/abstract.h ../libcschem/TODO.h ../libcschem/plug_io.h \ + ../libcschem/util_export.h ../libcschem/project.h ../libcschem/engine.h \ + ../libcschem/compile.h sheet.h export.h ../sch-rnd/draw.h +file_act.o: file_act.c ../libcschem/config.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/plug_library.h ../libcschem/event.h ../libcschem/cnc_grp.h \ + ../libcschem/operation.h ../libcschem/concrete.h ../libcschem/project.h \ + ../libcschem/engine.h ../libcschem/abstract.h ../libcschem/TODO.h \ + ../libcschem/plug_io.h ../libcschem/util_loclib.h sheet.h conf_core.h \ + build_run.h multi.h project.h +font.o: font.c ../libcschem/config.h ../libcschem/cnc_pen.h \ + ../libcschem/concrete.h ../libcschem/common_types.h ../libcschem/rtree.h \ + ../libcschem/attrib.h ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/cnc_text.h ../libcschem/cnc_text_dyn.h \ + ../libcschem/rotate.h conf_core.h draw.h font.h font_rnd.c \ + font_internal.c font_act.c funchash_core.h funchash_core_list.h +main_act.o: main_act.c ../libcschem/config.h crosshair.h conf_core.h \ + build_run.h ../libcschem/undo.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h +menu_default.o: menu_default.c +multi.o: multi.c ../libcschem/config.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/project.h ../libcschem/engine.h ../libcschem/abstract.h \ + ../libcschem/TODO.h ../libcschem/util_project.h ../libcschem/event.h \ + ../libcschem/plug_io.h conf_core.h sheet.h project.h multi.h +operation.o: operation.c ../libcschem/config.h ../libcschem/operation.h \ + ../libcschem/concrete.h ../libcschem/common_types.h ../libcschem/rtree.h \ + ../libcschem/attrib.h ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/cnc_text.h ../libcschem/concrete.h \ + ../libcschem/cnc_text_dyn.h ../libcschem/cnc_obj.h ../libcschem/event.h \ + ../libcschem/attrib.h ../libcschem/cnc_pen.h ../libcschem/cnc_text.h \ + draw.h search.h font.h operation.h +plug_io_act.o: plug_io_act.c config.h ../libcschem/config.h \ + ../libcschem/event.h ../libcschem/project.h ../libcschem/common_types.h \ + ../libcschem/concrete.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/engine.h ../libcschem/abstract.h ../libcschem/TODO.h \ + ../libcschem/plug_io.h ../libcschem/cnc_text.h \ + ../libcschem/cnc_text_dyn.h ../sch-rnd/multi.h ../sch-rnd/project.h \ + plug_io_act.h +project.o: project.c ../libcschem/config.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/project.h ../libcschem/engine.h ../libcschem/abstract.h \ + ../libcschem/TODO.h ../libcschem/util_parse.h \ + ../../src_3rd/load_cache/load_cache.h ../libcschem/event.h multi.h \ + conf_core.h +sch-rnd.o: sch-rnd.c config.h ../libcschem/config.h \ + ../libcschem/libcschem.h ../../src_3rd/libminuid/libminuid.h \ + ../libcschem/project.h ../libcschem/common_types.h \ + ../libcschem/concrete.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/engine.h ../libcschem/abstract.h ../libcschem/TODO.h \ + ../libcschem/compile.h ../libcschem/util_export.h ../libcschem/event.h \ + ../libcschem/csch_printf.h ../libcschem/hierarchy.h conf_core.h \ + crosshair.h build_run.h sheet.h draw.h font.h ../libcschem/cnc_text.h \ + ../libcschem/cnc_text_dyn.h emergency.h project.h multi.h plug_io_act.h \ + export.h ../sch-rnd/draw.h buildin.c funchash_core.h \ + funchash_core_list.h +search.o: search.c ../libcschem/config.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/operation.h ../libcschem/concrete.h ../libcschem/cnc_obj.h \ + ../libcschem/event.h ../libcschem/attrib.h ../libcschem/cnc_pen.h \ + ../libcschem/cnc_text.h ../libcschem/cnc_text_dyn.h \ + ../libcschem/cnc_text.h ../libcschem/search.h \ + ../libcschem/util_wirenet.h ../libcschem/cnc_line.h conf_core.h draw.h \ + search.h +select.o: select.c ../libcschem/config.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/operation.h ../libcschem/concrete.h \ + ../libcschem/cnc_any_obj.h ../libcschem/cnc_obj.h ../libcschem/event.h \ + ../libcschem/attrib.h ../libcschem/cnc_pen.h ../libcschem/cnc_text.h \ + ../libcschem/cnc_text_dyn.h ../libcschem/cnc_text.h conf_core.h draw.h \ + search.h select.h +select_act.o: select_act.c ../libcschem/config.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/search.h ../libcschem/operation.h ../libcschem/concrete.h \ + ../libcschem/util_wirenet.h ../libcschem/cnc_line.h funchash_core.h \ + funchash_core_list.h conf_core.h select.h +sheet.o: sheet.c ../libcschem/config.h \ + ../../src_3rd/libminuid/libminuid.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/project.h ../libcschem/engine.h ../libcschem/abstract.h \ + ../libcschem/TODO.h ../libcschem/plug_library.h ../libcschem/event.h \ + ../libcschem/libcschem.h ../libcschem/plug_io.h conf_core.h util_sheet.h \ + draw.h +style.o: style.c ../libcschem/config.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h ../../src_3rd/libminuid/libminuid.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/cnc_pen.h style.h +util_sheet.o: util_sheet.c config.h ../libcschem/config.h \ + ../libcschem/libcschem.h ../../src_3rd/libminuid/libminuid.h \ + ../libcschem/cnc_pen.h ../libcschem/concrete.h \ + ../libcschem/common_types.h ../libcschem/rtree.h ../libcschem/attrib.h \ + ../libcschem/oidpath.h ../libcschem/vtoid.h \ + ../../src_3rd/libuundo/uundo.h \ + ../../src_3rd/gengeo2d/typecfg_long_double.h ../../src_3rd/opc89.h \ + ../../src_3rd/gengeo2d/common.h ../../src_3rd/gengeo2d/prim.h \ + ../libcschem/project.h ../libcschem/engine.h ../libcschem/abstract.h \ + ../libcschem/TODO.h sheet.h util_sheet.h Index: tags/1.0.5/src/sch-rnd/Makefile.in =================================================================== --- tags/1.0.5/src/sch-rnd/Makefile.in (nonexistent) +++ tags/1.0.5/src/sch-rnd/Makefile.in (revision 10414) @@ -0,0 +1,224 @@ + +put /local/csch/root {../..} +put /local/csch/CFLAGS {-I. -I.. } +put /local/rnd/DEPDEPS {conf_internal.c defsheet_internal.c menu_default.c } +put /local/rnd/DEPCFLAGS {} + +include {template/cc.tmpasm} +include [@@/local/csch/librnd_template@/debug.tmpasm@] + +put /local/csch/OBJS [@ + buffer.o + conf_core.o + conf_internal.o + crosshair.o + defsheet_internal.o + draw.o + draw_xor.o + emergency.o + export.o + file_act.o + font.o + plug_io_act.o + sch-rnd.o + search.o + select.o + select_act.o + operation.o + build_run.o + main_act.o + menu_default.o + multi.o + project.o + style.o + sheet.o + util_sheet.o +@] + + +put /local/csch/LIBS_3RD [@ + $(ROOT)/src_3rd/libminuid/libminuid.a + $(ROOT)/src_3rd/libuundo/uundo.o + $(ROOT)/src_3rd/libuundo/uundo_debug.o + $(ROOT)/src_3rd/load_cache/load_cache.o +@] + +uniq /local/csch/LIBS_3RD + +put /local/csch/DEPDEPS {} + + +#---- modules ----# +# extra rules for modules +put /local/rnd/CLEANFILES {} +put /local/pcb/CLEANRULES {} +put /local/pcb/EXEDEPS {} +put /local/pcb/all {} +put /local/pcb/buildin_init {} +put /local/rnd/rules/install_ {} +put /local/rnd/rules/install {} +put /local/rnd/rules/linstall {} +put /local/rnd/rules/uninstall {} +put /local/rnd/mod/OBJS {} +put /local/rnd/mod/OBJS_C99 {} +put /local/rnd/mod/CONF {} +put /local/rnd/mod/LDFLAGS {} +put /local/rnd/mod/CFLAGS {} +put /local/rnd/mod/YACC {} +put /local/rnd/mod/LEX {} +put /local/rnd/mod/BYACCIC {} +put /local/rnd/mod/UREGLEX {} + +put /local/csch/tmpasm/buildin {../src/plugins/Buildin.tmpasm} +put /local/csch/tmpasm/plugin {../src/plugins/Plugin.tmpasm} +put /local/csch/tmpasm/disable {../src/plugins/Disable.tmpasm} +put /local/csch/tmpasm/common_enabled {../src/plugins/Common_enabled.tmpasm} +put /local/csch/tmpasm/plugin_sphash [@@/local/csch/librnd_template@/plugin_sphash.tmpasm@] +put /local/csch/tmpasm/plugin_conf [@@/local/csch/librnd_template@/plugin_conf.tmpasm@] +put /local/csch/tmpasm/plugin_intconf [@@/local/csch/librnd_template@/plugin_intconf.tmpasm@] +put /local/csch/tmpasm/plugin_intmenu [@@/local/csch/librnd_template@/plugin_intmenu.tmpasm@] +put /local/csch/tmpasm/comp_var [@@/local/csch/librnd_template@/comp_var.tmpasm@] + +include {../src/plugins/plugins_ALL.tmpasm} + +append /local/csch/OBJS ?/local/csch/MOD_OBJS + +uniq /local/csch/OBJS + +append /local/csch/CFLAGS ?/local/csch/MOD_CFLAGS +append /local/csch/LDFLAGS ?/local/csch/MOD_LDFLAGS + +### Makefile ### + +print [@ +ROOT=@/local/csch/root@ +include $(ROOT)/Makefile.conf +include $(LIBRND_MAK) + +RNDLIB_LDLIBS = -lrnd-hid -lrnd-font2 -lrnd-poly -lrnd-core -lrnd-3rd +ROOT=@/local/csch/root@ +CC=@cc/cc@ +CFLAGS=-I. @/local/csch/CFLAGS@ @/local/csch/c89flags@ @?/local/rnd/CFLAGS@ $(CFLAGS_LIBRND) @?/local/csch/librnd_extra_inc@ +C89FLAGS=$(CFLAGS) +CP=cp +MKDIR=mkdir -p +LDFLAGS=@/local/csch/LDFLAGS@ @?/local/rnd/LDFLAGS@ $(LDFLAGS_LIBRND) @?/local/csch/librnd_extra_ldf@ +OBJS = @/local/csch/OBJS@ +LDLIBS=$(RNDLIB_LDLIBS) $(LDFLAGS_LIBRND_FUNGW) @libs/ldl@ -lm +PLUGDIR=../plugins +PLUGIDIR=./plugins + +LIBMINUID_CFLAGS=@/local/csch/CFLAGS@ @?/local/rnd/CFLAGS@ +LIBMINUID_LDFLAGS=@/local/csch/LDFLAGS@ @?/local/rnd/LDFLAGS@ + +CLEAN_FILES = sch-rnd conf_core_fields.h buildin.c + +all: + $(MAKE) revcheck + $(MAKE) all_exe + +include $(ROOT)/Makefile.conf + +revcheck: + cd $(ROOT)/scconfig && ./revtest Rev.stamp < Rev.tab + +all_exe: sch-rnd @/local/pcb/all@ + +LIBCSCHEM=../libcschem +include $(LIBCSCHEM)/Makefile.objs + +sch-rnd: $(OBJS) $(LIBCSCHEM_OBJS) @/local/csch/LIBS_3RD@ + $(CC) -o sch-rnd $(OBJS) $(LIBCSCHEM_OBJS) $(LDFLAGS) @/local/csch/LIBS_3RD@ $(LDLIBS) + +buildin.c: $(PLUGDIR)/.builtin.pups $(PUPLUG) + cd $(PLUGDIR) && $(PUPLUG) buildin.c "-" < $(PLUGDIR)/.builtin.pups > ../sch-rnd/buildin.c + +conf_core_fields.h: conf_core.h + $(GENCONF) < conf_core.h > conf_core_fields.h + +conf_core.o: conf_core_fields.h + +$(LIBCSCHEM_OBJS): + cd $(ROOT)/src/libcschem && $(MAKE) libcschem.a + + +### embedded (internal) version of configs and data files ### + +conf_internal.c: sch-rnd-conf.lht $(CQUOTE) + $(CQUOTE) -n rnd_conf_internal < sch-rnd-conf.lht > conf_internal.c + +defsheet_internal.c: default-sheet.lht + $(CQUOTE) -n default_sheet_internal < default-sheet.lht > defsheet_internal.c + +menu_default.c: menu-default.lht $(CQUOTE) + $(CQUOTE) -n rnd_hidlib_default_embedded_menu menu_default.c + +### src_3rd explicit rules ### + +$(ROOT)/src_3rd/libminuid/libminuid.a: + cd $(ROOT)/src_3rd/libminuid && $(MAKE) LIBMINUID_CFLAGS="$(LIBMINUID_CFLAGS)" LIBMINUID_LDFLAGS="$(LIBMINUID_LDFLAGS)" + +$(ROOT)/src_3rd/libuundo/uundo.o $(ROOT)/src_3rd/libuundo/uundo_debug.o: + cd $(ROOT)/src_3rd/libuundo && $(MAKE) uundo.o uundo_debug.o "CC=$(CC)" "CFLAGS=$(CFLAGS)" + +$(ROOT)/src_3rd/load_cache/load_cache.o: + cd $(ROOT)/src_3rd/load_cache && $(MAKE) load_cache.o "CC=$(CC)" "CFLAGS=$(CFLAGS)" + +### misc ### +map_plugins: + cd ../plugins && ./map_plugins.sh + +clean: + -rm $(OBJS) sch-rnd @/local/rnd/CLEANFILES@ + -cd $(ROOT)/src_3rd/libminuid && $(MAKE) clean + -cd $(ROOT)/src_3rd/libuundo && $(MAKE) clean + -cd $(ROOT)/src_3rd/load_cache && $(MAKE) clean + +distclean: clean + -rm buildin.c conf_core_fields.h ../plugins/.builtin.pups Makefile defsheet_internal.c conf_internal.c + + +install_schrnd: + $(SCCBOX) mkdir -p "$(BINDIR)" "$(DATADIR)" "$(LIBDIR)" "$(LIBDIR)/plugins" "$(CONFDIR)" + $(SCCBOX) $(HOW) "sch-rnd$(EXE)" "$(BINDIR)/sch-rnd$(EXE)" + $(SCCBOX) $(HOW) "sch-rnd-conf.lht" "$(CONFDIR)/sch-rnd-conf.lht" + $(SCCBOX) $(HOW) "menu-default.lht" "$(CONFDIR)/menu-default.lht" + $(SCCBOX) $(HOW) "default-sheet.lht" "$(DATADIR)/default-sheet.lht"@/local/rnd/rules/install_@ + +install: + $(MAKE) install_schrnd HOW="install -f" + +linstall: + $(MAKE) install_schrnd HOW="linstall -f" + +uninstall: + $(MAKE) install_schrnd HOW="uninstall" + +@] + + +#---- rules ----# + +put /local/comp/OBJS_C89 /local/csch/OBJS +put /local/comp/C89FLAGS {$(C89FLAGS)} +include [@@/local/csch/librnd_template@/compile.tmpasm@] + +put /local/dep/OUTFN {../src/sch-rnd/Makefile.depgen} +put /local/dep/SRCS /local/csch/OBJS +put /local/dep/CFLAGS /local/csch/CFLAGS +gsub /local/dep/SRCS {.o } {.c } +include [@@/local/csch/librnd_template@/cdep.tmpasm@] + +print [@ + +# --- Extra rules from modules --- +@?/local/csch/MOD_RULES@ +@?/local/rnd/RULES@ + +@] + + +redir {../src/plugins/.builtin.pups} +print [@# Autogenerated by ./configure - do NOT edit - contains the list of buildins +@?/local/csch/buildin_pups@ +@] Index: tags/1.0.5/src/sch-rnd/buffer.c =================================================================== --- tags/1.0.5/src/sch-rnd/buffer.c (nonexistent) +++ tags/1.0.5/src/sch-rnd/buffer.c (revision 10414) @@ -0,0 +1,554 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - sch-rnd (executable) + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/* Paste buffers for copy/paste */ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "conf_core.h" +#include "crosshair.h" +#include "draw.h" +#include "search.h" +#include "funchash_core.h" + +#include "buffer.h" + +csch_sheet_t *sch_rnd_buffer[SCH_RND_BUFFER_MAX]; +csch_project_t sch_rnd_buffer_prj; + +RND_INLINE void get_obj_parent_sel(csch_sheet_t *sheet, csch_chdr_t *obj, int *skip, int *orphan) +{ + csch_cgrp_t *grp; + + *skip = 0; + *orphan = 0; + + if (obj->parent == &sheet->direct) + return; /* first level selected is always good to copy */ + + /* skip if any parent group is selected (will be copied by copying that group) */ + for(grp = obj->parent; grp != &sheet->direct; grp = grp->hdr.parent) { + if ((grp == NULL) || (grp->hdr.selected)) { + *skip = 1; + return; + } + } + + /* group-part object selected, but group is not selected */ + *orphan = 1; +} + +/* Create a new wirenet in the buffer for each wirenet on the sheet we are + copying wire object for */ +static csch_cgrp_t *buffer_wirenet(csch_sheet_t *buffer, csch_cgrp_t *sheet_wn, int alloc) +{ + htip_entry_t *e; + csch_cgrp_t *buff_wn; + csch_source_arg_t *src; + + for(e = htip_first(&buffer->direct.id2obj); e != NULL; e = htip_next(&buffer->direct.id2obj, e)) { + buff_wn = e->value; + if ((buff_wn->hdr.type == CSCH_CTYPE_GRP) && (buff_wn->role == CSCH_ROLE_WIRE_NET) && (buff_wn->hdr.mark_ptr == sheet_wn)) + return buff_wn; + } + + if (!alloc) + return NULL; + + buff_wn = csch_cgrp_alloc(buffer, &buffer->direct, csch_oid_new(buffer, &buffer->direct)); + src = csch_attrib_src_c(NULL, 0, 0, "wirenet copy to buffer"); + csch_attrib_set(&buff_wn->attr, 0, "role", "wire-net", src, NULL); + buff_wn->role = CSCH_ROLE_WIRE_NET; + buff_wn->hdr.mark_ptr = sheet_wn; + return buff_wn; +} + +/* Copy src attributes if dst doesn't have attributes yet. Both src and + dst are wirenets */ +static void maybe_copy_wirenet_attrs(csch_cgrp_t *dst, csch_cgrp_t *src) +{ + if (dst->attr.used > 1) + return; /* already copied */ + csch_attrib_copy_all(&dst->attr, &src->attr); +} + +int sch_rnd_buffer_copy_selected(csch_sheet_t *sheet, csch_sheet_t *buffer, csch_coord_t dx, csch_coord_t dy, int del) +{ + long n; + vtp0_t objs = {0}; + + if (csch_search_all_selected(sheet, NULL, &objs, 1) == 0) { + rnd_message(RND_MSG_ERROR, "Can't copy to buffer: nothing selected\n"); + return -1; + } + + csch_cobj_redraw_freeze(sheet); + uundo_freeze_serial(&sheet->undo); + uundo_freeze_add(&buffer->undo); + csch_wirenet_recalc_freeze(sheet); + csch_wirenet_recalc_freeze(buffer); + + for(n = 0; n < objs.used; n++) { + csch_chdr_t *obj = objs.array[n], *newo; + int skip, orphan, need_norm; + + get_obj_parent_sel(sheet, obj, &skip, &orphan); + if (skip) continue; + + newo = obj; + need_norm = 0; + rnd_event(&sheet->hidlib, CSCH_EVENT_BUFFER_COPY_CUSTOM, "pp", &newo, buffer); + if (newo == obj) { + /* nobody handled it: do a plain copy */ + if (obj->type == CSCH_CTYPE_CONN) /* do not copy conns, let the code recalc them */ + continue; + if (obj->type == CSCH_CTYPE_GRP_REF) { + rnd_message(RND_MSG_ERROR, "Can't copy group ref object to buffer\n"); + continue; + } + if (obj->parent->role == CSCH_ROLE_WIRE_NET) { /* need to put the object in the "same" wirenet within the buffer so the result is a wire not just a line */ + csch_cgrp_t *buff_wn = buffer_wirenet(buffer, obj->parent, 1); + newo = csch_cobj_dup(buffer, buff_wn, obj, 0, 0); + need_norm = 1; + if ((obj->type == CSCH_CTYPE_TEXT) && (((csch_text_t *)obj)->dyntext)) { + /* if wirenet dyntext is copied, assume all attributes should be copied too */ + maybe_copy_wirenet_attrs(buff_wn, obj->parent); + } + } + else + newo = csch_cobj_dup(buffer, &buffer->direct, obj, 0, 0); + } + + if (newo->floater || need_norm) + csch_inst2spec(sheet, newo, obj, 0); /* transform from parent to absolute */ + + if ((newo != NULL) && ((dx != 0) || (dy != 0))) + csch_move(buffer, newo, -dx, -dy, 0); + + if (del) + csch_op_remove(sheet, objs.array[n]); + } + + csch_wirenet_recalc_unfreeze(buffer); + csch_wirenet_recalc_unfreeze(sheet); + uundo_unfreeze_add(&buffer->undo); + uundo_unfreeze_serial(&sheet->undo); + uundo_inc_serial(&sheet->undo); + csch_cobj_redraw_unfreeze(sheet); + + vtp0_uninit(&objs); + return 0; +} + +void sch_rnd_buffer_paste(csch_sheet_t *sheet, csch_sheet_t *buffer, csch_coord_t dx, csch_coord_t dy) +{ + int warned = 0; + htip_entry_t *e; + + csch_cobj_redraw_freeze(sheet); + uundo_freeze_serial(&sheet->undo); + csch_wirenet_recalc_freeze(sheet); + + /* copy only the first level of the tree: groups will implicitly bring their sub-objects */ + for(e = htip_first(&buffer->direct.id2obj); e != NULL; e = htip_next(&buffer->direct.id2obj, e)) { + csch_chdr_t *obj = e->value, *newo; + int need_conn_recalc = 0; + + if ((obj == &buffer->direct.hdr) || (obj == &buffer->indirect.hdr)) + continue; + + newo = obj; + rnd_event(&sheet->hidlib, CSCH_EVENT_BUFFER_PASTE_CUSTOM, "p", &newo); + if (newo == obj) { + /* nobody handled it: do a plain copy */ + + if (obj->type == CSCH_CTYPE_CONN) /* rather let the code recalculate them */ + continue; + + if (obj->type == CSCH_CTYPE_GRP_REF) { + rnd_message(RND_MSG_ERROR, "Can't paste group ref object from buffer\n"); + continue; + } + newo = csch_cobj_dup(sheet, &sheet->direct, obj, 0, 0); + if (csch_obj_is_grp(newo)) { + csch_cgrp_t *newg = ((csch_cgrp_t *)newo); + newg->sym_prefer_loclib = 0; /* lib buffer paste related special casing */ + + if ((newg->role == CSCH_ROLE_SYMBOL) || (newg->role == CSCH_ROLE_TERMINAL) || (newg->role == CSCH_ROLE_WIRE_NET)) + need_conn_recalc = 1; /* recalc later, after the final coords are known */ + } + } + + if (newo != NULL) { + csch_cgrp_t *grp; + + if ((dx != 0) || (dy != 0)) + csch_move(sheet, newo, dx, dy, 0); + else if (csch_obj_is_grp(newo)) + csch_cgrp_update(sheet, (csch_cgrp_t *)newo, 1); + csch_op_inserted(sheet, newo->parent, newo); + + /* wirenet side effects */ + grp = (csch_cgrp_t *)newo; + if (csch_obj_is_grp(newo) && (grp->role == CSCH_ROLE_WIRE_NET)) { + TODO("merge#31: also put grp on a list that attemtps to merge lines using csch_wirenet_recalc_merges in unfreeze(); test case: draw wire, copy it to extend itself -> should be merged into a single line, pcb-rnd does that too"); + csch_wirenet_recalc_junctions(sheet, grp); /* we are under freeze; this really just adds the wn to the merge-recalc-list for the unfreeze */ + } + + if (need_conn_recalc) + csch_conn_auto_recalc(sheet, newo); + } + else { + if (!warned) { + rnd_message(RND_MSG_ERROR, "Failed to paste some of the buffer objects\n"); + warned = 1; + } + } + } + + csch_wirenet_recalc_unfreeze(sheet); + uundo_unfreeze_serial(&sheet->undo); + uundo_inc_serial(&sheet->undo); + csch_cobj_redraw_unfreeze(sheet); +} + +int sch_rnd_buffer_clear(csch_sheet_t *buffer) +{ + csch_chdr_t *obj, *next; + + uundo_freeze_add(&buffer->undo); + for(obj = gdl_first(&buffer->active); obj != NULL; obj = next) { + next = gdl_next(&buffer->active, obj); + if ((obj != &buffer->direct.hdr) && (obj != &buffer->indirect.hdr)) + csch_cobj_uninit(obj); + } + uundo_unfreeze_add(&buffer->undo); + + return 0; +} + +static const char csch_acts_BufferPaste[] = "BufferPaste([x, y])"; +static const char csch_acth_BufferPaste[] = "Paste selection from active paste buffer to the board at crosshair or x;y.\n"; +fgw_error_t csch_act_BufferPaste(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + csch_sheet_t *sheet = (csch_sheet_t *)RND_ACT_DESIGN; + csch_coord_t x = P2C(sch_rnd_crosshair_x), y = P2C(sch_rnd_crosshair_y); + + RND_ACT_MAY_CONVARG(1, FGW_COORD, BufferPaste, x = fgw_coord(&(argv[1]))); + RND_ACT_MAY_CONVARG(2, FGW_COORD, BufferPaste, y = fgw_coord(&(argv[2]))); + + sch_rnd_buffer_paste(sheet, SCH_RND_PASTEBUFFER, x, y); + RND_ACT_IRES(0); + return 0; +} + +static const char csch_acts_BufferCopy[] = "BufferCopy([x, y])"; +static const char csch_acth_BufferCopy[] = "Copy selection to currently active paste buffer.\n"; +fgw_error_t csch_act_BufferCopy(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + csch_sheet_t *sheet = (csch_sheet_t *)RND_ACT_DESIGN; + csch_coord_t x = P2C(sch_rnd_crosshair_x), y = P2C(sch_rnd_crosshair_y); + + RND_ACT_MAY_CONVARG(1, FGW_COORD, BufferCopy, x = fgw_coord(&(argv[1]))); + RND_ACT_MAY_CONVARG(2, FGW_COORD, BufferCopy, y = fgw_coord(&(argv[2]))); + + RND_ACT_IRES(sch_rnd_buffer_copy_selected(sheet, SCH_RND_PASTEBUFFER, x, y, 0)); + return 0; +} + +static const char csch_acts_BufferCut[] = "BufferCut()"; +static const char csch_acth_BufferCut[] = "Cut selection to currently active paste buffer: copy objects then remove them from the sheet.\n"; +fgw_error_t csch_act_BufferCut(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + csch_sheet_t *sheet = (csch_sheet_t *)RND_ACT_DESIGN; + RND_ACT_IRES(sch_rnd_buffer_copy_selected(sheet, SCH_RND_PASTEBUFFER, P2C(sch_rnd_crosshair_x), P2C(sch_rnd_crosshair_y), 1)); + return 0; +} + +static const char csch_acts_BufferClear[] = "BufferClear()"; +static const char csch_acth_BufferClear[] = "Empty currently active paste buffer.\n"; +fgw_error_t csch_act_BufferClear(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + RND_ACT_IRES(sch_rnd_buffer_clear(SCH_RND_PASTEBUFFER)); + return 0; +} + +static const char csch_acts_BufferSave[] = "BufferSave([group|symbol|all, [filename], [fmt])"; +static const char csch_acth_BufferSave[] = "Save content of buffer; if first arg is symbol, the first symbol group is saved, if sheet the whole buffer is saved as sheet\n"; +fgw_error_t csch_act_BufferSave(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + int rv = -1, cmd, anygrp = 0; + char *fn = NULL; + const char *fmt = "lihata"; + + RND_ACT_CONVARG(1, FGW_KEYWORD, BufferSave, cmd = fgw_keyword(&argv[1])); + RND_ACT_MAY_CONVARG(2, FGW_STR, BufferSave, fn = argv[2].val.str); + RND_ACT_MAY_CONVARG(3, FGW_STR, BufferSave, fmt = argv[3].val.str); + + if (fn == NULL) { + static char *default_file = NULL; + const char *ext = ".*"; + const char *title, *expl; + + if (cmd == F_Symbol) { + default_file = rnd_strdup("sym.ry"); + ext = ".ry"; + } + + switch(cmd) { + case F_Symbol: + title = "Save symbol from buffer..."; + expl = "Choose a file to save the symbol (group) to,\nfrom the paste buffer.\n"; + break; + + case F_All: + title = "Save whole buffer..."; + expl = "Choose a file to save the whole paste buffer to.\n"; + break; + + case F_Group: + default: + title = "Save group from buffer..."; + expl = "Choose a file to save the group to,\nfrom the paste buffer.\n"; + break; + } + + fn = rnd_hid_fileselect(rnd_gui, title, expl, default_file, ext, NULL, "grp", 0, NULL); + if (default_file != NULL) { + free(default_file); + default_file = NULL; + } + if (fn == NULL) { /* cancel */ + RND_ACT_IRES(-1); + return 0; + } + default_file = fn; + } + + switch(cmd) { + case F_Group: + anygrp = 1; + /* fall-thru */ + case F_Symbol: + { + csch_cgrp_t *grp = NULL, *dir = &(SCH_RND_PASTEBUFFER->direct); + htip_entry_t *e; + + for(e = htip_first(&dir->id2obj); e != NULL; e = htip_next(&dir->id2obj, e)) { + csch_cgrp_t *o = e->value; + if ((o->hdr.type == CSCH_CTYPE_GRP) && (anygrp || (o->role == CSCH_ROLE_SYMBOL))) { + grp = o; + break; + } + } + if (grp != NULL) + rv = csch_save_grp(grp, fn, fmt, 1); + } + break; + case F_All: + rv = csch_save_buffer(SCH_RND_PASTEBUFFER, fn, fmt); + break; + default: + rnd_message(RND_MSG_ERROR, "BufferSave: invalid first arg\n"); + break; + } + + RND_ACT_IRES(rv); + return 0; +} + +static const char csch_acts_BufferLoad[] = "BufferLoad([group|symbol|all, [filename], [fmt])"; +static const char csch_acth_BufferLoad[] = "Load content of buffer; if first arg is symbol, the first symbol group is saved, if sheet the whole buffer is saved as sheet\n"; +fgw_error_t csch_act_BufferLoad(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + int rv = -1, cmd = F_Sheet; + char *fn = NULL; + const char *fmt = "lihata"; + + RND_ACT_MAY_CONVARG(1, FGW_KEYWORD, BufferSave, cmd = fgw_keyword(&argv[1])); + RND_ACT_MAY_CONVARG(2, FGW_STR, BufferSave, fn = argv[2].val.str); + + if (fn == NULL) { + static char *default_file = NULL; + fn = rnd_hid_fileselect(rnd_gui, "Load group into buffer...", + "Choose a file to load the group from\ninto the paste buffer.\n", + default_file, ".*", NULL, "grp", RND_HID_FSD_READ, NULL); + if (default_file != NULL) { + free(default_file); + default_file = NULL; + } + if (fn == NULL) { /* cancel */ + RND_ACT_IRES(-1); + return 0; + } + default_file = fn; + } + + switch(cmd) { + case F_Symbol: + case F_Group: + if (csch_load_grp(SCH_RND_PASTEBUFFER, fn, fmt) != NULL) + rv = 0; + break; + case F_All: + rv = csch_load_buffer(SCH_RND_PASTEBUFFER, fn, fmt); + break; + default: + rnd_message(RND_MSG_ERROR, "BufferLoad: invalid first arg\n"); + break; + } + + RND_ACT_IRES(rv); + return 0; +} + +static const char csch_acts_BufferChk[] = "BufferChk(num)"; +static const char csch_acth_BufferChk[] = "Returns whether buffer num is active or not\n"; +fgw_error_t csch_act_BufferChk(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + int expected; + RND_ACT_CONVARG(1, FGW_INT, BufferChk, expected = argv[1].val.nat_int); + RND_ACT_IRES((conf_core.editor.buffer_number + 1) == expected); + return 0; +} + +static const char csch_acts_BufferSwitch[] = "BufferSwitch(num)"; +static const char csch_acth_BufferSwitch[] = "Activates buffer num\n"; +fgw_error_t csch_act_BufferSwitch(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + int bn; + RND_ACT_CONVARG(1, FGW_INT, BufferSwitch, bn = argv[1].val.nat_int); + + rnd_conf_set_design("editor/buffer_number", "%d", bn-1); + rnd_gui->invalidate_all(rnd_gui); + + RND_ACT_IRES(0); + return 0; +} + +static const char csch_acts_ReplaceSymbol[] = "ReplaceSymbol([object])"; +static const char csch_acth_ReplaceSymbol[] = "Replace target symbol with the first symbol from the buffer\n"; +fgw_error_t csch_act_ReplaceSymbol(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + csch_sheet_t *sheet = (csch_sheet_t *)RND_ACT_DESIGN; + int op = F_Object; + csch_chdr_t *dst; + csch_cgrp_t *dst_grp, *src_grp; + csch_coord_t x, y; + htip_entry_t *e; + + RND_ACT_MAY_CONVARG(1, FGW_KEYWORD, ReplaceSymbol, op = fgw_keyword(&argv[1])); + + e = htip_first(&SCH_RND_PASTEBUFFER->direct.id2obj); + if (e == NULL) { + rnd_message(RND_MSG_ERROR, "ReplaceSymbol(): buffer is empty, should contain a single symbol\n"); + goto error; + } + src_grp = e->value; + if (!csch_obj_is_grp(&src_grp->hdr) || (src_grp->role != CSCH_ROLE_SYMBOL)) { + rnd_message(RND_MSG_ERROR, "ReplaceSymbol(): buffer should contain a single symbol\n"); + goto error; + } + + switch(op) { + case F_Object: + if (sch_rnd_get_coords("Click on symbol to replace", &x, &y, 0) != 0) + goto error; + dst = sch_rnd_search_obj_at(sheet, x, y, sch_rnd_slop); + if (dst == NULL) { + rnd_message(RND_MSG_ERROR, "ReplaceSymbol(): no object under cursor\n"); + goto error; + } + dst_grp = (csch_cgrp_t *)dst; + if (!csch_obj_is_grp(dst) || (dst_grp->role != CSCH_ROLE_SYMBOL)) { + rnd_message(RND_MSG_ERROR, "ReplaceSymbol(): object under the cursor is not a symbol\n"); + goto error; + } + if (csch_cgrp_replace(dst->sheet, dst_grp, src_grp, CSCH_REPLGRP_KEEP_DST_ATTR | CSCH_REPLGRP_PREFER_DST_ATTR) != 0) { + rnd_message(RND_MSG_ERROR, "ReplaceSymbol(): failed to replace symbol\n"); + goto error; + } + break; + default: + rnd_message(RND_MSG_ERROR, "ReplaceSymbol(): invalid target argument\n"); + return FGW_ERR_ARG_CONV; + } + + RND_ACT_IRES(0); + return 0; + error:; + RND_ACT_IRES(-1); + return 0; +} + +static rnd_action_t buffer_action_list[] = { + {"BufferPaste", csch_act_BufferPaste, csch_acth_BufferPaste, csch_acts_BufferPaste}, + {"BufferCopy", csch_act_BufferCopy, csch_acth_BufferCopy, csch_acts_BufferCopy}, + {"BufferCut", csch_act_BufferCut, csch_acth_BufferCut, csch_acts_BufferCut}, + {"BufferClear", csch_act_BufferClear, csch_acth_BufferClear, csch_acts_BufferClear}, + {"BufferSave", csch_act_BufferSave, csch_acth_BufferSave, csch_acts_BufferSave}, + {"BufferLoad", csch_act_BufferLoad, csch_acth_BufferLoad, csch_acts_BufferLoad}, + {"BufferChk", csch_act_BufferChk, csch_acth_BufferChk, csch_acts_BufferChk}, + {"BufferSwitch", csch_act_BufferSwitch, csch_acth_BufferSwitch, csch_acts_BufferSwitch}, + {"ReplaceSymbol", csch_act_ReplaceSymbol, csch_acth_ReplaceSymbol, csch_acts_ReplaceSymbol} +}; + + +void sch_rnd_buffer_init2(void) +{ + int n; + for(n = 0; n < SCH_RND_BUFFER_MAX; n++) + sch_rnd_buffer[n] = csch_sheet_alloc(&sch_rnd_buffer_prj); + RND_REGISTER_ACTIONS(buffer_action_list, NULL); +} + +void sch_rnd_buffer_uninit(void) +{ + int n; + for(n = 0; n < SCH_RND_BUFFER_MAX; n++) + csch_sheet_free(sch_rnd_buffer[n]); +} + + + Index: tags/1.0.5/src/sch-rnd/buffer.h =================================================================== --- tags/1.0.5/src/sch-rnd/buffer.h (nonexistent) +++ tags/1.0.5/src/sch-rnd/buffer.h (revision 10414) @@ -0,0 +1,17 @@ +#ifndef SCH_RND_BUFFER_H +#define SCH_RND_BUFFER_H + +#include + +#define SCH_RND_BUFFER_MAX 5 +#define SCH_RND_BUFFER_SCRATCH (SCH_RND_BUFFER_MAX-1) + +extern csch_sheet_t *sch_rnd_buffer[SCH_RND_BUFFER_MAX]; +extern csch_project_t sch_rnd_buffer_prj; + +#define SCH_RND_PASTEBUFFER (sch_rnd_buffer[conf_core.editor.buffer_number % SCH_RND_BUFFER_MAX]) + +void sch_rnd_buffer_paste(csch_sheet_t *sheet, csch_sheet_t *buffer, csch_coord_t dx, csch_coord_t dy); +int sch_rnd_buffer_clear(csch_sheet_t *buffer); + +#endif \ No newline at end of file Index: tags/1.0.5/src/sch-rnd/build_run.c =================================================================== --- tags/1.0.5/src/sch-rnd/build_run.c (nonexistent) +++ tags/1.0.5/src/sch-rnd/build_run.c (revision 10414) @@ -0,0 +1,243 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996,2006 Thomas Nau + * pcb-rnd Copyright (C) 2017,2018 Alain Vigne + * pcb-rnd Copyright (C) 2018,2020,2021 Tibor 'Igor2' Palinkas + * sch-rnd Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#include +#include +#include +#include "conf_core.h" +#include "build_run.h" +#include +#include + +#include "emergency.h" + +extern void sch_rnd_main_uninit(void); + +void sch_rnd_quit_app(void) +{ + /* save data if necessary. It not needed, then don't trigger EmergencySave + * via our atexit() registering of csch_emergency_save(). We presumably wanted to + * exit here and thus it is not an emergency. */ + sch_rnd_emergency_save(); + + if (rnd_gui->do_exit == NULL) { + sch_rnd_main_uninit(); + exit(0); + } + else + rnd_gui->do_exit(rnd_gui); +} + +char *sch_rnd_get_info_program(void) +{ + static gds_t info; + static int first_time = 1; + + if (first_time) { + first_time = 0; + gds_init(&info); + gds_append_str(&info, "This is sch-rnd " CSCH_VERSION " (" CSCH_REVISION ")" "\nan interactive "); + gds_append_str(&info, "schematics editor\nfrom the Ringdove EDA suite\ncompiled using librnd version " RND_VER_STR "\nrunning with librnd version "); + gds_append_str(&info, rnd_ver_str); + gds_append(&info, '\n'); + } + return info.array; +} + +char *sch_rnd_get_info_copyright(void) +{ + static gds_t info; + static int first_time = 1; + + if (first_time) { + first_time = 0; + gds_init(&info); + + gds_append_str(&info, "sch-rnd copyright:\n"); + gds_append_str(&info, "Copyright (C) Tibor Palinkas 2019..2023\n"); + gds_append_str(&info, "With some code copied from fellow Ringdove application pcb-rnd\n(see http://www.repo.hu/projects/pcb-rnd)\n\n"); + } + return info.array; +} + +char *sch_rnd_get_info_websites(const char **url_out) +{ + static gds_t info; + static int first_time = 1; + static const char *URL = "http://www.repo.hu/projects/sch-rnd\n"; + + if (first_time) { + first_time = 0; + gds_init(&info); + + gds_append_str(&info, "For more information see:\n"); + gds_append_str(&info, URL); + } + + if (url_out != NULL) + *url_out = URL; + + return info.array; +} + +char *sch_rnd_get_info_comments(void) +{ + static gds_t info; + static int first_time = 1; + char *tmp; + + if (first_time) { + first_time = 0; + gds_init(&info); + + tmp = sch_rnd_get_info_program(); + gds_append_str(&info, tmp); + tmp = sch_rnd_get_info_websites(NULL); + gds_append_str(&info, tmp); + } + return info.array; +} + + +char *sch_rnd_get_info_compile_options(void) +{ + rnd_hid_t **hids; + int i; + static gds_t info; + static int first_time = 1; + +#define TAB " " + + if (first_time) { + first_time = 0; + gds_init(&info); + + gds_append_str(&info, "----- Run Time Options -----\n"); + gds_append_str(&info, "GUI: "); + if (rnd_gui != NULL) { + gds_append_str(&info, rnd_gui->name); + gds_append_str(&info, "\n"); + } + else + gds_append_str(&info, "none\n"); + + gds_append_str(&info, "\n----- Compile Time Options -----\n"); + hids = rnd_hid_enumerate(); + gds_append_str(&info, "GUI:\n"); + for (i = 0; hids[i]; i++) { + if (hids[i]->gui) { + gds_append_str(&info, TAB); + gds_append_str(&info, hids[i]->name); + gds_append_str(&info, " : "); + gds_append_str(&info, hids[i]->description); + gds_append_str(&info, "\n"); + } + } + + gds_append_str(&info, "Exporters:\n"); + for (i = 0; hids[i]; i++) { + if (hids[i]->exporter) { + gds_append_str(&info, TAB); + gds_append_str(&info, hids[i]->name); + gds_append_str(&info, " : "); + gds_append_str(&info, hids[i]->description); + gds_append_str(&info, "\n"); + } + } + + gds_append_str(&info, "Printers:\n"); + for (i = 0; hids[i]; i++) { + if (hids[i]->printer) { + gds_append_str(&info, TAB); + gds_append_str(&info, hids[i]->name); + gds_append_str(&info, " : "); + gds_append_str(&info, hids[i]->description); + gds_append_str(&info, "\n"); + } + } + } +#undef TAB + return info.array; +} + +char *sch_rnd_get_info_license(void) +{ + static gds_t info; + static int first_time = 1; + + if (first_time) { + first_time = 0; + gds_init(&info); + + gds_append_str(&info, "sch-rnd is licensed under the terms of the GNU\n"); + gds_append_str(&info, "General Public License version 2\n"); + gds_append_str(&info, "See the COPYING file for more information\n\n"); + } + return info.array; +} + +/* Catches signals which abort the program. */ +void sch_rnd_catch_signal(int Signal) +{ + const char *s; + + switch (Signal) { +#ifdef SIGHUP + case SIGHUP: + s = "SIGHUP"; + break; +#endif + case SIGINT: + s = "SIGINT"; + break; +#ifdef SIGQUIT + case SIGQUIT: + s = "SIGQUIT"; + break; +#endif + case SIGABRT: + s = "SIGABRT"; + break; + case SIGTERM: + s = "SIGTERM"; + break; + case SIGSEGV: + s = "SIGSEGV"; + break; + default: + s = "unknown"; + break; + } + rnd_message(RND_MSG_ERROR, "aborted by %s signal\n", s); + exit(1); +} Index: tags/1.0.5/src/sch-rnd/build_run.h =================================================================== --- tags/1.0.5/src/sch-rnd/build_run.h (nonexistent) +++ tags/1.0.5/src/sch-rnd/build_run.h (revision 10414) @@ -0,0 +1,58 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is xopied from pcb-rnd, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996,2006 Thomas Nau + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#ifndef PCB_BUILD_RUN_H +#define PCB_BUILD_RUN_H + +void sch_rnd_quit_app(void); + +/* Returns a string that has a bunch of information about this program. */ +char *sch_rnd_get_info_program(void); + +/* Returns a string that has a bunch of information about the copyrights. */ +char *sch_rnd_get_info_copyright(void); + +/* Returns a string about how the program is licensed. */ +char *sch_rnd_get_info_license(void); + +/* Returns a string that has a bunch of information about the websites. */ +char *sch_rnd_get_info_websites(const char **url_out); + +/* Returns a string as the concatenation of sch_rnd_get_info_program() and sch_rnd_get_info_websites() */ +char *sch_rnd_get_info_comments(void); + +/* Returns a string that has a bunch of information about the options selected at compile time. */ +char *sch_rnd_get_info_compile_options(void); + +/* Author's name: either from the config system (typically from the design) or + as a last resort from the OS */ +const char *csch_author(void); + +void sch_rnd_catch_signal(int Signal); + +#endif Index: tags/1.0.5/src/sch-rnd/conf_core.c =================================================================== --- tags/1.0.5/src/sch-rnd/conf_core.c (nonexistent) +++ tags/1.0.5/src/sch-rnd/conf_core.c (revision 10414) @@ -0,0 +1,93 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - sch-rnd (executable) + * Copyright (C) 2020 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include +#include +#include +#include +#include +#include "config.h" +#include "conf_core.h" + +conf_core_t conf_core; + +int sch_rnd_conf_dont_merge_node(const char *path, void *lhtn, int role, int default_prio, int default_policy, rnd_conf_native_t *target) +{ + if ((strncmp(path, "prj/", 4) == 0) && (role != RND_CFR_PROJECT)) { + rnd_message(RND_MSG_ERROR, "ERROR: ignoring conf node %s on role %s\nMust be in the project file\n(Not accepted from any other config)\n", path, rnd_conf_role_name(role)); + return 1; + } + if ((strcmp(path, "rc/font_dirs") == 0) && ((role == RND_CFR_DESIGN) || (role == RND_CFR_PROJECT))) { + rnd_message(RND_MSG_ERROR, "ERROR: ignoring conf node %s on role %s\nMust be in user or system config\n(Not accepted from design or project)\n", path, rnd_conf_role_name(role)); + /* Rationale: + Fonts are mapped on startup, before we read design or projects. + Fonts are not meant to be static or fixed in any way, they are + not to be shipped with the project. */ + return 1; + } + if (strcmp(path, "compile/views") == 0) { + if ((role == RND_CFR_DESIGN) || (role == RND_CFR_CLI)) { + rnd_message(RND_MSG_ERROR, "ERROR: ignoring conf node %s on role %s\nMust be in the project file, user or system config\n(Not accepted from design or cli)\n", path, rnd_conf_role_name(role)); + return 1; + } + } + if (strcmp(path, "editor/autocpmp") == 0) { + if ((role > RND_CFR_USER) && (role != RND_CFR_CLI)) { + rnd_message(RND_MSG_ERROR, "ERROR: ignoring conf node %s on role %s\nMust be in the user, system or CLI config\n", path, rnd_conf_role_name(role)); + return 1; + } + } + + return 0; +} + +static char *dotdir = NULL; + +void sch_rnd_conf_core_postproc(void) +{ + rnd_conf_force_set_str(conf_core.rc.path.prefix, SCH_PREFIX); rnd_conf_ro("rc/path/prefix"); + rnd_conf_force_set_str(conf_core.rc.path.lib, SCHLIBDIR); rnd_conf_ro("rc/path/lib"); + rnd_conf_force_set_str(conf_core.rc.path.bin, BINDIR); rnd_conf_ro("rc/path/bin"); + rnd_conf_force_set_str(conf_core.rc.path.share, SCHSHAREDIR); rnd_conf_ro("rc/path/share"); + + if (dotdir == NULL) + dotdir = rnd_concat(rnd_conf.rc.path.home, RND_DIR_SEPARATOR_S, rnd_app.dot_dir, NULL); + rnd_conf_force_set_str(conf_core.rc.path.dotdir, dotdir); rnd_conf_ro("rc/path/dotdir"); +} + + +void conf_core_init() +{ +#define conf_reg(field,isarray,type_name,cpath,cname,desc,flags) \ + rnd_conf_reg_field(conf_core, field,isarray,type_name,cpath,cname,desc,flags); +#include "conf_core_fields.h" + sch_rnd_conf_core_postproc(); +} + +void conf_core_uninit(void) +{ + free(dotdir); +} Index: tags/1.0.5/src/sch-rnd/conf_core.h =================================================================== --- tags/1.0.5/src/sch-rnd/conf_core.h (nonexistent) +++ tags/1.0.5/src/sch-rnd/conf_core.h (revision 10414) @@ -0,0 +1,130 @@ +#ifndef SCH_RND_CONF_CORE_H +#define SCH_RND_CONF_CORE_H + +#include +#include + +typedef struct { + const struct rc { + RND_CFT_REAL file_changed_interval; /* how often to check if the file has changed on the disk (in seconds); 0 or negative means no check at all */ + RND_CFT_INTEGER backup_interval; /* time between two backups in seconds; 0 means disabled (no backups) */ + RND_CFT_LIST library_search_paths; /* ordered list of paths that are each recursively searched for symbol files */ + RND_CFT_LIST hlibrary_search_paths; /* ordered list of paths that are each recursively searched for external hierarchic child sheets */ + + RND_CFT_STRING emergency_name; /* file name template for emergency save anonymous .sch files (when sch-rnd crashes); optional field: first %ld --> pid, second %ld --> sheet uid; must be shorter than 240 characters. Don't do emergency save if this item is empty. */ + RND_CFT_STRING backup_name; /* file name template for periodic backup of board files; optional fields (the usual % substitutions work) */ + + RND_CFT_BOOLEAN keep_save_backups; /* TODO: a copy is made before a save operation overwrites an existing file; if this setting is true, keep the copy even after a successful save */ + + RND_CFT_LIST default_sheet_file; /* ordered list of paths to load default sheet from when a new sheet needs to be created */ + + RND_CFT_LIST font_dirs; /* Unordered list of directories to pick up Ringdove fonts from */ + + RND_CFT_BOOLEAN silently_create_on_load; /* TODO: do not generate an error message if the board does not exist on load from command line argument, silently create it in memory */ + + struct debug { + RND_CFT_BOOLEAN draw_text_xform; /* draw arrows representing xform matrix of text object's parent */ + RND_CFT_BOOLEAN draw_arc_bbox; /* draw an 1 pixel line on every arc object bounding box */ + } debug; + + /***** automatically set (in postproc) *****/ + struct { + RND_CFT_STRING prefix; /* e.g. /usr/local */ + RND_CFT_STRING lib; /* e.g. /usr/lib/sch-rnd */ + RND_CFT_STRING bin; /* e.g. /usr/bin */ + RND_CFT_STRING share; /* e.g. /usr/share/sch-rnd */ + RND_CFT_STRING fontdir; /* rnd fonts are searched in these dirs */ + + RND_CFT_STRING design; /* directory path of the current design, or if the current design doesn't have a file name yet */ + + RND_CFT_STRING dotdir; /* user's config dir, normally ~/.sch-rnd */ + } path; + + } rc; + const struct editor { + RND_CFT_INTEGER click_time; /* default time for click expiration, in ms */ + RND_CFT_INTEGER edit_time; /* default time to wait in dialog boxes after declaring editing finished and auto-applying changes, in ms */ + RND_CFT_INTEGER autocomp_time; /* default time to wait after last change before running autocompile, in ms; <=0 means immediate; shall be set in the user config (not accepted from project or design) */ + RND_CFT_BOOLEAN autocomp; /* whether enable autocomp on startup; shall be set in the user config (not accepted from project or design) */ + RND_CFT_BOOLEAN save_in_tmp; /* emergency save unsaved sheet data (despite the user clicks don't save) when user quits sch-rnd. Does not affect the on-crash emergency save. */ + RND_CFT_BOOLEAN line_refraction; + RND_CFT_BOOLEAN line_cont; + RND_CFT_BOOLEAN lock_floaters; /* lock down floaters so they can not be moved or selected */ + RND_CFT_BOOLEAN only_floaters; /* lock down everything else but floaters so only floater objects can be moved or selected */ + RND_CFT_BOOLEAN paste_to_local_lib; /* automatically paste library entries from buffer to sheet-local library and use references from the sheet instead of heavy copies */ + RND_CFT_BOOLEAN rubber_band_mode; /* moving wires try to keep their connections to other wires */ + RND_CFT_BOOLEAN rubber_band_ortho; /* add orthogonal (90 degree) wire line segments when rubber banding */ + RND_CFT_INTEGER buffer_number; /* index of the current buffer */ + struct { + RND_CFT_BOOLEAN disable_negative; /* selection box behaviour: disable the negative-direction selection - any selection box will select only what's fully within the box */ + RND_CFT_BOOLEAN symmetric_negative; /* selection box behaviour: when set, the selection direction is considered negative only if the box has negative size in the X direction */ + } selection; + struct { + RND_CFT_LIST tool_circle_stroke; /* pen preference for the circle tool; pick the first existing pen or if none existing the first item */ + RND_CFT_LIST tool_line_stroke; /* pen preference for the line tool; pick the first existing pen or if none existing the first item */ + RND_CFT_LIST tool_text_stroke; /* pen preference for the text tool; pick the first existing pen or if none existing the first item */ + RND_CFT_LIST tool_wire_stroke; /* pen preference for the wire tool; pick the first existing pen or if none existing the first item */ + + + RND_CFT_LIST tool_rect_stroke; /* pen preference for the rectangle tool; pick the first existing pen or if none existing the first item; used only if tool_rect_has_pen is true */ + RND_CFT_BOOLEAN tool_rect_has_stroke; /* whether to stroke (use the pen to draw the outline) */ + RND_CFT_BOOLEAN tool_rect_has_fill; /* whether to fill (draw a filled polyogn using the fill color) */ + RND_CFT_LIST tool_rect_fill; /* polygon fill color; used only if tool_rect_has_fill is true */ + } style; + struct { + RND_CFT_STRING family; /* if pen font is not found, search for a fallbakc font using this font family */ + RND_CFT_STRING style; /* if pen font is not found, search for a fallbakc font using this font style */ + } default_font; + } editor; + const struct appearance { + struct color { + RND_CFT_COLOR attached; + RND_CFT_COLOR selected_stroke; + RND_CFT_COLOR selected_fill; + RND_CFT_COLOR connection_good; + RND_CFT_COLOR connection_bad; + RND_CFT_COLOR hilight_stroke; + RND_CFT_COLOR symbol_meta_embed; /* symbol meta bounding box and info text draw color for group objects */ + RND_CFT_COLOR symbol_meta_loclib; /* symbol meta bounding box and info text draw color for group refs to local lib */ + RND_CFT_COLOR non_graphical_background; /* color of non-graphical sheet background */ + RND_CFT_COLOR non_graphical_text; /* color of non-graphical sheet text */ + } color; + } appearance; + const struct compile { + RND_CFT_BOOLEAN multiport_net_merge; /* when multiple ports with the same component:port name connect to different nets: if true, allow merging those nets, else throw an error */ + const struct hierarchic { + RND_CFT_BOOLEAN net_allow_rename; /* When false: throw an error if a network is named on both parent and child side of a hierarchic descend; otherwise use net_rename_prefer_top to decide which name to keep; best place to set this is the project role. */ + RND_CFT_BOOLEAN net_rename_prefer_top; /* If net_allow_rename==true, this decides whether to prefer parent (top) sheet's net name (true) or child (bottom) sheet's net name (false) when merging the two nets; best place to set this is the project role. */ + } hierarchic; + RND_CFT_HLIST views; + } compile; + const struct prj { + RND_CFT_LIST root_sheets; /* when non-empty, it lists all root sheets that are part of the project; each root sheet is the root of a hierarchy (may be a single sheet hierarchy, tho) */ + RND_CFT_LIST aux_sheets; /* when non-empty, it lists all non-root sheets that can be referenced by root sheets or other aux sheets in a hierarchy */ + } prj; + const struct stance { + RND_CFT_STRING model; /* model type (within the product family) to build: current value */ + RND_CFT_LIST model_values; /* model type: possible values */ + RND_CFT_STRING sub_major; /* major subtype property: current value */ + RND_CFT_LIST sub_major_values; /* major subtype: possible values */ + RND_CFT_STRING sub_minor; /* minor subtype property: current value */ + RND_CFT_LIST sub_minor_values; /* minor subtype: possible values */ + + + RND_CFT_STRING test_bench; /* which test bench to use, e.g. for simulation */ + RND_CFT_LIST test_bench_values; /* test bench: possible values */ + } stance; +} conf_core_t; + + +void conf_core_init(); +void sch_rnd_conf_core_postproc(void); + +extern conf_core_t conf_core; + + +int sch_rnd_conf_dont_merge_node(const char *path, void *lhtn, int role, int default_prio, int default_policy, rnd_conf_native_t *target); + +void conf_core_uninit(void); + +#endif Index: tags/1.0.5/src/sch-rnd/config.h.in =================================================================== --- tags/1.0.5/src/sch-rnd/config.h.in (nonexistent) +++ tags/1.0.5/src/sch-rnd/config.h.in (revision 10414) @@ -0,0 +1,40 @@ +print [@ +#include + +/* Version number of package */ +#define SCH_VERSION "@/local/version@" +#define SCH_REVISION "@/local/revision@" + +/****************************************************************************/ +/* Paths */ + +/* Relative path from bindir to exec_prefix */ +#define BINDIR_TO_EXECPREFIX ".." + +/* the dot-dir: where to save user config under ther user's home; it's used + as ~/DOT_SCH_RND/ */ +#define DOT_SCH_RND "@/local/csch/dot_sch_rnd@" +@] + +switch sys/class + case {win32} + print [@ +#define SCH_PREFIX rnd_w32_root +#define SCHSHAREDIR rnd_w32_sharedir +#define SCHLIBDIR rnd_w32_libdir +#define BINDIR rnd_w32_bindir +#define SCHCONFDIR @/local/confdir@ +@] + end; + default + print [@ +#define SCH_PREFIX "@/local/prefix@" +#define SCHSHAREDIR SCH_PREFIX "/share/sch-rnd" +#define SCHLIBDIR SCH_PREFIX "/lib/sch-rnd" +#define BINDIR SCH_PREFIX "/bin" +#define SCHCONFDIR "@/local/confdir@" +@] + end; +end; + + Index: tags/1.0.5/src/sch-rnd/crosshair.c =================================================================== --- tags/1.0.5/src/sch-rnd/crosshair.c (nonexistent) +++ tags/1.0.5/src/sch-rnd/crosshair.c (revision 10414) @@ -0,0 +1,115 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - sch-rnd (executable) + * Copyright (C) 2019 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "conf_core.h" + +#include "draw.h" +#include "crosshair.h" + +rnd_hid_gc_t sch_rnd_crosshair_gc; +rnd_coord_t sch_rnd_crosshair_x, sch_rnd_crosshair_y; /* screen coords */ + +void sch_rnd_hidlib_crosshair_move_to(rnd_design_t *hl, rnd_coord_t abs_x, rnd_coord_t abs_y, int mouse_mot) +{ + /* grid fit */ + abs_x = rnd_grid_fit(abs_x, hl->grid, hl->grid_ox); + abs_y = rnd_grid_fit(abs_y, hl->grid, hl->grid_oy); + + if ((abs_x == sch_rnd_crosshair_x) && (abs_y == sch_rnd_crosshair_y)) + return; /* no change, don't waste CPU */ + + /* update the GUI, emit events */ + rnd_hid_notify_crosshair_change(hl, rnd_false); + + hl->ch_x = sch_rnd_crosshair_x = abs_x; + hl->ch_y = sch_rnd_crosshair_y = abs_y; + + rnd_gui->set_crosshair(rnd_gui, abs_x, abs_y, 0); + rnd_tool_adjust_attached(hl); + rnd_hid_notify_crosshair_change(hl, rnd_true); + +} + +void sch_rnd_draw_attached(rnd_design_t *hidlib, rnd_bool inhibit_drawing_mode) +{ + if (!inhibit_drawing_mode) { + rnd_gui->set_drawing_mode(rnd_gui, RND_HID_COMP_RESET, 1, NULL); + rnd_gui->set_drawing_mode(rnd_gui, RND_HID_COMP_POSITIVE_XOR, 1, NULL); + } + + rnd_gui->set_color(sch_rnd_crosshair_gc, &conf_core.appearance.color.attached); + rnd_hid_set_line_width(sch_rnd_crosshair_gc, -1); + rnd_hid_set_line_cap(sch_rnd_crosshair_gc, rnd_cap_round); + rnd_tool_draw_attached(hidlib); + + if (!inhibit_drawing_mode) + rnd_gui->set_drawing_mode(rnd_gui, RND_HID_COMP_FLUSH, 1, NULL); +} + +void sch_rnd_notify_crosshair_change(rnd_design_t *hl, rnd_bool changes_complete) +{ + rnd_hid_notify_crosshair_change(hl, changes_complete); +} + +void sch_rnd_crosshair_gui_init(void) +{ + sch_rnd_crosshair_gc = rnd_hid_make_gc(); + rnd_hid_set_draw_xor(sch_rnd_crosshair_gc, 1); + +} + +void sch_rnd_crosshair_gui_uninit(void) +{ + rnd_hid_destroy_gc(sch_rnd_crosshair_gc); +} + +int sch_rnd_get_coords(const char *msg, csch_coord_t *x, csch_coord_t *y, int force) +{ + rnd_coord_t qx, qy; + int res; + + res = rnd_hid_get_coords(msg, &qx, &qy, force); + if (res != 0) + return res; + + *x = P2C(sch_rnd_crosshair_x); + *y = P2C(sch_rnd_crosshair_y); + + return 0; +} + Index: tags/1.0.5/src/sch-rnd/crosshair.h =================================================================== --- tags/1.0.5/src/sch-rnd/crosshair.h (nonexistent) +++ tags/1.0.5/src/sch-rnd/crosshair.h (revision 10414) @@ -0,0 +1,24 @@ +#ifndef CSCH_CROSSHAIR_H +#define CSCH_CROSSHAIR_H 1 + +#include + +#include + +extern rnd_coord_t sch_rnd_crosshair_x, sch_rnd_crosshair_y; /* screen coords */ +extern rnd_hid_gc_t sch_rnd_crosshair_gc; + +void sch_rnd_notify_crosshair_change(rnd_design_t *hl, rnd_bool changes_complete); + +void sch_rnd_crosshair_gui_init(void); +void sch_rnd_crosshair_gui_uninit(void); + +void sch_rnd_hidlib_crosshair_move_to(rnd_design_t *hl, rnd_coord_t abs_x, rnd_coord_t abs_y, int mouse_mot); +void sch_rnd_draw_attached(rnd_design_t *hidlib, rnd_bool inhibit_drawing_mode); + +/* Same as rnd_hid_get_coords(), except it works with crosshair coords, + converted to csch_coord_t */ +int sch_rnd_get_coords(const char *msg, csch_coord_t *x, csch_coord_t *y, int force); + + +#endif Index: tags/1.0.5/src/sch-rnd/dad.h =================================================================== --- tags/1.0.5/src/sch-rnd/dad.h (nonexistent) +++ tags/1.0.5/src/sch-rnd/dad.h (revision 10414) @@ -0,0 +1,10 @@ +#include + +/* On the DAD side the value is stored in .crd in nanometer */ +#define RND_DAD_CSCH_COORD(table) \ +do { \ + RND_DAD_SPIN_ANY(table, RND_DAD_SPIN_UNIT_CRD, RND_HATT_COORD, 1, csch_unit_family_cschem); \ + RND_DAD_SPIN_SET_EMPTY_UNIT(table, csch_unit_base); \ + RND_DAD_SPIN_SET_FMT(table, "%$rr"); \ +} while(0) + Index: tags/1.0.5/src/sch-rnd/default-sheet.lht =================================================================== --- tags/1.0.5/src/sch-rnd/default-sheet.lht (nonexistent) +++ tags/1.0.5/src/sch-rnd/default-sheet.lht (revision 10414) @@ -0,0 +1,79 @@ +ha:cschem-sheet-v1 { + # (invisible) objects that are referenced but not directly placed on the sheet + ha:obj_indirect.1 { + li:objects { + } + } + + # (visible) objects directly under the sheet + ha:obj_direct.2 { + uuid=8/SYZ/pfBzxyqFA12WQAAAAB; + li:objects { + ha:pen.sheet-decor { shape=circle; size=125; color=#777777; font_height = 3000; font_family=sans;} + ha:pen.sheet-decor-fill { shape=circle; size=125; color=#BBBBBB; font_height = 3000; font_family=sans;} + ha:pen.titlebox-frame { shape=circle; size=250; color=#777777; } + ha:pen.titlebox-fill { shape=circle; size=250; color=#BBFFBB; } + ha:pen.titlebox-big { shape=circle; size=250; color=#777777; font_height = 3000; font_family=sans; } + ha:pen.titlebox-small { shape=circle; size=250; color=#777777; font_height = 1500; font_family=sans; } + ha:pen.wire { shape=circle; size=250; color=#2222BB; font_height = 3000; font_family=sans; } + ha:pen.bus { shape=circle; size=1500; color=#2222BB; font_height = 3000; font_family=sans; } + ha:pen.hub { shape=circle; size=3000; color=#6666FF; font_height = 3000; font_family=sans; } + ha:pen.sym-decor { shape=circle; size=125; color=#119911; font_height = 3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=circle; size=125; color=#99FF99; font_height = 3000; font_family=sans; } + ha:pen.sym-primary { shape=circle; size=125; color=#119911; font_height = 3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=circle; size=125; color=#33BB33; font_height = 3000; font_family=sans; } + ha:pen.term-decor { shape=circle; size=250; color=#222222; font_height = 3000; font_family=sans; } + ha:pen.term-primary { shape=circle; size=250; color=#222222; font_height = 3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=circle; size=250; color=#555555; font_height = 3000; font_family=sans; } + ha:pen.busterm-decor { shape=circle; size=1500; color=#222222; font_height = 3000; font_family=sans; } + ha:pen.busterm-primary { shape=circle; size=1500; color=#222222; font_height = 3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=circle; size=1500; color=#555555; font_height = 3000; font_family=sans; } + ha:pen.junction { shape=circle; size=1000; color=#2222BB; font_height = 3000; font_family=sans; } + + # titlebox + ha:group.1 { + uuid=8/SYZ/pfBzxyqFA12WQAAAAC; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAg; + li:objects { + ha:polygon.11 { + li:outline { + ha:line { x1=0; y1=0; x2=80000; y2=0; } + ha:line { x1=80000; y1=0; x2=80000; y2=20000; } + ha:line { x1=80000; y1=20000; x2=0; y2=20000; } + ha:line { x1=0; y1=20000; x2=0; y2=0; } + } + stroke = titlebox-frame; + fill = titlebox-fill; + } + # grid + ha:line.12 { x1=0; y1=10000; x2=80000; y2=10000; stroke=titlebox-frame; } + ha:line.13 { x1=40000; y1=10000; x2=40000; y2=0; stroke=titlebox-frame; } + + ha:text.20 { x1=1000; y1=16500; stroke=titlebox-big; text=TITLE; } + ha:text.21 { x1=1000; y1=10500; x2=79000; y2=16000; dyntext=1; stroke=titlebox-big; text={%../../A.title%}; } + + ha:text.22 { x1=1000; y1=5500; stroke=titlebox-small; text={PROJECT:}; } + ha:text.23 { x1=13000; y1=5500; x2=39000; y2=9500; dyntext=1; stroke=titlebox-big; text={%project.name%}; } + ha:text.24 { x1=1000; y1=500; stroke=titlebox-small; text={PAGE:}; } + ha:text.25 { x1=10000; y1=500; x2=39000; y2=4500; dyntext=1; stroke=titlebox-big; text={%../../A.page%}; } + + ha:text.26 { x1=41000; y1=5500; stroke=titlebox-small; text={FILE:}; } + ha:text.27 { x1=48000; y1=5500; x2=79000; y2=9500; dyntext=1; stroke=titlebox-big; text={%filename%}; } + ha:text.28 { x1=41000; y1=500; stroke=titlebox-small; text={MAINTAINER:}; } + ha:text.29 { x1=55000; y1=500; x2=79000; y2=4500; dyntext=1; stroke=titlebox-big; text={%../../A.maintainer%}; } + ha:text.30 { x1=79000; y1=16000; mirx=1; dyntext=1; stroke=sheet-decor; text=%stance.model% %stance.sub_major% %stance.sub_minor% %stance.test_bench% %view.name%; } + } + ha:attrib { + purpose = titlebox + } + } + } + ha:attrib { + drawing_min_width = 287000 + drawing_min_height = 200000 + print_page = {A/4} + title = {} + page = {} + maintainer = {} + } + } +} Index: tags/1.0.5/src/sch-rnd/draw.c =================================================================== --- tags/1.0.5/src/sch-rnd/draw.c (nonexistent) +++ tags/1.0.5/src/sch-rnd/draw.c (revision 10414) @@ -0,0 +1,773 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - sch-rnd (executable) + * Copyright (C) 2019,2020,2022,2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "conf_core.h" +#include "font.h" +#include "draw.h" +#include "search.h" + +static const char draw_cookie[] = "sch-rnd/draw.c"; + +typedef struct { + csch_sheet_t *sheet; + csch_abstract_t *abst; + rnd_hid_gc_t gc; + vtp0_t objlist; + rnd_xform_t *xform; +} draw_ctx_t; + +TODO("code dup with pcb-rnd") +static void pcb_draw_dashed_line(rnd_hid_gc_t GC, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2, unsigned int segs, rnd_bool_t cheap) +{ +/* TODO: we need a real geo lib... using double here is plain wrong */ + double dx = x2-x1, dy = y2-y1; + double len_mnt = RND_ABS(dx) + RND_ABS(dy); + int n; + rnd_coord_t minlen = rnd_render->coord_per_pix * 8; + + /* Ignore info->xform->bloat because a dashed line is always thin */ + + if (len_mnt < minlen*2) { + /* line too short, just draw it */ + rnd_render->draw_line(GC, x1, y1, x2, y2); + return; + } + + segs = (segs << 1) + 1; /* must be odd */ + + if (cheap) { + if ((segs > 3) && (len_mnt < minlen * segs)) + segs = 3; + else if ((segs > 5) && (len_mnt < minlen * 2 * segs)) + segs = 5; + } + + /* first seg is drawn from x1, y1 with no rounding error due to n-1 == 0 */ + for(n = 1; n < segs; n+=2) + rnd_render->draw_line(GC, + x1 + (dx * (double)(n-1) / (double)segs), y1 + (dy * (double)(n-1) / (double)segs), + x1 + (dx * (double)n / (double)segs), y1 + (dy * (double)n / (double)segs)); + + + /* make sure the last segment is drawn properly to x2 and y2, don't leave + room for rounding errors */ + rnd_render->draw_line(GC, + x2 - (dx / (double)segs), y2 - (dy / (double)segs), + x2, y2); +} + +RND_INLINE rnd_cap_style_t pen_cap(csch_cpen_t *pen) +{ + switch(pen->shape) { + case CSCH_PSHP_ROUND: return rnd_cap_round; + case CSCH_PSHP_SQUARE: return rnd_cap_square; + } + + /* fallback for invalid */ + return rnd_cap_round; +} + +static void lighten_color(const rnd_color_t *orig, rnd_color_t *dst, double factor) +{ + rnd_color_load_int(dst, MIN(255, orig->r * factor), MIN(255, orig->g * factor), MIN(255, orig->b * factor), 255); +} + + +RND_INLINE const rnd_color_t *sch_rnd_stroke_color(draw_ctx_t *ctx, const csch_chdr_t *obj, const csch_cpen_t *stroke, int selected) +{ + const rnd_color_t *res; + int no_render_select = (ctx->xform != NULL) && (ctx->xform->no_render_select); + int no_render_hilight = (ctx->xform != NULL) && (ctx->xform->no_render_hilight); + + if (obj->hilight && !no_render_hilight) + return &conf_core.appearance.color.hilight_stroke; + + if (no_render_select) + selected = 0; + + res = selected ? &conf_core.appearance.color.selected_stroke : &stroke->color; + if ((ctx->xform != NULL) && (ctx->xform->faded)) { + static rnd_color_t tmp; + lighten_color(res, &tmp, 0.5); + res = &tmp; + } + return res; +} + +RND_INLINE const rnd_color_t *sch_rnd_fill_color(draw_ctx_t *ctx, const csch_chdr_t *obj, const csch_cpen_t *fill, int selected) +{ + const rnd_color_t *res; + if (obj->hilight) + return &conf_core.appearance.color.hilight_stroke; + res = selected ? &conf_core.appearance.color.selected_fill : &fill->color; + if ((ctx->xform != NULL) && (ctx->xform->faded)) { + static rnd_color_t tmp; + lighten_color(res, &tmp, 0.5); + res = &tmp; + } + return res; +} + +#include "draw_poly.c" + +RND_INLINE void draw_layer_line(draw_ctx_t *ctx, csch_line_t *l, csch_cpen_t *pen, int selected) +{ + rnd_render->set_color(ctx->gc, sch_rnd_stroke_color(ctx, &l->hdr, pen, selected)); + rnd_hid_set_line_cap(ctx->gc, pen_cap(pen)); + rnd_hid_set_line_width(ctx->gc, C2P(pen->size)); + rnd_render->draw_line(ctx->gc, C2P(l->inst.c.p1.x), C2P(l->inst.c.p1.y), C2P(l->inst.c.p2.x), C2P(l->inst.c.p2.y)); +} + +RND_INLINE void draw_layer_conn(draw_ctx_t *ctx, csch_conn_t *c) +{ + long n, *crd; + + if (c->coords.used == 0) + return; + + rnd_render->set_color(ctx->gc, &conf_core.appearance.color.connection_good); + rnd_hid_set_line_cap(ctx->gc, rnd_cap_round); + rnd_hid_set_line_width(ctx->gc, -2); + + for(n = 0, crd = c->coords.array; n < c->coords.used; n += 4, crd += 4) { + long slop = sch_rnd_slop; + long dx = crd[0] - crd[2], dy = crd[1] - crd[3]; + dx = RND_ABS(dx); dy = RND_ABS(dy); + + if (dx + dy <= slop) + rnd_render->draw_arc(ctx->gc, C2P((crd[0] + crd[2])/2), C2P((crd[1] + crd[3])/2), C2P(256), C2P(256), 0, 360); + else + rnd_render->draw_line(ctx->gc, C2P(crd[0]), C2P(crd[1]), C2P(crd[2]), C2P(crd[3])); + } +} + +RND_INLINE void draw_vectors(draw_ctx_t *ctx, g2d_vect_t base, g2d_vect_t origin, g2d_xform_t mx) +{ + g2d_vect_t u[6]; + int n; + + u[0] = g2d_vect(1000, 0); + u[1] = g2d_vect(900, +100); + u[2] = g2d_vect(900, -100); + u[3] = g2d_vect(0, 1000); + u[4] = g2d_vect(+100, 900); + u[5] = g2d_vect(-100, 900); + for(n = 0; n < 6; n++) { + u[n].x += base.x; + u[n].y += base.y; + u[n] = g2d_xform_vect2vect(mx, u[n]); + } + rnd_render->draw_line(ctx->gc, C2P(origin.x), C2P(origin.y), C2P(u[0].x), C2P(u[0].y)); + rnd_render->draw_line(ctx->gc, C2P(origin.x), C2P(origin.y), C2P(u[3].x), C2P(u[3].y)); + rnd_render->draw_line(ctx->gc, C2P(u[0].x), C2P(u[0].y), C2P(u[1].x), C2P(u[1].y)); + rnd_render->draw_line(ctx->gc, C2P(u[0].x), C2P(u[0].y), C2P(u[2].x), C2P(u[2].y)); + rnd_render->draw_line(ctx->gc, C2P(u[3].x), C2P(u[3].y), C2P(u[4].x), C2P(u[4].y)); + rnd_render->draw_line(ctx->gc, C2P(u[3].x), C2P(u[3].y), C2P(u[5].x), C2P(u[5].y)); +} + +RND_INLINE void print_mx(const char *name, g2d_xform_t mx) +{ + int n; + rnd_trace("MX %s\n", name); + for(n = 0; n < 9; n++) { + rnd_trace(" %.2f", mx.v[n]); + if ((n % 3) == 2) + rnd_trace("\n"); + } + rnd_trace("\n"); +} + +RND_INLINE void draw_layer_text(draw_ctx_t *ctx, csch_text_t *t, csch_cpen_t *pen, int selected) +{ + int use_local = (ctx->xform != NULL) && ctx->xform->use_local_vis; + int vis_meta = use_local ? ctx->xform->local_vis[CSCH_DSPLY_TEXT_META] : csch_layer_vis[CSCH_DSPLY_TEXT_META]; + + if (vis_meta) { + rnd_render->set_color(ctx->gc, sch_rnd_stroke_color(ctx, &t->hdr, pen, selected)); + rnd_hid_set_line_cap(ctx->gc, pen_cap(pen)); + rnd_hid_set_line_width(ctx->gc, -1); + + rnd_render->draw_line(ctx->gc, C2P(t->inst1.x), C2P(t->inst1.y), C2P(t->inst15.x), C2P(t->inst15.y)); + rnd_render->draw_line(ctx->gc, C2P(t->inst1.x), C2P(t->inst1.y), C2P(t->inst25.x), C2P(t->inst25.y)); + rnd_render->draw_line(ctx->gc, C2P(t->inst2.x), C2P(t->inst2.y), C2P(t->inst15.x), C2P(t->inst15.y)); + rnd_render->draw_line(ctx->gc, C2P(t->inst2.x), C2P(t->inst2.y), C2P(t->inst25.x), C2P(t->inst25.y)); + } + if (conf_core.rc.debug.draw_text_xform) { + rnd_render->set_color(ctx->gc, sch_rnd_stroke_color(ctx, &t->hdr, pen, selected)); + rnd_hid_set_line_cap(ctx->gc, pen_cap(pen)); + rnd_hid_set_line_width(ctx->gc, -1); + draw_vectors(ctx, t->spec1, t->inst1, t->hdr.parent->xform.mx); + +#if 0 + { + g2d_xform_t imx; + print_mx("orig:", t->hdr.parent->xform.mx); + rnd_render->set_color(ctx->gc, rnd_color_red); + csch_cgrp_inverse_matrix(&imx, t->hdr.parent); + imx.v[2] = imx.v[2] < 0 ? -1000 : 1000; + imx.v[5] = imx.v[5] < 0 ? -1000 : 1000; + draw_vectors(ctx, t->inst1, t->inst1, imx); + print_mx("inv:", imx); + } +#endif + } + + + rnd_render->set_color(ctx->gc, sch_rnd_stroke_color(ctx, &t->hdr, pen, selected)); + sch_rnd_font_text_render(ctx->sheet, ctx->gc, t, pen); + + if (vis_meta) { + double vx, vy, len; + + rnd_render->set_color(ctx->gc, rnd_color_red); + rnd_hid_set_line_cap(ctx->gc, pen_cap(pen)); + rnd_hid_set_line_width(ctx->gc, -3); + + vx = t->inst15.x - t->inst1.x; + vy = t->inst15.y - t->inst1.y; + len = sqrt(vx*vx+vy*vy); + if (len > 0) { + vx /= len; vy /= len; + rnd_render->draw_line(ctx->gc, C2P(t->inst1.x), C2P(t->inst1.y), C2P((csch_coord_t)(t->inst1.x + vx*3000)), C2P((csch_coord_t)(t->inst1.y + vy*3000))); + } + + rnd_render->set_color(ctx->gc, rnd_color_magenta); + vx = t->inst25.x - t->inst1.x; + vy = t->inst25.y - t->inst1.y; + len = sqrt(vx*vx+vy*vy); + if (len > 0) { + vx /= len; vy /= len; + rnd_render->draw_line(ctx->gc, C2P(t->inst1.x), C2P(t->inst1.y), C2P((csch_coord_t)(t->inst1.x + vx*3000)), C2P((csch_coord_t)(t->inst1.y + vy*3000))); + } + } +} + +RND_INLINE void draw_layer_arc(draw_ctx_t *ctx, csch_arc_t *a, csch_cpen_t *pen, int selected) +{ + rnd_render->set_color(ctx->gc, sch_rnd_stroke_color(ctx, &a->hdr, pen, selected)); + rnd_hid_set_line_cap(ctx->gc, pen_cap(pen)); + rnd_hid_set_line_width(ctx->gc, C2P(pen->size)); + rnd_render->draw_arc(ctx->gc, C2P(a->inst.c.c.x), C2P(a->inst.c.c.y), C2P(a->inst.c.r), C2P(a->inst.c.r), (180.0 - a->inst.c.start * RND_RAD_TO_DEG), -(a->inst.c.delta * RND_RAD_TO_DEG)); + + if (conf_core.rc.debug.draw_arc_bbox) { + rnd_hid_set_line_width(ctx->gc, -1); + rnd_render->draw_line(ctx->gc, C2P(a->hdr.bbox.x1), C2P(a->hdr.bbox.y1), C2P(a->hdr.bbox.x2), C2P(a->hdr.bbox.y1)); + rnd_render->draw_line(ctx->gc, C2P(a->hdr.bbox.x1), C2P(a->hdr.bbox.y1), C2P(a->hdr.bbox.x1), C2P(a->hdr.bbox.y2)); + rnd_render->draw_line(ctx->gc, C2P(a->hdr.bbox.x2), C2P(a->hdr.bbox.y2), C2P(a->hdr.bbox.x2), C2P(a->hdr.bbox.y1)); + rnd_render->draw_line(ctx->gc, C2P(a->hdr.bbox.x2), C2P(a->hdr.bbox.y2), C2P(a->hdr.bbox.x1), C2P(a->hdr.bbox.y2)); + } +} + +static csch_rtree_dir_t predraw_layer_obj(void *ctx_, void *obj_, const csch_rtree_box_t *box) +{ + draw_ctx_t *ctx = (draw_ctx_t *)ctx_; + csch_chdr_t *obj = obj_; + + switch(obj->type) { + case CSCH_CTYPE_TEXT: /* need to update font in a separate pass because it changes the rtree we are searching */ + { + csch_text_t *t = (csch_text_t *)obj; + if ((rnd_render->draw_pixmap != NULL) && (t->pixmap == NULL)) + vtp0_append(&ctx->objlist, t); + } + break; + default: break; + } + + return csch_RTREE_DIR_FOUND_CONT; + +} + +static void draw_grp_meta(draw_ctx_t *ctx, csch_cgrp_t *grp, int selected) +{ + int use_local = (ctx->xform != NULL) && ctx->xform->use_local_vis; + int vis_meta_sym = use_local ? ctx->xform->local_vis[CSCH_DSPLY_SYMBOL_META] : csch_layer_vis[CSCH_DSPLY_SYMBOL_META]; + + if (vis_meta_sym && (grp->role == CSCH_ROLE_SYMBOL) && (grp->hdr.bbox.x1 < grp->hdr.bbox.x2)) { + int embed = grp->hdr.type == CSCH_CTYPE_GRP; + rnd_render->set_color(ctx->gc, (embed ? &conf_core.appearance.color.symbol_meta_embed : &conf_core.appearance.color.symbol_meta_loclib)); + rnd_hid_set_line_cap(ctx->gc, rnd_cap_round); + rnd_hid_set_line_width(ctx->gc, -1); + + pcb_draw_dashed_line(ctx->gc, C2P(grp->hdr.bbox.x1), C2P(grp->hdr.bbox.y1), C2P(grp->hdr.bbox.x2), C2P(grp->hdr.bbox.y1), 5, rnd_true); + pcb_draw_dashed_line(ctx->gc, C2P(grp->hdr.bbox.x2), C2P(grp->hdr.bbox.y1), C2P(grp->hdr.bbox.x2), C2P(grp->hdr.bbox.y2), 5, rnd_true); + pcb_draw_dashed_line(ctx->gc, C2P(grp->hdr.bbox.x2), C2P(grp->hdr.bbox.y2), C2P(grp->hdr.bbox.x1), C2P(grp->hdr.bbox.y2), 5, rnd_true); + pcb_draw_dashed_line(ctx->gc, C2P(grp->hdr.bbox.x1), C2P(grp->hdr.bbox.y2), C2P(grp->hdr.bbox.x1), C2P(grp->hdr.bbox.y1), 5, rnd_true); + + /* draw E or L for embed or local */ + rnd_hid_set_line_width(ctx->gc, -2); + rnd_render->draw_line(ctx->gc, C2P(grp->hdr.bbox.x1 + 1000), C2P(grp->hdr.bbox.y2 - 1000), C2P(grp->hdr.bbox.x1 + 1000), C2P(grp->hdr.bbox.y2 - 3000)); + rnd_render->draw_line(ctx->gc, C2P(grp->hdr.bbox.x1 + 1000), C2P(grp->hdr.bbox.y2 - 3000), C2P(grp->hdr.bbox.x1 + 2000), C2P(grp->hdr.bbox.y2 - 3000)); + if (embed) { + rnd_render->draw_line(ctx->gc, C2P(grp->hdr.bbox.x1 + 1000), C2P(grp->hdr.bbox.y2 - 1000), C2P(grp->hdr.bbox.x1 + 2000), C2P(grp->hdr.bbox.y2 - 1000)); + rnd_render->draw_line(ctx->gc, C2P(grp->hdr.bbox.x1 + 1000), C2P(grp->hdr.bbox.y2 - 2000), C2P(grp->hdr.bbox.x1 + 1500), C2P(grp->hdr.bbox.y2 - 2000)); + } + } + + /* mark origin */ + if (vis_meta_sym && (grp->role == CSCH_ROLE_SYMBOL)) { + rnd_render->set_color(ctx->gc, &conf_core.appearance.color.symbol_meta_embed); + rnd_hid_set_line_cap(ctx->gc, rnd_cap_round); + rnd_hid_set_line_width(ctx->gc, -1); + rnd_render->draw_line(ctx->gc, C2P(grp->x - 100), C2P(grp->y - 100), C2P(grp->x + 100), C2P(grp->y + 100)); + rnd_render->draw_line(ctx->gc, C2P(grp->x + 100), C2P(grp->y - 100), C2P(grp->x - 100), C2P(grp->y + 100)); + } + + /* draw omit and dnp */ + if ((ctx->abst != NULL) && (grp->role == CSCH_ROLE_SYMBOL) && (grp->hdr.bbox.x1 < grp->hdr.bbox.x2) && (grp->aid.used > 0)) { + int omit = 0, dnp = 0; + csch_ahdr_t *aobj; + + TODO("hierarchic: revise this"); + /* for now take only the first abstract's flag; in a more complicated + situation in hierarchic design, the attributes may differ from + abstract obj to abstract obj derived from the same concrete! */ + aobj = htip_get(&ctx->abst->aid2obj, grp->aid.array[0]); + omit = aobj != NULL ? aobj->omit : 0; + dnp = aobj != NULL ? aobj->dnp : 0; + + if (omit || dnp) { + rnd_render->set_color(ctx->gc, (selected ? &conf_core.appearance.color.selected_stroke : &conf_core.appearance.color.symbol_meta_embed)); + rnd_hid_set_line_cap(ctx->gc, rnd_cap_round); + rnd_hid_set_line_width(ctx->gc, -2); + } + + if (dnp) { + static void *f = NULL; + csch_coord_t cx = (grp->hdr.bbox.x1 + grp->hdr.bbox.x2)/2; + csch_coord_t cy = (grp->hdr.bbox.y1 + grp->hdr.bbox.y2)/2; + + if (f == NULL) + f = sch_rnd_font_lookup("sans", "regular"); + + sch_rnd_render_text_string(ctx->gc, f, C2P(cx-2500), C2P(cy+2000), 2, (unsigned char *)"DNP"); + } + + if (omit) { + rnd_render->draw_line(ctx->gc, C2P(grp->hdr.bbox.x1), C2P(grp->hdr.bbox.y1), C2P(grp->hdr.bbox.x2), C2P(grp->hdr.bbox.y2)); + rnd_render->draw_line(ctx->gc, C2P(grp->hdr.bbox.x1), C2P(grp->hdr.bbox.y2), C2P(grp->hdr.bbox.x2), C2P(grp->hdr.bbox.y1)); + } + } + + if ((ctx->abst != NULL) && (grp->role == CSCH_ROLE_WIRE_NET) && (grp->aid.used > 0)) { + int omit = 0; + csch_ahdr_t *aobj; + + TODO("hierarchic: revise this"); + /* for now take only the first abstract's flag; in a more complicated + situation in hierarchic design, the attributes may differ from + abstract obj to abstract obj derived from the same concrete! */ + aobj = htip_get(&ctx->abst->aid2obj, grp->aid.array[0]); + omit = (aobj != NULL) ? aobj->omit : 0; + + if (omit) { + htip_entry_t *e; + + rnd_render->set_color(ctx->gc, (selected ? &conf_core.appearance.color.selected_stroke : &conf_core.appearance.color.symbol_meta_embed)); + rnd_hid_set_line_cap(ctx->gc, rnd_cap_round); + rnd_hid_set_line_width(ctx->gc, -2); + + for(e = htip_first(&grp->id2obj); e != NULL; e = htip_next(&grp->id2obj, e)) { + csch_line_t *line = e->value; + csch_coord_t cx, cy, len = 500; + + if (line->hdr.type != CSCH_CTYPE_LINE) continue; + if ((line->inst.c.p1.x == line->inst.c.p2.x) && (line->inst.c.p1.y == line->inst.c.p2.y)) continue; + + cx = (line->inst.c.p1.x + line->inst.c.p2.x)/2; + cy = (line->inst.c.p1.y + line->inst.c.p2.y)/2; + rnd_render->draw_line(ctx->gc, C2P(cx-len), C2P(cy-len), C2P(cx+len), C2P(cy+len)); + rnd_render->draw_line(ctx->gc, C2P(cx-len), C2P(cy+len), C2P(cx+len), C2P(cy-len)); + } + } + } +} + +static csch_rtree_dir_t collect_layer_obj_fill(void *ctx_, void *obj_, const csch_rtree_box_t *box) +{ + draw_ctx_t *ctx = (draw_ctx_t *)ctx_; + csch_chdr_t *obj = obj_; + + switch(obj->type) { + case CSCH_CTYPE_POLY: + { + csch_cpoly_t *poly = (csch_cpoly_t *)obj; + if (poly->has_fill) { + if (poly->area < 0) + draw_poly_calc_area(ctx, poly); + vtp0_append(&ctx->objlist, obj); + } + } + break; + + case CSCH_CTYPE_ARC: + case CSCH_CTYPE_LINE: + case CSCH_CTYPE_TEXT: + case CSCH_CTYPE_CONN: + case CSCH_CTYPE_BITMAP: + case CSCH_CTYPE_GRP: + case CSCH_CTYPE_GRP_REF: + /* no fill */ + break; + + case CSCH_CTYPE_PEN: + case CSCH_CTYPE_invalid: + case CSCH_CTYPE_max: + /* no graphical representation */ + break; + } + + return csch_RTREE_DIR_FOUND_CONT; +} + + +static void draw_layer_obj_fill(draw_ctx_t *ctx, csch_chdr_t *obj) +{ + int sel = csch_chdr_is_selected(obj); + + switch(obj->type) { + case CSCH_CTYPE_POLY: draw_layer_poly_fill(ctx, (csch_cpoly_t *)obj, sel); break; + + case CSCH_CTYPE_ARC: + case CSCH_CTYPE_LINE: + case CSCH_CTYPE_TEXT: + case CSCH_CTYPE_CONN: + case CSCH_CTYPE_BITMAP: + case CSCH_CTYPE_GRP: + case CSCH_CTYPE_GRP_REF: + /* no fill */ + break; + + case CSCH_CTYPE_PEN: + case CSCH_CTYPE_invalid: + case CSCH_CTYPE_max: + /* no graphical representation */ + break; + } +} + + +static csch_rtree_dir_t draw_layer_obj_stroke(void *ctx_, void *obj_, const csch_rtree_box_t *box) +{ + draw_ctx_t *ctx = (draw_ctx_t *)ctx_; + csch_chdr_t *obj = obj_; + csch_cpen_t *stroke = csch_stroke_fallback_(obj, ctx->xform == NULL ? NULL : ctx->xform->fallback_pen); + int sel = csch_chdr_is_selected(obj); + + switch(obj->type) { + case CSCH_CTYPE_LINE: draw_layer_line(ctx, (csch_line_t *)obj, stroke, sel); break; + case CSCH_CTYPE_POLY: draw_layer_poly_stroke(ctx, (csch_cpoly_t *)obj, stroke, sel); break; + case CSCH_CTYPE_ARC: draw_layer_arc(ctx, (csch_arc_t *)obj, stroke, sel); break; + case CSCH_CTYPE_TEXT: draw_layer_text(ctx, (csch_text_t *)obj, stroke, sel); break; + case CSCH_CTYPE_CONN: draw_layer_conn(ctx, (csch_conn_t *)obj); break; + case CSCH_CTYPE_BITMAP: /* not supported yet */ break; + + case CSCH_CTYPE_GRP: + case CSCH_CTYPE_GRP_REF: + /* no need to draw groups since we are working from rtree, but need to draw meta */ + draw_grp_meta(ctx, (csch_cgrp_t *)obj, sel); + break; + + case CSCH_CTYPE_PEN: + case CSCH_CTYPE_invalid: + case CSCH_CTYPE_max: + /* no graphical representation */ + break; + } + + return csch_RTREE_DIR_FOUND_CONT; +} + +static csch_rtree_dir_t draw_layer_obj_nojunc(void *ctx_, void *obj_, const csch_rtree_box_t *box) +{ + if (!csch_obj_is_junction(obj_)) + return draw_layer_obj_stroke(ctx_, obj_, box); + return csch_RTREE_DIR_NOT_FOUND_CONT; +} + +static csch_rtree_dir_t draw_layer_obj_junc(void *ctx_, void *obj_, const csch_rtree_box_t *box) +{ + if (csch_obj_is_junction(obj_)) + draw_layer_obj_stroke(ctx_, obj_, box); + return csch_RTREE_DIR_NOT_FOUND_CONT; +} + +static int fill_area_cmp(const void *a_, const void *b_) +{ + const csch_cpoly_t **a = (const csch_cpoly_t **)a_, **b = (const csch_cpoly_t **)b_; + if ((*a)->area < (*b)->area) return 1; + return -1; +} + +RND_INLINE void draw_layer_fill(draw_ctx_t *ctx, csch_displayer_t layer, const csch_rtree_box_t *bbox) +{ + long n; + + if ((layer == CSCH_DSPLY_SYMBOL_META) || (layer == CSCH_DSPLY_TEXT_META)) + return; + + ctx->objlist.used = 0; + + csch_rtree_search_obj(&ctx->sheet->dsply_fill[layer], bbox, collect_layer_obj_fill, ctx); + + qsort(ctx->objlist.array, ctx->objlist.used, sizeof(void *), fill_area_cmp); + for(n = 0; n < ctx->objlist.used; n++) + draw_layer_obj_fill(ctx, ctx->objlist.array[n]); +} + + +RND_INLINE void draw_layer_stroke(draw_ctx_t *ctx, csch_displayer_t layer, const csch_rtree_box_t *bbox) +{ + long n; + + if ((layer == CSCH_DSPLY_SYMBOL_META) || (layer == CSCH_DSPLY_TEXT_META)) + return; + + ctx->objlist.used = 0; + + csch_rtree_search_obj(&ctx->sheet->dsply[layer], bbox, predraw_layer_obj, ctx); + + for(n = 0; n < ctx->objlist.used; n++) { + csch_chdr_t *obj = ctx->objlist.array[n]; + sch_rnd_font_text_update(ctx->sheet, (csch_text_t *)obj, csch_stroke_fallback_(obj, ctx->xform == NULL ? NULL : ctx->xform->fallback_pen)); + } + + if (layer == CSCH_DSPLY_WIRE) { + /* have to draw in two steps so junctions are always above wires */ + csch_rtree_search_obj(&ctx->sheet->dsply[layer], bbox, draw_layer_obj_nojunc, ctx); + csch_rtree_search_obj(&ctx->sheet->dsply[layer], bbox, draw_layer_obj_junc, ctx); + } + else + csch_rtree_search_obj(&ctx->sheet->dsply[layer], bbox, draw_layer_obj_stroke, ctx); +} + +RND_INLINE void sch_rnd_draw_sheet_graphical(csch_sheet_t *sheet, rnd_hid_gc_t gc, const rnd_hid_expose_ctx_t *region, rnd_xform_t *xform_caller) +{ + int n; + csch_rtree_box_t bb; + csch_project_t *prj = (csch_project_t *)sheet->hidlib.project; + draw_ctx_t ctx = {0}; + + ctx.sheet = sheet; + ctx.gc = gc; + ctx.xform = xform_caller; + if (prj != NULL) + ctx.abst = prj->abst; + + bb.x1 = P2C(region->view.X1); bb.y1 = P2C(region->view.Y1); + bb.x2 = P2C(region->view.X2); bb.y2 = P2C(region->view.Y2); + + for(n = 0; n < CSCH_DSPLY_max; n++) { + int use_local = (xform_caller != NULL) && xform_caller->use_local_vis; + int vis = use_local ? xform_caller->local_vis[n] : csch_layer_vis[n]; + if (vis) + draw_layer_fill(&ctx, n, &bb); + } + + for(n = 0; n < CSCH_DSPLY_max; n++) { + int use_local = (xform_caller != NULL) && xform_caller->use_local_vis; + int vis = use_local ? xform_caller->local_vis[n] : csch_layer_vis[n]; + if (vis) + draw_layer_stroke(&ctx, n, &bb); + } + + vtp0_uninit(&ctx.objlist); +} + +RND_INLINE void sch_rnd_draw_sheet_non_graphical(csch_sheet_t *sheet, rnd_hid_gc_t gc, const rnd_hid_expose_ctx_t *region, rnd_xform_t *xform_caller) +{ + static csch_text_t t; + static csch_cpen_t pen; + static int inited = 0; + draw_ctx_t ctx = {0}; + void *cookie = NULL; + long cnt = 0; + csch_coord_t y, step = 4000; + char *line; + + if (!inited) { + inited = 1; + + pen.size = 250; + pen.color = conf_core.appearance.color.non_graphical_text; + pen.font_height = 3000; + pen.font_family = "sans"; + t.inst1.x = 0; + t.inst1.y = 0; + } + + ctx.sheet = sheet; + ctx.gc = gc; + ctx.xform = NULL; + + rnd_render->set_color(gc, sch_rnd_stroke_color(&ctx, &t.hdr, &pen, 0)); + + if ((sheet->non_graphical_impl == NULL) || (sheet->non_graphical_impl->draw_getline == NULL)) { + t.bbox_calced = 0; + t.rtext = "non-graphical sheet."; + sch_rnd_font_text_render(sheet, gc, &t, &pen); + return; + } + + y = sheet->bbox.y2 - step; + while((line = sheet->non_graphical_impl->draw_getline(sheet, &cnt, &cookie)) != NULL) { + t.bbox_calced = 0; + t.inst1.y = y; + t.rtext = line; + sch_rnd_font_text_render(sheet, gc, &t, &pen); + y -= step; + } +} + +void sch_rnd_draw_sheet(csch_sheet_t *sheet, rnd_hid_gc_t gc, const rnd_hid_expose_ctx_t *region, rnd_xform_t *xform_caller) +{ + if (sheet->non_graphical) + sch_rnd_draw_sheet_non_graphical(sheet, gc, region, xform_caller); + else + sch_rnd_draw_sheet_graphical(sheet, gc, region, xform_caller); +} + + +void sch_rnd_expose_main(rnd_hid_t *hid, const rnd_hid_expose_ctx_t *region, rnd_xform_t *xform_caller) +{ + rnd_hid_gc_t gc; + int want_layer; + csch_sheet_t *sheet = (csch_sheet_t *)region->design; + rnd_hid_t *save = rnd_render; + + if ((rnd_render != NULL) && (!rnd_render->override_render)) + rnd_render = hid; + + gc = rnd_render->make_gc(rnd_render); + + rnd_render->render_burst(rnd_render, RND_HID_BURST_START, ®ion->view); + + /* the HID needs a group set, even if we don't do groups */ + if (rnd_render->set_layer_group != NULL) + want_layer = rnd_render->set_layer_group(rnd_render, region->design, 1, NULL, 0, 0, 0, 0, NULL); + else + want_layer = 0; + + if (want_layer) { + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_RESET, 1, ®ion->view); + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_POSITIVE, 1, ®ion->view); + + sch_rnd_draw_sheet(sheet, gc, region, xform_caller); + + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_FLUSH, 1, ®ion->view); + rnd_render->end_layer(rnd_render); + } + rnd_render->render_burst(rnd_render, RND_HID_BURST_END, ®ion->view); + + rnd_render->destroy_gc(gc); + rnd_render = save; +} + + +void sch_rnd_expose_preview(rnd_hid_t *hid, rnd_hid_expose_ctx_t *e) +{ + rnd_hid_gc_t gc = rnd_render->make_gc(rnd_render); + + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_RESET, 1, &e->view); + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_POSITIVE, 1, &e->view); + e->expose_cb(gc, e); + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_FLUSH, 1, &e->view); + rnd_render->end_layer(rnd_render); + + rnd_render->destroy_gc(gc); +} + +int sch_draw_setup_non_graphical(csch_sheet_t *sheet, long lines) +{ + sheet->bbox.x2 = 210*1000; + sheet->bbox.y2 = lines * 4000; + sheet->bbox_changed = 1; + rnd_conf_set(RND_CFR_DESIGN, "appearance/color/background", -1, conf_core.appearance.color.non_graphical_background.str, RND_POL_OVERWRITE); + rnd_conf_set(RND_CFR_DESIGN, "editor/draw_grid", -1, "0", RND_POL_OVERWRITE); + rnd_event(&sheet->hidlib, CSCH_EVENT_SHEET_EDITED, NULL); + return 0; +} + +void sch_rnd_redraw(rnd_design_t *target) +{ + rnd_design_t *curr = rnd_multi_get_current(); + + if ((target == NULL) || (target == curr)) + rnd_render->invalidate_all(rnd_render); +} + +void sch_rnd_box_redraw_ev(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + csch_rtree_box_t *box = argv[1].d.p; + rnd_design_t *curr = rnd_multi_get_current(); + + if (curr != hidlib) + return; + + assert(argv[1].type == RND_EVARG_PTR); + if (rnd_render->gui && (rnd_render->invalidate_lr != NULL)) + rnd_render->invalidate_lr(rnd_render, C2P(box->x1), C2P(box->x2), C2P(box->y1), C2P(box->y2)); + + /* rnd_trace("LR: %rc %rc - %rc %rc\n", box->x1, box->y1, box->x2, box->y2); */ + +} + +void sch_rnd_draw_init2(void) +{ + rnd_event_bind(CSCH_EVENT_BOX_NEEDS_REDRAW, sch_rnd_box_redraw_ev, NULL, draw_cookie); +} + +void sch_rnd_draw_uninit(void) +{ + draw_poly_uninit(); + rnd_event_unbind_allcookie(draw_cookie); +} Index: tags/1.0.5/src/sch-rnd/draw.h =================================================================== --- tags/1.0.5/src/sch-rnd/draw.h (nonexistent) +++ tags/1.0.5/src/sch-rnd/draw.h (revision 10414) @@ -0,0 +1,35 @@ +#ifndef SCH_RND_DRAW_H +#define SCH_RND_DRAW_H + +#include + +/* coordinate <-> "pixel" conversion */ +#define C2P(coord) ((rnd_coord_t)((coord) << 10)) +#define P2C(coord) ((csch_coord_t)((coord) >> 10)) + +struct rnd_xform_s { + unsigned faded:1; + unsigned use_local_vis:1; + unsigned no_render_select:1; /* ignore selection (don't render selected color override) */ + unsigned no_render_hilight:1; /* ignore object highlight (don't render obj->hilight color override) */ + int local_vis[CSCH_DSPLY_max]; + csch_cgrp_t *fallback_pen; /* if not NULL, use this group for final pen fallback before using invalid pen */ +}; + +/* redraw the entire screen */ +void sch_rnd_redraw(rnd_design_t *target); + +void sch_rnd_expose_main(rnd_hid_t *hid, const rnd_hid_expose_ctx_t *region, rnd_xform_t *xform_caller); +void sch_rnd_expose_preview(rnd_hid_t *hid, rnd_hid_expose_ctx_t *e); + + +/*** calls useful in preview ***/ +void sch_rnd_draw_sheet(csch_sheet_t *sheet, rnd_hid_gc_t gc, const rnd_hid_expose_ctx_t *region, rnd_xform_t *xform_caller); + +/*** helpers ***/ +/* Set up sheet for rendering the text of a non-graphical sheet; sets size and + colors and grid */ +int sch_draw_setup_non_graphical(csch_sheet_t *sheet, long lines); + + +#endif Index: tags/1.0.5/src/sch-rnd/draw_poly.c =================================================================== --- tags/1.0.5/src/sch-rnd/draw_poly.c (nonexistent) +++ tags/1.0.5/src/sch-rnd/draw_poly.c (revision 10414) @@ -0,0 +1,192 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - sch-rnd (executable) + * Copyright (C) 2019,2020,2022,2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/* #included from draw.c */ + +vtc0_t draw_poly_x, draw_poly_y; + +static void draw_poly_reset(void) +{ + draw_poly_x.used = draw_poly_y.used = 0; +} + +static void draw_poly_append(rnd_coord_t x, rnd_coord_t y) +{ + /* do not add duplicate points */ + if (draw_poly_x.used > 0) { + if ((draw_poly_x.array[draw_poly_x.used-1] == x) && (draw_poly_y.array[draw_poly_x.used-1] == y)) + return; + } + + vtc0_append(&draw_poly_x, x); + vtc0_append(&draw_poly_y, y); +} + +static void draw_poly_uninit(void) +{ + vtc0_uninit(&draw_poly_x); + vtc0_uninit(&draw_poly_y); +} + +RND_INLINE void draw_poly_arc(csch_arc_t *arc) +{ + double sa = arc->inst.c.start, da = arc->inst.c.delta; + long int n, steps; + double a, step; + + if (rnd_render != NULL) { + double cpp = rnd_render->coord_per_pix; + + if (cpp <= 0) + cpp = RND_MIL_TO_COORD(1000.0)/600.0; /* assume 600 DPI, for the exporters */ + + steps = (double)C2P(arc->inst.c.r) * (double)da / cpp / 10.0; + if (steps < 0) + steps= - steps; + if (steps < 3) + steps = 3; + else if (steps > 1000) + steps = 1000; + } + else + steps = 3; + + + step = da/steps; + for(a = sa, n = 0; n < steps; a += step, n++) { + csch_coord_t x, y; + x = rnd_round(arc->inst.c.c.x + arc->inst.c.r * cos(a)); + y = rnd_round(arc->inst.c.c.y + arc->inst.c.r * sin(a)); + draw_poly_append(C2P(x), C2P(y)); + } +} + +RND_INLINE void draw_layer_poly_fill(draw_ctx_t *ctx, csch_cpoly_t *p, int selected) +{ + long n; + csch_coutline_t *o; + + if (!p->has_fill) + return; + + rnd_render->set_color(ctx->gc, sch_rnd_fill_color(ctx, &p->hdr, csch_fill_fallback(p->hdr.sheet, p, ctx->xform == NULL ? NULL : ctx->xform->fallback_pen), selected)); + draw_poly_reset(); + for(n = 0, o = p->outline.array; n < p->outline.used; n++, o++) { + switch(o->hdr.type) { + case CSCH_CTYPE_LINE: + draw_poly_append(C2P(o->line.inst.c.p1.x), C2P(o->line.inst.c.p1.y)); + draw_poly_append(C2P(o->line.inst.c.p2.x), C2P(o->line.inst.c.p2.y)); + break; + case CSCH_CTYPE_ARC: + draw_poly_arc(&o->arc); + break; + default: + /* invalid object in contour, already warned */ + break; + } + } + rnd_render->fill_polygon(ctx->gc, draw_poly_x.used, draw_poly_x.array, draw_poly_y.array); +} + +RND_INLINE void draw_layer_poly_stroke(draw_ctx_t *ctx, csch_cpoly_t *p, csch_cpen_t *stroke, int selected) +{ + long n; + csch_coutline_t *o; + + if (!p->has_stroke) + return; + + rnd_render->set_color(ctx->gc, sch_rnd_stroke_color(ctx, &p->hdr, stroke, selected)); + rnd_hid_set_line_cap(ctx->gc, pen_cap(stroke)); + rnd_hid_set_line_width(ctx->gc, C2P(stroke->size)); + + for(n = 0, o = p->outline.array; n < p->outline.used; n++, o++) { + switch(o->hdr.type) { + case CSCH_CTYPE_LINE: + rnd_render->draw_line(ctx->gc, C2P(o->line.inst.c.p1.x), C2P(o->line.inst.c.p1.y), C2P(o->line.inst.c.p2.x), C2P(o->line.inst.c.p2.y)); + break; + case CSCH_CTYPE_ARC: + rnd_render->draw_arc(ctx->gc, C2P(o->arc.inst.c.c.x), C2P(o->arc.inst.c.c.y), C2P(o->arc.inst.c.r), C2P(o->arc.inst.c.r), (180.0 - o->arc.inst.c.start * RND_RAD_TO_DEG), -(o->arc.inst.c.delta * RND_RAD_TO_DEG)); + break; + default: + /* invalid, do not draw */ + break; + } + } +} + +#define poly_area_next(x, y) \ +do { \ + if (first) { \ + x1 = (x); \ + y1 = (y); \ + first = 0; \ + } \ + else \ + area += ((lx) - (x)) * ((ly) + (y));\ + lx = (x); \ + ly = (y);\ +} while(0) + +static void draw_poly_calc_area(draw_ctx_t *ctx, csch_cpoly_t *poly) +{ + long n; + int first = 1, i, steps = 4; + double a, sa, da, step, area = 0, r, x1, y1, lx, ly; + csch_coutline_t *o; + + for(n = 0, o = poly->outline.array; n < poly->outline.used; n++, o++) { + switch(o->hdr.type) { + case CSCH_CTYPE_LINE: + poly_area_next((double)o->line.inst.c.p1.x, (double)o->line.inst.c.p1.y); + poly_area_next((double)o->line.inst.c.p2.x, (double)o->line.inst.c.p2.y); + break; + case CSCH_CTYPE_ARC: + sa = o->arc.inst.c.start; + da = o->arc.inst.c.delta; + r = o->arc.inst.c.r; + step = da/steps; + for(a = sa, i = 0; i < steps; a += step, i++) { + double x, y; + x = (double)o->arc.inst.c.c.x + r * cos(a); + y = (double)o->arc.inst.c.c.y + r * sin(a); + poly_area_next(x, y); + } + break; + default: break; + } + } + if (!first) + poly_area_next(x1, y1); + + /* Unlikely: polygon specified in the wrong direction */ + if (area < 0) + area = -area; + + poly->area = area; +} Index: tags/1.0.5/src/sch-rnd/draw_xor.c =================================================================== --- tags/1.0.5/src/sch-rnd/draw_xor.c (nonexistent) +++ tags/1.0.5/src/sch-rnd/draw_xor.c (revision 10414) @@ -0,0 +1,184 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - sch-rnd (executable) + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "draw.h" +#include "draw_xor.h" +#include "font.h" + +typedef struct { + csch_sheet_t *sheet; + rnd_hid_gc_t gc; + csch_coord_t dx, dy; + unsigned thin:1; /* centerline */ + unsigned wire:1; /* wireframe */ + unsigned no_cap:1; /* omit end caps in wireframe */ + unsigned backref:1;/* floaters draw a line back to their original position */ +} xor_ctx_t; + +RND_INLINE void draw_xor_line(xor_ctx_t *ctx, csch_line_t *l, csch_cpen_t *stroke) +{ + if (ctx->thin || ctx->wire) + rnd_render->draw_line(ctx->gc, C2P(l->inst.c.p1.x + ctx->dx), C2P(l->inst.c.p1.y + ctx->dy), C2P(l->inst.c.p2.x + ctx->dx), C2P(l->inst.c.p2.y + ctx->dy)); +} + +RND_INLINE void draw_xor_arc(xor_ctx_t *ctx, csch_arc_t *a, csch_cpen_t *stroke) +{ + if (ctx->thin || ctx->wire) + rnd_render->draw_arc(ctx->gc, C2P(a->inst.c.c.x + ctx->dx), C2P(a->inst.c.c.y + ctx->dy), C2P(a->inst.c.r), C2P(a->inst.c.r), (180.0 - a->inst.c.start * RND_RAD_TO_DEG), -(a->inst.c.delta * RND_RAD_TO_DEG)); +} + +RND_INLINE void draw_xor_text(xor_ctx_t *ctx, csch_text_t *t, csch_cpen_t *stroke) +{ + if (ctx->thin || ctx->wire) { + /* if there's no spec2 calculated for a non-bbox-specified text, need to update it to get real dimensions */ + if (!t->has_bbox && (t->spec2.x == 0) && (t->spec2.y == 0)) + sch_rnd_font_text_update(t->hdr.sheet, t, csch_stroke_(&t->hdr)); + + rnd_render->draw_line(ctx->gc, C2P(t->inst1.x + ctx->dx), C2P(t->inst1.y + ctx->dy), C2P(t->inst2.x + ctx->dx), C2P(t->inst2.y + ctx->dy)); + rnd_render->draw_line(ctx->gc, C2P(t->inst15.x + ctx->dx), C2P(t->inst15.y + ctx->dy), C2P(t->inst25.x + ctx->dx), C2P(t->inst25.y + ctx->dy)); + rnd_render->draw_line(ctx->gc, C2P(t->inst1.x + ctx->dx), C2P(t->inst1.y + ctx->dy), C2P(t->inst15.x + ctx->dx), C2P(t->inst15.y + ctx->dy)); + rnd_render->draw_line(ctx->gc, C2P(t->inst1.x + ctx->dx), C2P(t->inst1.y + ctx->dy), C2P(t->inst25.x + ctx->dx), C2P(t->inst25.y + ctx->dy)); + rnd_render->draw_line(ctx->gc, C2P(t->inst2.x + ctx->dx), C2P(t->inst2.y + ctx->dy), C2P(t->inst15.x + ctx->dx), C2P(t->inst15.y + ctx->dy)); + rnd_render->draw_line(ctx->gc, C2P(t->inst2.x + ctx->dx), C2P(t->inst2.y + ctx->dy), C2P(t->inst25.x + ctx->dx), C2P(t->inst25.y + ctx->dy)); + } +} + +RND_INLINE void draw_xor_poly(xor_ctx_t *ctx, csch_cpoly_t *p, csch_cpen_t *stroke) +{ + int save; + long n; + csch_coutline_t *o; + + save = ctx->no_cap; + ctx->no_cap = 1; + for(n = 0, o = p->outline.array; n < p->outline.used; n++, o++) { + switch(o->hdr.type) { + case CSCH_CTYPE_LINE: draw_xor_line(ctx, &o->line, stroke); break; + case CSCH_CTYPE_ARC: draw_xor_arc(ctx, &o->arc, stroke); break; + default: /* invalid, do not draw */ break; + } + } + ctx->no_cap = save; +} + +static void sch_rnd_xor_draw_obj_(xor_ctx_t *ctx, csch_chdr_t *obj); + +RND_INLINE void draw_xor_grp(xor_ctx_t *ctx, csch_cgrp_t *grp) +{ + htip_entry_t *e; + for(e = htip_first(&grp->id2obj); e != NULL; e = htip_next(&grp->id2obj, e)) + sch_rnd_xor_draw_obj_(ctx, (csch_chdr_t *)e->value); +} + +/* Draw a line from the floater object back to its parent group */ +static void sch_rnd_xor_draw_obj_backref(xor_ctx_t *ctx, csch_chdr_t *obj) +{ + csch_cgrp_t *grp = obj->parent; + csch_coord_t ox, oy, px, py; + + ox = (obj->bbox.x1 + obj->bbox.x2) / 2 + ctx->dx; + oy = (obj->bbox.y1 + obj->bbox.y2) / 2 + ctx->dy; + px = (grp->hdr.bbox.x1 + grp->hdr.bbox.x2) / 2; + py = (grp->hdr.bbox.y1 + grp->hdr.bbox.y2) / 2; + + rnd_render->draw_line(ctx->gc, C2P(ox), C2P(oy), C2P(px), C2P(py)); +} + +static void sch_rnd_xor_draw_obj_(xor_ctx_t *ctx, csch_chdr_t *obj) +{ + switch(obj->type) { + case CSCH_CTYPE_LINE: draw_xor_line(ctx, (csch_line_t *)obj, csch_stroke_(obj)); break; + case CSCH_CTYPE_POLY: draw_xor_poly(ctx, (csch_cpoly_t *)obj, csch_stroke_(obj)); break; + case CSCH_CTYPE_ARC: draw_xor_arc(ctx, (csch_arc_t *)obj, csch_stroke_(obj)); break; + case CSCH_CTYPE_TEXT: draw_xor_text(ctx, (csch_text_t *)obj, csch_stroke_(obj)); break; + + case CSCH_CTYPE_GRP: + case CSCH_CTYPE_GRP_REF: + draw_xor_grp(ctx, (csch_cgrp_t *)obj); break; + + case CSCH_CTYPE_BITMAP: + TODO("bitmap: implement xor draw for this object"); + break; + case CSCH_CTYPE_CONN: + case CSCH_CTYPE_PEN: + case CSCH_CTYPE_max: + case CSCH_CTYPE_invalid: + /* no need to draw these */ + break; + } + + if (ctx->backref && obj->floater && (obj->parent != NULL) && (obj->parent != &obj->sheet->direct)) + sch_rnd_xor_draw_obj_backref(ctx, obj); +} + + +void sch_rnd_xor_draw_obj(csch_sheet_t *sheet, csch_chdr_t *obj, csch_coord_t dx, csch_coord_t dy, rnd_hid_gc_t gc, int thin, int wireframe) +{ + xor_ctx_t ctx; + + ctx.sheet = sheet; + ctx.gc = gc; + ctx.dx = dx; + ctx.dy = dy; + ctx.thin = thin; + ctx.wire = wireframe; + ctx.no_cap = 0; + ctx.backref = 1; + + sch_rnd_xor_draw_obj_(&ctx, obj); +} + + +void sch_rnd_xor_draw_buffer(csch_sheet_t *sheet, csch_sheet_t *buffer, csch_coord_t dx, csch_coord_t dy, rnd_hid_gc_t gc, int thin, int wireframe) +{ + xor_ctx_t ctx; + + ctx.sheet = sheet; + ctx.gc = gc; + ctx.dx = dx; + ctx.dy = dy; + ctx.thin = thin; + ctx.wire = wireframe; + ctx.no_cap = 0; + ctx.backref = 0; + + draw_xor_grp(&ctx, &buffer->direct); +} + Index: tags/1.0.5/src/sch-rnd/draw_xor.h =================================================================== --- tags/1.0.5/src/sch-rnd/draw_xor.h (nonexistent) +++ tags/1.0.5/src/sch-rnd/draw_xor.h (revision 10414) @@ -0,0 +1,3 @@ +void sch_rnd_xor_draw_obj(csch_sheet_t *sheet, csch_chdr_t *obj, csch_coord_t dx, csch_coord_t dy, rnd_hid_gc_t gc, int thin, int wireframe); + +void sch_rnd_xor_draw_buffer(csch_sheet_t *sheet, csch_sheet_t *buffer, csch_coord_t dx, csch_coord_t dy, rnd_hid_gc_t gc, int thin, int wireframe); Index: tags/1.0.5/src/sch-rnd/emergency.c =================================================================== --- tags/1.0.5/src/sch-rnd/emergency.c (nonexistent) +++ tags/1.0.5/src/sch-rnd/emergency.c (revision 10414) @@ -0,0 +1,178 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - sch-rnd (executable) + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/* Emergency and backup saves */ + +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "conf_core.h" + +#include "emergency.h" + +static const char *valid_emergency_name(void) +{ + static const char *stock = "SCH.%ld-%ld.save"; + const char *s; + int lds = 0; + + for(s = conf_core.rc.emergency_name; *s != '\0'; s++) { + if (*s == '%') { + s++; + while(isdigit(*s)) s++; + if ((s[0] == 'l') && (s[1] == 'd')) { + lds++; + s++; + } + else { + fprintf(stderr, "Invalid conf_core.rc.emergency_name: format string other than %%ld\n"); + return stock; + } + } + } + + if (lds > 2) { + fprintf(stderr, "Invalid conf_core.rc.emergency_name: more than two %%ld's \n"); + return stock; + } + + return conf_core.rc.emergency_name; +} + +void sch_rnd_save_in_tmp(csch_sheet_t *sheet) +{ + char filename[RND_PATH_MAX]; + + /* memory might have been released before this function is called */ + if ((sheet != NULL) && sheet->changed && (conf_core.rc.emergency_name != NULL) && (*conf_core.rc.emergency_name != '\0')) { + const char *fmt = "lihata"; + int res; + + sprintf(filename, valid_emergency_name(), (long int)rnd_getpid(), sheet->uid); + rnd_message(RND_MSG_INFO, "Trying to save your sheet in '%s'\n", filename); + res = csch_save_sheet(sheet, filename, fmt); + if (res != 0) + rnd_message(RND_MSG_INFO, " (failed)\n"); + } +} + +void sch_rnd_save_all_in_tmp(void) +{ + rnd_design_t *dsg; + + for(dsg = gdl_first(&rnd_designs); dsg != NULL; dsg = dsg->link.next) + sch_rnd_save_in_tmp((csch_sheet_t *)dsg); +} + + +/* front-end for pcb_save_in_tmp() to makes sure it is only called once */ +static rnd_bool dont_save_any_more = rnd_false; +void sch_rnd_emergency_save(void) +{ + if (!dont_save_any_more) { + dont_save_any_more = rnd_true; + sch_rnd_save_all_in_tmp(); + } +} + +void sch_rnd_disable_emergency_save(void) +{ + dont_save_any_more = rnd_true; +} + + +/*** Timed backup (autosave) ***/ + +static rnd_hidval_t backup_timer; + +/* + * If the backup interval is > 0 then set another timer. Otherwise + * we do nothing and it is up to the GUI to call sch_rnd_enable_autosave() + * after setting conf_core.rc.backup_interval > 0 again. + */ +static void backup_cb(rnd_hidval_t data) +{ + backup_timer.ptr = NULL; + sch_rnd_backup_all(); + if (conf_core.rc.backup_interval > 0 && rnd_gui->add_timer) + backup_timer = rnd_gui->add_timer(rnd_gui, backup_cb, 1000 * conf_core.rc.backup_interval, data); +} + +void sch_rnd_enable_autosave(void) +{ + rnd_hidval_t x; + + x.ptr = NULL; + + /* If we already have a timer going, then cancel it out */ + if (backup_timer.ptr != NULL && rnd_gui->stop_timer) + rnd_gui->stop_timer(rnd_gui, backup_timer); + + backup_timer.ptr = NULL; + /* Start up a new timer */ + if ((conf_core.rc.backup_interval > 0) && (rnd_gui->add_timer != NULL)) + backup_timer = rnd_gui->add_timer(rnd_gui, backup_cb, 1000 * conf_core.rc.backup_interval, x); +} + +/* Saves the board in a backup file using the name configured in conf_core.rc.backup_name */ +void sch_rnd_backup(csch_sheet_t *sheet) +{ + char *filename = NULL; + const char *fmt = "lihata"; + + if ((sheet->hidlib.fullpath == NULL) || (sheet->hidlib.fullpath[0] == '<')) + return; /* do not make backups of */ + + filename = rnd_build_fn(&sheet->hidlib, conf_core.rc.backup_name); + if (filename == NULL) { + fprintf(stderr, "sch_rnd_backup(): can't build file name for a backup\n"); + exit(1); + } + + csch_save_sheet_backup(sheet, filename, fmt); + + free(filename); +} + +void sch_rnd_backup_all(void) +{ + rnd_design_t *dsg; + for(dsg = gdl_first(&rnd_designs); dsg != NULL; dsg = dsg->link.next) + sch_rnd_backup((csch_sheet_t *)dsg); +} Index: tags/1.0.5/src/sch-rnd/emergency.h =================================================================== --- tags/1.0.5/src/sch-rnd/emergency.h (nonexistent) +++ tags/1.0.5/src/sch-rnd/emergency.h (revision 10414) @@ -0,0 +1,20 @@ +#include + +/* save all sheets */ +void sch_rnd_emergency_save(void); + +void sch_rnd_disable_emergency_save(void); + + + +/* Saves the board in a backup file using the name configured in conf_core.rc.backup_name */ +void sch_rnd_backup(csch_sheet_t *sheet); +void sch_rnd_backup_all(void); + +/* Start timer for autosave */ +void sch_rnd_enable_autosave(void); + + +/*** low level/internal ***/ +void sch_rnd_save_in_tmp(csch_sheet_t *sheet); +void sch_rnd_save_all_in_tmp(void); Index: tags/1.0.5/src/sch-rnd/export.c =================================================================== --- tags/1.0.5/src/sch-rnd/export.c (nonexistent) +++ tags/1.0.5/src/sch-rnd/export.c (revision 10414) @@ -0,0 +1,182 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - sch-rnd (executable) + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + + +/* Common export code (helpers) */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include "sheet.h" + +#include "export.h" + +sch_rnd_export_appspec_t sch_rnd_no_appspec = {0}; + + +RND_INLINE void vis_invert(rnd_xform_t *xform) +{ + int n; + for(n = 0; n < CSCH_DSPLY_max; n++) + xform->local_vis[n] = !xform->local_vis[n]; +} + +RND_INLINE void vis_set_all(rnd_xform_t *xform, int val) +{ + int n; + for(n = 0; n < CSCH_DSPLY_max; n++) + xform->local_vis[n] = val; +} + +RND_INLINE void vis_set_by_name(rnd_xform_t *xform, const char *name, int len, int val) +{ + int n, set = 0; + + for(n = 0; n < CSCH_DSPLY_max; n++) { + const char *dly = csch_dsply_name(n); + if (strncmp(name, dly, len) == 0) { + xform->local_vis[n] = val; + set = 1; + } + } + + if (set == 0) { + gds_t tmp = {0}; + gds_append_len(&tmp, name, len); + rnd_message(RND_MSG_ERROR, "Layer visibility: unknown layer name (prefix did not match any layer): '%s'\n", tmp.array); + gds_uninit(&tmp); + } +} + + +void sch_rnd_set_export_layers(rnd_xform_t *xform, const char *layers) +{ + const char *start, *next, *end; + + assert(sizeof(xform->local_vis) == sizeof(csch_export_layer_vis)); + + /* empty string should result in the default export layer visibility setup */ + memcpy(xform->local_vis, csch_export_layer_vis, sizeof(xform->local_vis)); + xform->use_local_vis = 1; + + for(start = layers; start != NULL; start = next) { + int len, inv = 0; + + /* get next word */ + while(isspace(*start) || (*start == ',')) start++; + if (*start == '\0') + break; + + end = next = strpbrk(start, ", \t\r\n"); + if (next != NULL) + next++; + else + end = start + strlen(start); + + /* read pefix */ + while(*start == '!') { + start++; + inv = !inv; + } + + /* decode instruction */ + len = end - start; + if ((len == 3) && ((strncmp(start, "gui", 3) == 0) || (strncmp(start, "GUI", 3) == 0))) { + memcpy(xform->local_vis, csch_layer_vis, sizeof(xform->local_vis)); + if (inv) vis_invert(xform); + } + else if ((len == 4) && (strncmp(start, "none", 4) == 0)) + vis_set_all(xform, inv ? 1 : 0); + else if ((len == 3) && (strncmp(start, "all", 3) == 0)) + vis_set_all(xform, inv ? 0 : 1); + else + vis_set_by_name(xform, start, len, inv ? 0 : 1); + } +} + +int sch_rnd_export_prj_abst(csch_project_t *prj, csch_sheet_t *sheet, int viewid, const char *exp_fmt, const char *explicit_name, rnd_hid_attr_val_t *options) +{ + int res = 0; + csch_abstract_t abs; + + csch_abstract_init(&abs); + res |= csch_compile_project(prj, viewid, &abs, 0); + + if (exp_fmt != NULL) { + char epath[CSCH_PATH_MAX]; + const char *final_path; + + if (explicit_name == NULL) { + csch_project_export_name(prj, sheet, epath, exp_fmt, NULL); + final_path = epath; + } + else + final_path = explicit_name; + csch_export_project_abst(&abs, final_path, exp_fmt, options); + } + + csch_abstract_uninit(&abs); + return res; +} + +static int sch_rnd_export_prj_sheets_multifile(rnd_hid_t *hid, rnd_design_t *design, rnd_hid_attr_val_t *options, sch_rnd_export_appspec_t *appspec, int (*exp_sheet)(rnd_hid_t *, rnd_design_t *, rnd_hid_attr_val_t *, sch_rnd_export_appspec_t *, int *ovr)) +{ + int res = 0, ovr = 0; + long page; + char fn_page_suffix[128]; + + appspec->fn_page_suffix = fn_page_suffix; + for(page = 0; page < design->project->designs.used; page++) { + sch_rnd_sheet_recalc_bbox((csch_sheet_t *)design->project->designs.array[page]); + sprintf(fn_page_suffix, "-p%ld", page+1); + res |= exp_sheet(hid, design->project->designs.array[page], options, appspec, &ovr); + } + appspec->fn_page_suffix = NULL; + + return res; +} + +int sch_rnd_export_project_or_sheet(rnd_hid_t *hid, rnd_design_t *design, rnd_hid_attr_val_t *options, sch_rnd_export_appspec_t *appspec, int (*exp_sheet)(rnd_hid_t *, rnd_design_t *, rnd_hid_attr_val_t *, sch_rnd_export_appspec_t *, int *ovr)) +{ + if (appspec->exp_prj) + return sch_rnd_export_prj_sheets_multifile(hid, design, options, appspec, exp_sheet); + + sch_rnd_sheet_recalc_bbox((csch_sheet_t *)design); + return exp_sheet(hid, design, options, appspec, NULL); +} Index: tags/1.0.5/src/sch-rnd/export.h =================================================================== --- tags/1.0.5/src/sch-rnd/export.h (nonexistent) +++ tags/1.0.5/src/sch-rnd/export.h (revision 10414) @@ -0,0 +1,29 @@ +#include + +/* Used as the appspec arg (except when a single sheet is exported) */ +typedef struct sch_rnd_export_appspec_s { + unsigned exp_prj:1; /* export a whole project when 1 */ + const char *fn_page_suffix; /* if not NULL, append page suffix to file name */ +} sch_rnd_export_appspec_t; + +/* Appspec with default values for the case NULL is passed to an exporter */ +extern sch_rnd_export_appspec_t sch_rnd_no_appspec; + +void sch_rnd_set_export_layers(rnd_xform_t *xform, const char *layers); + +/* Call the libcschem plug_io export mechanism to export a whole project's + abstract model; If not called on a specific sheet, sheet can be NULL. + Explicit name is either NULL or the output file name specified by the user. */ +int sch_rnd_export_prj_abst(csch_project_t *prj, csch_sheet_t *sheet, int viewid, const char *exp_fmt, const char *explicit_name, rnd_hid_attr_val_t *options); + +/* An export plugin can call this to export the whole project or the sheet + (depending on appspec). Project export may call exp_sheet() multiple times. + Returns 0 if all went well. */ +int sch_rnd_export_project_or_sheet(rnd_hid_t *hid, rnd_design_t *design, rnd_hid_attr_val_t *options, sch_rnd_export_appspec_t *appspec, int (*exp_sheet)(rnd_hid_t *, rnd_design_t *, rnd_hid_attr_val_t *, sch_rnd_export_appspec_t *, int *ovr)); + + +/* Returns whether appspec is for a project export; NULL may be passed */ +RND_INLINE int sch_rnd_export_appspec_prj(sch_rnd_export_appspec_t *appspec) +{ + return (appspec != NULL) && appspec->exp_prj; +} Index: tags/1.0.5/src/sch-rnd/file_act.c =================================================================== --- tags/1.0.5/src/sch-rnd/file_act.c (nonexistent) +++ tags/1.0.5/src/sch-rnd/file_act.c (revision 10414) @@ -0,0 +1,617 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - sch-rnd (executable) + * Copyright (C) 2022, 2023, 2024 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022, Entrust in 2023) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/* Generic actions usually related to the currently open file(s) */ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "sheet.h" +#include "conf_core.h" +#include "build_run.h" +#include "multi.h" +#include "project.h" + +/* Return 1 if any of the currently loaded sheets have changes on them */ +static int any_sheet_changed(void) +{ + csch_sheet_t *sheet; + for(sheet = gdl_first(&rnd_designs); sheet != NULL; sheet = sheet->hidlib.link.next) + if (sheet->changed) + return 1; + + return 0; +} + +static const char csch_acts_Quit[] = "Quit()"; +static const char csch_acth_Quit[] = "Quits sch-rnd after confirming."; +static fgw_error_t csch_act_Quit(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + csch_sheet_t *sheet = CSCH_ACT_SHEET; + const char *force = NULL; + RND_ACT_MAY_CONVARG(1, FGW_STR, Quit, force = argv[1].val.str); + + if ((force != NULL) && (rnd_strcasecmp(force, "force") == 0)) + exit(0); + + if (!any_sheet_changed() || (rnd_hid_message_box(RND_ACT_DESIGN, "warning", "Close: lose data", "Exiting sch-rnd will lose unsaved sheet modifications.", "cancel", 0, "ok", 1, NULL) == 1)) + sch_rnd_quit_app(); + + RND_ACT_IRES(-1); + return 0; +} + +static const char csch_acts_SymlibRehash[] = "SymlibRehash()"; +static const char csch_acth_SymlibRehash[] = "Rebuild the in-memory tree of symbol libraries"; +static fgw_error_t csch_act_SymlibRehash(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + csch_sheet_t *sheet = CSCH_ACT_SHEET; + csch_lib_master_t *master = csch_lib_get_master("symbol", 1); + + csch_lib_clear_sheet_lib(sheet, master->uid); + csch_lib_add_all(sheet, master, &conf_core.rc.library_search_paths, 1); + rnd_event(&sheet->hidlib, CSCH_EVENT_LIBRARY_CHANGED, NULL); + RND_ACT_IRES(0); + return 0; +} + +static const char csch_acts_SymlibReloadAllLocal[] = "SymlibReloadAllLocal()"; +static const char csch_acth_SymlibReloadAllLocal[] = "Replace all local symbols from a newer version of the same symbol from the symbol library"; +static fgw_error_t csch_act_SymlibReloadAllLocal(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + csch_sheet_t *sheet = CSCH_ACT_SHEET; + csch_lib_master_t *master = csch_lib_get_master("symbol", 0); + long cnt; + + cnt = csch_loclib_reload_all(sheet, sheet->local_libs.array[master->uid]); + rnd_message(RND_MSG_INFO, "Reloaded %ld local lib symbol(s) from external libs\n", cnt); + + rnd_event(&sheet->hidlib, CSCH_EVENT_LIBRARY_CHANGED, NULL); + RND_ACT_IRES(0); + return 0; +} + +static const char csch_acts_HlibraryRehash[] = "HlibraryRehash()"; +static const char csch_acth_HlibraryRehash[] = "Rebuild the in-memory tree of hierarchic sheet libraries"; +static fgw_error_t csch_act_HlibraryRehash(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + csch_sheet_t *sheet = CSCH_ACT_SHEET; + csch_lib_master_t *master = csch_lib_get_master("hlibrary", 1); + + csch_lib_clear_sheet_lib(sheet, master->uid); + csch_lib_add_all(sheet, master, &conf_core.rc.library_search_paths, 1); + rnd_event(&sheet->hidlib, CSCH_EVENT_LIBRARY_CHANGED, NULL); + RND_ACT_IRES(0); + return 0; +} + +static const char csch_acts_Revert[] = "Revert([sheet|project])"; +static const char csch_acth_Revert[] = "Revert to on-disk version of file(s). Default target is sheet."; +fgw_error_t csch_act_Revert(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *op = "sheet"; + csch_sheet_t *sheet = CSCH_ACT_SHEET; + + RND_ACT_MAY_CONVARG(1, FGW_STR, Revert, op = argv[1].val.str); + + if (rnd_strcasecmp(op, "sheet") == 0) { + csch_revert_sheet(sheet, sch_rnd_sheet_new4revert); + } + else if (rnd_strcasecmp(op, "project") == 0) { + rnd_message(RND_MSG_ERROR, "Revert(project,...) not yet implemented\n"); + } + else + RND_ACT_FAIL(Revert); + + RND_ACT_IRES(0); + return 0; +} + +static void prj_flush(csch_sheet_t *sheet, const char *listpath) +{ + const char *prjpath = NULL; + + rnd_conf_makedirty(RND_CFR_PROJECT); + rnd_conf_update(listpath, -1); + + if (sheet->hidlib.project != NULL) + prjpath = sheet->hidlib.project->fullpath; + + rnd_conf_save_file(&sheet->hidlib, prjpath, sheet->hidlib.fullpath, RND_CFR_PROJECT, NULL); +} + +/* Does NOT increment num_root_sheets, caller needs to do that */ +static void prj_append_sheet(csch_project_t *prj, csch_sheet_t *sheet, const char *listpath) +{ + lht_node_t *nd; + + if (prj->hdr.fullpath == NULL) + sch_rnd_project_create_file_for_sheet_gui(sheet); + + if (prj->hdr.fullpath == NULL) /* cancel - no project file created */ + sheet->stype = CSCH_SHTY_UNLISTED; + + + nd = rnd_conf_lht_get_at(RND_CFR_PROJECT, listpath, 1); + if (nd != NULL) { + char *val = NULL; + + if (prj->hdr.fullpath == NULL) + val = rnd_strdup(rnd_basename(sheet->hidlib.fullpath)); + else if ((sheet->hidlib.fullpath != NULL) && (*sheet->hidlib.fullpath != '<')) + val = rnd_relative_path_files(sheet->hidlib.fullpath, prj->hdr.fullpath); + else + rnd_message(RND_MSG_ERROR, "Failed to append sheet to project file's %s;\ntry to save the sheet first so it gets a file name!\n", listpath); + + if (val != NULL) { + lht_node_t *n = lht_dom_node_alloc(LHT_TEXT, NULL); + lht_dom_list_append(nd, n); + n->data.text.value = val; + + prj_flush(sheet, listpath); + } + } + else + rnd_message(RND_MSG_ERROR, "Failed to append sheet to project file's %s\n", listpath); +} + +static const char csch_acts_New[] = "New([scope, [root|aux|unlisted]])"; +static const char csch_acth_New[] = "Create a new sheet. Scope is a project path or @ for current project."; +fgw_error_t csch_act_New(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *scope = "@", *type = "root"; + char *fn, *path, *dn; + csch_sheet_t *ns, *curr = (csch_sheet_t *)RND_ACT_DESIGN; + csch_project_t *prj; + + RND_ACT_MAY_CONVARG(1, FGW_STR, New, scope = argv[1].val.str); + RND_ACT_MAY_CONVARG(2, FGW_STR, New, type = argv[2].val.str); + + if ((strcmp(type, "root") != 0) && (strcmp(type, "aux") != 0) && (strcmp(type, "unlisted") != 0)) { + rnd_message(RND_MSG_ERROR, "New(): invalid sheet type '%s'\n", type); + return FGW_ERR_ARG_CONV; + } + + if ((scope[0] != '@') || (scope[1] != '\0')) { + rnd_message(RND_MSG_ERROR, "New(): only current project scope (@) is supported at the moment\n"); + return FGW_ERR_ARG_CONV; + } + + dn = rnd_dirname(curr->hidlib.fullpath); + if (dn == NULL) { + if ((curr->hidlib.project != NULL) && (curr->hidlib.project->fullpath != NULL)) + dn = rnd_dirname(curr->hidlib.project->fullpath); + if (dn == NULL) { + rnd_message(RND_MSG_ERROR, "New(): project does not exist\n(Try saving current sheet first)\n"); + return FGW_ERR_ARG_CONV; + } + } + + + RND_ACT_IRES(0); + fn = rnd_hid_prompt_for(RND_ACT_DESIGN, "Please enter a file name of the new sheet.\nFile path is assumed to be the same as the project's path.\n(as a convention, it is recommended that the file name ends in .rs)", "new.rs", "File name of the new sheet"); + if (fn == NULL) /* cancel */ + return 0; + + path = rnd_concat(dn, "/", fn, NULL); + if (rnd_file_readable(RND_ACT_DESIGN, path)) { + int go_for_it; + char *msg; + + msg = rnd_concat("File ", path, " already exists.\nSaving the new sheet would overwrite it.\nAre you sure you want the create a new sheet on this name?", NULL); + go_for_it = rnd_hid_message_box(RND_ACT_DESIGN, "question", "New sheet: file already exists", msg, "yes", 1, "no/cancel", 0, NULL); + free(msg); + + if (!go_for_it) { + free(path); + return 0; + } + } + + rnd_multi_switch_to(NULL); /* empty conf so we can overwrite */ + + /* NOTE: this may be a contradiction to use curr->hidlib.project instead of + NULL: create a new unlisted sheet from menu, name it /tmp/foo.rs + and it will be put in the current project in memory, but not in + the project file (since it's unlisted). So this sheet is now using + the wrong project.lht that it wouldn't use when loaded */ + ns = sch_rnd_multi_new_empty_in_prj((csch_project_t *)curr->hidlib.project, path); + free(path); + + ns->changed = 1; /* sheet is unsaved when created */ + + prj = (csch_project_t *)ns->hidlib.project; + + switch(*type) { + case 'r': + ns->stype = CSCH_SHTY_ROOT; + prj->num_root_sheets++; + rnd_multi_switch_to_(&ns->hidlib); /* activate new, before project file write */ + prj_append_sheet(prj, ns, "prj/root_sheets"); + if (prj->hdr.fullpath == NULL) { + /* undo the counting if the user didn't create the project file */ + prj->num_root_sheets--; + ns->stype = CSCH_SHTY_UNLISTED; + } + rnd_event(&ns->hidlib, RND_EVENT_DESIGN_FN_CHANGED, NULL); /* get the final type displayed */ + break; + case 'a': + ns->stype = CSCH_SHTY_AUX; + prj->num_aux_sheets++; + rnd_multi_switch_to_(&ns->hidlib); /* activate new, before project file write */ + prj_append_sheet(prj, ns, "prj/aux_sheets"); + if (prj->hdr.fullpath == NULL) { + /* undo the counting if the user didn't create the project file */ + prj->num_aux_sheets--; + ns->stype = CSCH_SHTY_UNLISTED; + } + rnd_event(&ns->hidlib, RND_EVENT_DESIGN_FN_CHANGED, NULL); /* get the final type displayed */ + break; + case 'u': + ns->stype = CSCH_SHTY_UNLISTED; + rnd_multi_switch_to_(&ns->hidlib); /* activate new */ + break; + } + + return 0; +} + +static const char csch_acts_ProjectNew[] = "ProjectNew([path])"; +static const char csch_acth_ProjectNew[] = "Create a new project"; +fgw_error_t csch_act_ProjectNew(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *path = NULL; + char *freeme = NULL; + int ret = 1; + csch_project_t *prj; + + RND_ACT_MAY_CONVARG(1, FGW_STR, ProjectNew, path = argv[1].val.str); + + if (path == NULL) { + path = freeme = rnd_hid_fileselect(rnd_gui, "New project", "select the path/project.lht of the new project", "project.lht", NULL, NULL, "ProjectNew", 0, NULL); + if (path == NULL) + goto quit; + } + + if (rnd_file_readable(RND_ACT_DESIGN, path)) { + rnd_message(RND_MSG_ERROR, "Can't create project: project file already exists\n"); + goto quit; + } + + ret = sch_rnd_project_create_file(RND_ACT_DESIGN, path, &prj); + if ((ret == 0) && (prj != NULL)) { + csch_sheet_t *ns; + char *nam, *bn; + + rnd_multi_switch_to(NULL); /* empty conf so we can overwrite */ + ns = sch_rnd_multi_new_empty_in_prj(prj, NULL); + ns->changed = 1; /* sheet is unsaved when created */ + + nam = rnd_strdup(prj->hdr.fullpath); + bn = nam + strlen(nam) - 11; /* nam ends in project.lht */ + strcpy(bn, ""); + ns->hidlib.loadname = nam; /* sinde there's no full_path in hidlib, save_as will trigger on save */ + ns->stype = CSCH_SHTY_UNLISTED; + rnd_multi_switch_to_(&ns->hidlib); + } + + quit:; + free(freeme); + RND_ACT_IRES(ret); + return 0; +} + +static const char csch_acts_ProjectLoadPartial[] = "ProjectLoadPartial([@])"; +static const char csch_acth_ProjectLoadPartial[] = "Load sheet's missing files (or in other words, load the project file of the sheet)"; +fgw_error_t csch_act_ProjectLoadPartial(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *scope = "@"; + csch_sheet_t *sheet = (csch_sheet_t *)RND_ACT_DESIGN; + int ret; + csch_project_t *prj; + + RND_ACT_CONVARG(1, FGW_STR, ProjectLoadPartial, scope = argv[1].val.str); + + RND_ACT_IRES(1); + + if ((scope[0] != '@') || (scope[1] != '\0')) { + rnd_message(RND_MSG_ERROR, "ProjectLoadPartial(): only current project scope (@) is supported at the moment\n"); + return FGW_ERR_ARG_CONV; + } + + prj = (csch_project_t *)sheet->hidlib.project; + assert(prj != NULL); + + ret = rnd_actionva(&sheet->hidlib, "LoadFrom", "sheet", prj->hdr.fullpath, NULL); + + RND_ACT_IRES(ret); + return 0; +} + +static void prj_remove_sheet(csch_project_t *prj, const char *listpath, long pidx) +{ + lht_node_t *nd; + + if ((listpath == NULL) || (pidx < 0)) + return; + + nd = rnd_conf_lht_get_at(RND_CFR_PROJECT, listpath, 1); + if (nd != NULL) { + if (lht_tree_list_del_nth(nd, pidx) == LHTE_SUCCESS) { + if (listpath[4] == 'r') /* removed from prj/root_sheets */ + prj->num_root_sheets--; + if (listpath[4] == 'a') /* removed from prj/aux_sheets */ + prj->num_aux_sheets--; + } + } +} + +static long prj_find_sheet_in_(const char *prjdir, const rnd_conflist_t *lst, const char *fpath) +{ + int idx; + rnd_conf_listitem_t *item_li; + const char *item_str; + + rnd_conf_loop_list_str(lst, item_li, item_str, idx) { + char *sfp; + const char *sfn = item_str; + gds_t tmp = {0}; + + if (!rnd_is_path_abs(sfn)) { /* relative sheet file name is always relative to the project */ + gds_append_str(&tmp, prjdir); + gds_append(&tmp, '/'); + gds_append_str(&tmp, sfn); + sfn = tmp.array; + } + + sfp = rnd_lrealpath(sfn); + gds_uninit(&tmp); + + if (sfp != NULL) { + int res = strcmp(sfp, fpath); + free(sfp); + if (res == 0) + return idx; + } + } + return -1; +} + +/* convert each item of lst into a realpath and check if it matches fpath; + if it does, return its index on the list */ +static long prj_find_sheet_in(csch_project_t *prj, const rnd_conflist_t *lst, const char *fpath) +{ + long res; + char *bn; + + bn = rnd_dirname(prj->hdr.fullpath); + res = prj_find_sheet_in_(bn, lst, fpath); + free(bn); + + return res; +} + + + +static const char csch_acts_ProjectSheetType[] = "ProjectSheetType(@, sheet_fullpath, root|aux|unlisted|unload)"; +static const char csch_acth_ProjectSheetType[] = "Change the type of a sheet (addressed by its full path) in a project, making the necessary modifications in the project file"; +fgw_error_t csch_act_ProjectSheetType(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *scope, *fpath, *type, *listpath = NULL; + int also_unload = 0; + long n, pidx = -1; + csch_sheet_t *sheet = NULL, *old = NULL, *curr = (csch_sheet_t *)RND_ACT_DESIGN; + csch_project_t *prj; + + RND_ACT_CONVARG(1, FGW_STR, ProjectSheetType, scope = argv[1].val.str); + RND_ACT_CONVARG(2, FGW_STR, ProjectSheetType, fpath = argv[2].val.str); + RND_ACT_CONVARG(3, FGW_STR, ProjectSheetType, type = argv[3].val.str); + + RND_ACT_IRES(1); + + if ((scope[0] != '@') || (scope[1] != '\0')) { + rnd_message(RND_MSG_ERROR, "ProjectSheetType(): only current project scope (@) is supported at the moment\n"); + return FGW_ERR_ARG_CONV; + } + + prj = (csch_project_t *)curr->hidlib.project; + assert(prj != NULL); + + /* find the sheet */ + for(n = 0; n < prj->hdr.designs.used; n++) { + csch_sheet_t *sh = prj->hdr.designs.array[n]; + if (strcmp(sh->hidlib.fullpath, fpath) == 0) { + sheet = sh; + break; + } + } + + if (sheet == NULL) { + rnd_message(RND_MSG_ERROR, "ProjectSheetType(): sheet '%s' not found\n", fpath); + return 0; + } + + if ((sheet->hidlib.fullpath == NULL) || (*sheet->hidlib.fullpath == '<')) { + rnd_message(RND_MSG_ERROR, "sheet '%s' has no valid file name, try saving it first\n", fpath); + return 0; + } + + if (prj->hdr.fullpath == NULL) + sch_rnd_project_create_file_for_sheet_gui(curr); + + if (prj->hdr.fullpath == NULL) /* cancel - no project file created */ + return 0; + + /* figure index-on-config-array of target sheet, if there's a list to look into */ + switch(sheet->stype) { + case CSCH_SHTY_ROOT: listpath = "prj/root_sheets"; pidx = prj_find_sheet_in(prj, &conf_core.prj.root_sheets, fpath); break; + case CSCH_SHTY_AUX: listpath = "prj/aux_sheets"; pidx = prj_find_sheet_in(prj, &conf_core.prj.aux_sheets, fpath); break; + default: /* no list to remove from */; + } + + /* need to switch current sheet to get the project config */ + if (listpath != NULL) + old = sch_rnd_multi_switch_to(sheet); + + if (strcmp(type, "root") == 0) { + if (sheet->stype != CSCH_SHTY_ROOT) { + prj_remove_sheet(prj, listpath, pidx); + prj_append_sheet(prj, sheet, "prj/root_sheets"); + sheet->stype = CSCH_SHTY_ROOT; + prj->num_root_sheets++; + } + } + else if (strcmp(type, "aux") == 0) { + if (sheet->stype != CSCH_SHTY_AUX) { + prj_remove_sheet(prj, listpath, pidx); + prj_append_sheet(prj, sheet, "prj/aux_sheets"); + sheet->stype = CSCH_SHTY_AUX; + prj->num_aux_sheets++; + } + } + else if (strcmp(type, "unlisted") == 0) { + if (sheet->stype != CSCH_SHTY_UNLISTED) { + prj_remove_sheet(prj, listpath, pidx); + sheet->stype = CSCH_SHTY_UNLISTED; + if (type[3] == 'o') + also_unload = 1; + } + } + else if (strcmp(type, "unload") == 0) { + if (listpath != NULL) { + prj_remove_sheet(prj, listpath, pidx); + prj_flush(sheet, listpath); + } + + sheet->stype = CSCH_SHTY_UNLISTED; + also_unload = 1; + } + else { + rnd_message(RND_MSG_ERROR, "ProjectSheetType(): invalid sheet type '%s'\n", type); + goto error; + } + + rnd_event(&sheet->hidlib, RND_EVENT_DESIGN_FN_CHANGED, NULL); /* get the final type displayed */ + + if (old != NULL) + sch_rnd_multi_switch_to(old); + + if (also_unload) { + csch_sheet_t *next = (csch_sheet_t *)rnd_multi_neighbour_sheet(NULL); + if (next != NULL) { + sch_rnd_multi_unload(sheet); + if (old == sheet) + sch_rnd_multi_switch_to(next); + rnd_event(&next->hidlib, CSCH_EVENT_SHEET_POSTUNLOAD, NULL); + } + else + rnd_message(RND_MSG_ERROR, "ProjectSheetType(): can not unload the only sheet open\n"); + } + + RND_ACT_IRES(0); + return 0; + + error: + if (old != NULL) + sch_rnd_multi_switch_to(old); + return 0; +} + +static const char csch_acts_SaveAll[] = "SaveAll([currprj])"; +static const char csch_acth_SaveAll[] = "Save all unsaved sheets in current project (currprj)"; +fgw_error_t csch_act_SaveAll(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *scope = "currprj"; + csch_sheet_t *sheet = (csch_sheet_t *)RND_ACT_DESIGN; + long n; + csch_project_t *prj; + + RND_ACT_MAY_CONVARG(1, FGW_STR, SaveAll, scope = argv[1].val.str); + + RND_ACT_IRES(1); + + if (strcmp(scope, "currprj") != 0) { + rnd_message(RND_MSG_ERROR, "ProjectSaveAll(): only current project scope (currprj) is supported at the moment\n"); + return FGW_ERR_ARG_CONV; + } + + prj = (csch_project_t *)sheet->hidlib.project; + assert(prj != NULL); + + RND_ACT_IRES(0); + + for(n = 0; n < prj->hdr.designs.used; n++) { + csch_sheet_t *sheet = prj->hdr.designs.array[n]; + if (sheet->changed) { + if (csch_save_sheet(sheet, sheet->hidlib.fullpath, "lihata") != 0) { + rnd_message(RND_MSG_ERROR, "Can not save file '%s'\n", sheet->hidlib.fullpath); + RND_ACT_IRES(-1); + } + else + rnd_message(RND_MSG_INFO, "SaveAll: saved '%s'\n", sheet->hidlib.fullpath); + } + } + + return 0; +} + +static rnd_action_t file_action_list[] = { + {"Quit", csch_act_Quit, csch_acth_Quit, csch_acts_Quit}, + {"SymlibRehash", csch_act_SymlibRehash, csch_acth_SymlibRehash, csch_acts_SymlibRehash}, + {"SymlibReloadAllLocal", csch_act_SymlibReloadAllLocal, csch_acth_SymlibReloadAllLocal, csch_acts_SymlibReloadAllLocal}, + {"HlibraryRehash", csch_act_HlibraryRehash, csch_acth_HlibraryRehash, csch_acts_HlibraryRehash}, + {"Revert", csch_act_Revert, csch_acth_Revert, csch_acts_Revert}, + {"New", csch_act_New, csch_acth_New, csch_acts_New}, + {"Export", rnd_act_Export, rnd_acth_Export, rnd_acts_Export}, + {"ProjectNew", csch_act_ProjectNew, csch_acth_ProjectNew, csch_acts_ProjectNew}, + {"ProjectLoadPartial", csch_act_ProjectLoadPartial, csch_acth_ProjectLoadPartial, csch_acts_ProjectLoadPartial}, + {"ProjectSheetType", csch_act_ProjectSheetType, csch_acth_ProjectSheetType, csch_acts_ProjectSheetType}, + {"SaveAll", csch_act_SaveAll, csch_acth_SaveAll, csch_acts_SaveAll}, +}; + +void sch_rnd_file_act_init2(void) +{ + RND_REGISTER_ACTIONS(file_action_list, NULL); +} Index: tags/1.0.5/src/sch-rnd/font.c =================================================================== --- tags/1.0.5/src/sch-rnd/font.c (nonexistent) +++ tags/1.0.5/src/sch-rnd/font.c (revision 10414) @@ -0,0 +1,107 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - sch-rnd (executable) + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/* Font selection */ + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "conf_core.h" +#include "draw.h" + +#include "font.h" + +long sch_rnd_font_score_debug; + +#include "font_rnd.c" +#include "font_act.c" + +void sch_rnd_font_text_update(csch_sheet_t *sheet, csch_text_t *t, csch_cpen_t *pen) +{ + rf_text_update(sheet, t, pen); +} + +void sch_rnd_font_text_render(csch_sheet_t *sheet, rnd_hid_gc_t gc, csch_text_t *t, csch_cpen_t *pen) +{ + rf_text_render(sheet, gc, t, pen); +} + +static void text_inval_font(csch_sheet_t *sheet, csch_text_t *text) +{ + rf_inval_font(sheet, text); +} + +static void text_calc_bbox(csch_sheet_t *sheet, csch_text_t *text) +{ + csch_cpen_t *pen = csch_stroke_fallback_(&text->hdr, NULL); + sch_rnd_font_text_update(sheet, text, pen); +} + +static void pen_inval_font(csch_sheet_t *sheet, csch_cpen_t *pen) +{ + pen->font_handle_valid = 0; +} + +void *sch_rnd_font_lookup(const char *name, const char *style) +{ + return rf_font_lookup(NULL, name, style); +} + + +void sch_rnd_font_init2(void) +{ + sch_rnd_font_rnd_init2(); + + csch_cb_text_calc_bbox = text_calc_bbox; + csch_cb_text_invalidate_font = text_inval_font; + csch_cb_pen_invalidate_font = pen_inval_font; +} + +void sch_rnd_font_uninit(void) +{ + sch_rnd_font_rnd_uninit(); + + csch_cb_text_calc_bbox = NULL; + csch_cb_text_invalidate_font = NULL; + csch_cb_pen_invalidate_font = NULL; +} Index: tags/1.0.5/src/sch-rnd/font.h =================================================================== --- tags/1.0.5/src/sch-rnd/font.h (nonexistent) +++ tags/1.0.5/src/sch-rnd/font.h (revision 10414) @@ -0,0 +1,48 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - sch-rnd (executable) + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include + +/* Update the pixmap cache (and recalculate bbox for height-defined font) */ +void sch_rnd_font_text_update(csch_sheet_t *sheet, csch_text_t *t, csch_cpen_t *pen); + +/* render text object (assume gc and drawing code is already prepared) */ +void sch_rnd_font_text_render(csch_sheet_t *sheet, rnd_hid_gc_t gc, csch_text_t *t, csch_cpen_t *pen); + + +/* Look up best match for name/style or at least return a safe fallback font */ +void *sch_rnd_font_lookup(const char *name, const char *style); + + +void sch_rnd_font_init2(void); +void sch_rnd_font_uninit(void); + +/* direct draw text string (from draw.c) */ +void sch_rnd_render_text_string(rnd_hid_gc_t gc, void *font, rnd_coord_t x, rnd_coord_t y, rnd_coord_t size, const unsigned char *text_str); +void sch_rnd_render_text_string_scrotmir(rnd_hid_gc_t gc, void *font, rnd_coord_t x, rnd_coord_t y, double size, double rot, int mirrory, const unsigned char *text_str); + Index: tags/1.0.5/src/sch-rnd/font_act.c =================================================================== --- tags/1.0.5/src/sch-rnd/font_act.c (nonexistent) +++ tags/1.0.5/src/sch-rnd/font_act.c (revision 10414) @@ -0,0 +1,86 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - sch-rnd (executable) + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/* Included from font.c */ + +#include +#include "funchash_core.h" + + +static const char csch_acts_FontInfo[] = "FontInfo(TextWidth|TextHeight, str, [penname])"; +static const char csch_acth_FontInfo[] = "Test-render str and return width or height."; +static fgw_error_t csch_act_FontInfo(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + csch_sheet_t *sheet = CSCH_ACT_SHEET; + rnd_font_t *f; + rnd_coord_t cx[4], cy[4]; + csch_cpen_t *pen; + int op; + const char *text_str, *penname = "sheet-decor"; + + RND_ACT_CONVARG(1, FGW_KEYWORD, FontInfo, op = fgw_keyword(&argv[1])); + RND_ACT_CONVARG(2, FGW_STR, FontInfo, text_str = argv[2].val.str); + RND_ACT_MAY_CONVARG(3, FGW_STR, FontInfo, penname = argv[3].val.str); + + switch(op) { + case F_TextWidth: + case F_TextHeight: + + pen = csch_pen_get(sheet, &sheet->direct, penname); + if (penname == NULL) + return FGW_ERR_ARG_CONV; + + f = rf_resolve_pen(&sheet->hidlib, pen); + if (f == NULL) + return FGW_ERR_ARG_CONV; + + res->type = FGW_LONG; + if (op == F_TextHeight) { + res->val.nat_long = P2C(f->height); + return 0; + } + + rnd_font_string_bbox(cx, cy, f, (const unsigned char *)text_str, 0, 0, 1, 1, 0, 0, 0, 0); + cx[0] = 0; /* undo the effect of left side whitespace: we started to render from 0;0 */ + res->val.nat_long = P2C(cx[1] - cx[0]); + return 0; + + default: + return FGW_ERR_ARG_CONV; + + } + + return -1; +} + +static rnd_action_t font_action_list[] = { + {"FontInfo", csch_act_FontInfo, csch_acth_FontInfo, csch_acts_FontInfo} +}; + +void sch_rnd_font_act_init2(void) +{ + RND_REGISTER_ACTIONS(font_action_list, NULL); +} Index: tags/1.0.5/src/sch-rnd/font_internal.c =================================================================== --- tags/1.0.5/src/sch-rnd/font_internal.c (nonexistent) +++ tags/1.0.5/src/sch-rnd/font_internal.c (revision 10414) @@ -0,0 +1,818 @@ +/* This file is autogenerated by font2c.sh - DO NOT EDIT */ + +/* Internal copy of the default font; used when no font file is found */ + +static embf_line_t embf_line_32[] = { + {0,0,0,0} +}; +static embf_line_t embf_line_33[] = { /* ! */ + {0, 35, 0, 40, 8}, + {0, 0, 0, 25, 8} +}; +static embf_line_t embf_line_34[] = { /* " */ + {0, 0, 0, 10, 8}, + {10, 0, 10, 10, 8} +}; +static embf_line_t embf_line_35[] = { /* # */ + {0, 25, 20, 25, 8}, + {0, 15, 20, 15, 8}, + {15, 10, 15, 30, 8}, + {5, 10, 5, 30, 8} +}; +static embf_line_t embf_line_36[] = { /* $ */ + {15, 5, 20, 10, 8}, + {5, 5, 15, 5, 8}, + {0, 10, 5, 5, 8}, + {0, 10, 0, 15, 8}, + {0, 15, 5, 20, 8}, + {5, 20, 15, 20, 8}, + {15, 20, 20, 25, 8}, + {20, 25, 20, 30, 8}, + {15, 35, 20, 30, 8}, + {5, 35, 15, 35, 8}, + {0, 30, 5, 35, 8}, + {10, 0, 10, 40, 8} +}; +static embf_line_t embf_line_37[] = { /* % */ + {0, 5, 0, 10, 8}, + {0, 5, 5, 0, 8}, + {5, 0, 10, 0, 8}, + {10, 0, 15, 5, 8}, + {15, 5, 15, 10, 8}, + {10, 15, 15, 10, 8}, + {5, 15, 10, 15, 8}, + {0, 10, 5, 15, 8}, + {0, 40, 40, 0, 8}, + {35, 40, 40, 35, 8}, + {40, 30, 40, 35, 8}, + {35, 25, 40, 30, 8}, + {30, 25, 35, 25, 8}, + {25, 30, 30, 25, 8}, + {25, 30, 25, 35, 8}, + {25, 35, 30, 40, 8}, + {30, 40, 35, 40, 8} +}; +static embf_line_t embf_line_38[] = { /* & */ + {0, 35, 5, 40, 8}, + {0, 5, 0, 15, 8}, + {0, 5, 5, 0, 8}, + {0, 25, 15, 10, 8}, + {5, 40, 10, 40, 8}, + {10, 40, 20, 30, 8}, + {0, 15, 25, 40, 8}, + {5, 0, 10, 0, 8}, + {10, 0, 15, 5, 8}, + {15, 5, 15, 10, 8}, + {0, 25, 0, 35, 8} +}; +static embf_line_t embf_line_39[] = { /* ' */ + {0, 10, 10, 0, 8} +}; +static embf_line_t embf_line_40[] = { + {0, 35, 5, 40, 8}, + {0, 5, 5, 0, 8}, + {0, 5, 0, 35, 8} +}; +static embf_line_t embf_line_41[] = { + {0, 0, 5, 5, 8}, + {5, 5, 5, 35, 8}, + {0, 40, 5, 35, 8} +}; +static embf_line_t embf_line_42[] = { /* * */ + {0, 10, 20, 30, 8}, + {0, 30, 20, 10, 8}, + {0, 20, 20, 20, 8}, + {10, 10, 10, 30, 8} +}; +static embf_line_t embf_line_43[] = { /* + */ + {0, 20, 20, 20, 8}, + {10, 10, 10, 30, 8} +}; +static embf_line_t embf_line_44[] = { /* , */ + {0, 50, 10, 40, 8} +}; +static embf_line_t embf_line_45[] = { /* - */ + {0, 20, 20, 20, 8} +}; +static embf_line_t embf_line_46[] = { /* . */ + {0, 40, 5, 40, 8} +}; +static embf_line_t embf_line_47[] = { /* / */ + {0, 35, 30, 5, 8} +}; +static embf_line_t embf_line_48[] = { /* 0 */ + {0, 35, 5, 40, 8}, + {0, 5, 0, 35, 8}, + {0, 5, 5, 0, 8}, + {5, 0, 15, 0, 8}, + {15, 0, 20, 5, 8}, + {20, 5, 20, 35, 8}, + {15, 40, 20, 35, 8}, + {5, 40, 15, 40, 8}, + {0, 30, 20, 10, 8} +}; +static embf_line_t embf_line_49[] = { /* 1 */ + {0, 8, 8, 0, 8}, + {8, 0, 8, 40, 8}, + {0, 40, 15, 40, 8} +}; +static embf_line_t embf_line_50[] = { /* 2 */ + {0, 5, 5, 0, 8}, + {5, 0, 20, 0, 8}, + {20, 0, 25, 5, 8}, + {25, 5, 25, 15, 8}, + {0, 40, 25, 15, 8}, + {0, 40, 25, 40, 8} +}; +static embf_line_t embf_line_51[] = { /* 3 */ + {0, 5, 5, 0, 8}, + {5, 0, 15, 0, 8}, + {15, 0, 20, 5, 8}, + {15, 40, 20, 35, 8}, + {5, 40, 15, 40, 8}, + {0, 35, 5, 40, 8}, + {5, 18, 15, 18, 8}, + {20, 5, 20, 13, 8}, + {20, 23, 20, 35, 8}, + {20, 23, 15, 18, 8}, + {20, 13, 15, 18, 8} +}; +static embf_line_t embf_line_52[] = { /* 4 */ + {0, 25, 20, 0, 8}, + {0, 25, 25, 25, 8}, + {20, 0, 20, 40, 8} +}; +static embf_line_t embf_line_53[] = { /* 5 */ + {0, 0, 20, 0, 8}, + {0, 0, 0, 20, 8}, + {0, 20, 5, 15, 8}, + {5, 15, 15, 15, 8}, + {15, 15, 20, 20, 8}, + {20, 20, 20, 35, 8}, + {15, 40, 20, 35, 8}, + {5, 40, 15, 40, 8}, + {0, 35, 5, 40, 8} +}; +static embf_line_t embf_line_54[] = { /* 6 */ + {15, 0, 20, 5, 8}, + {5, 0, 15, 0, 8}, + {0, 5, 5, 0, 8}, + {0, 5, 0, 35, 8}, + {0, 35, 5, 40, 8}, + {15, 18, 20, 23, 8}, + {0, 18, 15, 18, 8}, + {5, 40, 15, 40, 8}, + {15, 40, 20, 35, 8}, + {20, 23, 20, 35, 8} +}; +static embf_line_t embf_line_55[] = { /* 7 */ + {5, 40, 25, 0, 8}, + {0, 0, 25, 0, 8} +}; +static embf_line_t embf_line_56[] = { /* 8 */ + {0, 35, 5, 40, 8}, + {0, 27, 0, 35, 8}, + {0, 27, 7, 20, 8}, + {7, 20, 13, 20, 8}, + {13, 20, 20, 27, 8}, + {20, 27, 20, 35, 8}, + {15, 40, 20, 35, 8}, + {5, 40, 15, 40, 8}, + {0, 13, 7, 20, 8}, + {0, 5, 0, 13, 8}, + {0, 5, 5, 0, 8}, + {5, 0, 15, 0, 8}, + {15, 0, 20, 5, 8}, + {20, 5, 20, 13, 8}, + {13, 20, 20, 13, 8} +}; +static embf_line_t embf_line_57[] = { /* 9 */ + {5, 40, 20, 20, 8}, + {20, 5, 20, 20, 8}, + {15, 0, 20, 5, 8}, + {5, 0, 15, 0, 8}, + {0, 5, 5, 0, 8}, + {0, 5, 0, 15, 8}, + {0, 15, 5, 20, 8}, + {5, 20, 20, 20, 8} +}; +static embf_line_t embf_line_58[] = { /* : */ + {0, 15, 5, 15, 8}, + {0, 25, 5, 25, 8} +}; +static embf_line_t embf_line_59[] = { /* ; */ + {0, 40, 10, 30, 8}, + {10, 15, 10, 20, 8} +}; +static embf_line_t embf_line_60[] = { /* < */ + {0, 20, 10, 10, 8}, + {0, 20, 10, 30, 8} +}; +static embf_line_t embf_line_61[] = { /* = */ + {0, 15, 20, 15, 8}, + {0, 25, 20, 25, 8} +}; +static embf_line_t embf_line_62[] = { /* > */ + {0, 10, 10, 20, 8}, + {0, 30, 10, 20, 8} +}; +static embf_line_t embf_line_63[] = { /* ? */ + {10, 20, 10, 25, 8}, + {10, 35, 10, 40, 8}, + {0, 5, 0, 10, 8}, + {0, 5, 5, 0, 8}, + {5, 0, 15, 0, 8}, + {15, 0, 20, 5, 8}, + {20, 5, 20, 10, 8}, + {10, 20, 20, 10, 8} +}; +static embf_line_t embf_line_64[] = { /* @ */ + {0, 0, 0, 30, 8}, + {0, 30, 10, 40, 8}, + {10, 40, 40, 40, 8}, + {50, 25, 50, 0, 8}, + {50, 0, 40, -10, 8}, + {40, -10, 10, -10, 8}, + {10, -10, 0, 0, 8}, + {15, 10, 15, 20, 8}, + {15, 20, 20, 25, 8}, + {20, 25, 30, 25, 8}, + {30, 25, 35, 20, 8}, + {35, 20, 40, 25, 8}, + {35, 20, 35, 5, 8}, + {35, 10, 30, 5, 8}, + {20, 5, 30, 5, 8}, + {20, 5, 15, 10, 8}, + {40, 25, 50, 25, 8} +}; +static embf_line_t embf_line_65[] = { /* A */ + {0, 10, 0, 40, 8}, + {0, 10, 7, 0, 8}, + {7, 0, 18, 0, 8}, + {18, 0, 25, 10, 8}, + {25, 10, 25, 40, 8}, + {0, 20, 25, 20, 8} +}; +static embf_line_t embf_line_66[] = { /* B */ + {0, 40, 20, 40, 8}, + {20, 40, 25, 35, 8}, + {25, 23, 25, 35, 8}, + {20, 18, 25, 23, 8}, + {5, 18, 20, 18, 8}, + {5, 0, 5, 40, 8}, + {0, 0, 20, 0, 8}, + {20, 0, 25, 5, 8}, + {25, 5, 25, 13, 8}, + {20, 18, 25, 13, 8} +}; +static embf_line_t embf_line_67[] = { /* C */ + {7, 40, 20, 40, 8}, + {0, 33, 7, 40, 8}, + {0, 7, 0, 33, 8}, + {0, 7, 7, 0, 8}, + {7, 0, 20, 0, 8} +}; +static embf_line_t embf_line_68[] = { /* D */ + {5, 0, 5, 40, 8}, + {18, 0, 25, 7, 8}, + {25, 7, 25, 33, 8}, + {18, 40, 25, 33, 8}, + {0, 40, 18, 40, 8}, + {0, 0, 18, 0, 8} +}; +static embf_line_t embf_line_69[] = { /* E */ + {0, 18, 15, 18, 8}, + {0, 40, 20, 40, 8}, + {0, 0, 0, 40, 8}, + {0, 0, 20, 0, 8} +}; +static embf_line_t embf_line_70[] = { /* F */ + {0, 0, 0, 40, 8}, + {0, 0, 20, 0, 8}, + {0, 18, 15, 18, 8} +}; +static embf_line_t embf_line_71[] = { /* G */ + {20, 0, 25, 5, 8}, + {5, 0, 20, 0, 8}, + {0, 5, 5, 0, 8}, + {0, 5, 0, 35, 8}, + {0, 35, 5, 40, 8}, + {5, 40, 20, 40, 8}, + {20, 40, 25, 35, 8}, + {25, 25, 25, 35, 8}, + {20, 20, 25, 25, 8}, + {10, 20, 20, 20, 8} +}; +static embf_line_t embf_line_72[] = { /* H */ + {0, 0, 0, 40, 8}, + {25, 0, 25, 40, 8}, + {0, 20, 25, 20, 8} +}; +static embf_line_t embf_line_73[] = { /* I */ + {0, 0, 10, 0, 8}, + {5, 0, 5, 40, 8}, + {0, 40, 10, 40, 8} +}; +static embf_line_t embf_line_74[] = { /* J */ + {7, 0, 15, 0, 8}, + {15, 0, 15, 35, 8}, + {10, 40, 15, 35, 8}, + {5, 40, 10, 40, 8}, + {0, 35, 5, 40, 8}, + {0, 35, 0, 30, 8} +}; +static embf_line_t embf_line_75[] = { /* K */ + {0, 0, 0, 40, 8}, + {0, 20, 20, 0, 8}, + {0, 20, 20, 40, 8} +}; +static embf_line_t embf_line_76[] = { /* L */ + {0, 0, 0, 40, 8}, + {0, 40, 20, 40, 8} +}; +static embf_line_t embf_line_77[] = { /* M */ + {0, 0, 0, 40, 8}, + {0, 0, 15, 20, 8}, + {15, 20, 30, 0, 8}, + {30, 0, 30, 40, 8} +}; +static embf_line_t embf_line_78[] = { /* N */ + {0, 0, 0, 40, 8}, + {0, 0, 25, 40, 8}, + {25, 0, 25, 40, 8} +}; +static embf_line_t embf_line_79[] = { /* O */ + {0, 5, 0, 35, 8}, + {0, 5, 5, 0, 8}, + {5, 0, 15, 0, 8}, + {15, 0, 20, 5, 8}, + {20, 5, 20, 35, 8}, + {15, 40, 20, 35, 8}, + {5, 40, 15, 40, 8}, + {0, 35, 5, 40, 8} +}; +static embf_line_t embf_line_80[] = { /* P */ + {5, 0, 5, 40, 8}, + {0, 0, 20, 0, 8}, + {20, 0, 25, 5, 8}, + {25, 5, 25, 15, 8}, + {20, 20, 25, 15, 8}, + {5, 20, 20, 20, 8} +}; +static embf_line_t embf_line_81[] = { /* Q */ + {0, 5, 0, 35, 8}, + {0, 5, 5, 0, 8}, + {5, 0, 15, 0, 8}, + {15, 0, 20, 5, 8}, + {20, 5, 20, 30, 8}, + {10, 40, 20, 30, 8}, + {5, 40, 10, 40, 8}, + {0, 35, 5, 40, 8}, + {10, 25, 20, 40, 8} +}; +static embf_line_t embf_line_82[] = { /* R */ + {0, 0, 20, 0, 8}, + {20, 0, 25, 5, 8}, + {25, 5, 25, 15, 8}, + {20, 20, 25, 15, 8}, + {5, 20, 20, 20, 8}, + {5, 0, 5, 40, 8}, + {13, 20, 25, 40, 8} +}; +static embf_line_t embf_line_83[] = { /* S */ + {20, 0, 25, 5, 8}, + {5, 0, 20, 0, 8}, + {0, 5, 5, 0, 8}, + {0, 5, 0, 15, 8}, + {0, 15, 5, 20, 8}, + {5, 20, 20, 20, 8}, + {20, 20, 25, 25, 8}, + {25, 25, 25, 35, 8}, + {20, 40, 25, 35, 8}, + {5, 40, 20, 40, 8}, + {0, 35, 5, 40, 8} +}; +static embf_line_t embf_line_84[] = { /* T */ + {0, 0, 20, 0, 8}, + {10, 0, 10, 40, 8} +}; +static embf_line_t embf_line_85[] = { /* U */ + {0, 0, 0, 35, 8}, + {0, 35, 5, 40, 8}, + {5, 40, 15, 40, 8}, + {15, 40, 20, 35, 8}, + {20, 0, 20, 35, 8} +}; +static embf_line_t embf_line_86[] = { /* V */ + {0, 0, 10, 40, 8}, + {10, 40, 20, 0, 8} +}; +static embf_line_t embf_line_87[] = { /* W */ + {0, 0, 0, 20, 8}, + {0, 20, 5, 40, 8}, + {5, 40, 15, 20, 8}, + {15, 20, 25, 40, 8}, + {25, 40, 30, 20, 8}, + {30, 20, 30, 0, 8} +}; +static embf_line_t embf_line_88[] = { /* X */ + {0, 40, 25, 0, 8}, + {0, 0, 25, 40, 8} +}; +static embf_line_t embf_line_89[] = { /* Y */ + {0, 0, 10, 20, 8}, + {10, 20, 20, 0, 8}, + {10, 20, 10, 40, 8} +}; +static embf_line_t embf_line_90[] = { /* Z */ + {0, 0, 25, 0, 8}, + {0, 40, 25, 0, 8}, + {0, 40, 25, 40, 8} +}; +static embf_line_t embf_line_91[] = { /* [ */ + {0, 0, 5, 0, 8}, + {0, 0, 0, 40, 8}, + {0, 40, 5, 40, 8} +}; +static embf_line_t embf_line_92[] = { /* \ */ + {0, 5, 30, 35, 8} +}; +static embf_line_t embf_line_93[] = { /* ] */ + {0, 0, 5, 0, 8}, + {5, 0, 5, 40, 8}, + {0, 40, 5, 40, 8} +}; +static embf_line_t embf_line_94[] = { /* ^ */ + {0, 5, 5, 0, 8}, + {5, 0, 10, 5, 8} +}; +static embf_line_t embf_line_95[] = { /* _ */ + {0, 40, 20, 40, 8} +}; +static embf_line_t embf_line_97[] = { /* a */ + {15, 20, 20, 25, 8}, + {5, 20, 15, 20, 8}, + {0, 25, 5, 20, 8}, + {0, 25, 0, 35, 8}, + {0, 35, 5, 40, 8}, + {20, 20, 20, 35, 8}, + {20, 35, 25, 40, 8}, + {5, 40, 15, 40, 8}, + {15, 40, 20, 35, 8} +}; +static embf_line_t embf_line_98[] = { /* b */ + {0, 0, 0, 40, 8}, + {0, 35, 5, 40, 8}, + {5, 40, 15, 40, 8}, + {15, 40, 20, 35, 8}, + {20, 25, 20, 35, 8}, + {15, 20, 20, 25, 8}, + {5, 20, 15, 20, 8}, + {0, 25, 5, 20, 8} +}; +static embf_line_t embf_line_99[] = { /* c */ + {5, 20, 20, 20, 8}, + {0, 25, 5, 20, 8}, + {0, 25, 0, 35, 8}, + {0, 35, 5, 40, 8}, + {5, 40, 20, 40, 8} +}; +static embf_line_t embf_line_100[] = { /* d */ + {20, 0, 20, 40, 8}, + {15, 40, 20, 35, 8}, + {5, 40, 15, 40, 8}, + {0, 35, 5, 40, 8}, + {0, 25, 0, 35, 8}, + {0, 25, 5, 20, 8}, + {5, 20, 15, 20, 8}, + {15, 20, 20, 25, 8} +}; +static embf_line_t embf_line_101[] = { /* e */ + {5, 40, 20, 40, 8}, + {0, 35, 5, 40, 8}, + {0, 25, 0, 35, 8}, + {0, 25, 5, 20, 8}, + {5, 20, 15, 20, 8}, + {15, 20, 20, 25, 8}, + {0, 30, 20, 30, 8}, + {20, 30, 20, 25, 8} +}; +static embf_line_t embf_line_102[] = { /* f */ + {5, 5, 5, 40, 8}, + {5, 5, 10, 0, 8}, + {10, 0, 15, 0, 8}, + {0, 20, 10, 20, 8} +}; +static embf_line_t embf_line_103[] = { /* g */ + {15, 20, 20, 25, 8}, + {5, 20, 15, 20, 8}, + {0, 25, 5, 20, 8}, + {0, 25, 0, 35, 8}, + {0, 35, 5, 40, 8}, + {5, 40, 15, 40, 8}, + {15, 40, 20, 35, 8}, + {0, 50, 5, 55, 8}, + {5, 55, 15, 55, 8}, + {15, 55, 20, 50, 8}, + {20, 20, 20, 50, 8} +}; +static embf_line_t embf_line_104[] = { /* h */ + {0, 0, 0, 40, 8}, + {0, 25, 5, 20, 8}, + {5, 20, 15, 20, 8}, + {15, 20, 20, 25, 8}, + {20, 25, 20, 40, 8} +}; +static embf_line_t embf_line_105[] = { /* i */ + {0, 10, 0, 11, 10}, + {0, 25, 0, 40, 8} +}; +static embf_line_t embf_line_106[] = { /* j */ + {5, 10, 5, 11, 10}, + {5, 25, 5, 50, 8}, + {0, 55, 5, 50, 8} +}; +static embf_line_t embf_line_107[] = { /* k */ + {0, 0, 0, 40, 8}, + {0, 25, 15, 40, 8}, + {0, 25, 10, 15, 8} +}; +static embf_line_t embf_line_108[] = { /* l */ + {0, 0, 0, 35, 8}, + {0, 35, 5, 40, 8} +}; +static embf_line_t embf_line_109[] = { /* m */ + {5, 25, 5, 40, 8}, + {5, 25, 10, 20, 8}, + {10, 20, 15, 20, 8}, + {15, 20, 20, 25, 8}, + {20, 25, 20, 40, 8}, + {20, 25, 25, 20, 8}, + {25, 20, 30, 20, 8}, + {30, 20, 35, 25, 8}, + {35, 25, 35, 40, 8}, + {0, 20, 5, 25, 8} +}; +static embf_line_t embf_line_110[] = { /* n */ + {5, 25, 5, 40, 8}, + {5, 25, 10, 20, 8}, + {10, 20, 15, 20, 8}, + {15, 20, 20, 25, 8}, + {20, 25, 20, 40, 8}, + {0, 20, 5, 25, 8} +}; +static embf_line_t embf_line_111[] = { /* o */ + {0, 25, 0, 35, 8}, + {0, 25, 5, 20, 8}, + {5, 20, 15, 20, 8}, + {15, 20, 20, 25, 8}, + {20, 25, 20, 35, 8}, + {15, 40, 20, 35, 8}, + {5, 40, 15, 40, 8}, + {0, 35, 5, 40, 8} +}; +static embf_line_t embf_line_112[] = { /* p */ + {5, 25, 5, 55, 8}, + {0, 20, 5, 25, 8}, + {5, 25, 10, 20, 8}, + {10, 20, 20, 20, 8}, + {20, 20, 25, 25, 8}, + {25, 25, 25, 35, 8}, + {20, 40, 25, 35, 8}, + {10, 40, 20, 40, 8}, + {5, 35, 10, 40, 8} +}; +static embf_line_t embf_line_113[] = { /* q */ + {20, 25, 20, 55, 8}, + {15, 20, 20, 25, 8}, + {5, 20, 15, 20, 8}, + {0, 25, 5, 20, 8}, + {0, 25, 0, 35, 8}, + {0, 35, 5, 40, 8}, + {5, 40, 15, 40, 8}, + {15, 40, 20, 35, 8} +}; +static embf_line_t embf_line_114[] = { /* r */ + {5, 25, 5, 40, 8}, + {5, 25, 10, 20, 8}, + {10, 20, 20, 20, 8}, + {0, 20, 5, 25, 8} +}; +static embf_line_t embf_line_115[] = { /* s */ + {5, 40, 20, 40, 8}, + {20, 40, 25, 35, 8}, + {20, 30, 25, 35, 8}, + {5, 30, 20, 30, 8}, + {0, 25, 5, 30, 8}, + {0, 25, 5, 20, 8}, + {5, 20, 20, 20, 8}, + {20, 20, 25, 25, 8}, + {0, 35, 5, 40, 8} +}; +static embf_line_t embf_line_116[] = { /* t */ + {5, 0, 5, 35, 8}, + {5, 35, 10, 40, 8}, + {0, 15, 10, 15, 8} +}; +static embf_line_t embf_line_117[] = { /* u */ + {0, 20, 0, 35, 8}, + {0, 35, 5, 40, 8}, + {5, 40, 15, 40, 8}, + {15, 40, 20, 35, 8}, + {20, 20, 20, 35, 8} +}; +static embf_line_t embf_line_118[] = { /* v */ + {0, 20, 10, 40, 8}, + {20, 20, 10, 40, 8} +}; +static embf_line_t embf_line_119[] = { /* w */ + {0, 20, 0, 35, 8}, + {0, 35, 5, 40, 8}, + {5, 40, 10, 40, 8}, + {10, 40, 15, 35, 8}, + {15, 20, 15, 35, 8}, + {15, 35, 20, 40, 8}, + {20, 40, 25, 40, 8}, + {25, 40, 30, 35, 8}, + {30, 20, 30, 35, 8} +}; +static embf_line_t embf_line_120[] = { /* x */ + {0, 20, 20, 40, 8}, + {0, 40, 20, 20, 8} +}; +static embf_line_t embf_line_121[] = { /* y */ + {0, 20, 0, 35, 8}, + {0, 35, 5, 40, 8}, + {20, 20, 20, 50, 8}, + {15, 55, 20, 50, 8}, + {5, 55, 15, 55, 8}, + {0, 50, 5, 55, 8}, + {5, 40, 15, 40, 8}, + {15, 40, 20, 35, 8} +}; +static embf_line_t embf_line_122[] = { /* z */ + {0, 20, 20, 20, 8}, + {0, 40, 20, 20, 8}, + {0, 40, 20, 40, 8} +}; +static embf_line_t embf_line_123[] = { + {5, 5, 10, 0, 8}, + {5, 5, 5, 15, 8}, + {0, 20, 5, 15, 8}, + {0, 20, 5, 25, 8}, + {5, 25, 5, 35, 8}, + {5, 35, 10, 40, 8} +}; +static embf_line_t embf_line_124[] = { /* | */ + {0, 0, 0, 40, 8} +}; +static embf_line_t embf_line_125[] = { + {0, 0, 5, 5, 8}, + {5, 5, 5, 15, 8}, + {5, 15, 10, 20, 8}, + {5, 25, 10, 20, 8}, + {5, 25, 5, 35, 8}, + {0, 40, 5, 35, 8} +}; +static embf_line_t embf_line_126[] = { /* ~ */ + {0, 25, 5, 20, 8}, + {5, 20, 10, 20, 8}, + {10, 20, 15, 25, 8}, + {15, 25, 20, 25, 8}, + {20, 25, 25, 20, 8} +}; +/***************************************************************/ +static int embf_minx = 0; +static int embf_miny = -10; +static int embf_maxx = 50; +static int embf_maxy = 55; +static embf_font_t embf_font[] = { + {0, NULL, 0}, + {0, NULL, 0}, + {0, NULL, 0}, + {0, NULL, 0}, + {0, NULL, 0}, + {0, NULL, 0}, + {0, NULL, 0}, + {0, NULL, 0}, + {0, NULL, 0}, + {0, NULL, 0}, + {0, NULL, 0}, + {0, NULL, 0}, + {0, NULL, 0}, + {0, NULL, 0}, + {0, NULL, 0}, + {0, NULL, 0}, + {0, NULL, 0}, + {0, NULL, 0}, + {0, NULL, 0}, + {0, NULL, 0}, + {0, NULL, 0}, + {0, NULL, 0}, + {0, NULL, 0}, + {0, NULL, 0}, + {0, NULL, 0}, + {0, NULL, 0}, + {0, NULL, 0}, + {0, NULL, 0}, + {0, NULL, 0}, + {0, NULL, 0}, + {0, NULL, 0}, + {0, NULL, 0}, + {18, embf_line_32, 0}, + {12, embf_line_33, 2}, + {12, embf_line_34, 2}, + {12, embf_line_35, 4}, + {12, embf_line_36, 12}, + {12, embf_line_37, 17}, + {12, embf_line_38, 11}, + {12, embf_line_39, 1}, + {12, embf_line_40, 3}, + {12, embf_line_41, 3}, + {12, embf_line_42, 4}, + {12, embf_line_43, 2}, + {12, embf_line_44, 1}, + {12, embf_line_45, 1}, + {12, embf_line_46, 1}, + {12, embf_line_47, 1}, + {12, embf_line_48, 9}, + {12, embf_line_49, 3}, + {12, embf_line_50, 6}, + {12, embf_line_51, 11}, + {12, embf_line_52, 3}, + {12, embf_line_53, 9}, + {12, embf_line_54, 10}, + {12, embf_line_55, 2}, + {12, embf_line_56, 15}, + {12, embf_line_57, 8}, + {12, embf_line_58, 2}, + {12, embf_line_59, 2}, + {12, embf_line_60, 2}, + {12, embf_line_61, 2}, + {12, embf_line_62, 2}, + {12, embf_line_63, 8}, + {12, embf_line_64, 17}, + {12, embf_line_65, 6}, + {12, embf_line_66, 10}, + {12, embf_line_67, 5}, + {12, embf_line_68, 6}, + {12, embf_line_69, 4}, + {12, embf_line_70, 3}, + {12, embf_line_71, 10}, + {12, embf_line_72, 3}, + {12, embf_line_73, 3}, + {12, embf_line_74, 6}, + {12, embf_line_75, 3}, + {12, embf_line_76, 2}, + {12, embf_line_77, 4}, + {12, embf_line_78, 3}, + {12, embf_line_79, 8}, + {12, embf_line_80, 6}, + {12, embf_line_81, 9}, + {12, embf_line_82, 7}, + {12, embf_line_83, 11}, + {12, embf_line_84, 2}, + {12, embf_line_85, 5}, + {12, embf_line_86, 2}, + {12, embf_line_87, 6}, + {12, embf_line_88, 2}, + {12, embf_line_89, 3}, + {12, embf_line_90, 3}, + {12, embf_line_91, 3}, + {12, embf_line_92, 1}, + {12, embf_line_93, 3}, + {12, embf_line_94, 2}, + {12, embf_line_95, 1}, + {0, NULL, 0}, + {12, embf_line_97, 9}, + {12, embf_line_98, 8}, + {12, embf_line_99, 5}, + {12, embf_line_100, 8}, + {12, embf_line_101, 8}, + {10, embf_line_102, 4}, + {12, embf_line_103, 11}, + {12, embf_line_104, 5}, + {10, embf_line_105, 2}, + {10, embf_line_106, 3}, + {12, embf_line_107, 3}, + {10, embf_line_108, 2}, + {12, embf_line_109, 10}, + {12, embf_line_110, 6}, + {12, embf_line_111, 8}, + {12, embf_line_112, 9}, + {12, embf_line_113, 8}, + {12, embf_line_114, 4}, + {12, embf_line_115, 9}, + {10, embf_line_116, 3}, + {12, embf_line_117, 5}, + {12, embf_line_118, 2}, + {12, embf_line_119, 9}, + {12, embf_line_120, 2}, + {12, embf_line_121, 8}, + {12, embf_line_122, 3}, + {12, embf_line_123, 6}, + {12, embf_line_124, 1}, + {12, embf_line_125, 6}, + {12, embf_line_126, 5}, + {0, NULL, 0} +}; Index: tags/1.0.5/src/sch-rnd/font_rnd.c =================================================================== --- tags/1.0.5/src/sch-rnd/font_rnd.c (nonexistent) +++ tags/1.0.5/src/sch-rnd/font_rnd.c (revision 10414) @@ -0,0 +1,573 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - sch-rnd (executable) + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/* Font engine: librnd font */ + +#include +#include +#include +#include +#include +#include +#include + +#define FONTMAP_MAX_DEPTH 128 + +static htsp_t rf_map; +static rnd_font_t *embf; +static rnd_font_t loadme; /* special value: font is not yet loaded */ +static int embf_parsed; + +#include "font_internal.c" + +static int iolht_error(lht_node_t *nd, char *fmt, ...) +{ + gds_t str; + va_list ap; + + gds_init(&str); + gds_append_str(&str, "font lihata parse error"); + if (nd != NULL) + rnd_append_printf(&str, " at %s:%d.%d: ", nd->file_name, nd->line, nd->col); + else + gds_append_str(&str, ": "); + + va_start(ap, fmt); + rnd_safe_append_vprintf(&str, 0, fmt, ap); + va_end(ap); + + rnd_message(RND_MSG_ERROR, "%s", str.array); + + gds_uninit(&str); + return -1; +} + +/* Load the rnd_coord_t value of a text node into res. Return 0 on success */ +static int parse_coord(rnd_coord_t *res, lht_node_t *nd) +{ + double tmp; + rnd_bool success; + + if (nd == NULL) return iolht_error(nd, "Missing coord value\n"); + if (nd->type != LHT_TEXT) return iolht_error(nd, "Invalid coord type: '%d'\n", nd->type); + + tmp = rnd_get_value_ex(nd->data.text.value, NULL, NULL, NULL, NULL, &success); + if (!success) return iolht_error(nd, "Invalid coord value: '%s'\n", nd->data.text.value); + + *res = tmp; + return 0; +} + +/* Load the duble value of a text node into res. Return 0 on success */ +static int parse_double(double *res, lht_node_t *nd) +{ + double tmp; + char *end; + + if (nd == NULL) return iolht_error(nd, "Missing floating point number\n"); + if (nd->type != LHT_TEXT) return iolht_error(nd, "Invalid floating point number type: '%d'\n", nd->type); + + tmp = strtod(nd->data.text.value, &end); + + if (*end != '\0') return iolht_error(nd, "Invalid floating point value: '%s'\n", nd->data.text.value); + + *res = tmp; + return 0; +} + +static lht_node_t *hash_get(lht_node_t *hash, const char *name) +{ + lht_node_t *nd = lht_dom_hash_get(hash, name); + if (nd != NULL) return nd; + iolht_error(hash, "Missing hash field: '%s'\n", name); + return NULL; +} + +#define PARSE_COORD(dst, src) parse_coord(dst, src) +#define PARSE_DOUBLE(dst, src) parse_double(dst, src) +#define HASH_GET(hash, name) hash_get(hash, name) +#define RND_LHT_ERROR iolht_error + +#include + + +/* text object fields: + - crd_sx, crd_sy: unrotated text's bbox size (framing spaces included) + - net_sx: unrotated text's net width, <= crd_sx +*/ + +static rnd_font_t *rf_font_lookup_(rnd_design_t *hidlib, const char *name, const char *style) +{ + long best_score; + htsp_entry_t *e, *best; + re_sei_t *rxname, *rxstyle; + int namelen, stylelen, fnlen; + + if ((name == NULL) || (*name == '\0')) + name = "."; + if ((style == NULL) || (*style == '\0')) + style = "regular"; + + if (sch_rnd_font_score_debug) + fprintf(stderr, " --- font lookup: '%s' '%s'\n", name, style); + + rxname = re_sei_comp(name); + rxstyle = re_sei_comp(style); + + namelen = strlen(name); + stylelen = strlen(style); + + retry:; + + if (sch_rnd_font_score_debug) + fprintf(stderr, " try\n"); + + best_score = -1000000l; + best = NULL; + for(e = htsp_first(&rf_map); e != NULL; e = htsp_next(&rf_map, e)) { + const char *s, *name = e->key; + long score = 0; + + for(s = name; *s != '\0'; s++) { + if ((*s == '/') || (*s == '\\')) + name = s+1; + } + + fnlen = strlen(name); + + if (rxname != NULL) + score += re_sei_exec(rxname, name); + if (rxstyle != NULL) + score += re_sei_exec(rxstyle, name); + + score -= (fnlen - namelen - stylelen)*32; + + if (sch_rnd_font_score_debug) + fprintf(stderr, " %ld FONT: '%s'\n", score, name); + if (score > best_score) { + best_score = score; + best = e; + } + } + + if ((best != NULL) && (best->value == &loadme)) { + rnd_font_t *f = calloc(sizeof(rnd_font_t), 1); + + if (sch_rnd_font_score_debug) + fprintf(stderr, " load: %s\n", best->key); + + if (rnd_font_load(hidlib, f, best->key, 0) != 0) { + /* failed to load the font, remove from hash, try another */ + free(f); + htsp_popentry(&rf_map, best->key); + if (sch_rnd_font_score_debug) + fprintf(stderr, " FAILED\n"); + goto retry; + } + rnd_font_fix_v1(f); + best->value = f; + } + + if (sch_rnd_font_score_debug && (best != NULL) && (best->value != &loadme)) + fprintf(stderr, " use: %s\n", best->key); + + if (rxname != NULL) + re_sei_free(rxname); + if (rxstyle != NULL) + re_sei_free(rxstyle); + + if (sch_rnd_font_score_debug) + fprintf(stderr, "\n"); + + return best == NULL ? NULL : best->value; +} + +static rnd_font_t *rf_font_lookup(rnd_design_t *hidlib, const char *name, const char *style) +{ + rnd_font_t *res = rf_font_lookup_(hidlib, name, style); + + if (res == NULL) /* fall back to configured default */ + res = rf_font_lookup_(hidlib, conf_core.editor.default_font.family, conf_core.editor.default_font.style); + + if (res == NULL) { /* fall back to embedded */ + if (!embf_parsed) { + embf = malloc(sizeof(rnd_font_t)); + rnd_font_load_internal(embf, embf_font, sizeof(embf_font) / sizeof(embf_font[0]), embf_minx, embf_miny, embf_maxx, embf_maxy); + embf_parsed = 1; + htsp_set(&rf_map, "__embedded/internal__", embf); + } + res = embf; + } + return res; +} + +static rnd_font_t *rf_resolve_pen(rnd_design_t *hidlib, csch_cpen_t *pen) +{ + static int epic_fail = 0; + rnd_font_t *f; + htsp_entry_t *e; + const char *family, *style; + + if (epic_fail) + return NULL; + + if (pen->font_handle_valid) + return pen->font_handle; + + retry:; + f = NULL; + + /* get pen's preferred font */ + if ((pen->font_family != NULL) || (pen->font_style != NULL)) { + f = rf_font_lookup(hidlib, pen->font_family, pen->font_style); + if (f != NULL) { + family = pen->font_family; + style = pen->font_style; + } + } + + /* fall back to configured default */ + if (f == NULL) { + family = conf_core.editor.default_font.family; + style = conf_core.editor.default_font.style; + if ((family != NULL) || (style != NULL)) + f = rf_font_lookup(hidlib, family, style); + if (f == NULL) + family = style = NULL; + } + + /* final fallback: any font we know of */ + if (f == NULL) { + printf("FONT: final fallback"); + e = htsp_first(&rf_map); + if (e != NULL) + f = e->value; + family = ""; + style = ""; + } + + if (f == NULL) { + static int warned = 0; + if (!warned) { + rnd_message(RND_MSG_ERROR, "Failed to find absolutely _any_ font; text rendering is impossible.\nPlease revise rc/font_dirs in your conf!\n"); + epic_fail = 1; + } + return NULL; + } + + if (f == &loadme) { + if (e != NULL) + htsp_popentry(&rf_map, e->key); /* don't try this again */ + goto retry; + } + + pen->font_handle = f; + pen->font_handle_valid = 1; + return f; +} + +RND_INLINE int count_spaces(const unsigned char *str, int *nospc) +{ + int cnt, ns; + for(cnt = ns = 0; *str != '\0'; str++) + if (isspace(*str)) + cnt++; + else + ns++; + + *nospc = ns; + return cnt; +} + +RND_INLINE csch_coord_t rf_text_halign(const unsigned char *str, csch_halign_t halign, csch_coord_t avail, csch_coord_t used, double scale, csch_coord_t *extra_glyph, csch_coord_t *extra_spc, csch_coord_t *net_sx) +{ + int spaces, nospc; + double left; + + switch(halign) { + case CSCH_HALIGN_invalid: + case CSCH_HALIGN_START: *net_sx = used; return 0; + case CSCH_HALIGN_CENTER: center:; *net_sx = used; return rnd_round((double)(avail - used) / 2.0); + case CSCH_HALIGN_END: *net_sx = used; return avail - used; + case CSCH_HALIGN_WORD_JUST: + spaces = count_spaces(str, &nospc); + if (spaces == 0) + goto center; + *net_sx = avail; + *extra_spc = floor((double)(avail - used) / (double)spaces / scale); + /* rnd_trace("space = %ld %ld - %ld spaces=%d extra_spc=%ld\n", avail - used, avail, used, spaces, *extra_spc); */ + return 0; + case CSCH_HALIGN_JUST: + spaces = count_spaces(str, &nospc); + left = (double)(avail - used); + if (spaces > 0) { + *extra_spc = floor((left / 2.0) / (double)spaces / scale); + left = left / 2.0; + } + *extra_glyph = floor(left / (double)nospc / scale); + *net_sx = avail; + return 0; + } + return 0; +} + +static void rf_text_update(csch_sheet_t *sheet, csch_text_t *t, csch_cpen_t *pen) +{ + rnd_font_t *f; + double w, h; + const unsigned char *text_str; + rnd_coord_t cx[4], cy[4]; + int save; + + if (t->scale != 0) + return; /* already calculated */ + + f = rf_resolve_pen(&sheet->hidlib, pen); + if (f == NULL) + return; + + text_str = (const unsigned char *)csch_text_get_rtext(t); + + t->extra_glyph = t->extra_spc = 0; + + /* get initial size */ + rnd_font_string_bbox(cx, cy, f, text_str, 0, 0, 1, 1, 0, 0, 0, 0); + cx[0] = 0; /* undo the effect of left side whitespace: we started to render from 0;0 */ + w = P2C(cx[1] - cx[0]); + h = P2C(f->height); + + /* figure which kind of text fitting to use */ + if (t->has_bbox) { /* fit in bbox */ + double scx, scy; + + t->crd_sx = t->spec2.x - t->spec1.x; + t->crd_sy = t->spec2.y - t->spec1.y; + scx = (double)t->crd_sx / (double)w; + scy = (double)t->crd_sy / (double)h; + + if (scx < scy) { + t->scale = scx; + t->off_x = -P2C(cx[0])*t->scale;; + t->off_y = (t->crd_sy - h * scx) / 2; + } + else { + t->scale = scy; + t->off_x = rf_text_halign(text_str, t->halign, t->crd_sx, w * scy, t->scale, &t->extra_glyph, &t->extra_spc, &t->net_sx); + if (t->off_x < 0) t->off_x = 0; + t->off_x -= P2C(cx[0])*t->scale; + t->off_y = 0; + } + } + else { /* fixed height */ + t->scale = (double)pen->font_height / (double)P2C(f->height); + t->net_sx = t->crd_sx = w * t->scale; + t->crd_sy = pen->font_height; + t->off_x = -P2C(cx[0])*t->scale; + t->off_y = 0; + + t->spec2.x = t->spec1.x + t->crd_sx; + t->spec2.y = t->spec1.y + t->crd_sy; + } + + /* recalculate bbox */ + save = t->bbox_calcing; + t->bbox_calcing = 1; + csch_text_update(sheet, t, 1); + t->bbox_calcing = save; +} + +typedef struct { +/* csch_sheet_t *sheet;*/ + rnd_hid_gc_t gc; +/* csch_text_t *t; + csch_cpen_t *pen;*/ +} rf_draw_t; + +static void rf_draw_atom_cb(void *cb_ctx, const rnd_glyph_atom_t *a) +{ + rf_draw_t *ctx = cb_ctx; + long h; + + switch(a->type) { + case RND_GLYPH_LINE: + rnd_hid_set_line_width(ctx->gc, a->line.thickness); + rnd_render->draw_line(ctx->gc, a->line.x1, a->line.y1, a->line.x2, a->line.y2); + break; + case RND_GLYPH_ARC: + rnd_hid_set_line_width(ctx->gc, a->arc.thickness); + rnd_render->draw_arc(ctx->gc, a->arc.cx, a->arc.cy, a->arc.r, a->arc.r, a->arc.start, a->arc.delta); + break; + case RND_GLYPH_POLY: + h = a->poly.pts.used / 2; + rnd_render->fill_polygon(ctx->gc, h, &a->poly.pts.array[0], &a->poly.pts.array[h]); + break; + } +} + +void sch_rnd_render_text_string(rnd_hid_gc_t gc, void *font, rnd_coord_t x, rnd_coord_t y, rnd_coord_t size, const unsigned char *text_str) +{ + rf_draw_t ctx; + + ctx.gc = gc; + + rnd_font_draw_string_justify(font, text_str, x, y, size, size, 0, + RND_FONT_MIRROR_Y, -3, 0, RND_FONT_TINY_CHEAP, + 0, 0, rf_draw_atom_cb, &ctx); +} + +void sch_rnd_render_text_string_scrotmir(rnd_hid_gc_t gc, void *font, rnd_coord_t x, rnd_coord_t y, double size, double rot, int mirrory, const unsigned char *text_str) +{ + rf_draw_t ctx; + + ctx.gc = gc; + + rnd_font_draw_string_justify(font, text_str, x, y, size, size, rot, + mirrory ? RND_FONT_MIRROR_Y : 0, -3, 0, RND_FONT_TINY_CHEAP, + 0, 0, rf_draw_atom_cb, &ctx); +} + +static void rf_text_render(csch_sheet_t *sheet, rnd_hid_gc_t gc, csch_text_t *t, csch_cpen_t *pen) +{ + const unsigned char *text_str; + rf_draw_t ctx; + rnd_font_t *font; + rnd_coord_t x, y, xo, yo; + double rad, deg; + int mirx, miry; + + if (t->scale == 0) + rf_text_update(sheet, t, pen); + + if (t->scale == 0) + return; + +/* ctx.sheet = sheet;*/ + ctx.gc = gc; +/* ctx.t = t; + ctx.pen = pen;*/ + + + rnd_hid_set_line_cap(gc, rnd_cap_round); + + text_str = (const unsigned char *)csch_text_get_rtext(t); + + font = pen->font_handle; + mirx = t->inst_mirx; + miry = t->inst_miry; + + xo = C2P(t->inst1.x); + yo = C2P(t->inst1.y); + + deg = t->inst_raw_rot; + + if ((deg > 360.0) || (deg < -360.0)) + deg = fmod(deg, 360.0); + + /* rnd_trace("deg=%f %d %d '%s' \n", deg, mirx, miry, text_str); */ + + x = xo + C2P(mirx ? -t->off_x : +t->off_x) - (mirx ? C2P(t->net_sx) : 0); + y = yo + C2P(miry ? -t->off_y : +t->off_y) + (!miry ? font->height * t->scale : 0); + + rad = -deg / RND_RAD_TO_DEG; + rnd_rotate(&x, &y, xo, yo, cos(rad), sin(rad)); + + rnd_font_draw_string_justify(font, text_str, x, y, t->scale, t->scale, deg, + RND_FONT_MIRROR_Y | RND_FONT_HTAB | RND_FONT_INVIS_TAB, + 0, 0, RND_FONT_TINY_CHEAP, + C2P(t->extra_glyph), C2P(t->extra_spc), rf_draw_atom_cb, &ctx); +} + +static void rf_inval_font(csch_sheet_t *sheet, csch_text_t *text) +{ + text->scale = 0; +} + +static void map_fontdir(rnd_design_t *hidlib, const char *dr, int depth) +{ + DIR *dir; + struct dirent *de; + + if (depth > FONTMAP_MAX_DEPTH) { + rnd_message(RND_MSG_ERROR, "map_fontdor(): went too deep at %s\n", dr); + return; + } + + dir = rnd_opendir(hidlib, dr); + if (dir == NULL) + return; + + while((de = rnd_readdir(dir)) != NULL) { + char *fp; + + if (de->d_name[0] == '.') + continue; + + fp = rnd_concat(dr, "/", de->d_name, NULL); + if (rnd_is_dir(hidlib, fp)) { + map_fontdir(hidlib, fp, depth+1); + free(fp); + } + else + htsp_set(&rf_map, fp, &loadme); + } + rnd_closedir(dir); +} + +static void sch_rnd_font_rnd_init2(void) +{ + rnd_conf_listitem_t *ci; + + htsp_init(&rf_map, strhash, strkeyeq); + + for(ci = rnd_conflist_first((rnd_conflist_t *)&conf_core.rc.font_dirs); ci != NULL; ci = rnd_conflist_next(ci)) { + char *dr = rnd_build_fn(NULL, ci->val.string[0]); + map_fontdir(NULL, dr, 0); + free(dr); + } +} + +static void sch_rnd_font_rnd_uninit(void) +{ + htsp_entry_t *e; + for(e = htsp_first(&rf_map); e != NULL; e = htsp_next(&rf_map, e)) { + rnd_font_t *f = e->value; + if (f != &loadme) { + rnd_font_free(f); + free(f); + } + free(e->key); + } + htsp_uninit(&rf_map); + free(embf); + embf = NULL; + embf_parsed = 0; +} + + + + Index: tags/1.0.5/src/sch-rnd/funchash_core.h =================================================================== --- tags/1.0.5/src/sch-rnd/funchash_core.h (nonexistent) +++ tags/1.0.5/src/sch-rnd/funchash_core.h (revision 10414) @@ -0,0 +1,16 @@ +/* central, auto-generated enum of core function IDs */ + + +#ifndef SCH_RND_FUNCHASH_H +#define SCH_RND_FUNCHASH_H + +#include + +#define action_entry(x) F_ ## x, +typedef enum { +#include "funchash_core_list.h" +F_END +} pcb_function_id_t; +#undef action_entry + +#endif Index: tags/1.0.5/src/sch-rnd/funchash_core_list.h =================================================================== --- tags/1.0.5/src/sch-rnd/funchash_core_list.h (nonexistent) +++ tags/1.0.5/src/sch-rnd/funchash_core_list.h (revision 10414) @@ -0,0 +1,34 @@ +/* + Central list of function IDs + The core and core plugins use these from a single, central hash + This list is used to cpp-generate the F_* constants in enum pcb_function_id_t +*/ + +action_entry(All) +action_entry(AllProject) +action_entry(Any) +action_entry(Auto) +action_entry(Buffer) +action_entry(Global) +action_entry(Group) +action_entry(Horizontal) +action_entry(Invert) +action_entry(Idpath) +action_entry(List) +action_entry(Lock) +action_entry(Object) +action_entry(Objarr) +action_entry(Only) +action_entry(Poly) +action_entry(Polygon) +action_entry(Project) +action_entry(Selected) +action_entry(SelectedProject) +action_entry(Sheet) +action_entry(Sym) +action_entry(Symbol) +action_entry(Term) +action_entry(Terminal) +action_entry(TextHeight) +action_entry(TextWidth) +action_entry(Vertical) Index: tags/1.0.5/src/sch-rnd/main_act.c =================================================================== --- tags/1.0.5/src/sch-rnd/main_act.c (nonexistent) +++ tags/1.0.5/src/sch-rnd/main_act.c (revision 10414) @@ -0,0 +1,306 @@ +/* + * COPYRIGHT + * + * sch-rnd, interactive printed circuit board design + * (this file is copied from pcb-rnd, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 Thomas Nau + * Copyright (C) 1997, 1998, 1999, 2000, 2001 Harry Eaton + * Copyright (C) 2020,2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + * + * Old contact info: + * Harry Eaton, 6697 Buttonhole Ct, Columbia, MD 21044, USA + * haceaton@aplcomm.jhuapl.edu + * + */ + +#define Progname "sch-rnd" + +#include + +#include + +#include "crosshair.h" +#include +#include +#include "conf_core.h" +#include "build_run.h" +#include +#include +#include + +/* print usage lines */ +RND_INLINE void u(const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + fputc('\n', stderr); + va_end(ap); +} + +static const char csch_acts_PrintUsage[] = + "PrintUsage()\n" + "PrintUsage(plugin)"; + +static const char csch_acth_PrintUsage[] = "Print command line arguments of sch-rnd or a plugin loaded."; + +static int help0(void) +{ + rnd_hid_t **hl = rnd_hid_enumerate(); + int i; + + u("sch-rnd - Ringdove schematics program, http://repo.hu/projects/sch-rnd"); + u("For more information, please read the topic help pages:"); + u(" %s --help topic", Progname); + u("Topics are:"); + u(" invocation how to run sch-rnd"); + u(" main main/misc flags (affecting none or all plugins)"); + for (i = 0; hl[i]; i++) + if (hl[i]->usage != NULL) + u(" %-20s %s", hl[i]->name, hl[i]->description); + return 0; +} + +extern const char *sch_rnd_action_args[]; +extern const int PCB_ACTION_ARGS_WIDTH; +static int help_main(void) { + const char **cs; + for(cs = sch_rnd_action_args; cs[2] != NULL; cs += RND_ACTION_ARGS_WIDTH) { + fprintf(stderr, "%s [", Progname); + if (cs[0] != NULL) + fprintf(stderr, "-%s", cs[0]); + if ((cs[0] != NULL) && (cs[1] != NULL)) + fprintf(stderr, "|"); + if (cs[1] != NULL) + fprintf(stderr, "-%s", cs[1]); + fprintf(stderr, "] %s\n", cs[3]); + } + return 0; +} + +static int help_invoc(void) +{ + rnd_hid_t **hl = rnd_hid_enumerate(); + int i; + int n_printer = 0, n_gui = 0, n_exporter = 0; + + u("sch-rnd invocation:"); + u(""); + u("%s [main options] See --help main", Progname); + u(""); + u("%s [generics] [--gui GUI] [gui options] interactive GUI", Progname); + + u("Available GUI hid%s:", n_gui == 1 ? "" : "s"); + rnd_hid_print_all_gui_plugins(); + + u("\n%s [generics] -p [printing options] \tto print", Progname); + u("Available printing hid%s:", n_printer == 1 ? "" : "s"); + for (i = 0; hl[i]; i++) + if (hl[i]->printer) + fprintf(stderr, "\t%-8s %s\n", hl[i]->name, hl[i]->description); + + u("\n%s [generics] -x hid [export options] \tto export a single sheet", Progname); + u("%s [generics] -x hid [export options] ...\tto export a multi-sheet as project", Progname); + u("%s [generics] -x hid [export options] project.lht\tto export a whole project (multi-sheet)", Progname); + u("Available export hid%s:", n_exporter == 1 ? "" : "s"); + for (i = 0; hl[i]; i++) + if (hl[i]->exporter) + fprintf(stderr, "\t%-8s %s\n", hl[i]->name, hl[i]->description); + + + u("\nGenerics:"); + u("-c conf/path=value set the value of a configuration item (in RND_CFR_CLI)"); + u("-C conffile load config file (as RND_CFR_CLI; after all -c's)"); + + return 0; +} + +fgw_error_t csch_act_PrintUsage(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *topic = NULL, *subt = NULL; + RND_ACT_MAY_CONVARG(1, FGW_STR, PrintUsage, topic = argv[1].val.str); + RND_ACT_IRES(0); + + u(""); + if (topic != NULL) { + rnd_hid_t **hl = rnd_hid_enumerate(); + int i; + + if (strcmp(topic, "invocation") == 0) return help_invoc(); + if (strcmp(topic, "main") == 0) return help_main(); + + for (i = 0; hl[i]; i++) { + if ((hl[i]->usage != NULL) && (strcmp(topic, hl[i]->name) == 0)) { + RND_ACT_MAY_CONVARG(2, FGW_STR, PrintUsage, subt = argv[2].val.str); + RND_ACT_IRES(hl[i]->usage(hl[i], subt)); + return 0; + } + } + fprintf(stderr, "No help available for %s\n", topic); + RND_ACT_IRES(-1); + return 0; + } + else + help0(); + return 0; +} + + +static const char csch_acts_PrintVersion[] = "PrintVersion()"; +static const char csch_acth_PrintVersion[] = "Print version."; +fgw_error_t csch_act_PrintVersion(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + printf("%s\n", sch_rnd_get_info_program()); + RND_ACT_IRES(0); + return 0; +} + +static const char csch_acts_DumpVersion[] = "DumpVersion()"; +static const char csch_acth_DumpVersion[] = "Dump version in script readable format."; +fgw_error_t csch_act_DumpVersion(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + printf("%s\n", CSCH_VERSION); + printf("%s\n", CSCH_REVISION); + RND_ACT_IRES(0); + return 0; +} + +static const char csch_acts_PrintCopyright[] = "PrintCopyright()"; +static const char csch_acth_PrintCopyright[] = "Print copyright notice."; +fgw_error_t csch_act_PrintCopyright(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + printf("%s\n", sch_rnd_get_info_copyright()); + printf("%s\n", sch_rnd_get_info_license()); + + printf(" This program is free software; you can redistribute it and/or modify\n" + " it under the terms of the GNU General Public License as published by\n" + " the Free Software Foundation; either version 2 of the License, or\n" + " (at your option) any later version.\n\n"); + printf(" This program is distributed in the hope that it will be useful,\n" + " but WITHOUT ANY WARRANTY; without even the implied warranty of\n" + " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" + " GNU General Public License for more details.\n\n"); + printf(" You should have received a copy of the GNU General Public License\n" + " along with this program; if not, write to the Free Software\n" + " Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n\n"); + RND_ACT_IRES(0); + return 0; +} + +static const char csch_acts_PrintPaths[] = "PrintPaths()"; +static const char csch_acth_PrintPaths[] = "Print full paths and search paths."; +static void print_list(const rnd_conflist_t *cl) +{ + int n; + rnd_conf_listitem_t *ci; + const char *p; + + printf(" "); + rnd_conf_loop_list_str(cl, ci, p, n) { + printf("%c%s", (n == 0) ? '"' : ':', p); + } + printf("\"\n"); +} +fgw_error_t csch_act_PrintPaths(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + htsp_entry_t *e; + rnd_conf_fields_foreach(e) { + rnd_conf_native_t *n = e->value; + if ((strncmp(n->hash_path, "rc/path/", 8) == 0) && (n->type == RND_CFN_STRING) && (n->used == 1)) + printf("%-32s = %s\n", n->hash_path, n->val.string[0]); + } + printf("rc/font_dirs ="); print_list(&conf_core.rc.font_dirs); + printf("rc/library_search_paths ="); print_list(&conf_core.rc.library_search_paths); + printf("rc/hlibrary_search_paths ="); print_list(&conf_core.rc.hlibrary_search_paths); + + RND_ACT_IRES(0); + return 0; +} + +/* Note: this can not be in librnd because of the app-specific setenvs */ +static const char csch_acts_System[] = "System(shell_cmd)"; +static const char csch_acth_System[] = "Run shell command"; +fgw_error_t csch_act_System(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + char tmp[128]; + const char *cmd; + + RND_ACT_CONVARG(1, FGW_STR, System, cmd = argv[1].val.str); + RND_ACT_IRES(0); + + rnd_setenv("SCH_RND_SHEET_FILE_NAME", RND_ACT_DESIGN->fullpath == NULL ? "" : RND_ACT_DESIGN->fullpath, 1); + rnd_snprintf(tmp, sizeof(tmp), "%rr", sch_rnd_crosshair_x); + rnd_setenv("SCH_RND_CROSSHAIR_X", tmp, 1); + rnd_snprintf(tmp, sizeof(tmp), "%rr", sch_rnd_crosshair_y); + rnd_setenv("SCH_RND_CROSSHAIR_Y", tmp, 1); + + /* for compatibility with old sch-rnd versions */ + rnd_setenv("PCB_RND_SHEET_FILE_NAME", RND_ACT_DESIGN->fullpath == NULL ? "" : RND_ACT_DESIGN->fullpath, 1); + rnd_snprintf(tmp, sizeof(tmp), "%mm", sch_rnd_crosshair_x); + rnd_setenv("PCB_RND_CROSSHAIR_X_MM", tmp, 1); + rnd_snprintf(tmp, sizeof(tmp), "%mm", sch_rnd_crosshair_y); + rnd_setenv("PCB_RND_CROSSHAIR_Y_MM", tmp, 1); + RND_ACT_IRES(rnd_system(RND_ACT_DESIGN, cmd)); + return 0; +} + +static int csch_act_execute_file(rnd_design_t *hidlib, const char *fn) +{ + int res; + + res = rnd_act_execute_file(hidlib, fn); + + csch_undo_inc_serial((csch_sheet_t *)hidlib); + rnd_gui->invalidate_all(rnd_gui); + + return res; +} + +static const char csch_acts_ExecActionFile[] = "ExecActionFile(filename)"; +static const char csch_acth_ExecActionFile[] = "Run actions from the given file."; +fgw_error_t csch_act_ExecActionFile(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *fname; + + RND_ACT_CONVARG(1, FGW_STR, ExecActionFile, fname = argv[1].val.str); + RND_ACT_IRES(csch_act_execute_file(RND_ACT_DESIGN, fname)); + return 0; +} + +static rnd_action_t main_action_list[] = { + {"PrintUsage", csch_act_PrintUsage, csch_acth_PrintUsage, csch_acts_PrintUsage}, + {"PrintVersion", csch_act_PrintVersion, csch_acth_PrintVersion, csch_acts_PrintVersion}, + {"DumpVersion", csch_act_DumpVersion, csch_acth_DumpVersion, csch_acts_DumpVersion}, + {"PrintCopyright", csch_act_PrintCopyright, csch_acth_PrintCopyright, csch_acts_PrintCopyright}, + {"PrintPaths", csch_act_PrintPaths, csch_acth_PrintPaths, csch_acts_PrintPaths}, + {"System", csch_act_System, csch_acth_System, csch_acts_System}, + {"ExecCommand", csch_act_System, csch_acth_System, csch_acts_System}, + {"ExecActionFile", csch_act_ExecActionFile, csch_acth_ExecActionFile, csch_acts_ExecActionFile} +}; + +void sch_rnd_main_act_init2(void) +{ + RND_REGISTER_ACTIONS(main_action_list, NULL); +} Index: tags/1.0.5/src/sch-rnd/menu-default.lht =================================================================== --- tags/1.0.5/src/sch-rnd/menu-default.lht (nonexistent) +++ tags/1.0.5/src/sch-rnd/menu-default.lht (revision 10414) @@ -0,0 +1,645 @@ +ha:rnd-menu-v1 { + li:mouse { + li:left { + li:press = { Tool(Press) } + li:press-shift = { Tool(Press) } + li:press-ctrl = { Tool(Press) } + li:release = { Tool(Release) } + li:release-shift = { Tool(Release) } + li:release-ctrl = { Tool(Release) } + } + li:middle { + li:press = { Pan(1) } + li:release = { Pan(0) } + } + li:right { + li:press = { } + li:release = { Tool(Escape); Popup(popup-obj, obj-type) } + li:shift-release = { Popup(popup-obj-misc) } + li:press-ctrl = { Display(CycleCrosshair) } + } + li:scroll-up { + li:press = { Zoom(0.8) } + li:press-shift = { Scroll(up) } + li:press-ctrl = { Scroll(left) } + } + li:scroll-down { + li:press = { Zoom(1.25) } + li:press-shift = { Scroll(down) } + li:press-ctrl = { Scroll(right) } + } + } + + # List of tool names for the toolbar. + # Do not specify keys here, they are specified in the menu; the GUI will + # not pick up keys from this subtree. There's also no action here: the + # plugin handling this subtree will always pick the tool. + li:toolbar_static { + ha:circle {tip={draw a circle (atomic, drawing primitive)}} + ha:wirenet {tip={draw a line segment for a network (wire-net)}} + ha:line {tip={draw a line (atomic, drawing primitive)}} + ha:text {tip={draw text on the sheet}} + ha:rect {tip={draw a rectangle (4 lines)}} + ha:buffer {tip={paste the current buffer on the board}} + ha:remove {tip={remove object at location clicked}} + ha:rotate {tip={rotate object by 90 degree at location clicked}} + ha:xmirror {tip={horizontal mirror (changes x coords)}} + ha:ymirror {tip={vertical mirror (changes y coords)}} + ha:arrow {tip={switch to arrow mode}} + ha:lock {tip={lock or unlock object clicked}} + + ha:move {tip={drag&drop move objects}} + ha:copy {tip={drag&drop copy objects}} + ha:polyedit {tip={edit polygon (move corner)}} + } + + li:main_menu { + ### File Menu + ha:File { + li:submenu { + ha:Project... { + li:submenu { + ha:New root sheet = { li:a={{f;n}; {Ctrln};}; action=New(@, root); tip=Creates new root sheet in current project (adding it to the project file)} + ha:New aux sheet = { a={f;Shiftn}; action=New(@, aux); tip=Creates new auxiliary sheet in current project (adding it to the project file)} + ha:New unlisted sheet = { action=New(@, unlisted); tip=Creates new unlisted sheet in current project's directory (not adding it to the project file)} + - + ha:Load missing sheets = { action=ProjectLoadPartial(@); tip=Loads missing sheets in a partially loaded project } + - + ha:New project = { action=ProjectNew(); tip=Creates a new project } + ha:Project properties = { action=ProjectDialog(@); tip=Edit properties of current project } + ha:Project stances = { action=StanceDialog(); tip=Edit stances (build options) of current project } + - + ha:Circuit simulation = { action=SimDialog(); tip=Edit simulation setups and run simulations } + } + } + ha:Revert sheet = { a={f;r}; action=Revert(sheet); tip=Revert to the sheet stored on disk } + ha:Unload sheet = { a={f;u}; action=Unload(sheet) } + - + ha:Load... = { a={f;o}; action=Load() } + - + ha:Save sheet... = { li:a={{f;s}; {Ctrls};}; action=Save() } + ha:Save sheet as... = { a={f;a}; action=SaveAs() } + ha:Save all in prj... = { action=SaveAll(currprj) } + - + ha:Import { + li:submenu { + ha:Load symbol/group to paste-buffer = { li:action={BufferClear(); BufferLoad(Symbol); Tool(buffer); } } + ha:Load back annotation file = { li:action={Backann();} } + } + } + - + ha:Print sheet... = { a={f;p}; action=Print()} + ha:Export Sheet... = { a={f;e}; action=ExportDialog()} + ha:Export Project... = { a={f;j}; action=ExportProjectDialog()} + - + ha:Preferences... = { a={i;c;p}; action=preferences} + ha:Maintenance { + li:submenu { + ha:Re-scan the symbol library = { a={i;c;r}; action=SymlibRehash(); tip={Re-read all configured symbol library directories, mapping all available symbols again. Run this after changing symbol library paths or creating a new root symbol dir.} } + ha:Re-scan the devmap library = { a={i;c;d}; action=devmaplibRehash(); tip={Re-read all configured device map library directories, mapping all available devmaps again. Run this after changing devmap library paths or creating a new root devmap dir.} } + ha:Re-scan the funcmap library = { a={i;c;u}; action=funcmaplibRehash(); tip={Re-read all configured funcmap library directories, mapping all available funcmaps again. Run this after changing funcmap library paths or creating a new root funcmap dir.} } + ha:Data integrity check = { a={i;c;i}; action=Integrity() } + - + ha:Reload symbols in local lib = { action=SymlibReloadAllLocal(); tip={Reload all symbols in the sheet local symbol lib from from external libraries. (Not undoable) } } + ha:Clean devmap sheet local lib = { action=DevmaplibCleanLocal(); tip={Remove all devmaps from the current sheet's local library; devmap files will be reloaded and reinserted in the local library upon the next compilation. } } + ha:Clean funcmap sheet local lib = { action=FuncmaplibCleanLocal(); tip={Remove all funcmaps from the current sheet's local library; funcmap files will be reloaded and reinserted in the local library upon the next compilation. } } + - + ha:Undo dialog (for debugging) = { a={u;d;}; action=UndoDialog() } + } + } + - + ha:Quit = { a={f;q}; action=Quit() } + } + } + + ha:Edit { + li:submenu { + ha:Undo last operation = { li:a={{u; u}; {Ctrlz};}; action=Undo() } + ha:Redo last undone operation = { li:a={{u; r}; {Ctrly};}; action=Redo() } + ha:Clear undo-buffer = { a={u; c}; action=Undo(ClearList) } + - + ha:Cut selection to buffer = { li:a={{e; x}; a=Ctrlx;}; li:action={ GetXY(Click to set the snap point for this buffer); BufferClear(Clear); BufferCut(MoveSelected); Tool(buffer) } } + ha:Copy selection to buffer = { li:a={{e; c}; {Ctrlc;};}; li:action={ GetXY(Click to set the snap point for this buffer); BufferClear(Clear); BufferCopy(); Unselect(All); Tool(buffer) } } + ha:Paste buffer to layout = { a={Ctrlv;}; action=Tool(buffer) } + - + ha:Remove object = { li:a={{e;d};{Delete};}; li:action={Tool(Save); Tool(remove); GetXY(Click on object to remove); Tool(Press); Tool(Restore)} } + ha:Whirl object (rotate 90 deg) = { li:a={{e;w};}; action=Rotate90(auto); } + ha:Mirror object horizontally = { li:a={{e;h};}; action=Mirror(auto, horizontal); } + ha:Mirror object vertically = { li:a={{e;v};}; action=Mirror(auto, vertical); } + ha:Place template { + li:submenu { + ha:place terminal = { a={p;t}; li:action={GetXy(Click where the new terminal should be placed); PlaceTerminal()}; } + ha:place attribute text = { a={p;a}; li:action={GetXy(Click where the new attribute should be placed); PlaceAttrib()}; } + } + } + - + ha:Change object { + li:submenu { + ha:Text string = { li:a={{e;t};}; action=EditText(Object) } + ha:Stroke = { li:a={{e;s};}; action={pendialog(object)} } + } + } + ha:Change multiple objects { + li:submenu { + ha:Renumber symbols = { li:a={{e;m;r};}; action=RenumberDialog } + } + } + ha:Object Properties... = { a={e; p}; action=PropEdit(selection) } + } + } + + ha:View { + li:submenu { + ha:Grid { + li:submenu { + ha:Enable visible grid = { a={g; v}; checked=editor/draw_grid; action=conf(toggle, editor/draw_grid, design) } + ha:Enable local grid = { a={g; l}; checked=editor/local_grid/enable; action=conf(toggle, editor/local_grid/enable, design) } + ha:Grid size = { + li:submenu { + ha:No Grid = { checked=ChkGridSize(none); action=SetGrid(1); update_on={editor/grid} } + - + @grid + - + ha:Previous grid = { li:a={{g; b};{[};}; action=Grid(down) } + ha:Next grid = { li:a={{g; f};{]};}; action=Grid(up) } + ha:Custom grid = { li:a={{g; c};}; action=Grid(ask) } + - + ha:Grid *2 = { a={g; d}; action=SetGrid(*2) } + ha:Grid /2 = { a={g; h}; action=SetGrid(/2) } + } + } + ha:Grid properties = { + li:submenu { + ha:Enable local grid = { checked=editor/local_grid/enable; action=conf(toggle, editor/local_grid/enable, design) } + - + ha:local grid radius 4 = { checked={conf(iseq, editor/local_grid/radius, 4)}; li:action={conf(set, editor/local_grid/radius, 4, design); conf(set, editor/local_grid/enable, 1, design) } update_on={} } + ha:local grid radius 8 = { checked={conf(iseq, editor/local_grid/radius, 8)}; li:action={conf(set, editor/local_grid/radius, 8, design); conf(set, editor/local_grid/enable, 1, design) } update_on={} } + ha:local grid radius 16 = { checked={conf(iseq, editor/local_grid/radius, 16)}; li:action={conf(set, editor/local_grid/radius, 16, design); conf(set, editor/local_grid/enable, 1, design) } update_on={} } + ha:local grid radius 32 = { checked={conf(iseq, editor/local_grid/radius, 32)}; li:action={conf(set, editor/local_grid/radius, 32, design); conf(set, editor/local_grid/enable, 1, design) } update_on={} } + - + ha:sparse global grid = { checked=editor/global_grid/sparse; action=conf(toggle, editor/global_grid/sparse, design) } + ha:global grid density 4 = { checked={conf(iseq, editor/global_grid/min_dist_px, 4)}; li:action={conf(set, editor/global_grid/min_dist_px, 4, design); conf(set, editor/local_grid/enable, 0, design) } update_on={} } + ha:global grid density 8 = { checked={conf(iseq, editor/global_grid/min_dist_px, 8)}; li:action={conf(set, editor/global_grid/min_dist_px, 8, design); conf(set, editor/local_grid/enable, 0, design) } update_on={} } + ha:global grid density 16 = { checked={conf(iseq, editor/global_grid/min_dist_px, 16)}; li:action={conf(set, editor/global_grid/min_dist_px, 16, design); conf(set, editor/local_grid/enable, 0, design) } update_on={} } + } + } +# ha:Realign grid = { a={g; r}; action={ Display(RealignGrid) } } + } + } + + ha:Zoom { + li:submenu { + ha:Zoom In 20% = { li:a={{z;z;}; {+};} action=Zoom(-1.2) } + ha:Zoom Out 20% = { li:a={{z;x;}; {-};} action=Zoom(+1.2) } + ha:Zoom In 2X = { action=Zoom(-2) } + ha:Zoom Out 2X = { action=Zoom(+2) } + ha:Zoom to 0.025k/px = { action={Zoom(=25)} } + ha:Zoom to 0.05k/px = { action={Zoom(=50)} } + ha:Zoom to 0.10k/px = { a={z;1;}; action={Zoom(=100)} } + ha:Zoom to 0.25k/px = { a={z;2;}; action={Zoom(=250)} } + ha:Zoom to 0.50k/px = { a={z;5;}; action={Zoom(=500)} } + ha:Zoom In 20% and center = { li:action={Zoom(-1.2); Center()} } + ha:Zoom Out 20% and center= { li:action={Zoom(+1.2); Center()} } + - + ha:Zoom Extents = { li:a={{z;e;}; {v;f};}; action=Zoom() } + ha:Zoom to selection = { a={z;s;}; action=ZoomTo(selected) } + - + ha:Center cursor = { a={v; c} action=Center() } + } + } + ha:Current layer { + li:submenu { + ha:TODO { li:a={{l;r}; {l;-};}; action=Layer(remove) } + } + } + ha:Full screen = { checked=editor/fullscreen; a=\\; action=fullscreen(toggle) } + ha:Reset { + li:submenu { + ha:Reset View = { a={v; r; v}; sy:action={/scripts/view_reset}; tip={Reset all visibility related states to make sure all objects are visible} } + ha:Reset GUI = { a={v; r; g}; sy:action={/scripts/gui_reset}; tip={Reset all GUI related states } } + } + } + ha:Sheet { + li:submenu { + ha:Previous = { li:a={{v; d; p};{<};}; action={SwitchRelative(-1)}; tip={Switch to the previous sheet on the list of all-loaded-sheets} } + ha:Next = { li:a={{v; d; n};{\>};}; action={SwitchRelative(+1)}; tip={Switch to the next sheet on the list of all-loaded-sheets} } + } + } + } + } + + + ha:Mode = { + li:submenu { + ha:Lines and nets { + li:submenu { + ha:Cycle line clip/refraction (toggle) = { li:a={{m; l; f}; {/};}; action=conf(toggle, editor/line_refraction, design) } + ha:Continuous draw (toggle) = { li:a={{m; l; c};}; action=conf(toggle, editor/line_cont, design) } + ha:Rubber band mode = { a={m; r; r}; checked=editor/rubber_band_mode; action=conf(toggle, editor/rubber_band_mode, design) } + ha:Rubber band\: orthogonal lines = { a={m; r; o}; checked=editor/rubber_band_ortho; action=conf(toggle, editor/rubber_band_ortho, design) } + } + } + ha:Drawing { + li:submenu { + ha:Lock floaters = { a={m; f; l}; checked=editor/lock_floaters; action=ToggleFloaters(lock); } + ha:Only floaters = { a={m; f; o}; checked=editor/only_floaters; action=ToggleFloaters(only); } + } + } + ha:Symbols and libraries { + li:submenu { + ha:Enable symbol auto-pasting to local lib = { a={m; s; p}; checked=editor/paste_to_local_lib; action=conf(toggle, editor/paste_to_local_lib, design); tip={When enabled, symbols placed from (external) symbol library are first copied into the local symbol library then group references to the local copy are placed}} + } + } + ha:Loose symbol (no sym lock) = { a={m; k; s}; checked={propget(sheet, p/sheet/loose_sym)}; action={proptoggle(sheet, p/sheet/loose_sym)}; update_on={} } + ha:Tool { + li:submenu { + ha:Circle = { checked=ChkMode(circle); li:a={{t;c};{F1};}; action=Tool(circle); update_on={editor/mode} } + ha:Wirenet = { checked=ChkMode(wirenet); li:a={{t;w};{F2};}; action=Tool(wirenet); update_on={editor/mode} } + ha:Line = { checked=ChkMode(line); li:a={{t;l};{F3};}; action=Tool(line); update_on={editor/mode} } + ha:Text = { checked=ChkMode(text); li:a={{t;t};{F4};}; action=Tool(text); update_on={editor/mode} } + ha:Rectangle = { checked=ChkMode(rect); li:a={{t;r};{F5};}; action=Tool(rect); update_on={editor/mode} } + ha:Buffer = { checked=ChkMode(buffer); li:a={{t;b};{F7};}; action=Tool(buffer); update_on={editor/mode} } + ha:Del/remove = { checked=ChkMode(remove); li:a={{t;d};{F8};}; action=Tool(remove); update_on={editor/mode} } + ha:Whirl (rotate 90 deg) = {checked=ChkMode(rotate);li:a={{t;o};{F9};}; action=Tool(rotate); update_on={editor/mode} } + ha:xmirror = { checked=ChkMode(xmirror); li:a={{t;x};}; action=Tool(xmirror); update_on={editor/mode} } + ha:ymirror = { checked=ChkMode(ymirror); li:a={{t;y};}; action=Tool(ymirror); update_on={editor/mode} } + ha:Arrow = { checked=ChkMode(arrow); li:a={{t;n};{F11};}; action=Tool(arrow); update_on={editor/mode} } + ha:Lock = { checked=ChkMode(lock); li:a={{t;k};{F12};}; action=Tool(lock); update_on={editor/mode} } + ha:Move = { checked=ChkMode(move); li:a={{t;m};}; action=Tool(move); update_on={editor/mode} } + ha:Copy = { checked=ChkMode(copy); li:a={{t;Shiftp};}; action=Tool(copy); update_on={editor/mode} } + - + ha:Cancel = { a={Escape}; action=Tool(escape); } + ha:Change pen = { a={t;p}; action=Preferences(colors); } + } + } # Tool + } + } + + ha:Select = { + li:submenu { + ha:Select all visible objects on sheet = { a={s; a; a;}; action=Select(All) } + ha:Unselect all objects on sheet = { a={s; u; a;}; action=Unselect(All) } + ha:Unselect all objects in projet = { a={s; u; p;}; action=Unselect(AllProject) } + ha:Invert selection on sheet = { a={s; i; }; action=Select(Invert) } + - + ha:Advanced search and select = { a={s; s;} action=SearchDialog() } + ha:List locked objects = { a={s; l; k;} action={query(view, "@.locked == 1")} } + ha:List unnamed symbols = { a={s; l; u;} action={query(view, '@.a.role == "sym" || @.a.name ~ "[?]$"') } } + - + ha:Remove selected objects = { a={s; r;} action=RemoveSelected() } + ha:Convert selection to { + li:submenu { + ha:Polygon = { a={s;c;p}; li:action={GetXY(Click to set origin); Convert(selected, polygon);} } + ha:Symbol = { a={s;c;s}; li:action={GetXY(Click to set origin); Convert(selected, symbol);} } + ha:Terminal = { a={s;c;t}; li:action={GetXY(Click to set origin); Convert(selected, terminal);} } + ha:Custom group = { a={s;c;g}; li:action={GetXY(Click to set origin); Convert(selected, group);} } + } + } + ha:Break up selected... { + li:submenu { + ha:objects = { a={s;b;b}; action=Breakup(selected, any, sheet); } + ha:groups = { a={s;b;g}; action=Breakup(selected, group, sheet); } + ha:polygons = { a={s;b;p}; action=Breakup(selected, poly, sheet); } + } + } + ha:Change selected objects { + li:submenu { + ha:Edit properties = { a={s; p}; action=propedit(selection) } + ha:Testbench affiliation = { a={s; t}; action=TestBenchDialog(selected) } + } + } + } + } # Select + + ha:Buffer { + li:submenu { + ha:Rotate buffer 90 deg CCW (left) = { a={b;r;l}; action=Rotate90(Buffer, 1); } + ha:Rotate buffer 90 deg CW (right) = { a={b;r;r}; action=Rotate90(Buffer, -1); } + ha:Arbitrarily Rotate Buffer = { a={b;r;a}; action=Rotate(Buffer, ask); } + ha:Mirror buffer (left/right) = { a={b;m;l}; action=Mirror(Buffer, horizontal);} + ha:Mirror buffer (up/down) = { a={b;m;u}; action=Mirror(Buffer, vertical); } +# ha:Scale = { } +# ha:Normalize = { a={b;n}; } + - + ha:Clear buffer = { a={b;c;c;}; action=BufferClear() } + ha:Save buffer content to file = { a={b;f;s;}; action=BufferSave(All) } + ha:Load buffer content from file = { a={b;f;l;}; li:action={BufferClear(); BufferLoad(All); Tool(buffer);} } + - +# ha:Convert buffer to polygon = { a={b;c;p}; action=Convert(buffer, polygon); } +# ha:Convert buffer to symbol = { a={b;c;s}; action=Convert(buffer, symbol); } +# ha:Convert buffer to terminal = { a={b;c;t}; action=Convert(buffer, terminal); } +# ha:Convert buffer to custom group = { a={b;c;g}; action=Convert(buffer, group); } +# ha:Break up buffer = { a={b;b;b}; action=Breakup(buffer, any, sheet); } +# ha:Break up buffer groups = { a={b;b;g}; action=Breakup(buffer, group, sheet); } +# ha:Break up buffer polygons = { a={b;b;p}; action=Breakup(buffer, poly, sheet); } + - + ha:Save buffer symbol to file = { a={b;s;s}; action=BufferSave(Symbol); tip={save one symbol group from the buffer as a group file} } + ha:Save buffer group to file = { a={b;s;g}; action=BufferSave(Group); tip={save one group from the buffer as a group file} } + ha:Load buffer symbol/group from file = { a={b;l;s}; li:action={BufferLoad(Symbol); Tool(buffer);}; tip={load one group from file into the paste buffer } } + - + ha:Buffer selection { + li:submenu { + ha:Select Buffer \#1 = { checked=BufferChk(1); a={b;1;} action=BufferSwitch(1); update_on={editor/buffer_number} } + ha:Select Buffer \#2 = { checked=BufferChk(2); a={b;2;} action=BufferSwitch(2); update_on={editor/buffer_number} } + ha:Select Buffer \#3 = { checked=BufferChk(3); a={b;3;} action=BufferSwitch(3); update_on={editor/buffer_number} } + ha:Select Buffer \#4 = { checked=BufferChk(4); a={b;4;} action=BufferSwitch(4); update_on={editor/buffer_number} } + ha:Select scratchpad = { checked=BufferChk(5); a={b;5;} action=BufferSwitch(5); update_on={editor/buffer_number} } + } + } + } + } # Buffer + + ha:Attributes { + li:submenu { + ha:Generic group { + li:submenu { + ha:Change role = { a={a;o;}; action=QuickAttr(object, role); tip={Change the role attribute of a group} } + ha:Change name = { a={a;n;}; action=AttributeDialog(object, name); tip={Change the name attribute of a group (refdes, pin number, etc)} } + } + } + ha:Symbol { + li:submenu { + ha:Change name (refdes) = { a={a;r}; action=AttributeDialog(object, name); tip={Change the name attribute of a group (refdes)} } + ha:Change value = { a={a;v}; action=AttributeDialog(object, value); tip={Change the value attribute of a group} } + ha:Change slot num = { a={a;s}; action=AttributeDialog(object, -slot); tip={Change the slot number attribute of a group} } + ha:Change devmap = { a={a;d;}; action=QuickAttr(object, devmap); tip={Change the devmap attribute of a symbol (device+footprint+pinout mapping) } } + ha:Change portmap = { a={a;p;}; action=QuickAttr(object, portmap); tip={Change the portmap attribute of a group} } + ha:Change connections = { a={a;c;}; action=QuickAttr(object, connect); tip={Change the symbol terminal to network connection list } } + ha:Change footprint = { a={a;f}; action=AttributeDialog(object, footprint); tip={Change the footprint attribute of a group} } + ha:Change funcmap = { a={a;u;}; action=QuickAttr(object, funcmap); tip={Change the funcmap attribute of a symbol (alternative pin function map) } } + } + } + - + ha:Change name (refdes) = { a={a;a}; action=AttributeDialog(object, name); tip={Invoke attribute editor} } + } + } # Attributes + + ha:Plugins { + li:submenu { + ha:feature plugins = { + # submenu dedicated for feature plugins to register their menu items + li:submenu { + @feature_plugins + } + } + ha:script = { + # submenu dedicated for user scripts to register their menu items + li:submenu { + @scripts + } + } + ha:Manage plugins... = { a={p;m;p;}; action=ManagePlugins() } + ha:Manage scripts... = { a={p;m;s;}; action=BrowseScripts() } + } + } # Plugins + + ha:Window { + li:submenu { + ha:Message Log = { a={w;m}; action=LogDialog() } + ha:Command Entry = { li:a={a={w;c}; {:};} action=Command() } + ha:Tree view = { a={w;t}; action=TreeDialog() } + ha:Abstract model = { a={w;a}; action=AbstractDialog() } + - + ha:Library = { a={w;l}; action=LibraryDialog(symbol, sheet) } + ha:devmaps = { a={w;w;d}; action=LibraryDialog(devmap, sheet) } + ha:funcmaps = { a={w;w;u}; action=LibraryDialog(funcmap, sheet) } + ha:spice libs = { a={w;w;s}; action=LibraryDialog(spicelib, sheet) } + - + ha:Key Bindings { + li:submenu { +# ha:Cycle object being dragged = { li:a={{,};{e;y;};}; action=CycleDrag() } + ha:Step Cursor { + li:submenu { + ha:Step Up = { li:a={{Up};{k;k};}; action=Cursor(Warp,0,-1,grid) } + ha:Step Down = { li:a={{Down};{k;j};}; action=Cursor(Warp,0,1,grid) } + ha:Step Left = { li:a={{Left};{k;h};}; action=Cursor(Warp,-1,0,grid) } + ha:Step Right = { li:a={{Right};{k;l};}; action=Cursor(Warp,1,0,grid) } + ha:Step +Up = { a=ShiftUp; action=Cursor(Pan,0,-50,view) } + ha:Step +Down = { a=ShiftDown; action=Cursor(Pan,0,50,view) } + ha:Step +Left = { a=ShiftLeft; action=Cursor(Pan,-50,0,view) } + ha:Step +Right = { a=ShiftRight; action=Cursor(Pan,50,0,view) } + ha:Scroll Up = { li:a={{CtrlUp};{j;k};}; action=Scroll(up) } + ha:Scroll Down = { li:a={{CtrlDown};{j;j};}; action=Scroll(down) } + ha:Scroll Left = { li:a={{CtrlLeft};{j;h};}; action=Scroll(left) } + ha:Scroll Right = { li:a={{CtrlRight};{j;l};}; action=Scroll(right) } + ha:Click (left) = { li:a={{Enter};{k;space};}; li:action={Tool(Press); Tool(Release)} } + ha:Click (right) = { a={k;r}; li:action={Tool(Release); Popup(popup-obj, obj-type)} } + } + } + ha:attribute layer keys { + li:submenu { + anon3=@layerkeys + } + } + ha:generic layer keys { + li:submenu { + ha:Select previous layer = { a={l; k}; action=LayerByStack(Select, Prev); } + ha:Select next layer = { a={l; l}; action=LayerByStack(Select, Next); } + - + ha:Select Layer 1 = { a=1; action=SelectLayer(1) } + ha:Select Layer 2 = { a=2; action=SelectLayer(2) } + ha:Select Layer 3 = { a=3; action=SelectLayer(3) } + ha:Select Layer 4 = { a=4; action=SelectLayer(4) } + ha:Select Layer 5 = { a=5; action=SelectLayer(5) } + ha:Select Layer 6 = { a=6; action=SelectLayer(6) } + ha:Select Layer 7 = { a=7; action=SelectLayer(7) } + ha:Select Layer 8 = { a=8; action=SelectLayer(8) } + ha:Select Layer 9 = { a=9; action=SelectLayer(9) } + ha:Select Layer 10 = { a=0; action=SelectLayer(10) } + ha:Select Layer 11 = { a=Alt1; action=SelectLayer(11) } + ha:Select Layer 12 = { a=Alt2; action=SelectLayer(12) } + ha:Select Layer 13 = { a=Alt3; action=SelectLayer(13) } + ha:Select Layer 14 = { a=Alt4; action=SelectLayer(14) } + ha:Select Layer 15 = { a=Alt5; action=SelectLayer(15) } + ha:Select Layer 16 = { a=Alt6; action=SelectLayer(16) } + ha:Select Layer 17 = { a=Alt7; action=SelectLayer(17) } + ha:Select Layer 18 = { a=Alt8; action=SelectLayer(18) } + ha:Select Layer 19 = { a=Alt9; action=SelectLayer(19) } + ha:Select Layer 20 = { a=Alt0; action=SelectLayer(20) } + - + ha:Toggle Layer 1 = { a=Ctrl1; action=ToggleView(1) } + ha:Toggle Layer 2 = { a=Ctrl2; action=ToggleView(2) } + ha:Toggle Layer 3 = { a=Ctrl3; action=ToggleView(3) } + ha:Toggle Layer 4 = { a=Ctrl4; action=ToggleView(4) } + ha:Toggle Layer 5 = { a=Ctrl5; action=ToggleView(5) } + ha:Toggle Layer 6 = { a=Ctrl6; action=ToggleView(6) } + ha:Toggle Layer 7 = { a=Ctrl7; action=ToggleView(7) } + ha:Toggle Layer 8 = { a=Ctrl8; action=ToggleView(8) } + ha:Toggle Layer 9 = { a=Ctrl9; action=ToggleView(9) } + ha:Toggle Layer 10 = { a=Ctrl0; action=ToggleView(10) } + ha:Toggle Layer 11 = { a=Ctrl-Alt1; action=ToggleView(11) } + ha:Toggle Layer 12 = { a=Ctrl-Alt2; action=ToggleView(12) } + ha:Toggle Layer 13 = { a=Ctrl-Alt3; action=ToggleView(13) } + ha:Toggle Layer 14 = { a=Ctrl-Alt4; action=ToggleView(14) } + ha:Toggle Layer 15 = { a=Ctrl-Alt5; action=ToggleView(15) } + ha:Toggle Layer 16 = { a=Ctrl-Alt6; action=ToggleView(16) } + ha:Toggle Layer 17 = { a=Ctrl-Alt7; action=ToggleView(17) } + ha:Toggle Layer 18 = { a=Ctrl-Alt8; action=ToggleView(18) } + ha:Toggle Layer 19 = { a=Ctrl-Alt9; action=ToggleView(19) } + ha:Toggle Layer 20 = { a=Ctrl-Alt0; action=ToggleView(20) } + } + } # layer keys + + ha:polygon drawing { + li:submenu { + ha:Polygon PreviousPoint = { a={p; p; p}; action=Polygon(PreviousPoint) } + ha:Polygon Close = { a={p; p; c}; action=Polygon(Close) } + } + } + } + } + } + } + + ha:Help { + li:submenu { + ha:About = { action=About() } + } + } + } #main_menu + + li:popups { +# context sensitive right click: popup per object type under the cursor + + ha:layer { + li:submenu { + ha:TODO { } + } + } + + ha:popup-obj-polygon { + li:submenu { + ha:edit polygon properties... { action=propedit(object) } + ha:polygon in tree view... { action=TreeDialog(object) } + } + } + + ha:popup-obj-arc { + li:submenu { + ha:edit arc properties... { action=propedit(object) } + ha:arc in tree view... { action=TreeDialog(object) } + } + } + + ha:popup-obj-line { + li:submenu { + ha:edit line properties... { action=propedit(object) } + ha:line in tree view... { action=TreeDialog(object) } + } + } + + ha:popup-obj-text { + li:submenu { + ha:edit text properties... { action=propedit(object) } + ha:text in tree view... { action=TreeDialog(object) } + ha:edit text string { action=EditText(Object) } + } + } + + ha:popup-obj-symbol { + li:submenu { + ha:edit symbol properties... { action=propedit(object) } + ha:edit symbol attributes... { action=AttributeDialog(last-click) } + ha:edit symbol pens... { action=pendialog(object, non-modal) } + ha:symbol in tree view... { action=TreeDialog(object) } + - + ha:Change name (refdes) { action=AttributeDialog(object, name); tip={Change the name attribute of a group (refdes)} } + ha:Change devmap { action=QuickAttr(object, devmap); tip={Change the devmap attribute of a symbol (device+footprint+pinout mapping) } } + ha:Change funcmap { action=QuickAttr(object, funcmap); tip={Change the funcmap attribute of a symbol (alternative pin function mapping) } } + ha:Per port funcmap... { action=FuncmapComponentDialog(object); tip={Open the per port alternate function table for the component the symbol creates } } + ha:Conditional... { + li:submenu { + ha:DNP (do not populate) { action=ConditionalDialog(object, dnp); tip="Condition to mark the the component Do-Not-Populate in export" } + ha:omit (no-export) { action=ConditionalDialog(object, omit); tip="Condition to omit the component from exports" } + } + } + ha:Testbench affiliation = { action=TestBenchDialog(object) } + - + ha:update symbol from ext. lib { } + ha:move symbol to local lib ref. { action=SymLocLib(object, toref); } + ha:convert from local lib ref. to embedded { action=SymLocLib(object, togrp); } + } + } + + ha:popup-obj-terminal { + li:submenu { + ha:edit terminal properties... { action=propedit(object) } + ha:edit terminal attributes... { action=AttributeDialog(last-click) } + ha:edit terminal pens... { action=pendialog(object, non-modal) } + ha:funcmap\: change alternate function...{ action=FuncmapPortDialog(object); tip={Open a dialog box to select alternate function of the pin if the component features alternate funcmap } } + ha:terminal in tree view... { action=TreeDialog(object) } + ha:set terminal name { action={message(ERROR, not yet implemented)}; } + } + } + + ha:popup-obj-wire-net { + li:submenu { + ha:edit wirenet properties... { action=propedit(parent) } + ha:edit net attributes... { action=AttributeDialog(parent) } + ha:wirenet object in tree view... { action=TreeDialog(object) } + - + ha:Conditional... { + li:submenu { + ha:omit (no-export) { action=ConditionalDialog(object, omit); tip="Condition to omit the component from exports" } + } + } + } + } + + ha:popup-obj-user-grp-unknown { + li:submenu { + ha:edit group properties... { action=propedit(object) } + ha:edit group attributes... { action=AttributeDialog(last-click) } + ha:edit group pens... { action=pendialog(object, non-modal) } + ha:group in tree view... { action=TreeDialog(object) } + } + } + + ha:sheet { + li:submenu { + ha:edit sheet properties... { action=propedit(sheet) } + ha:edit sheet attributes... { action=AttributeDialog(sheet) } + ha:edit sheet pens... { action={PenDialog(object=/2)} } + } + } + + ha:symbol-as-sheet { + li:submenu { + ha:edit top symbol properties... { action=propedit(sheet) } + ha:edit top symbol attributes... { action=AttributeDialog(sheet) } + ha:edit top symbol pens... { action={PenDialog(object=/2)} } + } + } + + } #popups + + ha:scripts { + # set all visibility related conf nodes (view/mode/drawing in the menu) + # to safe defaults that makes sure everything is visible + mode_reset { +# conf(set, editor/wireframe_draw, 0, design); +# conf(set, editor/thin_draw, 0, design); +# conf(set, editor/thin_draw_poly, 0, design); + Display(Redraw); + } + + # set all visibility related states to safe defaults that makes sure + # everything is visible + li:view_reset { + sy:mdr = {/scripts/mode_reset} +#TODO: LayerVisReset(); + zoom(); + } + + # set all GUI states to safe defaults to get the UI to a known state + li:gui_reset { + sy:vr = {/scripts/view_reset} + fullscreen(off); + conf(set, editor/draw_grid, 1, design); + conf(set, editor/local_grid/enable, 0, design); + Tool(arrow); +# Display(Redraw); + } + } # scripts + +} # root Index: tags/1.0.5/src/sch-rnd/multi.c =================================================================== --- tags/1.0.5/src/sch-rnd/multi.c (nonexistent) +++ tags/1.0.5/src/sch-rnd/multi.c (revision 10414) @@ -0,0 +1,470 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - sch-rnd (executable) + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "conf_core.h" +#include "sheet.h" +#include "project.h" + +#include "multi.h" + +csch_sheet_t *sch_rnd_multi_switch_to(csch_sheet_t *s) +{ + return (csch_sheet_t *)rnd_multi_switch_to(s == NULL ? NULL : &s->hidlib); +} + +void sch_rnd_multi_switch_to_initial(csch_sheet_t *s) +{ + rnd_multi_switch_to_(&s->hidlib); +} + +void sch_rnd_multi_switch_to_delta(csch_sheet_t *curr, int step) +{ + rnd_multi_switch_to_delta(curr == NULL ? NULL : &curr->hidlib, step); +} + +static csch_project_t *sch_rnd_multi_load_project_(const char *project_fn) +{ + csch_project_t *prj = htsp_get(&rnd_projects, project_fn); + if (prj == NULL) { + char *pfn = rnd_strdup(project_fn); + prj = csch_load_project_by_sheet_name(pfn, 0, rnd_conf.rc.quiet); + if (prj->hdr.loadname != NULL) { + htsp_set(&rnd_projects, prj->hdr.loadname, prj); + free(pfn); + } + else { + TODO("memleak: this leaks pfn; happens when loading a sheet without a project file"); + htsp_set(&rnd_projects, pfn, prj); + } + } + return prj; +} + + +csch_project_t *sch_rnd_multi_load_project(const char *load_fn, const char *project_fn_in) +{ + char *project_fn, *project_dir; + char *freeme1, *freeme2; + csch_project_t *prj; + + if (project_fn_in != NULL) { + char *realp = rnd_lrealpath(project_fn_in); + if (realp == NULL) + return NULL; + prj = sch_rnd_multi_load_project_(realp); + free(realp); + return prj; + } + + /* there may be no existing project file - assume project is the directory */ + project_dir = freeme1 = rnd_dirname_real(load_fn); + project_fn = freeme2 = rnd_concat(project_dir, "/project.lht", NULL); + + prj = sch_rnd_multi_load_project_(project_fn); + + free(freeme1); + free(freeme2); + return prj; +} + +static csch_sheet_t *sch_rnd_multi_load_(const char *fn, const char *fmt, const char *project_fn, int *is_project, rnd_conflist_t *root_sheets_out, rnd_conflist_t *aux_sheets_out); + +/* Append all unique file names to fns (keeps order) */ +static void map_all_sheets(const rnd_conflist_t *list, vts0_t *fns) +{ + rnd_conf_listitem_t *item; + const char *shfn; + int idx, n; + + rnd_conf_loop_list_str(list, item, shfn, idx) { + int found = 0; + + for(n = 0; n < fns->used; n++) { + if (strcmp(fns->array[n], shfn) == 0) { + rnd_message(RND_MSG_ERROR, "Redundant file name in project: %s\n", shfn); + found = 1; + break; + } + } + + if (!found) + vts0_append(fns, rnd_strdup(shfn)); + } +} + +/* Load a project file from prj_fn and all sheets; return first sheet */ +static csch_sheet_t *sch_rnd_multi_load_project_sheets(const char *prj_fn) +{ + csch_project_t *prj; + csch_sheet_t *res = NULL; + vts0_t fns = {0}; + long n, aux_start; + char *prj_fn_real; + + /* need to load by real name for comparisons/lookups/hash */ + prj_fn_real = rnd_lrealpath(prj_fn); + if (prj_fn_real == NULL) + return NULL; + + prj = sch_rnd_multi_load_project_(prj_fn_real); + free(prj_fn_real); + + if (prj == NULL) + return NULL; + + rnd_conf_load_project(prj_fn, NULL); + rnd_conf_merge_all("prj/root_sheets"); + rnd_conf_merge_all("prj/aux_sheets"); + + + map_all_sheets(&conf_core.prj.root_sheets, &fns); + aux_start = fns.used; + map_all_sheets(&conf_core.prj.aux_sheets, &fns); + + /* load usign raw "loadname" picked up from the project file because it + may be a symlink or relative to the project file */ + if (fns.used > 0) { + for(n = 0; n < fns.used; n++) { + csch_sheet_t *sheet = sch_rnd_multi_load_(fns.array[n], NULL, prj_fn, NULL, NULL, NULL); + if (sheet != NULL) { + if (res == NULL) + res = sheet; + sheet->stype = (n >= aux_start) ? CSCH_SHTY_AUX : CSCH_SHTY_ROOT; + } + free(fns.array[n]); + } + } + else + rnd_message(RND_MSG_ERROR, "Can not load project file '%s': does not name any sheet\n", prj_fn); + + vts0_uninit(&fns); + + return res; +} + +int sch_rnd_is_fn_project_file(const char *fn) +{ + const char *end = fn + strlen(fn) - 11; + return strcmp(end, "project.lht") == 0; +} + +/* sch-rnd, app-specific tasks on any newly loaded sheet */ +static void sch_rnd_multi_load_post(csch_sheet_t *sheet) +{ + rnd_tool_select_by_name(&sheet->hidlib, "arrow"); + + /* this loads and initializes sheet engines; this must come before + events because events may rely on engines already initialized + (e.g. devmap) */ + sch_rnd_prj_postproc((csch_project_t *)sheet->hidlib.project); + + rnd_event(&sheet->hidlib, CSCH_EVENT_SHEET_POSTLOAD, NULL); + rnd_event(&sheet->hidlib, RND_EVENT_LOAD_POST, NULL); +} + +static csch_sheet_t *sch_rnd_multi_load_(const char *fn, const char *fmt, const char *project_fn, int *is_project, rnd_conflist_t *root_sheets_out, rnd_conflist_t *aux_sheets_out) +{ + csch_sheet_t *sheet; + csch_project_t *prj; + const char *real_fn = fn; + char *freeme = NULL; + int lres; + rnd_conf_state_t *ncs; + FILE *f = NULL; + void *cookie, *io; + + if ((project_fn == NULL) && ((fmt == NULL) || (*fmt == '\0'))) { + if (sch_rnd_is_fn_project_file(fn)) { + if (is_project != NULL) + *is_project = 1; + return sch_rnd_multi_load_project_sheets(fn); + } + } + + /* try load as bundled */ + { + prj = htsp_get(&rnd_projects, (char *)fn); + if (prj != NULL) { /* already loaded */ + if (prj->hdr.designs.used > 0) + return prj->hdr.designs.array[0]; + return NULL; + } + + cookie = csch_test_parse_bundled(NULL, real_fn, CSCH_IOTYP_SHEET, &f, &io); + if (cookie != NULL) { + if (f != NULL) { + sheet = csch_load_bundled_sheets(cookie, io, f, fn, sch_rnd_multi_load_post); + fclose(f); + if (root_sheets_out != NULL) + memcpy(root_sheets_out, &conf_core.prj.root_sheets, sizeof(rnd_conflist_t)); + + if (sheet != NULL) { + prj = (csch_project_t *)sheet->hidlib.project; + htsp_set(&rnd_projects, (char *)fn, prj); + } + return sheet; + } + } + } + + /* not bundled; single sheet loader with all the extra rounds for project files */ + + if (is_project != NULL) + *is_project = 0; + + rnd_conf_multi_pre_new_design(&ncs); + rnd_conf_reset(RND_CFR_DESIGN, fn); + + prj = sch_rnd_multi_load_project(fn, project_fn); + + rnd_conf_merge_all(NULL); /* get font settings right for the text update in the loader */ + + /* If sheet name is not absolute and there is a project file being loaded, + sheet name needs to be translated relative to the project file's dir */ + if ((project_fn != NULL) && !rnd_is_path_abs(fn)) { + const char *s, *sep = NULL; + + /* check if project file is not in ./; sep is the last path separator */ + for(s = project_fn; *s != '\0'; s++) { + if ((*s == '/') || (*s == RND_DIR_SEPARATOR_C)) + sep = s; + } + + /* project file is not in ./, change real_fn */ + if (sep != NULL) { + gds_t tmp = {0}; + gds_append_len(&tmp, project_fn, sep - project_fn + 1); /* +1 to keep the sep in project file's path */ + gds_append_str(&tmp, real_fn); + real_fn = freeme = tmp.array; + } + } + + lres = csch_project_load_sheet(prj, real_fn, fmt, &sheet, rnd_conf.rc.quiet, f); + if (f != NULL) + fclose(f); + rnd_conf_multi_post_new_design(&ncs, &sheet->hidlib); + if (lres != 0) { + free(freeme); + return NULL; + } + + rnd_multi_load_prj_for_dsg(&sheet->hidlib); + + rnd_conf_state_new_design(&sheet->hidlib); + rnd_conf_merge_all(NULL); /* to get the project file applied */ + + if (root_sheets_out != NULL) + memcpy(root_sheets_out, &conf_core.prj.root_sheets, sizeof(rnd_conflist_t)); + if (aux_sheets_out != NULL) + memcpy(aux_sheets_out, &conf_core.prj.aux_sheets, sizeof(rnd_conflist_t)); + + sch_rnd_multi_load_post(sheet); + rnd_conf_state_save(sheet->hidlib.saved_rnd_conf); + + free(freeme); + return sheet; +} + +csch_sheet_t *sch_rnd_multi_load(const char *fn, const char *fmt, int *is_project) +{ + rnd_conflist_t roots = {0}, aux = {0}; + csch_sheet_t *sheet; + + sheet = sch_rnd_multi_load_(fn, fmt, NULL, is_project, &roots, &aux); + if ((sheet != NULL) && (sheet->stype == CSCH_SHTY_unknown)) { +/* rnd_conf_merge_all("prj/root_sheets"); + rnd_conf_merge_all("prj/aux_sheets");*/ + csch_sheet_type_detect(sheet, &roots, &aux); + } + + /* Do not free roots or aux, they are owned by the conf system */ + + return sheet; +} + +csch_sheet_t *sch_rnd_app_load_sheet(csch_project_t *proj, const char *path) +{ + int is_project; + csch_sheet_t *res; + rnd_design_t *last; + + last = rnd_multi_switch_to(NULL); /* empty conf so we can overwrite */ + res = sch_rnd_multi_load_(path, NULL, proj->hdr.loadname, &is_project, NULL, NULL); + res->stype = CSCH_SHTY_EXTERNAL; + rnd_multi_switch_to_(last); /* activate the original */ + + return res; +} + + +static csch_sheet_t *sch_rnd_multi_new_empty_(csch_project_t *prj, const char *fn) +{ + csch_sheet_t *sheet; + static csch_project_t *prj_none = NULL; + rnd_conf_state_t *ncs; + + rnd_conf_multi_pre_new_design(&ncs); + rnd_conf_reset(RND_CFR_DESIGN, NULL); + + if ((prj == NULL) && (fn != NULL)) + prj = sch_rnd_multi_load_project(fn, NULL); + + if (prj == NULL) { + if (prj_none == NULL) { + prj_none = csch_project_alloc(); + htsp_set(&rnd_projects, rnd_strdup(""), prj_none); + } + prj = prj_none; + } + + sheet = sch_rnd_sheet_new(prj); + + /* set filename before postprocessing the sheet so that libs dependeing + on $(rc.path.design) already have it filled in */ + if (fn == NULL) + fn = ""; + + if (!rnd_is_dir(NULL, fn)) { + /* If we failed to load a file with a given file name and created an + empty sheet instead, remember the file name for the new sheet so + {f s} saves using that name specified originally */ + if (sheet != NULL) { + sheet->hidlib.loadname = rnd_strdup(fn); + sheet->hidlib.fullpath = rnd_strdup(fn); + } + } + else + rnd_message(RND_MSG_ERROR, "Supplied sheet name '%s' is a directory, can't save sheet by that name.\n", fn); + + rnd_conf_multi_post_new_design(&ncs,&sheet->hidlib); + + if (sheet != NULL) { + rnd_multi_load_prj_for_dsg(&sheet->hidlib); + rnd_conf_state_new_design(&sheet->hidlib); + + rnd_conf_merge_all(NULL); /* to get the project file applied */ + sch_rnd_prj_postproc(prj); + rnd_tool_select_by_name(&sheet->hidlib, "arrow"); + rnd_event(&sheet->hidlib, CSCH_EVENT_SHEET_POSTLOAD, NULL); + rnd_event(&sheet->hidlib, RND_EVENT_LOAD_POST, NULL); + } + else { + TODO("multi: memleak"); +/* sch_rnd_prj_free(prj);*/ + } + + + rnd_conf_state_save(sheet->hidlib.saved_rnd_conf); + + return sheet; +} + +csch_sheet_t *sch_rnd_multi_new_empty(const char *fn) +{ + return sch_rnd_multi_new_empty_(NULL, fn); +} + +csch_sheet_t *sch_rnd_multi_new_empty_in_prj(csch_project_t *prj, const char *path) +{ + return sch_rnd_multi_new_empty_(prj, path); +} + + +void sch_rnd_multi_unload(csch_sheet_t *sheet) +{ + csch_project_t *prj; + + if (sheet == NULL) + sheet = (csch_sheet_t *)rnd_multi_get_current(); + + if (sheet == NULL) + return; + + prj = (csch_project_t *)sheet->hidlib.project; + if (prj != NULL) + sch_rnd_prj_remove_sheet(sheet); + + csch_sheet_uninit(sheet); + rnd_conf_free(RND_CFR_DESIGN); + rnd_conf_state_del_design(&sheet->hidlib); +} + +const char sch_rnd_multi_cookie[] = "sch-rnd/multi.c"; + +void sch_rnd_multi_init(void) +{ + rnd_conf_state_plug_reg(&conf_core, sizeof(conf_core), sch_rnd_multi_cookie); +} + +void sch_rnd_multi_uninit(void) +{ + rnd_conf_state_plug_unreg_all_cookie(sch_rnd_multi_cookie); +} + +void sch_rnd_sheet_free_all(void) +{ + rnd_design_t *curr, *next; + htsp_entry_t *e; + + /* free all projects (will free all sheets too) */ + while((e = htsp_first(&rnd_projects)) != NULL) { + csch_project_t *prj = e->value; + + htsp_delentry(&rnd_projects, e); + csch_project_free(prj); + } + + /* just in case anything left outside of known projects */ + for(curr = gdl_first(&rnd_designs); curr != NULL; curr = next) { + next = gdl_next(&rnd_designs, curr); + + csch_sheet_uninit((csch_sheet_t *)curr); + rnd_conf_state_del_design(curr); /* also removes curr from rnd_designs */ + free(curr); + } +} Index: tags/1.0.5/src/sch-rnd/multi.h =================================================================== --- tags/1.0.5/src/sch-rnd/multi.h (nonexistent) +++ tags/1.0.5/src/sch-rnd/multi.h (revision 10414) @@ -0,0 +1,35 @@ +#include + +/* Make s the current sheet (in the GUI). Returns previous current sheet. */ +csch_sheet_t *sch_rnd_multi_switch_to(csch_sheet_t *s); + +/* Change current sheet to curr+step in the linear sheet list; + if curr is NULL, use the GUI-current sheet */ +void sch_rnd_multi_switch_to_delta(csch_sheet_t *curr, int step); + +/* Special case: first switch after loading all pages from the command line */ +void sch_rnd_multi_switch_to_initial(csch_sheet_t *s); + +csch_project_t *sch_rnd_multi_load_project(const char *load_fn, const char *project_fn_in); + + +csch_sheet_t *sch_rnd_multi_load(const char *fn, const char *fmt, int *is_project); +csch_sheet_t *sch_rnd_multi_new_empty(const char *fn); +csch_sheet_t *sch_rnd_multi_new_empty_in_prj(csch_project_t *prj, const char *path); + +/* App-side loader for external hierarchic child sheets from hlibrary */ +csch_sheet_t *sch_rnd_app_load_sheet(csch_project_t *proj, const char *path); + +/* Assuming s is not the current sheet, unload it, removing from the list of + sheets. If s is NULL, unload currently active sheet. */ +void sch_rnd_multi_unload(csch_sheet_t *s); + +/* Returns whether fn is a path to a project file (project.lht) */ +int sch_rnd_is_fn_project_file(const char *fn); + + +/* Free all sheets currently loaded (useful on exit) */ +void sch_rnd_sheet_free_all(void); + +void sch_rnd_multi_init(void); +void sch_rnd_multi_uninit(void); Index: tags/1.0.5/src/sch-rnd/operation.c =================================================================== --- tags/1.0.5/src/sch-rnd/operation.c (nonexistent) +++ tags/1.0.5/src/sch-rnd/operation.c (revision 10414) @@ -0,0 +1,88 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - sch-rnd (executable) + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include +#include +#include +#include +#include + +#include "draw.h" +#include "search.h" +#include "font.h" + +#include "operation.h" + +static int remove_obj(csch_sheet_t *sheet, csch_chdr_t *obj) +{ + obj = csch_cobj_first_unlocked(obj); + if (obj != NULL) + csch_op_remove(sheet, obj); + return 1; +} + +int sch_rnd_op_remove_xy(csch_sheet_t *sheet, rnd_coord_t x, rnd_coord_t y) +{ + csch_chdr_t *obj; + + obj = sch_rnd_search_obj_at(sheet, x, y, sch_rnd_slop); + if (obj == NULL) + return 0; + + return remove_obj(sheet, obj); +} + +static void rotate90_obj(csch_sheet_t *sheet, csch_chdr_t *obj, rnd_coord_t x, rnd_coord_t y, int n) +{ + obj = csch_cobj_first_unlocked(obj); + if (obj != NULL) + csch_rotate90(sheet, obj, x, y, n, 1); +} + + +void sch_rnd_op_rotate90_xy(csch_sheet_t *sheet, rnd_coord_t x, rnd_coord_t y, int n) +{ + csch_chdr_t *obj = sch_rnd_search_obj_at(sheet, x, y, sch_rnd_slop); + if (obj != NULL) + rotate90_obj(sheet, obj, x, y, n); +} + +void sch_rnd_op_text_edit(csch_sheet_t *sheet, csch_text_t *text, const char *new_str) +{ + int has_bb = text->has_bbox; + text->has_bbox = 0; + csch_text_modify(sheet, text, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &new_str, NULL, NULL, 1, 0); + if (!has_bb) { /* height-defined font: recalculate bbox */ + if (!text->hdr.indirect) { /* alien load postproc may edit the indirect tree, where no visual update should be done */ + csch_cobj_update_pen(&text->hdr); + sch_rnd_font_text_update(sheet, text, text->hdr.stroke); + } + } + text->has_bbox = has_bb; +} + Index: tags/1.0.5/src/sch-rnd/operation.h =================================================================== --- tags/1.0.5/src/sch-rnd/operation.h (nonexistent) +++ tags/1.0.5/src/sch-rnd/operation.h (revision 10414) @@ -0,0 +1,49 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - sch-rnd (executable) + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + + +#ifndef SCH_RND_OPERATIONS_H +#define SCH_RND_OPERATIONS_H + +#include +#include + +/* Remove first visible object at x;y (typically: click-to-remove tool); + Returns number of removed objects (0 or 1). */ +int sch_rnd_op_remove_xy(csch_sheet_t *sheet, rnd_coord_t x, rnd_coord_t y); + +/* Rotate first visible object at x;y (typically: click-to-rotate tool) + by n steps */ +void sch_rnd_op_rotate90_xy(csch_sheet_t *sheet, rnd_coord_t x, rnd_coord_t y, int n); + + +/* Undoably edit text string; recalculate bounding box if text is + font-height-specified */ +void sch_rnd_op_text_edit(csch_sheet_t *sheet, csch_text_t *text, const char *new_str); + +#endif Index: tags/1.0.5/src/sch-rnd/plug_io_act.c =================================================================== --- tags/1.0.5/src/sch-rnd/plug_io_act.c (nonexistent) +++ tags/1.0.5/src/sch-rnd/plug_io_act.c (revision 10414) @@ -0,0 +1,196 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - sch-rnd (executable) + * Copyright (C) 2020,2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust in 2023) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include "config.h" + +#include + +#include +#include +#include +#include +#include +#include +#include + + +#include +#include + +#include "plug_io_act.h" + +static const char *plug_io_cookie = "plug_io_act"; + +static const char csch_acts_LoadFrom[] = "LoadFrom(Sheet|Project,filename[,format])"; +static const char csch_acth_LoadFrom[] = "Load project or sheet data from a file."; +fgw_error_t csch_act_LoadFrom(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *op, *name, *format = NULL; + + RND_ACT_CONVARG(1, FGW_STR, LoadFrom, op = argv[1].val.str); + RND_ACT_CONVARG(2, FGW_STR, LoadFrom, name = argv[2].val.str); + RND_ACT_MAY_CONVARG(3, FGW_STR, LoadFrom, format = argv[3].val.str); + + if (rnd_strcasecmp(op, "sheet") == 0) { + csch_sheet_t *sheet; + rnd_design_t *last; + + last = rnd_multi_switch_to(NULL); /* empty conf so we can overwrite */ + sheet = sch_rnd_multi_load(name, format, NULL); + if (sheet == NULL) { + rnd_multi_switch_to_(last); /* go back to last */ + rnd_message(RND_MSG_ERROR, "Can not load file '%s'\n", name); + RND_ACT_IRES(-1); + return 0; + } + rnd_multi_switch_to_(&sheet->hidlib); /* activate new */ + } + else if (rnd_strcasecmp(op, "project") == 0) { + TODO("the actual project load"); + rnd_message(RND_MSG_ERROR, "LoadFrom(project,...) not yet implemented\n"); + } + else + RND_ACT_FAIL(LoadFrom); + + RND_ACT_IRES(0); + return 0; +} + +static const char csch_acts_Unload[] = "Unload(Sheet|Project)"; +static const char csch_acth_Unload[] = "Unload (close) current project or sheet"; +fgw_error_t csch_act_Unload(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *op; + + RND_ACT_CONVARG(1, FGW_STR, Unload, op = argv[1].val.str); + + if (rnd_strcasecmp(op, "sheet") == 0) { + rnd_design_t *dsg = rnd_multi_get_current(); + csch_sheet_t *next = (csch_sheet_t *)rnd_multi_neighbour_sheet(NULL); + + rnd_event(dsg, CSCH_EVENT_SHEET_PREUNLOAD, NULL); + + sch_rnd_multi_unload((csch_sheet_t *)dsg); + if (next == NULL) { + /* unloaded the last sheet */ + exit(1); + } + + rnd_event(&next->hidlib, CSCH_EVENT_SHEET_POSTUNLOAD, NULL); + rnd_multi_switch_to(&next->hidlib); /* activate new */ + } + else if (rnd_strcasecmp(op, "project") == 0) { + TODO("the actual project load"); + rnd_message(RND_MSG_ERROR, "Unload(project,...) not yet implemented\n"); + } + else + RND_ACT_FAIL(Unload); + + RND_ACT_IRES(0); + return 0; +} + + +static const char csch_acts_SaveTo[] = "SaveTo(Sheet|Project,filename[,format])"; +static const char csch_acth_SaveTo[] = "Save project or sheet to a file."; +fgw_error_t csch_act_SaveTo(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *op, *name, *format = "lihata"; + csch_sheet_t *sheet = CSCH_ACT_SHEET; + int renamed; + + RND_ACT_CONVARG(1, FGW_STR, SaveTo, op = argv[1].val.str); + RND_ACT_CONVARG(2, FGW_STR, SaveTo, name = argv[2].val.str); + RND_ACT_MAY_CONVARG(3, FGW_STR, SaveTo, format = argv[3].val.str); + + if (rnd_strcasecmp(op, "sheet") == 0) { + renamed = ((sheet->hidlib.fullpath == NULL) || (strcmp(name, sheet->hidlib.fullpath) != 0)); + if (csch_save_sheet(sheet, name, format) != 0) { + rnd_message(RND_MSG_ERROR, "Can not save file '%s'\n", name); + RND_ACT_IRES(-1); + return 0; + } + if (renamed) { + { /* load new project file */ + const char *try, *fn = rnd_conf_get_project_conf_name(NULL, sheet->hidlib.fullpath, &try); + csch_project_t *new_prj; + + new_prj = sch_rnd_multi_load_project(sheet->hidlib.fullpath, fn); + if (&new_prj->hdr != sheet->hidlib.project) { + if (fn == NULL) + rnd_message(RND_MSG_INFO, "Project file changed (to non-existing) for sheet upon save-as into a different directory.\n"); + else + rnd_message(RND_MSG_INFO, "Project file changed to '%s' for sheet upon save-as into a different directory.\n", fn); + + rnd_conf_free(RND_CFR_PROJECT); + if (sch_rnd_prj_remove_sheet(sheet) > 0) + rnd_project_append_design(&new_prj->hdr, &sheet->hidlib); + rnd_conf_load_as(RND_CFR_PROJECT, fn, 0); + rnd_conf_merge_all(NULL); + sch_rnd_prj_postproc(new_prj); + + /* get the GUI updated for the new conf (e.g. color) */ + rnd_event(&sheet->hidlib, RND_EVENT_DESIGN_SET_CURRENT_INTR, "p", &sheet->hidlib); + rnd_event(&sheet->hidlib, RND_EVENT_DESIGN_SET_CURRENT, "p", &sheet->hidlib); + } + } + + /* invalidate dynamic text objects so that %project.name% is recalculated */ + csch_text_invalidate_all_sheet(sheet, 1); + + /* get sheetsel updated */ + rnd_event(&sheet->hidlib, RND_EVENT_DESIGN_META_CHANGED, NULL); + rnd_event(&sheet->hidlib, RND_EVENT_DESIGN_FN_CHANGED, NULL); + } + } + else if (rnd_strcasecmp(op, "project") == 0) { + rnd_message(RND_MSG_ERROR, "SaveTo(project,...) not yet implemented\n"); + } + else + RND_ACT_FAIL(SaveTo); + + RND_ACT_IRES(0); + return 0; +} + +static rnd_action_t csch_plug_io_act_list[] = { + {"SaveTo", csch_act_SaveTo, csch_acth_SaveTo, csch_acts_SaveTo}, + {"LoadFrom", csch_act_LoadFrom, csch_acth_LoadFrom, csch_acts_LoadFrom}, + {"Unload", csch_act_Unload, csch_acth_Unload, csch_acts_Unload}, +}; + +void csch_plug_io_act_init(void) +{ + RND_REGISTER_ACTIONS(csch_plug_io_act_list, plug_io_cookie); +} + +void csch_plug_io_act_uninit(void) +{ + rnd_remove_actions_by_cookie(plug_io_cookie); +} + Index: tags/1.0.5/src/sch-rnd/plug_io_act.h =================================================================== --- tags/1.0.5/src/sch-rnd/plug_io_act.h (nonexistent) +++ tags/1.0.5/src/sch-rnd/plug_io_act.h (revision 10414) @@ -0,0 +1,5 @@ +#include + +void csch_plug_io_act_init(void); +void csch_plug_io_act_uninit(void); + Index: tags/1.0.5/src/sch-rnd/project.c =================================================================== --- tags/1.0.5/src/sch-rnd/project.c (nonexistent) +++ tags/1.0.5/src/sch-rnd/project.c (revision 10414) @@ -0,0 +1,421 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - sch-rnd (executable) + * Copyright (C) 2019,2022,2023 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "multi.h" + +#include "conf_core.h" + +static char prj_cookie[] = "sch-rnd/project.c"; + +static char *hash_get_strip(lht_node_t *parent, const char *name, gds_t *tmp) +{ + lht_node_t *n = lht_dom_hash_get(parent, name); + const char *s; + long i; + + if ((n == NULL) || (n->type != LHT_TEXT)) + return NULL; + + tmp->used = 0; + s = n->data.text.value; + while(isspace(*s)) s++; + gds_append_str(tmp, s); + for(i = tmp->used-1; i >= 0; i--) { + if (!isspace(tmp->array[i])) + break; + tmp->array[i] = '\0'; + tmp->used--; + } + return tmp->array; +} + +static void prj_append_view_cfg(csch_project_t *prj, rnd_conf_listitem_t *i) +{ + lht_node_t *nd = i->prop.src; + int changed = 0; + + if ((nd != NULL) && (nd->type == LHT_HASH)) { + gds_t tmp1 = {0}, tmp2 = {0}; + lht_node_t *e, *eng = lht_dom_hash_get(nd, "engines"); + if ((eng != NULL) && (eng->type == LHT_LIST)) { + csch_view_t *view = csch_view_create(prj, nd->name); + for(e = eng->data.list.first; e != NULL; e = e->next) { + if (e->type == LHT_HASH) { + char *plugin = hash_get_strip(e, "plugin", &tmp1); + char *options = hash_get_strip(e, "options", &tmp2); + if (plugin != NULL) { + csch_view_eng_append(view, e->name, plugin, options); + changed = 1; + } + else + rnd_message(RND_MSG_ERROR, "View conf error: missing plugin name for engine %s/%s in %s:%ld\n", nd->name, e->name, e->file_name, e->line); + } + else + rnd_message(RND_MSG_ERROR, "View conf error: plugin not a hash in engine %s/%s in %s:%ld\n", nd->name, e->name, e->file_name, e->line); + } + } + else + rnd_message(RND_MSG_ERROR, "View conf error: missing engines list in view %s in %s:%ld\n", nd->name, nd->file_name, nd->line); + gds_uninit(&tmp1); + gds_uninit(&tmp2); + } + + if (changed) + csch_views_changed(prj); +} + +void sch_rnd_prj_conf2prj(csch_project_t *prj) +{ + rnd_conflist_t *lst = (rnd_conflist_t *)&conf_core.compile.views; + rnd_conf_listitem_t *ci; + + csch_view_remove_all(prj); + + /* fill in view list from current conf */ + for(ci = rnd_conflist_first(lst); ci != NULL; ci = rnd_conflist_next(ci)) + prj_append_view_cfg(prj, ci); + + prj->num_root_sheets = rnd_conflist_length(&conf_core.prj.root_sheets); + prj->num_aux_sheets = rnd_conflist_length(&conf_core.prj.aux_sheets); +} + +void sch_rnd_prj_postproc(csch_project_t *prj) +{ + sch_rnd_prj_conf2prj(prj); + prj->curr = -1; + csch_view_activate(prj, 0); +} + +void sch_rnd_prj_regen(csch_project_t *prj) +{ + csch_project_clean_views(prj); + sch_rnd_prj_conf2prj(prj); +} + +static int sch_rnd_project_create_file_(rnd_design_t *dsg, const char *pname) +{ + FILE *f; + + f = rnd_fopen(dsg, pname, "w"); + if (f == NULL) { + rnd_message(RND_MSG_ERROR, "Failed to create project file:\n%s\n", pname); + return -1; + } + fclose(f); + return 0; +} + +int sch_rnd_project_view_lib2lht(csch_view_t *view) +{ + lht_node_t *nr, *nv, *nviews = rnd_conf_lht_get_at(RND_CFR_PROJECT, "compile/views", 1); + + for(nv = nviews->data.list.first; nv != NULL; nv = nv->next) { + if ((nv->type == LHT_HASH) && (strcmp(nv->name, view->fgw_ctx.name) == 0)) { + /* replace existing */ + nr = csch_view2lht_in(nv, view); + return (nr == NULL) ? -1 : 0; + } + } + + /* view not found, create new and append */ + nv = csch_view2lht(view); + if (nv == NULL) + return -1; + + lht_dom_list_append(nviews, nv); + return 0; +} + +static int project_create_postproc(csch_project_t *prj, const char *apname, int load, int copy_views) +{ + if (load) + rnd_conf_load_as(RND_CFR_PROJECT, apname, 0); + + rnd_conf_lht_get_first(RND_CFR_PROJECT, 1); + + if (copy_views) { /* copy all existing views into the new project file */ + long n; + lht_node_t *nnewv, *nviews = rnd_conf_lht_get_at(RND_CFR_PROJECT, "compile/views", 1); + for(n = 0; n < prj->views.used; n++) { + csch_view_t *view = prj->views.array[n]; + nnewv = csch_view2lht(view); + if (nnewv != NULL) + lht_dom_list_append(nviews, nnewv); + } + } + return 0; +} + +extern lht_doc_t *rnd_conf_main_root[RND_CFR_max_alloc]; + +int sch_rnd_project_create_file_for_sheet_gui(csch_sheet_t *sheet) +{ + gds_t tmp = {0}; + const char *pname; + char *apname; + int go_for_it; + csch_project_t *prj = (csch_project_t *)sheet->hidlib.project; + + rnd_conf_get_project_conf_name(NULL, sheet->hidlib.loadname, &pname); + if (*pname == '<') { + rnd_message(RND_MSG_ERROR, "Failed to generate a project file name: %s;\nPlease save the sheet first!\n", pname); + return -1; + } + + /* do not create it if it's already there */ + if (rnd_file_readable(&sheet->hidlib, pname)) + return 0; + + gds_append_str(&tmp, "Do you want to create a project file "); + gds_append_str(&tmp, pname); + gds_append(&tmp, '?'); + + go_for_it = rnd_hid_message_box(&sheet->hidlib, "question", "Creating project file", tmp.array, "yes", 1, "no/cancel", 0, NULL); + if (!go_for_it) + return -1; + + apname = rnd_strdup(pname); + if (rnd_conf_lht_get_first(RND_CFR_PROJECT, 0) == NULL) + lht_dom_loc_newfile(rnd_conf_main_root[RND_CFR_PROJECT], apname); + + /* create a new project file */ + if (sch_rnd_project_create_file_(&sheet->hidlib, pname) != 0) { + free(apname); + return -1; + } + + if (project_create_postproc(prj, apname, 0, 1) != 0) { + free(apname); + return -1; + } + + rnd_conf_makedirty(RND_CFR_PROJECT); /* to force save */ + if (rnd_conf_save_file(&sheet->hidlib, apname, sheet->hidlib.fullpath, RND_CFR_PROJECT, NULL) != 0) { + rnd_message(RND_MSG_ERROR, "Failed to create project file (#2):\n%s\n", pname); + return -1; + } + + free(apname); + prj->hdr.fullpath = rnd_strdup(pname); + prj->hdr.loadname = rnd_strdup(pname); + prj->dummy = 0; + + return 0; +} + +int sch_rnd_project_create_file(rnd_design_t *dsg, const char *pname, csch_project_t **prj_out) +{ + csch_sheet_t *orig = NULL, *first = NULL; + csch_project_t *prj; + char *realp; + long n; + + if (prj_out != NULL) + *prj_out = NULL; + + if (sch_rnd_project_create_file_(dsg, pname) != 0) + return -1; + + realp = rnd_lrealpath(pname); + if (realp == NULL) + return -1; + + prj = htsp_get(&rnd_projects, realp); + if (prj == NULL) { + prj = sch_rnd_multi_load_project(NULL, realp); + free(prj->hdr.fullpath); + prj->hdr.fullpath = realp; /* do not free realp */ + if (prj_out != NULL) + *prj_out = prj; + return (prj == NULL) ? -1 : 0; + } + + + if (prj->hdr.designs.used == 0) + sch_rnd_multi_new_empty(realp); + + free(prj->hdr.fullpath); + prj->hdr.fullpath = realp; + + for(n = 0; n < prj->hdr.designs.used; n++) { + csch_sheet_t *sh = prj->hdr.designs.array[n]; + csch_sheet_t *old = sch_rnd_multi_switch_to(sh); + project_create_postproc(prj, realp, 1, (orig == NULL)); + if (orig == NULL) { + orig = old; + first = sh; + } + } + + if (orig != NULL) { + /* get sheetsel updated */ + rnd_event(&first->hidlib, RND_EVENT_DESIGN_FN_CHANGED, NULL); + + sch_rnd_multi_switch_to(orig); + } + + if (prj_out != NULL) + *prj_out = prj; + + /* do not free realp, it's owhed by prj now */ + return 0; +} + + + +int sch_rnd_project_append_view(csch_sheet_t *sheet, const char *view_name, int silent) +{ + lht_node_t *nnewv, *nengs, *nviews = rnd_conf_lht_get_at(RND_CFR_PROJECT, "compile/views", 1); + csch_project_t *prj = (csch_project_t *)sheet->hidlib.project; + + if (nviews == NULL) { + if (!silent) + rnd_message(RND_MSG_ERROR, "Failed to find or create the compile/views in the project config tree\n"); + return -1; + } + nnewv = lht_dom_node_alloc(LHT_HASH, view_name); + lht_dom_list_append(nviews, nnewv); + nengs = lht_dom_node_alloc(LHT_LIST, "engines"); + lht_dom_hash_put(nnewv, nengs); + rnd_conf_makedirty(RND_CFR_PROJECT); + rnd_conf_merge_all("compile/views"); + sch_rnd_prj_regen(prj); + csch_views_changed(prj); + return 0; +} + +int sch_rnd_project_del_view(csch_sheet_t *sheet, long idx, int silent) +{ + lht_node_t *nviews = rnd_conf_lht_get_at(RND_CFR_PROJECT, "compile/views", 0); + csch_project_t *prj = (csch_project_t *)sheet->hidlib.project; + + if (nviews == NULL) { + if (!silent) + rnd_message(RND_MSG_ERROR, "Failed to find or create the compile/views in the project config tree\n"); + return -1; + } + + if (lht_tree_list_del_nth(nviews, idx) != 0) + return -1; + + rnd_conf_makedirty(RND_CFR_PROJECT); /* to force save */ + rnd_conf_merge_all("compile/views"); + sch_rnd_prj_regen(prj); + return 0; +} + +void sch_rnd_project_views_save(csch_sheet_t *sheet) +{ + rnd_conf_merge_all("compile/views"); + rnd_conf_save_file(&sheet->hidlib, sheet->hidlib.project->fullpath, NULL, RND_CFR_PROJECT, NULL); +} + +static rnd_conf_hid_callbacks_t cbs; +static rnd_conf_hid_id_t cfgid; +static rnd_conf_native_t *nat_views = NULL; + +#define PATH_VIEWS "compile/views" + +static void prj_conf_hlist(rnd_conf_native_t *cfg, rnd_conf_listitem_t *i, void *user_data) +{ + csch_sheet_t *sheet = (csch_sheet_t *)rnd_multi_get_current(); + csch_project_t *prj; + + if (nat_views == NULL) { + if (strncmp(cfg->hash_path, PATH_VIEWS, strlen(PATH_VIEWS)) == 0) { + nat_views = cfg; + nat_views->shared->gui_edit_act = "EditConfCompileViews"; + } + } + + if ((cfg != nat_views) || (sheet == NULL)) + return; + + prj = (csch_project_t *)sheet->hidlib.project; + if (cfg->rnd_conf_rev > prj->view_conf_rev) { + prj->view_conf_rev = cfg->rnd_conf_rev; + csch_project_clean_views(prj); + } + + prj_append_view_cfg(prj, i); +} + +void sch_rnd_prj_post_remove_sheet(rnd_project_t *prj) +{ + const char *ldn; + rnd_project_t *old; + + if (prj->designs.used != 0) + return; + + ldn = (prj->loadname == NULL) ? "" : prj->loadname; + rnd_message(RND_MSG_INFO, "Unloading project '%s' as no sheet loaded for it anymore\n", ldn); + + ldn = (prj->fullpath == NULL) ? "" : prj->fullpath; + old = htsp_pop(&rnd_projects, ldn); + if (old != NULL) { + rnd_project_uninit(old); + free(old); + } +} + +int sch_rnd_prj_remove_sheet(csch_sheet_t *sheet) +{ + rnd_project_t *prj = sheet->hidlib.project; + int res = rnd_project_remove_design(prj, &sheet->hidlib); + sch_rnd_prj_post_remove_sheet(prj); + return res; +} + +void sch_rnd_project_init(void) +{ + cbs.new_hlist_item_post = prj_conf_hlist; + cfgid = rnd_conf_hid_reg(prj_cookie, &cbs); +} + +void sch_rnd_project_uninit(void) +{ + rnd_conf_hid_unreg(prj_cookie); +} Index: tags/1.0.5/src/sch-rnd/project.h =================================================================== --- tags/1.0.5/src/sch-rnd/project.h (nonexistent) +++ tags/1.0.5/src/sch-rnd/project.h (revision 10414) @@ -0,0 +1,31 @@ +void sch_rnd_prj_postproc(csch_project_t *prj); + +/* Checks the project file for the given sheet. If it exists, returns 0. + Else asks the user and creates the project file for sheet; returns 0 + if created, -1 if not (cancel or error; errors are reported in + the message log) */ +int sch_rnd_project_create_file_for_sheet_gui(csch_sheet_t *sheet); + +/* Create project file by project file name; update the config of + all sheets already open for the project and existing dummy project, if any */ +int sch_rnd_project_create_file(rnd_design_t *dsg, const char *pname, csch_project_t **prj_out); + + +/* Create a new empty view and append it in the current project config; + creates project file if needed */ +int sch_rnd_project_append_view(csch_sheet_t *sheet, const char *view_name, int silent); + +/* Remove the idxth view from the current project config; + creates project file if needed */ +int sch_rnd_project_del_view(csch_sheet_t *sheet, long idx, int silent); + +/* Merge the engine list and save the project file */ +void sch_rnd_project_views_save(csch_sheet_t *sheet); + +/* Convert view data (engines) into project role config in the backing lihata + doc of the currently active config tree */ +int sch_rnd_project_view_lib2lht(csch_view_t *view); + +/* Remove sheet from its current project; remove project if it became empty. + Return number of sheet removals (should be 0 or 1 normally). */ +int sch_rnd_prj_remove_sheet(csch_sheet_t *sheet); Index: tags/1.0.5/src/sch-rnd/sch-rnd-conf.lht =================================================================== --- tags/1.0.5/src/sch-rnd/sch-rnd-conf.lht (nonexistent) +++ tags/1.0.5/src/sch-rnd/sch-rnd-conf.lht (revision 10414) @@ -0,0 +1,179 @@ +li:sch-rnd-conf-v1 { + ha:overwrite { + ha:rc { + li:preferred_gui = { gtk2_gl; gtk2_gdk; gtk4_gl; lesstif; batch } + hid_fallback = 1 + menu_file = {default} + li:library_search_paths = { + ?../../library/symbol + ?$(rc.path.design)/symbol + ?~/.sch-rnd/symbol/ + $(rc.path.share)/symbol + } + li:hlibrary_search_paths = { + ?../../library/hlibrary + ?$(rc.path.design)/hlibrary + ?~/.sch-rnd/hlibrary/ + $(rc.path.share)/hlibrary + } + li:default_sheet_file = { + {./default-sheet.lht} + {$(rc.path.share)/default-sheet.lht} + } + li:font_dirs = { + {../../font} + {$(rc.path.share)/font} + } + emergency_name = {SCH.%ld-%ld.save} + backup_interval = 60 + backup_name = {%F.%P.backup} + file_changed_interval = 2 + ha:debug { + draw_text_xform = 0 + draw_arc_bbox = 0 + } + } + ha:editor { + click_time = 200 + edit_time = 800 + autocomp = 1 + autocomp_time = 1500 + draw_grid = 1 + buffer_number = 0 + lock_floaters = 0 + only_floaters = 0 + grid_unit = mm + # default "pin grid" as per sch-rnd convention + grid = 4 k + li:grids = { + # our grid coords are: k is the cschem 1000 unit (needs a *1.024 for librnd screen conv) + {1 k}; {2 k}; {4 k}; {8 k}; {16 k}; + } + grids_idx = 2 + + line_refraction=0 + line_cont=1 + paste_to_local_lib=0 + rubber_band_mode=0 + rubber_band_ortho=0 + ha:style { + li:tool_circle_stroke { sheet-decor; decor;} + li:tool_line_stroke { sheet-decor; decor;} + li:tool_text_stroke { sheet-decor; decor;} + li:tool_wire_stroke { wire; } + + li:tool_rect_stroke { sheet-decor; decor;} + tool_rect_has_stroke {true} + li:tool_rect_fill { sheet-decor-fill; } + tool_rect_has_fill {true} + } + ha:selection { + disable_negative = 0 + symmetric_negative = 0 + } + ha:default_font { + family=sans + style=oblique + } + ha:local_grid { + enable = 0 + radius = 16 + } + ha:global_grid { + sparse = 0 + min_dist_px = 4 + } + } + ha:appearance { + layer_alpha = 1 + ha:loglevels { + debug_tag = {} + debug_popup = false + info_tag = {} + info_popup = false + warning_tag = {} + warning_popup = true + error_tag = {} + error_popup = true + } + ha:color { + background = {#e5e5e5} + cross = {#00cdcd} + off_limit = {#aaaaaa} + grid = {#ff0000} + attached = {#ff0000} + hilight_stroke = {#FF0000} + selected_stroke = {#00cccc} + selected_fill = {#99ffff} + connection_good = {#00ff00} + connection_bad = {#ff0000} + symbol_meta_embed = {#ff0000} + symbol_meta_loclib = {#990000} + non_graphical_background = {#000000} + non_graphical_text = {#00AA00} + } + } + + ha:compile { + multiport_net_merge = 0 + ha:hierarchic { + net_allow_rename = 1 + net_rename_prefer_top = 1 + } + li:views { + ha:pcb { + li:engines { + ha:std_forge { plugin=std_forge } + ha:std_cschem { plugin=std_cschem } + ha:std_devmap { plugin=std_devmap } + ha:funcmap { plugin=funcmap } + ha:target_pcb { plugin=target_pcb } + } + } + ha:sim_ngspice { + li:engines { + ha:std_forge { plugin=std_forge } + ha:std_cschem { plugin=std_cschem } + ha:std_devmap { plugin=std_devmap } + ha:funcmap { plugin=funcmap } + ha:target_sim_ngspice { plugin=target_sim_ngspice } + } + } + ha:spice_raw { + li:engines { + ha:std_forge { plugin=std_forge } + ha:std_cschem { plugin=std_cschem } + ha:std_devmap { plugin=std_devmap } + ha:funcmap { plugin=funcmap } + ha:target_spice { plugin=target_spice } + } + } + ha:raw { + li:engines { + ha:std_forge { plugin=std_forge } + ha:std_cschem { plugin=std_cschem } + ha:target_none { plugin=target_none } + } + } + } + } + + ha:plugins { + ha:lib_hid_common { + ha:cli_history { + file = {$(rc.path.home)/.sch-rnd/cli_history} + slots = 64 + } + } + ha:hid_gtk { + ha:dialog { + transient_modal = 1 + transient_modeless = 1 + auto_present = 0 + } + } + } # plugins + + } +} + Index: tags/1.0.5/src/sch-rnd/sch-rnd.c =================================================================== --- tags/1.0.5/src/sch-rnd/sch-rnd.c (nonexistent) +++ tags/1.0.5/src/sch-rnd/sch-rnd.c (revision 10414) @@ -0,0 +1,492 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - sch-rnd (executable) + * Copyright (C) 2019..2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include /* Seed for srand() */ + +/* hidlib headers */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "conf_core.h" +#include "crosshair.h" +#include "build_run.h" +#include "sheet.h" +#include "draw.h" +#include "font.h" +#include "emergency.h" +#include "project.h" +#include "multi.h" +#include "plug_io_act.h" +#include "export.h" + +csch_chdr_t *csch_obj_clicked = NULL; + +#define pup_buildins sch_rnd_buildins +#include "buildin.c" +#undef pup_buildins + +static const char *EXPERIMENTAL = NULL; + +static const char *menu_file_paths[8]; +static const char *menu_name_fmt = "menu-%s.lht"; + +#define CONF_USER_DIR "~/" DOT_SCH_RND + +static rnd_conf_ignore_t sch_rnd_conf_ignores[] = { + {"stance/opt", 10, 1, NULL}, /* do not warn: dynamically created by the user */ + {NULL, 0, 0, NULL} +}; + +static int sch_rnd_human_coord(rnd_coord_t coord, double *out_val, const char **out_suffix) +{ + *out_val = P2C(coord); + if (*out_val > 100) { + *out_val = *out_val / 1000.0; + *out_suffix = "k"; + } + else + *out_suffix = ""; + + return 1; +} + +static char *main_path_init(char *exec_prefix) +{ + char *tmp; + int se = 0; + + /* export the most important paths and data for child processes (e.g. parametric footprints) */ + tmp = rnd_concat(SCHSHAREDIR, "/footprint", NULL); + se |= rnd_setenv("SCH_RND_VERSION", SCH_VERSION, 1); + se |= rnd_setenv("SCH_RND_REVISION", SCH_REVISION, 1); + se |= rnd_setenv("SCH_RND_PCBLIB", tmp, 1); /* for backward compatibility - do not use */ + se |= rnd_setenv("SCH_RND_FOOTPRINT", tmp, 1); + se |= rnd_setenv("SCH_RND_SHARE", SCHSHAREDIR, 1); + se |= rnd_setenv("SCH_RND_LIB", SCHLIBDIR, 1); + se |= rnd_setenv("SCH_RND_EXEC_PREFIX", exec_prefix, 1); + free(tmp); + + if (se != 0) + fprintf(stderr, "WARNING: setenv() failed - external commands such as parametric footprints may not have a proper environment\n"); + + menu_file_paths[0] = "./"; + menu_file_paths[1] = "~/" DOT_SCH_RND "/"; + menu_file_paths[2] = rnd_concat(SCHCONFDIR, "/", NULL); + menu_file_paths[3] = NULL; + assert((sizeof(menu_file_paths)/sizeof(menu_file_paths[0])) > 3); + + rnd_conf_postproc(); /* get ~ (home dir) set */ + + rnd_app.conf_sysdir_path = SCHSHAREDIR; + rnd_app.conf_sys_path = SCHCONFDIR "/sch-rnd-conf.lht"; + rnd_app.lib_dir = SCHLIBDIR; + rnd_app.conf_userdir_path = CONF_USER_DIR; + rnd_app.conf_user_path = rnd_concat(CONF_USER_DIR, "/conf_core.lht", NULL); + rnd_app.conf_ignores = sch_rnd_conf_ignores; + rnd_app.human_coord = sch_rnd_human_coord; + + return exec_prefix; +} + +static void main_path_uninit(void) +{ + /* const for all other parts of the code, but we had to concat (alloc) it above */ + free((char *)menu_file_paths[2]); + free((char *)rnd_app.conf_user_path); +} + + +/* initialize signal and error handlers */ +static void main_sighand_init(void) +{ +#ifdef RND_HAVE_SIGHUP + signal(SIGHUP, sch_rnd_catch_signal); +#endif +#ifdef RND_HAVE_SIGQUIT + signal(SIGQUIT, sch_rnd_catch_signal); +#endif +#ifdef RND_HAVE_SIGTERM + signal(SIGTERM, sch_rnd_catch_signal); +#endif +#ifdef RND_HAVE_SIGINT + signal(SIGINT, sch_rnd_catch_signal); +#endif + +#ifdef NDEBUG +/* so that we get a core dump on segfault in debug mode */ +# ifdef RND_HAVE_SIGABRT + signal(SIGABRT, sch_rnd_catch_signal); +# endif +# ifdef RND_HAVE_SIGSEGV + signal(SIGSEGV, sch_rnd_catch_signal); +# endif +#endif + +/* calling external program by popen() may cause a PIPE signal, so we ignore it */ +#ifdef RND_HAVE_SIGPIPE + signal(SIGPIPE, SIG_IGN); +#endif +} + + +static void gui_support_plugins(int load) +{ + static int loaded = 0; + static pup_plugin_t *puphand; + + if (load && !loaded) { + static const char *plugin_name = "sch_dialogs"; + int state = 0; + loaded = 1; + rnd_message(RND_MSG_DEBUG, "Loading GUI support plugin: '%s'\n", plugin_name); + puphand = pup_load(&rnd_pup, (const char **)rnd_pup_paths, plugin_name, 0, &state); + if (puphand == NULL) + rnd_message(RND_MSG_ERROR, "Error: failed to load GUI support plugin '%s'\n-> expect missing widgets and dialog boxes\n", plugin_name); + } + if (!load && loaded && (puphand != NULL)) { + pup_unload(&rnd_pup, puphand, NULL); + loaded = 0; + puphand = NULL; + } +} + +/* action table number of columns for a single action */ +const char *sch_rnd_action_args[] = { +/*short, -long, action, help, hint-on-error */ + NULL, "-show-actions", "PrintActions()", "Print all available actions (human readable) and exit", NULL, + NULL, "-dump-actions", "DumpActions()", "Print all available actions (script readable) and exit", NULL, + NULL, "-dump-plugins", "DumpPlugins()", "Print all available plugins (script readable) and exit", NULL, + NULL, "-dump-plugindirs", "DumpPluginDirs()", "Print directories plugins might be loaded from and exit", NULL, + NULL, "-dump-oflags", "DumpObjFlags()", "Print object flags and exit", NULL, + NULL, "-show-paths", "PrintPaths()", "Print all configured paths and exit", NULL, + "V", "-version", "PrintVersion()", "Print version info and exit", NULL, + "V", "-dump-version", "DumpVersion()", "Print version info in script readable format and exit", NULL, + NULL, "-copyright", "PrintCopyright()", "Print copyright and exit", NULL, + NULL, NULL, NULL, NULL, NULL /* terminator */ +}; + +#include "funchash_core.h" +#define action_entry(x) { #x, F_ ## x}, +static rnd_funchash_table_t Functions[] = { +#include "funchash_core_list.h" + {"F_END", F_END} +}; + +static void gui_act_init(void) +{ + +} + +extern void sch_rnd_main_act_init2(void); +extern void sch_rnd_file_act_init2(void); +extern void sch_rnd_font_act_init2(void); +extern void sch_rnd_select_act_init2(void); +extern void sch_rnd_draw_init2(void); +extern void sch_rnd_buffer_init2(void); +extern void sch_rnd_sheet_init2(void); +extern void sch_rnd_project_init(void); + +/*extern void rnd_main_act_init2(void);*/ + +/* call before conf init */ +static void sch_rnd_csch_init() +{ + csch_init(); + sch_rnd_multi_init(); + sch_rnd_project_init(); +} + +/* call after conf init */ +static void sch_rnd_main_init(void) +{ + csch_init_actions(); + sch_rnd_main_act_init2(); + sch_rnd_sheet_init2(); + sch_rnd_file_act_init2(); + sch_rnd_font_act_init2(); + sch_rnd_select_act_init2(); + sch_rnd_font_init2(); + sch_rnd_draw_init2(); + sch_rnd_buffer_init2(); +/* rnd_main_act_init2();*/ +} + +#define LIBCSCHEM_CFG_BIND(csch_cfg, native) \ + do { \ + if (sizeof(*csch_cfg) == sizeof(native)) \ + csch_cfg = &native; \ + else \ + rnd_message(RND_MSG_ERROR, "Can not enable " #native " on this arch. Please report this bug.\n"); \ + } while(0) + +/* Bind conf_core natives to libcschem config API; this is needed because + libcschem can't access conf_core directly as it can't depend on app code */ +static void libcschem_cfg_init(void) +{ + LIBCSCHEM_CFG_BIND(csch_cfg_multiport_net_merge, conf_core.compile.multiport_net_merge); + LIBCSCHEM_CFG_BIND(csch_cfg_hier_net_allow_rename, conf_core.compile.hierarchic.net_allow_rename); + LIBCSCHEM_CFG_BIND(csch_cfg_hier_net_rename_prefer_top, conf_core.compile.hierarchic.net_rename_prefer_top); + csch_app_load_sheet_cb = sch_rnd_app_load_sheet; +} + +extern void sch_rnd_draw_uninit(void); +extern void sch_rnd_buffer_uninit(void); +extern void sch_rnd_sheet_uninit(void); +extern void sch_rnd_project_uninit(void); + +void sch_rnd_main_uninit(void) +{ + TODO("librnd4.3: can't enable this because librnd sefaults on exit when it prints a log message and the gui is already uninited; fixed inlibrnd 4.3"); +/* rnd_tool_uninit();*/ + sch_rnd_multi_uninit(); + rnd_funchash_uninit(); + csch_plug_io_act_uninit(); + csch_uninit(); + sch_rnd_draw_uninit(); + sch_rnd_font_uninit(); + sch_rnd_buffer_uninit(); + sch_rnd_sheet_uninit(); + sch_rnd_project_uninit(); + gui_support_plugins(0); + rnd_hidlib_uninit(); /* plugin unload */ + main_path_uninit(); + fgw_atexit(); + conf_core_uninit(); + rnd_log_uninit(); + csch_uninit_last(); +} + +extern const char *rnd_conf_internal; +extern const char *rnd_hidlib_default_embedded_menu; + +int main(int argc, char *argv[]) +{ + int n, res = 0; + const char *fmt = NULL, *first_fn = NULL; + char *exec_prefix; + rnd_main_args_t ga; + csch_sheet_t *first_sheet = NULL; + sch_rnd_export_appspec_t appspec = {0}; + + srand(time(NULL)); /* Set seed for rand() */ + + rnd_app.package = "sch-rnd"; + rnd_app.version = SCH_VERSION; + rnd_app.url = "http://www.repo.hu/projects/sch-rnd"; + + rnd_app.menu_file_paths = menu_file_paths; + rnd_app.menu_name_fmt = menu_name_fmt; + rnd_app.default_embedded_menu = rnd_hidlib_default_embedded_menu; + + rnd_app.conf_core_postproc = sch_rnd_conf_core_postproc; + rnd_app.conf_userdir_path = CONF_USER_DIR; + rnd_app.conf_user_path = CONF_USER_DIR "/sch-rnd-conf.lht"; + rnd_app.conf_internal = rnd_conf_internal; + rnd_app.dot_dir = DOT_SCH_RND; + + rnd_app.crosshair_move_to = sch_rnd_hidlib_crosshair_move_to; + rnd_app.draw_attached = sch_rnd_draw_attached; + rnd_app.expose_main = sch_rnd_expose_main; + rnd_app.expose_preview = sch_rnd_expose_preview; + rnd_app.conf_dont_merge_node = sch_rnd_conf_dont_merge_node; + rnd_app.multi_design = 1; + + rnd_printf_app_format = csch_printf_app_format; + + rnd_fix_locale_and_env(); + exec_prefix = rnd_exec_prefix(argv[0], BINDIR, BINDIR_TO_EXECPREFIX); + main_path_init(exec_prefix); + sch_rnd_csch_init(); + + rnd_main_args_init(&ga, argc, sch_rnd_action_args); + rnd_hidlib_init1(conf_core_init, exec_prefix); + free(exec_prefix); + + csch_event_init_app(); + for(n = 1; n < argc; n++) + n += rnd_main_args_add(&ga, argv[n], argv[n+1]); + + rnd_hidlib_init2(pup_buildins, sch_rnd_buildins); + + csch_init_units(); + gui_act_init(); + csch_plug_io_act_init(); + sch_rnd_main_init(); + rnd_conf_set(RND_CFR_CLI, "editor/view/flip_y", 0, "1", RND_POL_OVERWRITE); + + libcschem_cfg_init(); + + rnd_funchash_set_table(Functions, RND_ENTRIES(Functions), NULL); + + /* Would be called from signal handlers too, using exit() */ + atexit(sch_rnd_emergency_save); + + + rnd_hidlib_init3_auto(); + + if (rnd_main_args_setup1(&ga) != 0) { + sch_rnd_main_uninit(); + rnd_main_args_uninit(&ga); + exit(1); + } + +/* Initialize actions only when the gui is already known so only the right + one is registered (there can be only one GUI). */ +TODO("action list"); +/*#include "generated_lists.h"*/ + + if (rnd_main_args_setup2(&ga, &res) != 0) { + sch_rnd_main_uninit(); + rnd_main_args_uninit(&ga); + exit(res); + } + + for(n = 0; ga.hid_argc > 0; n++, ga.hid_argc--) { + const char *fn = ga.hid_argv[n]; + csch_sheet_t *sheet; + int is_project = 0; + + sheet = sch_rnd_multi_load(fn, fmt, &is_project); + if ((first_fn == NULL) && !is_project) + first_fn = fn; + + /* check if failed to load the sheet */ + if (sheet == NULL) { + if (rnd_main_exporting) { + rnd_message(RND_MSG_ERROR, "Can not load file '%s' (specified on command line) for exporting or printing\n", fn); + rnd_log_print_uninit_errs("Export load error"); + exit(1); + } + else if (!sch_rnd_is_fn_project_file(fn)) { + sheet = sch_rnd_multi_new_empty(fn); + rnd_message(RND_MSG_INFO, "Creating new empty sheet for non-existing file '%s' (specified on command line)\n", fn); + if (sheet == NULL) { + rnd_log_print_uninit_errs("Sheet creation error"); + fprintf(stderr, "Failed to create new sheet (by loading the default sheet), exiting\n"); + sch_rnd_main_uninit(); + rnd_main_args_uninit(&ga); + exit(1); + } + } + else { + rnd_log_print_uninit_errs("Project load error"); + fprintf(stderr, "Failed to load project '%s', exiting\n", fn); + sch_rnd_main_uninit(); + rnd_main_args_uninit(&ga); + exit(1); + } + } + + + if (first_sheet == NULL) + first_sheet = sheet; + else + appspec.exp_prj = 1; + if (is_project) + appspec.exp_prj = 1; + } + + main_sighand_init(); + + /* switch to the first sheet for export so that the project config is applied */ + if (rnd_main_exporting) + sch_rnd_multi_switch_to_initial(first_sheet); + + if (rnd_main_exported(&ga, &first_sheet->hidlib, 0, &appspec)) { + rnd_log_print_uninit_errs("Export finished"); + sch_rnd_sheet_free_all(); + sch_rnd_main_uninit(); + rnd_main_args_uninit(&ga); + exit(0); + } + + /* started with no sheet, create an unknown */ + if (first_sheet == NULL) { + first_sheet = sch_rnd_multi_new_empty(NULL); + if (first_sheet == NULL) { + fprintf(stderr, "Failed to create new sheet (by loading the default sheet)\n"); + sch_rnd_main_uninit(); + rnd_main_args_uninit(&ga); + exit(1); + } + } + + sch_rnd_multi_switch_to_initial(first_sheet); + sch_rnd_crosshair_gui_init(); + + + sch_rnd_enable_autosave(); + + /* main loop */ + if (RND_HAVE_GUI_ATTR_DLG) + gui_support_plugins(1); + if (EXPERIMENTAL != NULL) { + rnd_message(RND_MSG_ERROR, "******************************** IMPORTANT ********************************\n"); + rnd_message(RND_MSG_ERROR, "This revision of sch-rnd is experimental, unstable, do NOT attempt to use\n"); + rnd_message(RND_MSG_ERROR, "it for production. The reason for this state is:\n"); + rnd_message(RND_MSG_ERROR, "%s\n", EXPERIMENTAL); + rnd_message(RND_MSG_ERROR, "******************************** IMPORTANT ********************************\n"); + } + + rnd_mainloop_interactive(&ga, &first_sheet->hidlib); + + sch_rnd_crosshair_gui_uninit(); + + sch_rnd_main_uninit(); + rnd_main_args_uninit(&ga); + return res; +} Index: tags/1.0.5/src/sch-rnd/sch-rnd.h =================================================================== --- tags/1.0.5/src/sch-rnd/sch-rnd.h (nonexistent) +++ tags/1.0.5/src/sch-rnd/sch-rnd.h (revision 10414) @@ -0,0 +1 @@ + Index: tags/1.0.5/src/sch-rnd/search.c =================================================================== --- tags/1.0.5/src/sch-rnd/search.c (nonexistent) +++ tags/1.0.5/src/sch-rnd/search.c (revision 10414) @@ -0,0 +1,121 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - sch-rnd (executable) + * Copyright (C) 2021 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include + +#include + +#include +#include +#include +#include +#include + +#include "conf_core.h" +#include "draw.h" + +#include "search.h" + +static int search_obj_at_filter(csch_search_obj_first_t *ctx, csch_chdr_t *obj) +{ + if ((obj->parent->role == CSCH_ROLE_WIRE_NET) && csch_obj_is_junction(obj)) + return 1; /* always ignore junctions */ + if (conf_core.editor.lock_floaters && obj->floater) + return 1; + if (conf_core.editor.only_floaters && !obj->floater) + return 1; + + return 0; +} + +/* also ignore selected */ +static int search_obj_at_filter_unsel(csch_search_obj_first_t *ctx, csch_chdr_t *obj) +{ + return (search_obj_at_filter(ctx, obj) || obj->selected); +} + + +/* Return the preferred visible object at x;y or NULL if nothing found */ +csch_chdr_t *sch_rnd_search_obj_at(csch_sheet_t *sheet, csch_coord_t x, csch_coord_t y, csch_coord_t radius) +{ + csch_rtree_box_t box; + + box.x1 = x - radius; box.y1 = y - radius; + box.x2 = x + radius; box.y2 = y + radius; + + return csch_search_first_gui_filter(sheet, &box, search_obj_at_filter); +} + +csch_chdr_t *sch_rnd_search_obj_at_unsel(csch_sheet_t *sheet, csch_coord_t x, csch_coord_t y, csch_coord_t radius) +{ + csch_rtree_box_t box; + + box.x1 = x - radius; box.y1 = y - radius; + box.x2 = x + radius; box.y2 = y + radius; + + return csch_search_first_gui_filter(sheet, &box, search_obj_at_filter_unsel); +} + +csch_chdr_t *sch_rnd_search_first_gui_inspect(csch_sheet_t *sheet, rnd_coord_t x, rnd_coord_t y) +{ + csch_rtree_box_t q; + q.x1 = P2C(x)-sch_rnd_slop; q.x2 = P2C(x)+sch_rnd_slop; + q.y1 = P2C(y)-sch_rnd_slop; q.y2 = P2C(y)+sch_rnd_slop; + + return csch_search_first_gui_inspect_filter(sheet, &q, search_obj_at_filter); +} + + +void sch_rnd_search_obj_box(csch_sheet_t *sheet, vtp0_t *res, csch_rtree_box_t *box) +{ + int n; + + for(n = 0; n < CSCH_DSPLY_max; n++) { + csch_chdr_t *o; + csch_rtree_it_t it; + + if (!csch_layer_vis[n]) + continue; + + /* prefere/find unlocked object first */ + for(o = csch_rtree_first(&it, &sheet->dsply[n], box); o != NULL; o = csch_rtree_next(&it)) { + if (csch_cobj_is_locked(o)) + continue; + if (csch_isc_with_box(o, box)) + vtp0_append(res, o); + } + + + /* fall back to parent of locked objects (e.g. clicked a group-locked + object, return group) */ + for(o = csch_rtree_first(&it, &sheet->dsply[n], box); o != NULL; o = csch_rtree_next(&it)) { + csch_chdr_t *cand = csch_cobj_first_unlocked(o); + if ((cand != NULL) && csch_isc_with_box(cand, box)) + vtp0_append(res, cand); + } + + } +} Index: tags/1.0.5/src/sch-rnd/search.h =================================================================== --- tags/1.0.5/src/sch-rnd/search.h (nonexistent) +++ tags/1.0.5/src/sch-rnd/search.h (revision 10414) @@ -0,0 +1,29 @@ +#ifndef SCH_RND_SEARCH_H +#define SCH_RND_SEARCH_H + +#include +#include +#include +#include + + +#define SCH_RND_SLOP_ 5 +#define sch_rnd_slop (SCH_RND_SLOP_ * P2C(rnd_pixel_slop)) + +/* Return the preferred visible object at x;y or NULL if nothing found; + the unsel version ignores selected objects */ +csch_chdr_t *sch_rnd_search_obj_at(csch_sheet_t *sheet, csch_coord_t x, csch_coord_t y, csch_coord_t radius); +csch_chdr_t *sch_rnd_search_obj_at_unsel(csch_sheet_t *sheet, csch_coord_t x, csch_coord_t y, csch_coord_t radius); + + +/* Return the preferred visible object at x;y for inspection (e.g. right click + popup) or NULL if nothing found */ +csch_chdr_t *sch_rnd_search_first_gui_inspect(csch_sheet_t *sheet, rnd_coord_t x, rnd_coord_t y); + + +/* Append all visible objects that has a bbox intersecting with box to res */ +void sch_rnd_search_obj_box(csch_sheet_t *sheet, vtp0_t *res, csch_rtree_box_t *box); + + + +#endif Index: tags/1.0.5/src/sch-rnd/select.c =================================================================== --- tags/1.0.5/src/sch-rnd/select.c (nonexistent) +++ tags/1.0.5/src/sch-rnd/select.c (revision 10414) @@ -0,0 +1,264 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - sch-rnd (executable) + * Copyright (C) 2021,2023 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include +#include +#include +#include +#include +#include +#include +#include + + +#include "conf_core.h" +#include "draw.h" +#include "search.h" + +#include "select.h" + +static void sel_chg_notify(csch_sheet_t *sheet) +{ + rnd_event(&sheet->hidlib, CSCH_EVENT_SELECTION_CHANGED, NULL); +} + +void sch_rnd_unselect_all(csch_sheet_t *sheet) +{ + int n; + + csch_cobj_redraw_freeze(sheet); + + for(n = 0; n < CSCH_DSPLY_max; n++) { + csch_chdr_t *o; + csch_rtree_it_t it; + for(o = csch_rtree_all_first(&it, &sheet->dsply[n]); o != NULL; o = csch_rtree_all_next(&it)) + csch_chdr_unselect_wp(o); + } + + sel_chg_notify(sheet); + csch_cobj_redraw_unfreeze(sheet); +} + +void sch_rnd_select_add_obj(csch_sheet_t *sheet, csch_chdr_t *obj, int meta, int no_par) +{ + csch_cgrp_t *par = obj->parent; + int par_atomic = 0, par_is_grp; + + par_is_grp = csch_obj_is_grp(&par->hdr); + + if (!meta) { /* some parents are atomic by default, even if not requested via meta */ + par_atomic = csch_grp_is_atomic(sheet, par); + if (par_atomic && no_par) + return; + } + + if (conf_core.editor.lock_floaters && obj->floater) + return; + if (conf_core.editor.only_floaters && !obj->floater) + return; + + if (par_is_grp && (meta || par_atomic) && !obj->floater) { + if ((par != &sheet->direct) && (par != &sheet->indirect)) + sch_rnd_select_add_obj(sheet, &par->hdr, 0, 0); + } + else + csch_cobj_select(sheet, obj); +} + +void sch_rnd_select_click(csch_sheet_t *sheet, csch_coord_t x, csch_coord_t y) +{ + csch_chdr_t *obj; + + if (rnd_gui->shift_is_pressed(rnd_gui)) + obj = sch_rnd_search_obj_at(sheet, x, y, sch_rnd_slop); /* for the shift+click unselect */ + else + obj = sch_rnd_search_obj_at_unsel(sheet, x, y, sch_rnd_slop); + + if (obj == NULL) { /* clicked away or clicked on selected */ + /* check for selected wire for second click */ + obj = sch_rnd_search_obj_at(sheet, x, y, sch_rnd_slop); + if ((obj != NULL) && (obj->parent->role == CSCH_ROLE_WIRE_NET)) { + sch_rnd_select_add_obj(sheet, obj, 1, 0); + return; + } + + if (!rnd_gui->shift_is_pressed(rnd_gui)) + sch_rnd_unselect_all(sheet); + return; + } + + if (csch_chdr_is_selected(obj)) { + if (rnd_gui->shift_is_pressed(rnd_gui)) + csch_chdr_unselect_wp(obj); + else + sch_rnd_select_add_obj(sheet, obj, 1, 0); + } + else { + if (!rnd_gui->shift_is_pressed(rnd_gui)) + sch_rnd_unselect_all(sheet); + sch_rnd_select_add_obj(sheet, obj, 0, 0); + } + sel_chg_notify(sheet); +} + + +void sch_rnd_select_box(csch_sheet_t *sheet, csch_coord_t x1, csch_coord_t y1, csch_coord_t x2, csch_coord_t y2) +{ + int neg = 0; + vtp0_t res = {0}; + csch_coord_t slop = sch_rnd_slop; + csch_rtree_box_t rbox; + long n; + + csch_cobj_redraw_freeze(sheet); + + if (!rnd_gui->shift_is_pressed(rnd_gui)) + sch_rnd_unselect_all(sheet); + + /* figure if selection is negative */ + if (!conf_core.editor.selection.disable_negative) { + int negx = x2 < x1, negy = y1 < y2; /* y is inverted on screen */ + + if (!conf_core.editor.selection.symmetric_negative) + neg = negy; + + neg |= negx; + } + + /* make the box canonical */ + if (x1 > x2) rnd_swap(csch_coord_t, x1, x2); + if (y1 > y2) rnd_swap(csch_coord_t, y1, y2); + + rbox.x1 = x1 - slop; rbox.y1 = y1 - slop; + rbox.x2 = x2 + slop; rbox.y2 = y2 + slop; + sch_rnd_search_obj_box(sheet, &res, &rbox); + + for(n = 0; n < res.used; n++) { + csch_chdr_t *o = res.array[n]; + + if (neg) { /* select anything that intersects */ + if (csch_isc_with_box(o, &rbox)) + sch_rnd_select_add_obj(sheet, o, 0, 0); + } + else { /* select anything that is fully within */ + if ((o->bbox.x1 >= rbox.x1) && (o->bbox.y1 >= rbox.y1) && (o->bbox.x2 <= rbox.x2) && (o->bbox.y2 <= rbox.y2)) + sch_rnd_select_add_obj(sheet, o, 0, 1); + } + } + +TODO("if not neg, do a search on group bboxes too - that's the way a positiv box would select any symbol"); + sel_chg_notify(sheet); + + vtp0_uninit(&res); + + csch_cobj_redraw_unfreeze(sheet); +} + + +void sch_rnd_select_invert_grp(csch_chdr_t *obj, int recursive) +{ + if (recursive) { + if (csch_obj_is_grp(obj)) { + csch_cgrp_t *grp = (csch_cgrp_t *)obj; + htip_entry_t *e; + + for(e = htip_first(&grp->id2obj); e != NULL; e = htip_next(&grp->id2obj, e)) + sch_rnd_select_invert_grp(e->value, recursive); + } + else + obj->selected = !obj->selected; + } + else { + if (obj->selected) + csch_cobj_unselect(obj->sheet, obj); + else + sch_rnd_select_add_obj(obj->sheet, obj, 0, 1); + } +} + +void sch_rnd_select_invert(csch_sheet_t *sheet) +{ + htip_entry_t *e; + + csch_cobj_redraw_freeze(sheet); + + for(e = htip_first(&sheet->direct.id2obj); e != NULL; e = htip_next(&sheet->direct.id2obj, e)) { + csch_chdr_t *obj = e->value; + + if (csch_obj_is_grp(obj)) { + csch_cgrp_t *grp = (csch_cgrp_t *)obj; + if (!csch_grp_is_atomic(sheet, grp)) { + sch_rnd_select_invert_grp(&grp->hdr, 1); + continue; + } + } + sch_rnd_select_invert_grp(obj, 0); + } + sel_chg_notify(sheet); + csch_cobj_redraw_unfreeze(sheet); +} + +static long grp_add_sel_bbox(csch_rtree_box_t *dst, csch_cgrp_t *grp) +{ + htip_entry_t *e; + long cnt = 0; + + for(e = htip_first(&grp->id2obj); e != NULL; e = htip_next(&grp->id2obj, e)) { + csch_chdr_t *obj = e->value; + if (obj->selected) { + cnt++; + csch_bbox_bump(dst, x, grp->bbox_flt.x1); + csch_bbox_bump(dst, x, grp->bbox_flt.x2); + csch_bbox_bump(dst, y, grp->bbox_flt.y1); + csch_bbox_bump(dst, y, grp->bbox_flt.y2); + } + if (csch_obj_is_grp(obj)) + cnt += grp_add_sel_bbox(dst, (csch_cgrp_t *)obj); + } + + return cnt; +} + +long sch_rnd_get_selection_bbox(csch_rtree_box_t *dst, csch_sheet_t *sheet) +{ + dst->x1 = dst->y1 = RND_MAX_COORD; + dst->x2 = dst->y2 = -RND_MAX_COORD; + + return grp_add_sel_bbox(dst, &sheet->direct); +} + +long sch_rnd_get_selection_bbox_gui(rnd_box_t *dst, csch_sheet_t *sheet) +{ + long res; + csch_rtree_box_t cb; + + res = sch_rnd_get_selection_bbox(&cb, sheet); + dst->X1 = C2P(cb.x1); + dst->Y1 = C2P(cb.y1); + dst->X2 = C2P(cb.x2); + dst->Y2 = C2P(cb.y2); + return res; +} Index: tags/1.0.5/src/sch-rnd/select.h =================================================================== --- tags/1.0.5/src/sch-rnd/select.h (nonexistent) +++ tags/1.0.5/src/sch-rnd/select.h (revision 10414) @@ -0,0 +1,23 @@ +#ifndef CSCH_SELECT_H +#define CSCH_SELECT_H + +#include +#include + +/* Select object clicked or select parent object (if already selected) or + unselect (if clicked away) */ +void sch_rnd_select_click(csch_sheet_t *sheet, csch_coord_t x, csch_coord_t y); + +void sch_rnd_select_box(csch_sheet_t *sheet, csch_coord_t x1, csch_coord_t y1, csch_coord_t x2, csch_coord_t y2); + + +void sch_rnd_unselect_all(csch_sheet_t *sheet); + +void sch_rnd_select_invert(csch_sheet_t *sheet); + +/* Compute bbox of selected objects on sheet; returns number of selected + objects considered (0 means no selection, negative means error). Fills + dst in with screen (rnd_coord_t) coordinates */ +long sch_rnd_get_selection_bbox_gui(rnd_box_t *dst, csch_sheet_t *sheet); + +#endif Index: tags/1.0.5/src/sch-rnd/select_act.c =================================================================== --- tags/1.0.5/src/sch-rnd/select_act.c (nonexistent) +++ tags/1.0.5/src/sch-rnd/select_act.c (revision 10414) @@ -0,0 +1,164 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - sch-rnd (executable) + * Copyright (C) 2022,2023 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "funchash_core.h" +#include "conf_core.h" +#include "select.h" + +static const char csch_acts_RemoveSelected[] = "RemoveSelected()"; +static const char csch_acth_RemoveSelected[] = "Remove all selected objects"; +static fgw_error_t csch_act_RemoveSelected(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + csch_sheet_t *sheet = CSCH_ACT_SHEET; + vtp0_t sel = {0}; + long n; + + uundo_freeze_serial(&sheet->undo); + + csch_wirenet_recalc_freeze(sheet); + + /* First remove top level (groups); this will remove some selected + group-part-objects as well */ + csch_search_all_selected(sheet, NULL, &sel, 0); + for(n = 0; n < sel.used; n++) + csch_op_remove(sheet, sel.array[n]); + sel.used = 0; + + csch_wirenet_recalc_unfreeze(sheet); + + /* Search again recursively; this will catch group-part objects that + were selected without parent group selection; remove only floaters */ + csch_search_all_selected(sheet, NULL, &sel, 1); + for(n = 0; n < sel.used; n++) { + csch_chdr_t *obj = sel.array[n]; + if (obj->floater) + csch_op_remove(sheet, obj); + } + vtp0_uninit(&sel); + + uundo_unfreeze_serial(&sheet->undo); + uundo_inc_serial(&sheet->undo); + + RND_ACT_IRES(0); + return 0; +} + +static const char csch_acts_Select[] = "Select([All|Invert])"; +static const char csch_acth_Select[] = "Select objects; all=all visible; invert=invert selection; default is all."; +static fgw_error_t csch_act_Select(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + int op = F_All; + + RND_ACT_MAY_CONVARG(1, FGW_KEYWORD, Select, op = fgw_keyword(&argv[1])); + + switch(op) { + case F_All: + sch_rnd_select_box(CSCH_ACT_SHEET, -CSCH_COORD_MAX, -CSCH_COORD_MAX, CSCH_COORD_MAX, CSCH_COORD_MAX); + break; + case F_Invert: + sch_rnd_select_invert(CSCH_ACT_SHEET); + break; + default: + rnd_message(RND_MSG_ERROR, "Invalid first arg for Select(); Syntax: %s\n", csch_acts_Select); + RND_ACT_IRES(-1); + return 0; + } + RND_ACT_IRES(0); + return 0; +} + +static const char csch_acts_UnSelect[] = "UnSelect([All|AllProject])"; +static const char csch_acth_UnSelect[] = "Unselect all objects. When first argument is omitted or is All, the action operates on the current sheet. When the first argument is AllProject, it operates on all sheets of the current project."; +static fgw_error_t csch_act_UnSelect(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + csch_sheet_t *sheet = CSCH_ACT_SHEET; + const char *op = "All"; + RND_ACT_MAY_CONVARG(1, FGW_STR, UnSelect, op = argv[1].val.str); + + if (rnd_strcasecmp(op, "allproject") == 0) { + rnd_project_t *prj = sheet->hidlib.project; + long n; + + for(n = 0; n < prj->designs.used; n++) + sch_rnd_unselect_all(prj->designs.array[n]); + } + else + sch_rnd_unselect_all(sheet); + RND_ACT_IRES(0); + return 0; +} + +static const char csch_acts_ToggleFloaters[] = "ToggleFloaters(only|lock)"; +static const char csch_acth_ToggleFloaters[] = "Toggle the setting for only-floaters ot lock-floaters"; +static fgw_error_t csch_act_ToggleFloaters(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + int op = F_All; + + RND_ACT_MAY_CONVARG(1, FGW_KEYWORD, Select, op = fgw_keyword(&argv[1])); + + switch(op) { + case F_Only: + rnd_conf_toggle_editor(only_floaters); + rnd_conf_set_editor(lock_floaters, 0); + break; + case F_Lock: + rnd_conf_toggle_editor(lock_floaters); + rnd_conf_set_editor(only_floaters, 0); + break; + default: + rnd_message(RND_MSG_ERROR, "Invalid first arg for ToggleFloaters(); Syntax: %s\n", csch_acts_Select); + RND_ACT_IRES(-1); + return 0; + } + + RND_ACT_IRES(0); + return 0; +} + +static rnd_action_t file_action_list[] = { + {"RemoveSelected", csch_act_RemoveSelected, csch_acth_RemoveSelected, csch_acts_RemoveSelected}, + {"Select", csch_act_Select, csch_acth_Select, csch_acts_Select}, + {"UnSelect", csch_act_UnSelect, csch_acth_UnSelect, csch_acts_UnSelect}, + {"ToggleFloaters", csch_act_ToggleFloaters, csch_acth_ToggleFloaters, csch_acts_ToggleFloaters} +}; + +void sch_rnd_select_act_init2(void) +{ + RND_REGISTER_ACTIONS(file_action_list, NULL); +} + Index: tags/1.0.5/src/sch-rnd/sheet.c =================================================================== --- tags/1.0.5/src/sch-rnd/sheet.c (nonexistent) +++ tags/1.0.5/src/sch-rnd/sheet.c (revision 10414) @@ -0,0 +1,234 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - sch-rnd (executable) + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +/* Sheet related app operations */ + +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "conf_core.h" +#include "util_sheet.h" +#include "draw.h" + +static const char sheet_cookie[] = "sch-rnd/sheet.c"; + +extern const char *default_sheet_internal; + +RND_INLINE rnd_coord_t sheet_attr_crd(csch_sheet_t *sheet, const char *key, rnd_coord_t defval) +{ + const char *s = csch_attrib_get_str(&sheet->direct.attr, key); + double val; + rnd_bool succ; + + if (s == NULL) + return defval; + + val = rnd_get_value_ex(s, NULL, NULL, NULL, "nm", &succ); + if (!succ) + return defval; + + return val; +} + +rnd_coord_t sch_rnd_sheet_attr_crd(csch_sheet_t *sheet, const char *key, rnd_coord_t defval) +{ + return sheet_attr_crd(sheet, key, defval); +} + +static void warn_size(csch_sheet_t *sheet, csch_coord_t c) +{ + if (sheet->warned_too_large) + return; + + if (c > P2C(RND_COORD_MAX)/2) { + rnd_message(RND_MSG_ERROR, "Sheet is too large. Please consider recompiling librnd with 64 bit coords.\n"); + sheet->warned_too_large = 1; + } +} + +void sch_rnd_sheet_warn_size(csch_sheet_t *sheet, csch_coord_t x1, csch_coord_t y1, csch_coord_t x2, csch_coord_t y2) +{ + if (sheet->warned_too_large) + return; + warn_size(sheet, x1); warn_size(sheet, y1); + warn_size(sheet, x2); warn_size(sheet, y2); +} + +void sch_rnd_sheet_recalc_bbox(csch_sheet_t *sheet) +{ + rnd_coord_t min_x = sheet_attr_crd(sheet, "drawing_min_width", 0); + rnd_coord_t min_y = sheet_attr_crd(sheet, "drawing_min_height", 0); + + csch_sheet_bbox_update(sheet); + + sheet->hidlib.dwg.X1 = C2P(sheet->bbox.x1); + sheet->hidlib.dwg.Y1 = C2P(sheet->bbox.y1); + sheet->hidlib.dwg.X2 = C2P(RND_MAX(min_x, sheet->bbox.x2)); + sheet->hidlib.dwg.Y2 = C2P(RND_MAX(min_y, sheet->bbox.y2)); + + sch_rnd_sheet_warn_size(sheet, sheet->bbox.x1, sheet->bbox.y1, RND_MAX(min_x, sheet->bbox.x2), RND_MAX(min_y, sheet->bbox.y2)); +} + +void sch_rnd_sheet_postproc(csch_sheet_t *sheet) +{ + sheet->hidlib.grid = rnd_conf.editor.grid; + + if (!sheet->non_graphical) + sch_rnd_sheet_recalc_bbox(sheet); + + if (sheet->hidlib.fullpath != NULL) { + sheet->design_dir = rnd_dirname(sheet->hidlib.fullpath); + rnd_conf_force_set_str(conf_core.rc.path.design, sheet->design_dir); + } + else { + sheet->design_dir = NULL; + rnd_conf_force_set_str(conf_core.rc.path.design, ""); + } + rnd_conf_ro("rc/path/design"); + + if (!sheet->non_graphical) { + /* This works from load only because the conf state is already set up for + the new sheet, even tho librnd's current sheet is not yet set */ + csch_lib_add_all(sheet, csch_lib_get_master("symbol", 1), &conf_core.rc.library_search_paths, 0); + csch_lib_add_all(sheet, csch_lib_get_master("hlibrary", 1), &conf_core.rc.hlibrary_search_paths, 0); + } + + if (sheet->is_symbol) + sch_rnd_reconf_for_symbol_as_sheet(); +} + +static csch_sheet_t *sch_rnd_sheet_new_(csch_project_t *prj, csch_sheet_t *dst_sheet, int emit_ev) +{ + csch_sheet_t *sheet = NULL; + int dsch = -1; + + rnd_hid_menu_merge_inhibit_inc(); + if (dst_sheet == NULL) + rnd_conf_list_foreach_path_first(NULL, dsch, &conf_core.rc.default_sheet_file, csch_project_load_sheet(prj, __path__, NULL, &sheet, 1, NULL)); + else + rnd_conf_list_foreach_path_first(NULL, dsch, &conf_core.rc.default_sheet_file, ((sheet = csch_load_sheet_io(NULL, dst_sheet, __path__, __path__, NULL, 0, NULL)) == NULL)); + rnd_hid_menu_merge_inhibit_dec(); + + if (dsch != 0) { /* no default sheet file found, use embedded version */ + FILE *f; + char *efn; + const char *tmp_fn = ".sch-rnd.default-sheet.lht"; + + /* We can parse from file only, make a temp file */ + f = rnd_fopen_fn(NULL, tmp_fn, "wb", &efn); + if (f != NULL) { + fwrite(default_sheet_internal, strlen(default_sheet_internal), 1, f); + fclose(f); + if (dst_sheet != NULL) { + sheet = csch_load_sheet_io(NULL, dst_sheet, efn, efn, NULL, 0, NULL); + if (sheet != NULL) + dsch = 0; + else + dsch = 1; + } + else + dsch = csch_project_load_sheet(prj, efn, NULL, &sheet, rnd_conf.rc.quiet, NULL); + + if (dsch == 0) + rnd_message(RND_MSG_WARNING, "Couldn't find default sheet - using the embedded fallback\n"); + else + rnd_message(RND_MSG_ERROR, "Couldn't find default sheet and failed to load the embedded fallback\n"); + rnd_remove(NULL, efn); + free(efn); + } + } + + /* final fallback: empty sheet */ + if (sheet == NULL) { + if (dst_sheet != NULL) + sheet = dst_sheet; + else + sheet = csch_sheet_alloc(prj); + } + + /* do not remember default sheet's file name so that a 'save' won't overwrite it */ + free(sheet->hidlib.fullpath); + sheet->hidlib.fullpath = NULL; + sheet->newname = sheet->hidlib.loadname; + sheet->hidlib.loadname = NULL; + minuid_gen(&csch_minuid, sheet->direct.uuid); + minuid_clr(sheet->direct.data.grp.src_uuid); + + if (emit_ev) + rnd_event(&sheet->hidlib, CSCH_EVENT_SHEET_POSTLOAD, NULL); + + return sheet; +} + +csch_sheet_t *sch_rnd_sheet_new(csch_project_t *prj, csch_sheet_t *sheet) +{ + return sch_rnd_sheet_new_(prj, NULL, 0); +} + +csch_sheet_t *sch_rnd_sheet_new4revert(csch_sheet_t *sheet) +{ + csch_sheet_t *newsh = sch_rnd_sheet_new_(NULL, sheet, 1); + if (newsh->hidlib.fullpath == NULL) + newsh->hidlib.fullpath = rnd_strdup(""); + return newsh; +} + + +static void sch_rnd_sheet_postload_ev(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + csch_sheet_t *sheet = (csch_sheet_t *)hidlib; + + sch_rnd_sheet_postproc(sheet); +} + +void sch_rnd_sheet_init2(void) +{ + rnd_event_bind(CSCH_EVENT_SHEET_POSTLOAD, sch_rnd_sheet_postload_ev, NULL, sheet_cookie); +} + +void sch_rnd_sheet_uninit(void) +{ + rnd_event_unbind_allcookie(sheet_cookie); +} + Index: tags/1.0.5/src/sch-rnd/sheet.h =================================================================== --- tags/1.0.5/src/sch-rnd/sheet.h (nonexistent) +++ tags/1.0.5/src/sch-rnd/sheet.h (revision 10414) @@ -0,0 +1,11 @@ +csch_sheet_t *sch_rnd_sheet_new(csch_project_t *prj); /* doesn't emit postproc event */ +csch_sheet_t *sch_rnd_sheet_new4revert(csch_sheet_t *sheet); +void sch_rnd_sheet_postproc(csch_sheet_t *sheet); + +rnd_coord_t sch_rnd_sheet_attr_crd(csch_sheet_t *sheet, const char *key, rnd_coord_t defval); + +/* Throw an error when sheet gets too large (only once per sheet) */ +void sch_rnd_sheet_warn_size(csch_sheet_t *sheet, csch_coord_t x1, csch_coord_t y1, csch_coord_t x2, csch_coord_t y2); + +/* Recalc from scratch - time consuming but accurate */ +void sch_rnd_sheet_recalc_bbox(csch_sheet_t *sheet); Index: tags/1.0.5/src/sch-rnd/style.c =================================================================== --- tags/1.0.5/src/sch-rnd/style.c (nonexistent) +++ tags/1.0.5/src/sch-rnd/style.c (revision 10414) @@ -0,0 +1,63 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - sch-rnd (executable) + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include + +#include +#include +#include + +#include "style.h" + +csch_cpen_t *sch_rnd_style_get_pen(csch_sheet_t *sheet, csch_cgrp_t *grp, const rnd_conflist_t *lst, const char **strout) +{ + rnd_conf_listitem_t *ci; + csch_cpen_t *pen; + const char *first = NULL; + + for(ci = rnd_conflist_first((rnd_conflist_t *)lst); ci != NULL; ci = rnd_conflist_next(ci)) { + const char *pn = ci->val.string[0]; + + if (first == NULL) + first = pn; + + if ((pn != NULL) && (*pn != '\0')) { + pen = csch_pen_get(sheet, grp, pn); + if (pen != NULL) { + if (strout != NULL) + *strout = pn; + return pen; + } + } + } + + if (strout != NULL) + *strout = first; + return &csch_pen_default_unknown; +} + Index: tags/1.0.5/src/sch-rnd/style.h =================================================================== --- tags/1.0.5/src/sch-rnd/style.h (nonexistent) +++ tags/1.0.5/src/sch-rnd/style.h (revision 10414) @@ -0,0 +1,36 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - sch-rnd (executable) + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include +#include + +csch_cpen_t *sch_rnd_style_get_pen(csch_sheet_t *sheet, csch_cgrp_t *grp, const rnd_conflist_t *lst, const char **str_out); + +#define SCH_RND_DIRECT_PEN(sheet, confname, strout) \ + sch_rnd_style_get_pen(sheet, &sheet->direct, &conf_core.editor.style.confname, strout) + Index: tags/1.0.5/src/sch-rnd/util_sheet.c =================================================================== --- tags/1.0.5/src/sch-rnd/util_sheet.c (nonexistent) +++ tags/1.0.5/src/sch-rnd/util_sheet.c (revision 10414) @@ -0,0 +1,71 @@ +/* + * COPYRIGHT + * + * sch-rnd - modular/flexible schematics editor - sch-rnd (executable) + * Copyright (C) 2023 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 Entrust in 2023) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version.* + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include "sheet.h" + +#include "util_sheet.h" + +void sch_rnd_sheet_setup(csch_sheet_t *dst, sch_rnd_sheet_setup_cfg_t cfg, int (*chk_copy_pen)(void *udata, csch_sheet_t *dst, csch_cpen_t *p), void *udata) +{ + if (cfg & SCH_RND_SSC_PENS) { /* create temp new sheet only if we are to do anything */ + csch_sheet_t *tmp = sch_rnd_sheet_new((csch_project_t *)dst->hidlib.project); + htip_entry_t *e; + for(e = htip_first(&tmp->direct.id2obj); e != NULL; e = htip_next(&tmp->direct.id2obj, e)) { + csch_cpen_t *p = e->value, *pnew; + if ((p->hdr.type == CSCH_CTYPE_PEN) && (csch_pen_get(dst, &dst->direct, p->name.str) == NULL)) { + if ((chk_copy_pen == NULL) || chk_copy_pen(udata, dst, p)) { + pnew = csch_pen_dup(dst, &dst->direct, p); + if (cfg & SCH_RND_SSC_PEN_MARK_DEFAULT) + pnew->copied_from_default = 1; + } + } + } + csch_project_remove_sheet((csch_project_t *)dst->hidlib.project, tmp); + } + + if (cfg & SCH_RND_SSC_UUID) { + minuid_gen(&csch_minuid, dst->direct.uuid); + minuid_clr(dst->direct.data.grp.src_uuid); + } +} + +void sch_rnd_reconf_for_symbol_as_sheet(void) +{ + rnd_conf_set(RND_CFR_DESIGN, "editor/style/tool_circle_stroke", 0, "sym-decor", RND_POL_OVERWRITE); + rnd_conf_set(RND_CFR_DESIGN, "editor/style/tool_line_stroke", 0, "sym-decor", RND_POL_OVERWRITE); + rnd_conf_set(RND_CFR_DESIGN, "editor/style/tool_text_stroke", 0, "sym-decor", RND_POL_OVERWRITE); + rnd_conf_set(RND_CFR_DESIGN, "editor/style/tool_rect_stroke", 0, "sym-decor", RND_POL_OVERWRITE); + rnd_conf_set(RND_CFR_DESIGN, "editor/style/tool_rect_fill", 0, "sym-decor-fill", RND_POL_OVERWRITE); +} Index: tags/1.0.5/src/sch-rnd/util_sheet.h =================================================================== --- tags/1.0.5/src/sch-rnd/util_sheet.h (nonexistent) +++ tags/1.0.5/src/sch-rnd/util_sheet.h (revision 10414) @@ -0,0 +1,18 @@ +#include + +typedef enum sch_rnd_sheet_setup_cfg_e { /* bitfield */ + SCH_RND_SSC_PENS = 1, /* create pens */ + SCH_RND_SSC_UUID = 2, /* set up a new uuid for direct */ + SCH_RND_SSC_PEN_MARK_DEFAULT = 4 /* mark new pens copied from default */ +} sch_rnd_sheet_setup_cfg_t; + +/* Copy defaults into dst (from the default sheet) as cfg dictates; if + CSCH_SSC_PENS is true chk_copy_pen is called on each pen and the pen + is copied only if it returns non-zero. If chk_copy_pen is NULL, it is + assumed to always return 1. */ +void sch_rnd_sheet_setup(csch_sheet_t *dst, sch_rnd_sheet_setup_cfg_t cfg, int (*chk_copy_pen)(void *udata, csch_sheet_t *dst, csch_cpen_t *p), void *udata); + +/* Change DESIGN role configuration on current sheet for symbol-as-sheet + editing */ +void sch_rnd_reconf_for_symbol_as_sheet(void); + Index: tags/1.0.5/src_3rd/Makefile =================================================================== --- tags/1.0.5/src_3rd/Makefile (nonexistent) +++ tags/1.0.5/src_3rd/Makefile (revision 10414) @@ -0,0 +1,30 @@ +ROOT=.. + +all: libminuid/minuid + +clean: + cd libminuid && make clean && cd .. + cd libucdf && make clean && cd .. + cd libuundo && make clean && cd .. + cd load_cache && make clean && cd .. + -rm rnd_inclib/font/*.o + +distclean: clean + +install_: libminuid/minuid + -$(SCCBOX) mkdir -p $(LIBDIR)/boxsym-rnd + $(CPC) "`pwd`/libminuid/minuid" "$(LIBDIR)/minuid" + +install: + $(MAKE) install_ CPC="$(SCCBOX) install" + +linstall: + $(MAKE) install_ CPC="$(SCCBOX) linstall" + +uninstall: + $(MAKE) install_ CPC="$(SCCBOX) uninstall" + +include $(ROOT)/Makefile.conf + +libminuid/minuid: + cd ../src/libcschem && make ../../src_3rd/libminuid/minuid && cd .. Index: tags/1.0.5/src_3rd/Makefile.common =================================================================== --- tags/1.0.5/src_3rd/Makefile.common (nonexistent) +++ tags/1.0.5/src_3rd/Makefile.common (revision 10414) @@ -0,0 +1 @@ + Index: tags/1.0.5/src_3rd/Makefile.conf =================================================================== --- tags/1.0.5/src_3rd/Makefile.conf (nonexistent) +++ tags/1.0.5/src_3rd/Makefile.conf (revision 10414) @@ -0,0 +1 @@ + Index: tags/1.0.5/src_3rd/load_cache/COPYING =================================================================== --- tags/1.0.5/src_3rd/load_cache/COPYING (nonexistent) +++ tags/1.0.5/src_3rd/load_cache/COPYING (revision 10414) @@ -0,0 +1,502 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! Index: tags/1.0.5/src_3rd/load_cache/Makefile =================================================================== --- tags/1.0.5/src_3rd/load_cache/Makefile (nonexistent) +++ tags/1.0.5/src_3rd/load_cache/Makefile (revision 10414) @@ -0,0 +1,9 @@ +CFLAGS = -I.. -Wall -std=c89 -pedantic + +all: load_cache.o + +load_cache.o: load_cache.c load_cache.h + $(CC) $(CFLAGS) -c -o load_cache.o load_cache.c + +clean: + -rm load_cache.o Index: tags/1.0.5/src_3rd/load_cache/README =================================================================== --- tags/1.0.5/src_3rd/load_cache/README (nonexistent) +++ tags/1.0.5/src_3rd/load_cache/README (revision 10414) @@ -0,0 +1,80 @@ +load_cache is a minilib for caching parsed data of files in-memory. + +The abstraction is: + ++-context-------------------------------------------------------------------+ +| | +| +---file #1-----------+ +---file #2-----------+ +---file #3-----------+ | +| | | | | | | | +| | metadata | | metadata | | metadata | | +| | | | | | | | +| | +---low_payload---+ | | +---low_payload---+ | | +---low_payload---+ | | +| | | | | | | | | | | | | | +| | +-----------------+ | | +-----------------+ | | +-----------------+ | | +| | | | | | | | +| | +-high_payload #1-+ | | +-high_payload #1-+ | | +-high_payload #1-+ | | +| | | | | | | | | | | | | | +| | +-----------------+ | | +-----------------+ | | +-----------------+ | | +| | | | | | | | +| | +-high_payload #2-+ | | +-high_payload #2-+ | | +-high_payload #2-+ | | +| | | | | | | | | | | | | | +| | +-----------------+ | | +-----------------+ | | +-----------------+ | | +| | | | | | | | +| | +-high_payload #3-+ | | +-high_payload #3-+ | | +-high_payload #3-+ | | +| | | | | | | | | | | | | | +| | +-----------------+ | | +-----------------+ | | +-----------------+ | | +| +---------------------+ +---------------------+ +---------------------+ | ++---------------------------------------------------------------------------+ + +Files are assumed to be encoded using 2 levels: a low level format, e.g. +xml, json, lihata (generic) and a high level (application specific) format. +A file always has a singe low level format, but may have multiple high level +parses (e.g. if different high level parsers read different parts of the file). + +Each context may have multiple files; each file has some metadata (path to +the file, last modification time seen on disk, parsers to use). A file is +always loaded with a combination of file name, low level and high level parser. +When a file is loaded for the first time, the low level parser is called +and the result is saved in low_payload. Then the requested high level +parser is ran on low_payload to produce the high_payload which is +returned to the caller. + +When the application requests the same filename/low/high combination and +the file did not change on disk, the parsed high level payload is served +from memory, without any parsing. + +When the application requests a known filename/low with a new high, only +the high level parsing is done and result is cached/returned. + +If the file changes on disk, upon the next load request the low level payload +and all high level payloads are purged from the cache and the normal +first-time-load procedure is followed. + +The above terms translate to API as follows: + + context: ldch_ctx_t + file: ldch_file_t + high_payload: ldch_data_t + + +Parsers are registered in contexts as ldch_low_parser_t and +ldch_high_parser_t. They are specified by their name and a few callback +functions the host application needs to implement. + +When a new low level parse is done the ->parse_alloc() is called first. +This should call ldch_file_alloc() with a payload size specific to the format. +The payload is typically the parser context struct of the file format and +is stored at the end of the ldch_file_t struct. Then ->parse() is called. + +A high level parser's ->parse is called then, with the low level data already +in memory for the ldch_file_t *. It should follow the same pattern in +allocating a ldch_data_t struct with extra payload_size room for storing +the parsed data. + +Isn't keeping the low level parse in memory all the time expensive? On the +one hand yes, it looks like a waste if there is only one high level parser +for a file. On the other hand, file formats will normally have a lot of +strings stored. Since it is guaranteed that the low level parse data is +always available when the high level data is, the high level does not need +to make copies of those strings but can reference directly into the low level +payload. Index: tags/1.0.5/src_3rd/load_cache/load_cache.c =================================================================== --- tags/1.0.5/src_3rd/load_cache/load_cache.c (nonexistent) +++ tags/1.0.5/src_3rd/load_cache/load_cache.c (revision 10414) @@ -0,0 +1,266 @@ +/* + load_cache - cache loading/parsing files + Copyright (C) 2020 Tibor 'Igor2' Palinkas + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + Project page: http://repo.hu/projects/libminuid + Source code: svn://repo.hu/libminuid/trunk + Author: emailto: libminuid [at] igor2.repo.hu +*/ + +#include +#include +#include +#include + +/* These are required for stat() and are C89. */ +#include +#include + +#include "load_cache.h" + +char *ldch_strdup(const char *s) +{ + int l = strlen(s); + char *o = malloc(l+1); + return memcpy(o, s, l+1); +} + +double ldch_file_mtime(const char *path) +{ + struct stat st; + if (stat(path, &st) != 0) + return -1; + return st.st_mtime; +} + + +void ldch_init(ldch_ctx_t *ctx) +{ + memset(ctx, 0, sizeof(ldch_ctx_t)); + htsp_init(&ctx->low_parsers, strhash, strkeyeq); + htsp_init(&ctx->high_parsers, strhash, strkeyeq); + htsp_init(&ctx->files, strhash, strkeyeq); + ctx->next_low_uid = 1; +} + +ldch_low_parser_t *ldch_reg_low_parser(ldch_ctx_t *ctx, const char *name) +{ + ldch_low_parser_t *p; + + p = htsp_get(&ctx->low_parsers, name); + if (p != NULL) + return NULL; + + p = calloc(sizeof(ldch_low_parser_t), 1); + p->ctx = ctx; + p->name = ldch_strdup(name); + p->uid = ctx->next_low_uid++; + htsp_set(&ctx->low_parsers, p->name, p); + return p; +} + +ldch_high_parser_t *ldch_reg_high_parser(ldch_ctx_t *ctx, const char *name) +{ + ldch_high_parser_t *p; + + p = htsp_get(&ctx->high_parsers, name); + if (p != NULL) + return NULL; + + p = calloc(sizeof(ldch_high_parser_t), 1); + p->ctx = ctx; + p->name = ldch_strdup(name); + htsp_set(&ctx->high_parsers, p->name, p); + return p; +} + +ldch_low_parser_t *ldch_lookup_low_parser(ldch_ctx_t *ctx, const char *name) +{ + return htsp_get(&ctx->low_parsers, name); +} + +ldch_high_parser_t *ldch_lookup_high_parser(ldch_ctx_t *ctx, const char *name) +{ + return htsp_get(&ctx->high_parsers, name); +} + +void ldch_data_free(ldch_ctx_t *ctx, ldch_data_t *data) +{ + if ((data->high_parser != NULL) && (data->high_parser->free_payload != NULL)) + data->high_parser->free_payload(data); + free(data); +} + +static void ldch_free_file_low(ldch_ctx_t *ctx, ldch_file_t *file) +{ + long n; + + for(n = 0; n < file->data.used; n++) + if (file->data.array[n] != NULL) + ldch_data_free(ctx, file->data.array[n]); + + vtp0_uninit(&file->data); + + if (file->low_parser->free_payload != NULL) + file->low_parser->free_payload(file->low_parser, file); +} + +static void ldch_free_file(ldch_ctx_t *ctx, ldch_file_t *file) +{ + ldch_free_file_low(ctx, file); + free(file->load_name); + free(file->real_name); + free(file); +} + + +static char *get_real_name(ldch_ctx_t *ctx, const char *load_name, ldch_low_parser_t *low, ldch_high_parser_t *high, void *low_call_ctx, void *high_call_ctx) +{ + if (ctx->load_name_to_real_name != NULL) + return ctx->load_name_to_real_name(ctx, load_name, low, high, low_call_ctx, high_call_ctx); + return ldch_strdup(load_name); +} + +ldch_data_t *ldch_load_(ldch_ctx_t *ctx, const char *load_name, ldch_low_parser_t *low, ldch_high_parser_t *high, void *low_call_ctx, void *high_call_ctx) +{ + ldch_file_t *file = htsp_get(&ctx->files, load_name); + void **d; + ldch_data_t *data; + + /* get low level */ + if (file == NULL) { + char *real_name = get_real_name(ctx, load_name, low, high, low_call_ctx, high_call_ctx); + if (real_name == NULL) + return NULL; + file = low->parse_alloc(low, low_call_ctx, real_name); + if (file == NULL) { + free(real_name); + return NULL; + } + file->real_name = real_name; + file->load_name = ldch_strdup(load_name); + if (low->parse(low, low_call_ctx, file, file->real_name) != 0) { + ldch_unload(ctx, file); + return NULL; + } + file->last_low_parsed = ldch_file_mtime(file->real_name); + htsp_set(&ctx->files, file->load_name, file); + } + else { + double fmd = ldch_file_mtime(file->real_name); + if (fmd < 0) + return NULL; + if (low->uid != file->low_parser->uid) + return NULL; /* can't parse the same file twice, with different low level */ + if (fmd > file->last_low_parsed) { /* changed on disk */ + ldch_free_file_low(ctx, file); + low->parse(low, low_call_ctx, file, file->real_name); + } + } + + /* get high level parsing donw */ + d = vtp0_get(&file->data, low->uid, 1); + if (d == NULL) + return NULL; /* allocation error */ + + if (*d == NULL) { + data = high->parse(high, high_call_ctx, file); + if (data == NULL) + return NULL; + *d = data; + data->high_parser = high; + } + else + data = *d; + + return data; +} + + +ldch_data_t *ldch_load(ldch_ctx_t *ctx, const char *load_name, const char *lows, const char *highs, void *low_call_ctx, void *high_call_ctx) +{ + ldch_low_parser_t *low; + ldch_high_parser_t *high; + + low = ldch_lookup_low_parser(ctx, lows); + if (low == NULL) + return NULL; + + high = ldch_lookup_high_parser(ctx, highs); + if (high == NULL) + return NULL; + + return ldch_load_(ctx, load_name, low, high, low_call_ctx, high_call_ctx); +} + +void ldch_unload(ldch_ctx_t *ctx, ldch_file_t *file) +{ + htsp_pop(&ctx->files, file->load_name); + ldch_free_file(ctx, file); +} + +void ldch_unreg_low_parser(ldch_low_parser_t *low) +{ + if (low->unreg != NULL) + low->unreg(low); + free(low->name); + free(low); +} + +void ldch_unreg_high_parser(ldch_ctx_t *ctx, ldch_high_parser_t *high) +{ + if (high->unreg != NULL) + high->unreg(high); + free(high->name); + free(high); +} + +void ldch_uninit(ldch_ctx_t *ctx) +{ + htsp_entry_t *e; + + for(e = htsp_first(&ctx->files); e != NULL; e = htsp_next(&ctx->files, e)) + ldch_unload(ctx, e->value); + htsp_uninit(&ctx->files); + + for(e = htsp_first(&ctx->low_parsers); e != NULL; e = htsp_next(&ctx->low_parsers, e)) + ldch_unreg_low_parser(e->value); + htsp_uninit(&ctx->low_parsers); + + for(e = htsp_first(&ctx->high_parsers); e != NULL; e = htsp_next(&ctx->high_parsers, e)) + ldch_unreg_high_parser(ctx, e->value); + htsp_uninit(&ctx->high_parsers); +} + +ldch_data_t *ldch_data_alloc(ldch_file_t *file, ldch_high_parser_t *high_parser, size_t payload_size) +{ + ldch_data_t *data = calloc(sizeof(ldch_data_t) - 1 + payload_size, 1); + data->parent = file; + data->high_parser = high_parser; + data->payload_size = payload_size; + return data; +} + +ldch_file_t *ldch_file_alloc(ldch_ctx_t *ctx, ldch_low_parser_t *low_parser, size_t low_payload_size) +{ + ldch_file_t *file = calloc(sizeof(ldch_file_t) - 1 + low_payload_size, 1); + file->parent = ctx; + file->low_parser = low_parser; + file->low_payload_size = low_payload_size; + return file; +} + Index: tags/1.0.5/src_3rd/load_cache/load_cache.h =================================================================== --- tags/1.0.5/src_3rd/load_cache/load_cache.h (nonexistent) +++ tags/1.0.5/src_3rd/load_cache/load_cache.h (revision 10414) @@ -0,0 +1,111 @@ +/* + load_cache - cache loading/parsing files + Copyright (C) 2020 Tibor 'Igor2' Palinkas + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + Project page: http://repo.hu/projects/libminuid + Source code: svn://repo.hu/libminuid/trunk + Author: emailto: libminuid [at] igor2.repo.hu +*/ + +#ifndef LOAD_CACHE_H +#define LOAD_CACHE_H + +#include +#include + +typedef struct ldch_ctx_s ldch_ctx_t; +typedef struct ldch_data_s ldch_data_t; +typedef struct ldch_file_s ldch_file_t; +typedef struct ldch_low_parser_s ldch_low_parser_t; +typedef struct ldch_high_parser_s ldch_high_parser_t; +typedef int ldch_uid_t; + +struct ldch_low_parser_s { + char *name; + ldch_uid_t uid; + ldch_file_t *(*parse_alloc)(ldch_low_parser_t *parser, void *call_ctx, const char *fn); /* called when the file is first loaded; should allocate (ldch_file_t *) */ + int (*parse)(ldch_low_parser_t *parser, void *call_ctx, ldch_file_t *file, const char *fn); /* called after parse_alloc() on initial load or after free_payload() on reload */ + void (*free_payload)(ldch_low_parser_t *low, ldch_file_t *file); /* should free the in-memory document/parse-tree; a call to parse() may follow when reloading */ + void (*unreg)(ldch_low_parser_t *low); + ldch_ctx_t *ctx; + void *used_data; +}; + +struct ldch_high_parser_s { + char *name; + ldch_data_t *(*parse)(ldch_high_parser_t *parser, void *call_ctx, ldch_file_t *file); + void (*free_payload)(ldch_data_t *data); + void (*unreg)(ldch_high_parser_t *high); + ldch_ctx_t *ctx; + void *used_data; +}; + +struct ldch_data_s { + ldch_file_t *parent; + ldch_high_parser_t *high_parser; + size_t payload_size; + char payload[1]; /* real size: payload_size (caches parsed data) */ +}; + +struct ldch_file_s { + ldch_ctx_t *parent; + char *load_name; /* file name: as the user refers to it (strdup'd variant, also the hash key) */ + char *real_name; /* file name: full path on the file system */ + vtp0_t data; /* -> (ldch_data_t *), indexed by high_parser uid */ + void *user_data; + ldch_low_parser_t *low_parser; + double last_low_parsed; /* time stamp the file was last low-level parsed */ + size_t low_payload_size; + char low_payload[1]; /* real size: low_payload_size (caches low level parsed data) */ +}; + +struct ldch_ctx_s { + htsp_t low_parsers; + htsp_t high_parsers; + htsp_t files; /* of ldch_file_t */ + char *(*load_name_to_real_name)(ldch_ctx_t *ctx, const char *load_name, ldch_low_parser_t *low, ldch_high_parser_t *high, void *low_call_ctx, void *high_call_ctx); /* simple strdup() if NULL */ + void *user_data; + ldch_uid_t next_low_uid; +}; + +/* The host application may keep multiple, independent cache contexts */ +void ldch_init(ldch_ctx_t *ctx); +void ldch_uninit(ldch_ctx_t *ctx); + +/* Parsers need to be registered in the context so they can be referenced by name.*/ +ldch_low_parser_t *ldch_reg_low_parser(ldch_ctx_t *ctx, const char *name); +ldch_high_parser_t *ldch_reg_high_parser(ldch_ctx_t *ctx, const char *name); +ldch_low_parser_t *ldch_lookup_low_parser(ldch_ctx_t *ctx, const char *name); +ldch_high_parser_t *ldch_lookup_high_parser(ldch_ctx_t *ctx, const char *name); + +/* Load a file from disk or from memory; in any case if the modification timestamp + on disk is higher than the cached timestamp, reload the file */ +ldch_data_t *ldch_load_(ldch_ctx_t *ctx, const char *load_name, ldch_low_parser_t *low, ldch_high_parser_t *high, void *low_call_ctx, void *high_call_ctx); +ldch_data_t *ldch_load(ldch_ctx_t *ctx, const char *load_name, const char *low, const char *high, void *low_call_ctx, void *high_call_ctx); + +/* Remove a single file from a context, freeing all memory taken by the parsed + data. Will be re-loaded upon next request */ +void ldch_unload(ldch_ctx_t *ctx, ldch_file_t *file); + + +/*** calls for parsers ***/ +ldch_data_t *ldch_data_alloc(ldch_file_t *file, ldch_high_parser_t *high_parser, size_t payload_size); +void ldch_data_free(ldch_ctx_t *ctx, ldch_data_t *data); + +ldch_file_t *ldch_file_alloc(ldch_ctx_t *ctx, ldch_low_parser_t *low_parser, size_t low_payload_size); + +#endif Index: tags/1.0.5/src_3rd/opc89.h =================================================================== --- tags/1.0.5/src_3rd/opc89.h (nonexistent) +++ tags/1.0.5/src_3rd/opc89.h (revision 10414) @@ -0,0 +1,16 @@ +#ifdef __OPC89__ + +/* Being compiled with opc89: use attributes to mark types and functions */ +# define funcops __attribute__((opc89_ops)) +# define opfunc __attribute__((opc89_opfunc)) + +/* make sure asserts are kept as is */ +#define assert(a) + +#else + +/* Being compiled with a c compiler: make opc marks invisible */ +# define funcops +# define opfunc + +#endif Index: tags/1.0.5/src_3rd =================================================================== --- tags/1.0.5/src_3rd (nonexistent) +++ tags/1.0.5/src_3rd (revision 10414) Property changes on: tags/1.0.5/src_3rd ___________________________________________________________________ Added: svn:externals ## -0,0 +1,5 ## +libminuid -r39 svn://svn.repo.hu/libminuid/trunk/libminuid +gengeo2d -r300 svn://svn.repo.hu/gengeo2d/trunk/gengeo2d +libuundo -r78 svn://svn.repo.hu/libuundo/trunk/libuundo +libucdf -r38781 svn://svn.repo.hu/pcb-rnd/trunk/src_3rd/libucdf +rnd_inclib -r38781 svn://svn.repo.hu/pcb-rnd/trunk/src_3rd/rnd_inclib Index: tags/1.0.5/tests/Makefile =================================================================== --- tags/1.0.5/tests/Makefile (nonexistent) +++ tags/1.0.5/tests/Makefile (revision 10414) @@ -0,0 +1,29 @@ +all: + cd export_abst && $(MAKE) all && cd .. + cd export_spice && $(MAKE) all && cd .. + cd std_forge_cond && $(MAKE) all && cd .. + cd hier && $(MAKE) all && cd .. + +test: + @cd export_abst && $(MAKE) test && cd .. + @cd export_spice && $(MAKE) test && cd .. + @cd std_forge_cond && $(MAKE) test && cd .. + @cd hier && $(MAKE) test && cd .. + @echo "" + @echo "=======================================================" + @echo "=== All tests passed; it is safe to install sch-rnd ===" + @echo "=======================================================" + @echo "" + +clean: + cd export_abst && $(MAKE) clean && cd .. + cd export_spice && $(MAKE) clean && cd .. + cd std_forge_cond && $(MAKE) clean && cd .. + cd hier && $(MAKE) clean && cd .. + + +distclean: + cd export_abst && $(MAKE) distclean && cd .. + cd export_spice && $(MAKE) distclean && cd .. + cd std_forge_cond && $(MAKE) distclean && cd .. + cd hier && $(MAKE) distclean && cd .. Index: tags/1.0.5/tests/export_abst/Makefile =================================================================== --- tags/1.0.5/tests/export_abst/Makefile (nonexistent) +++ tags/1.0.5/tests/export_abst/Makefile (revision 10414) @@ -0,0 +1,11 @@ +all: + +test: + @echo "export_abst:" + @./test.sh + +clean: + @touch A.log A.out + rm *.log *.out + +distclean: clean Index: tags/1.0.5/tests/export_abst/devmap.ref =================================================================== --- tags/1.0.5/tests/export_abst/devmap.ref (nonexistent) +++ tags/1.0.5/tests/export_abst/devmap.ref (revision 10414) @@ -0,0 +1,255 @@ +cschem abstract model v1 +components + anon_comp_11 + attributes + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + sym-license-dist=GPLv2+ + role=symbol + sym-license-use=Public Domain + sym-source=sch-rnd default symbol lib + connect [] + 1:Vcc + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + anon_comp_3 + attributes + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + sym-license-dist=GPLv2+ + role=symbol + sym-license-use=Public Domain + sym-source=sch-rnd default symbol lib + connect [] + 1:GND + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + anon_comp_4 + attributes + role=symbol + device=RESISTOR + refdes=R1 + ports + anon_8 + attributes + pinlabel=2 + pinnumber=2 + pintype=pas + role=terminal + display/name=anon_8 + pinseq=2 + anon_9 + attributes + pinlabel=1 + pinnumber=1 + pintype=pas + role=terminal + display/name=anon_9 + pinseq=1 + anon_comp_5 + attributes + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + sym-license-dist=GPLv2+ + role=symbol + sym-license-use=Public Domain + sym-source=sch-rnd default symbol lib + connect [] + 1:Vcc + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + CONN1 + attributes + role=symbol + name=CONN1 + ports + 3 + attributes + role=terminal + display/name=3 + name=3 + 1 + attributes + role=terminal + display/name=1 + name=1 + 2 + attributes + role=terminal + display/name=2 + name=2 + anon_comp_7 + attributes + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + sym-license-dist=GPLv2+ + role=symbol + sym-license-use=Public Domain + sym-source=sch-rnd default symbol lib + connect [] + 1:GND + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + CONN2 + attributes + role=symbol + name=CONN2 + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + 2 + attributes + role=terminal + display/name=2 + name=2 + anon_comp_9 + attributes + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + sym-license-dist=GPLv2+ + role=symbol + sym-license-use=Public Domain + sym-source=sch-rnd default symbol lib + connect [] + 1:GND + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + Q1 + attributes + portmap [] + G->pcb/pinnum=1 + S->pcb/pinnum=2 + D->pcb/pinnum=3 + devmap=2n7002_sot23 + footprint=sot23 + role=symbol + sym-source=sch-rnd default symbol lib + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + sym-license-use=Public Domain + name=Q1 + sym-license-dist=GPLv2+ + ports + S + attributes + pcb/pinnum=2 + role=terminal + display/name=2 + name=S + D + attributes + pcb/pinnum=3 + role=terminal + display/name=3 + name=D + G + attributes + pcb/pinnum=1 + role=terminal + display/name=1 + name=G + Q2 + attributes + portmap [] + G->pcb/pinnum=1 + S->pcb/pinnum=3 + D->pcb/pinnum=2 + devmap=irf510_to220 + footprint=TO220 + role=symbol + sym-source=sch-rnd default symbol lib + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + sym-license-use=Public Domain + name=Q2 + sym-license-dist=GPLv2+ + ports + S + attributes + pcb/pinnum=3 + role=terminal + display/name=3 + name=S + D + attributes + pcb/pinnum=2 + role=terminal + display/name=2 + name=D + G + attributes + pcb/pinnum=1 + role=terminal + display/name=1 + name=G + anon_comp_10 + attributes + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + sym-license-dist=GPLv2+ + role=symbol + sym-license-use=Public Domain + sym-source=sch-rnd default symbol lib + connect [] + 1:GND + ports + 1 + attributes + role=terminal + display/name=1 + name=1 +nets + Vcc + attributes + role=wire-net + conns 5 + CONN1-3 + anon_comp_11-1 + anon_comp_4-anon_8 + anon_comp_5-1 + Q2-G + GND + attributes + role=wire-net + conns 8 + Q1-S + anon_comp_3-1 + Q2-S + anon_comp_7-1 + CONN2-1 + anon_comp_9-1 + CONN1-1 + anon_comp_10-1 + anon_net_3 + attributes + role=wire-net + conns 2 + Q2-D + CONN2-2 + anon_net_7 + attributes + role=wire-net + conns 2 + Q1-G + CONN1-2 + anon_net_9 + attributes + role=wire-net + conns 2 + Q1-D + anon_comp_4-anon_9 Index: tags/1.0.5/tests/export_abst/psu.ref =================================================================== --- tags/1.0.5/tests/export_abst/psu.ref (nonexistent) +++ tags/1.0.5/tests/export_abst/psu.ref (revision 10414) @@ -0,0 +1,253 @@ +cschem abstract model v1 +components + anon_comp_11 + attributes + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + sym-license-dist=GPLv2+ + role=symbol + sym-license-use=Public Domain + sym-source=sch-rnd default symbol lib + connect [] + 1:GND + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + anon_comp_12 + attributes + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + sym-license-dist=GPLv2+ + role=symbol + sym-license-use=Public Domain + sym-source=sch-rnd default symbol lib + connect [] + 1:GND + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + anon_comp_3 + attributes + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + sym-license-dist=GPLv2+ + role=symbol + sym-license-use=Public Domain + sym-source=sch-rnd default symbol lib + connect [] + 1:GND + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + CONN1 + attributes + role=symbol + footprint=connector(2,1) + name=CONN1 + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + 2 + attributes + role=terminal + display/name=2 + name=2 + CONN2 + attributes + role=symbol + footprint=connector(2,1) + name=CONN2 + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + 2 + attributes + role=terminal + display/name=2 + name=2 + anon_comp_7 + attributes + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + sym-license-dist=GPLv2+ + role=symbol + sym-license-use=Public Domain + sym-source=sch-rnd default symbol lib + connect [] + 1:GND + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + U1 + attributes + footprint=TO220 + role=symbol + sym-source=sch-rnd default symbol lib + symbol_generator=boxsym-rnd + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + sym-license-use=Public Domain + name=U1 + sym-license-dist=GPLv2+ + ports + out + attributes + display/name=3 + role=terminal + pinnum=3 + name=out + in + attributes + display/name=1 + role=terminal + pinnum=1 + name=in + gnd + attributes + display/name=2 + role=terminal + pinnum=2 + name=gnd + anon_comp_9 + attributes + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + sym-license-dist=GPLv2+ + role=symbol + sym-license-use=Public Domain + sym-source=sch-rnd default symbol lib + connect [] + 1:GND + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + C1 + attributes + portmap [] + N->pcb/pinnum=1 + P->pcb/pinnum=2 + footprint=rcy(300) + role=symbol + sym-source=sch-rnd default symbol lib + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + value=10u + sym-license-use=Public Domain + name=C1 + sym-license-dist=GPLv2+ + ports + N + attributes + pcb/pinnum=1 + role=terminal + display/name=1 + name=N + P + attributes + pcb/pinnum=2 + role=terminal + display/name=2 + name=P + C2 + attributes + footprint=1206 + role=symbol + sym-source=sch-rnd default symbol lib + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + value=100n + sym-license-use=Public Domain + name=C2 + sym-license-dist=GPLv2+ + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + 2 + attributes + role=terminal + display/name=2 + name=2 + C3 + attributes + footprint=1206 + role=symbol + sym-source=sch-rnd default symbol lib + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + value=100n + sym-license-use=Public Domain + name=C3 + sym-license-dist=GPLv2+ + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + 2 + attributes + role=terminal + display/name=2 + name=2 + anon_comp_10 + attributes + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + sym-license-dist=GPLv2+ + role=symbol + sym-license-use=Public Domain + sym-source=sch-rnd default symbol lib + connect [] + 1:GND + ports + 1 + attributes + role=terminal + display/name=1 + name=1 +nets + GND + attributes + role=wire-net + conns 12 + C1-N + anon_comp_11-1 + U1-gnd + anon_comp_12-1 + CONN1-1 + anon_comp_3-1 + CONN2-1 + anon_comp_7-1 + anon_comp_9-1 + C3-2 + C2-2 + anon_comp_10-1 + anon_net_3 + attributes + role=wire-net + conns 4 + CONN1-2 + U1-in + C1-P + C2-1 + anon_net_4 + attributes + role=wire-net + conns 3 + U1-out + CONN2-2 + C3-1 Index: tags/1.0.5/tests/export_abst/slot.ref =================================================================== --- tags/1.0.5/tests/export_abst/slot.ref (nonexistent) +++ tags/1.0.5/tests/export_abst/slot.ref (revision 10414) @@ -0,0 +1,388 @@ +cschem abstract model v1 +components + anon_comp_11 + attributes + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + sym-license-dist=GPLv2+ + role=symbol + sym-license-use=Public Domain + sym-source=sch-rnd default symbol lib + connect [] + 1:GND + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + anon_comp_1 + attributes + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + sym-license-dist=GPLv2+ + role=symbol + sym-license-use=Public Domain + sym-source=sch-rnd default symbol lib + connect [] + 1:GND + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + anon_comp_2 + attributes + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + sym-license-dist=GPLv2+ + role=symbol + sym-license-use=Public Domain + sym-source=sch-rnd default symbol lib + connect [] + 1:GND + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + anon_comp_15 + attributes + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + sym-license-dist=GPLv2+ + role=symbol + sym-source=sch-rnd default symbol lib + sym-license-use=Public Domain + connect [] + 1:Vcc + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + anon_comp_14 + attributes + role=symbol + connect [] + 1:Vcc + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + anon_comp_17 + attributes + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + sym-license-dist=GPLv2+ + role=symbol + sym-source=sch-rnd default symbol lib + sym-license-use=Public Domain + connect [] + 1:Vcc + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + anon_comp_6 + attributes + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + sym-license-dist=GPLv2+ + role=symbol + sym-license-use=Public Domain + sym-source=sch-rnd default symbol lib + connect [] + 1:GND + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + anon_comp_7 + attributes + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + sym-license-dist=GPLv2+ + role=symbol + sym-license-use=Public Domain + sym-source=sch-rnd default symbol lib + connect [] + 1:GND + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + CONN2 + attributes + role=symbol + name=CONN2 + ports + 3 + attributes + role=terminal + display/name=3 + name=3 + 1 + attributes + role=terminal + display/name=1 + name=1 + 2 + attributes + role=terminal + display/name=2 + name=2 + anon_comp_9 + attributes + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + sym-license-dist=GPLv2+ + role=symbol + sym-license-use=Public Domain + sym-source=sch-rnd default symbol lib + connect [] + 1:GND + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + U1 + attributes + portmap [] + 1/in- -> pcb/pinnum=2 + 1/in+ -> pcb/pinnum=3 + 1/out -> pcb/pinnum=1 + 1/V+ -> pcb/pinnum=8 + 1/V- -> pcb/pinnum=4 + 2/in- -> pcb/pinnum=6 + 2/in+ -> pcb/pinnum=5 + 2/out -> pcb/pinnum=7 + 2/V+ -> pcb/pinnum=8 + 2/V- -> pcb/pinnum=4 + devmap=lm358_so8 + footprint=so(8) + role=symbol + sym-source=sch-rnd default symbol lib + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + sym-license-use=Public Domain + name=U1 + sym-license-dist=GPLv2+ + ports + 2/V+ + attributes + pcb/pinnum=8 + display/name=8 + role=terminal + spice/pinnum=4 + name=V+ + 2/in+ + attributes + pcb/pinnum=5 + display/name=5 + role=terminal + spice/pinnum=2 + name=in+ + 2/V- + attributes + pcb/pinnum=4 + display/name=4 + role=terminal + spice/pinnum=5 + name=V- + 2/in- + attributes + pcb/pinnum=6 + display/name=6 + role=terminal + spice/pinnum=1 + name=in- + 1/V+ + attributes + pcb/pinnum=8 + display/name=8 + role=terminal + spice/pinnum=4 + name=V+ + 1/V- + attributes + pcb/pinnum=4 + display/name=4 + role=terminal + spice/pinnum=5 + name=V- + 2/out + attributes + pcb/pinnum=7 + display/name=7 + role=terminal + spice/pinnum=3 + name=out + 1/in+ + attributes + pcb/pinnum=3 + display/name=3 + role=terminal + spice/pinnum=2 + name=in+ + 1/in- + attributes + pcb/pinnum=2 + display/name=2 + role=terminal + spice/pinnum=1 + name=in- + 1/out + attributes + pcb/pinnum=1 + display/name=1 + role=terminal + spice/pinnum=3 + name=out + CONN1 + attributes + role=symbol + name=CONN1 + ports + 3 + attributes + role=terminal + display/name=3 + name=3 + 1 + attributes + role=terminal + display/name=1 + name=1 + 2 + attributes + role=terminal + display/name=2 + name=2 + anon_comp_16 + attributes + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + sym-license-dist=GPLv2+ + role=symbol + sym-source=sch-rnd default symbol lib + sym-license-use=Public Domain + connect [] + 1:Vcc + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + C1 + attributes + role=symbol + sym-source=sch-rnd default symbol lib + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + value=100n + sym-license-use=Public Domain + name=C1 + sym-license-dist=GPLv2+ + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + 2 + attributes + role=terminal + display/name=2 + name=2 + R1 + attributes + role=symbol + sym-source=sch-rnd default symbol lib + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + value=470k + sym-license-use=Public Domain + name=R1 + sym-license-dist=GPLv2+ + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + 2 + attributes + role=terminal + display/name=2 + name=2 + R2 + attributes + role=symbol + sym-source=sch-rnd default symbol lib + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + value=470k + sym-license-use=Public Domain + name=R2 + sym-license-dist=GPLv2+ + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + 2 + attributes + role=terminal + display/name=2 + name=2 +nets + mid + attributes + role=wire-net + name=mid + conns 6 + CONN2-2 + R1-2 + R2-1 + C1-2 + U1-2/in- + U1-2/out + in + attributes + role=wire-net + name=in + conns 4 + C1-1 + CONN1-2 + U1-1/in- + U1-1/out + Vcc + attributes + role=wire-net + conns 7 + U1-1/V+ + anon_comp_15-1 + anon_comp_14-1 + CONN2-3 + anon_comp_17-1 + R1-1 + anon_comp_16-1 + GND + attributes + role=wire-net + conns 12 + CONN1-1 + anon_comp_11-1 + anon_comp_1-1 + U1-1/V- + anon_comp_2-1 + U1-1/in+ + R2-2 + anon_comp_6-1 + anon_comp_7-1 + U1-2/in+ + CONN2-1 + anon_comp_9-1 Index: tags/1.0.5/tests/export_abst/slot2.ref =================================================================== --- tags/1.0.5/tests/export_abst/slot2.ref (nonexistent) +++ tags/1.0.5/tests/export_abst/slot2.ref (revision 10414) @@ -0,0 +1,285 @@ +cschem abstract model v1 +components + anon_comp_6 + attributes + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + sym-license-dist=GPLv2+ + role=symbol + sym-license-use=Public Domain + sym-source=sch-rnd default symbol lib + connect [] + 1:GND + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + anon_comp_7 + attributes + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + sym-license-dist=GPLv2+ + role=symbol + sym-license-use=Public Domain + sym-source=sch-rnd default symbol lib + connect [] + 1:Vcc + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + CONN3 + attributes + role=symbol + name=CONN3 + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + 2 + attributes + role=terminal + display/name=2 + name=2 + U1 + attributes + portmap [] + 1/A -> pcb/pinnum=1 + 2/A -> pcb/pinnum=4 + 3/A -> pcb/pinnum=9 + 4/A -> pcb/pinnum=12 + 1/B -> pcb/pinnum=2 + 2/B -> pcb/pinnum=5 + 3/B -> pcb/pinnum=10 + 4/B -> pcb/pinnum=13 + 1/Z -> pcb/pinnum=3 + 2/Z -> pcb/pinnum=6 + 3/Z -> pcb/pinnum=8 + 4/Z -> pcb/pinnum=11 + role=symbol + device=7400 + name=U1 + symbol_generator=boxsym-rnd + ports + 2/A + attributes + pcb/pinnum=4 + display/name=4 + role=terminal + pinnum=1 + name=A + 1/Z + attributes + pcb/pinnum=3 + display/name=3 + role=terminal + pinnum=3 + name=Z + 2/B + attributes + pcb/pinnum=5 + display/name=5 + role=terminal + pinnum=2 + name=B + 1/A + attributes + pcb/pinnum=1 + display/name=1 + role=terminal + pinnum=1 + name=A + 1/B + attributes + pcb/pinnum=2 + display/name=2 + role=terminal + pinnum=2 + name=B + Vcc + attributes + display/name=14 + role=terminal + pinnum=14 + name=Vcc + gnd + attributes + display/name=7 + role=terminal + pinnum=7 + name=gnd + 4/Z + attributes + pcb/pinnum=11 + display/name=11 + role=terminal + pinnum=3 + name=Z + 3/Z + attributes + pcb/pinnum=8 + display/name=8 + role=terminal + pinnum=3 + name=Z + 4/A + attributes + pcb/pinnum=12 + display/name=12 + role=terminal + pinnum=1 + name=A + 4/B + attributes + pcb/pinnum=13 + display/name=13 + role=terminal + pinnum=2 + name=B + 2/Z + attributes + pcb/pinnum=6 + display/name=6 + role=terminal + pinnum=3 + name=Z + 3/A + attributes + pcb/pinnum=9 + display/name=9 + role=terminal + pinnum=1 + name=A + 3/B + attributes + pcb/pinnum=10 + display/name=10 + role=terminal + pinnum=2 + name=B + CONN2 + attributes + role=symbol + name=CONN2 + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + 2 + attributes + role=terminal + display/name=2 + name=2 + CONN1 + attributes + role=symbol + name=CONN1 + ports + 3 + attributes + role=terminal + display/name=3 + name=3 + 1 + attributes + role=terminal + display/name=1 + name=1 + 2 + attributes + role=terminal + display/name=2 + name=2 + C1 + attributes + role=symbol + sym-source=sch-rnd default symbol lib + sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + value=100n + sym-license-use=Public Domain + name=C1 + sym-license-dist=GPLv2+ + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + 2 + attributes + role=terminal + display/name=2 + name=2 +nets + clk + attributes + role=wire-net + name=clk + conns 3 + U1-1/B + U1-2/A + CONN1-2 + Q' + attributes + role=wire-net + name=Q' + conns 3 + U1-4/Z + U1-3/B + CONN2-1 + Q + attributes + role=wire-net + name=Q + conns 3 + U1-3/Z + U1-4/A + CONN2-2 + R + attributes + role=wire-net + name=R + conns 2 + U1-2/B + CONN1-1 + anon_net_2 + attributes + role=wire-net + conns 2 + U1-1/Z + U1-3/A + S + attributes + role=wire-net + name=S + conns 2 + CONN1-3 + U1-1/A + anon_net_1 + attributes + role=wire-net + conns 2 + U1-4/B + U1-2/Z + Vcc + attributes + role=wire-net + conns 4 + U1-Vcc + anon_comp_7-1 + CONN3-2 + C1-1 + GND + attributes + role=wire-net + conns 4 + anon_comp_6-1 + U1-gnd + C1-2 + CONN3-1 Index: tags/1.0.5/tests/export_abst/test.sh =================================================================== --- tags/1.0.5/tests/export_abst/test.sh (nonexistent) +++ tags/1.0.5/tests/export_abst/test.sh (revision 10414) @@ -0,0 +1,35 @@ +#!/bin/sh +ROOT=../.. +SCHDIR=`pwd`/$ROOT/doc/examples +HERE=`pwd` +REFS=`ls *.ref` +SRC=$ROOT/src/sch-rnd +bad=0 + + +cd $SRC +for ref in $REFS +do + bn="${ref%%.ref}" + rs="$SCHDIR/$bn.rs" + out="$HERE/$bn.out" + log="$HERE/$bn.log" + ./sch-rnd -x abst --outfile "$out" "$rs" >"$log" 2>&1 + diff "$HERE/$ref" "$out" + if test $? -eq 0 + then + rm "$out" + else + bad=1 + fi +done + +if test $bad -eq 0 +then + echo "*** QC PASS ***" + exit 0 +else + exit 1 +fi + + Property changes on: tags/1.0.5/tests/export_abst/test.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/1.0.5/tests/export_spice/01_dc.cir.ref =================================================================== --- tags/1.0.5/tests/export_spice/01_dc.cir.ref (nonexistent) +++ tags/1.0.5/tests/export_spice/01_dc.cir.ref (revision 10414) @@ -0,0 +1,17 @@ +.title sch-rnd export using export_spice + +*** circuit *** +V1 in 0 DC 5V +R1 in out1 2.2k +R2 out1 out2 1k +R3 out2 0 1k + +*** sch-rnd/export_spice: commands *** +.control + +op +print v(out1) v(out2) + + +.endc +.end Index: tags/1.0.5/tests/export_spice/04_passive_tr.cir.ref =================================================================== --- tags/1.0.5/tests/export_spice/04_passive_tr.cir.ref (nonexistent) +++ tags/1.0.5/tests/export_spice/04_passive_tr.cir.ref (revision 10414) @@ -0,0 +1,17 @@ +.title sch-rnd export using export_spice + +*** circuit *** +V1 in 0 PULSE (0 5 1u 1u 1u 1 1) +C1 mid 0 1u +C2 out 0 1.2u +R1 in mid 10k +R2 mid out 15k + +*** sch-rnd/export_spice: commands *** +.control + +tran 0.1ms 200ms +plot v(in) v(mid) v(out) xlimit 0 200ms + +.endc +.end Index: tags/1.0.5/tests/export_spice/06_passive_ac.cir.ref =================================================================== --- tags/1.0.5/tests/export_spice/06_passive_ac.cir.ref (nonexistent) +++ tags/1.0.5/tests/export_spice/06_passive_ac.cir.ref (revision 10414) @@ -0,0 +1,27 @@ +.title sch-rnd export using export_spice + +*** circuit *** +V1 in 0 dc 0 ac 1 +C1 anon_net_3 0 1u +C2 out 0 100n +R1 in anon_net_3 10k +R2 anon_net_3 out 1k + +*** sch-rnd/export_spice: commands *** +.control + +ac dec 10 1 100k + +settype decibel out +plot vdb(out) xlimit 1 100k ylabel 'small signal gain' + +settype phase out +plot cph(out) xlimit 1 100k ylabel 'phase (in rad)' + +let outd = 180/PI*cph(out) +settype phase outd +plot outd xlimit 1 100k ylabel 'phase (in deg)' + + +.endc +.end Index: tags/1.0.5/tests/export_spice/10_bjt_amp_tr.cir.ref =================================================================== --- tags/1.0.5/tests/export_spice/10_bjt_amp_tr.cir.ref (nonexistent) +++ tags/1.0.5/tests/export_spice/10_bjt_amp_tr.cir.ref (revision 10414) @@ -0,0 +1,36 @@ +.title sch-rnd export using export_spice + +*** sch-rnd/export_spice: model card: _spice_model_card_bc817 *** +* (C) 2023 Tibor 'Igor2' Palinkas +* License: CC0 (no rights reserved): https://creativecommons.org/publicdomain/zero/1.0/ +* Source: based on Vishay's datasheet: https://archive.org/details/bc817_spice_vishay +* +.MODEL schrnd__spice_model_card_bc817 npn ( ++ IS=2.43485e-13 VAF=10 BF=270 IKF=1.12487 NE=1.84302 ISE=7.17747e-12 ++ IKR=0.149889 ISC=2.42047e-12 NC=3.94859 NR=1.04566 BR=2.51332 RC=0.407107 ++ CJC=5.516e-11 FC=0.8 MJC=0.529364 VJC=0.4 CJE=5.10473e-11 MJE=0.412728 ++ VJE=0.561234 TF=7.1424e-10 ITF=0.175457 VTF=1.86025 XTF=1.09929 RB=6.50128 ++ IRB=0.1 RBM=0.1 RE=0.0814215 TR=1e-07 ++ ) + + + +*** circuit *** +V1 in 0 SINE(0 0.01 1k) +C1 in int_b 10u +C2 int_c out 10u +V2 Vcc 0 dc 5 +Q1 int_c int_b 0 schrnd__spice_model_card_bc817 +R1 Vcc int_b 87k +R2 int_b 0 10k +R3 Vcc int_c 33k +R4 out 0 100k + +*** sch-rnd/export_spice: commands *** +.control + +tran 1u 10m +plot v(out) v(in) + +.endc +.end Index: tags/1.0.5/tests/export_spice/12_bjt_amp_ac.cir.ref =================================================================== --- tags/1.0.5/tests/export_spice/12_bjt_amp_ac.cir.ref (nonexistent) +++ tags/1.0.5/tests/export_spice/12_bjt_amp_ac.cir.ref (revision 10414) @@ -0,0 +1,40 @@ +.title sch-rnd export using export_spice + +*** sch-rnd/export_spice: model card: _spice_model_card_bc817 *** +* (C) 2023 Tibor 'Igor2' Palinkas +* License: CC0 (no rights reserved): https://creativecommons.org/publicdomain/zero/1.0/ +* Source: based on Vishay's datasheet: https://archive.org/details/bc817_spice_vishay +* +.MODEL schrnd__spice_model_card_bc817 npn ( ++ IS=2.43485e-13 VAF=10 BF=270 IKF=1.12487 NE=1.84302 ISE=7.17747e-12 ++ IKR=0.149889 ISC=2.42047e-12 NC=3.94859 NR=1.04566 BR=2.51332 RC=0.407107 ++ CJC=5.516e-11 FC=0.8 MJC=0.529364 VJC=0.4 CJE=5.10473e-11 MJE=0.412728 ++ VJE=0.561234 TF=7.1424e-10 ITF=0.175457 VTF=1.86025 XTF=1.09929 RB=6.50128 ++ IRB=0.1 RBM=0.1 RE=0.0814215 TR=1e-07 ++ ) + + + +*** circuit *** +V1 in 0 dc 0 ac 0.1 +C1 in int_b 10u +C2 int_c out 10u +V2 Vcc 0 dc 5 +Q1 int_c int_b 0 schrnd__spice_model_card_bc817 +R1 Vcc int_b 87k +R2 int_b 0 10k +R3 Vcc int_c 33k +R4 out 0 100k + +*** sch-rnd/export_spice: commands *** +.control + +ac dec 10 1 1000k +settype decibel out +plot vdb(out) xlimit 1 1000k ylabel 'small signal gain' +settype phase out +plot cph(out) xlimit 1 1000k ylabel 'phase (in rad)' + + +.endc +.end Index: tags/1.0.5/tests/export_spice/16_opamp_dc.cir.ref =================================================================== --- tags/1.0.5/tests/export_spice/16_opamp_dc.cir.ref (nonexistent) +++ tags/1.0.5/tests/export_spice/16_opamp_dc.cir.ref (revision 10414) @@ -0,0 +1,84 @@ +.title sch-rnd export using export_spice + +*** sch-rnd/export_spice: model card: _spice_model_card_lm358 *** +* lm358 - low power opamp model (single slot) +* +* (C) 2023 Tibor 'Igor2' Palinkas +* License: CC0 (no rights reserved): https://creativecommons.org/publicdomain/zero/1.0/ +* Source: from ST's datasheet: https://archive.org/details/st-ts321 +* (st321 is reasonably close to lm358 for simple simulation cases; see +* warnings on page 7) +* +* +** CONNECTIONS: +* 1 inverting input +* 2 non-inverting INPUT +* 3 output +* 4 positive power supply +* 5 negative power supply +.SUBCKT schrnd__spice_model_card_lm358 1 2 3 4 5 + +.MODEL MDTH D IS=1E-8 KF=3.104131E-15 CJO=10F + +* INPUT STAGE +CIP 2 5 1.000000E-12 +CIN 1 5 1.000000E-12 +EIP 10 5 2 5 1 +EIN 16 5 1 5 1 +RIP 10 11 2.600000E+01 +RIN 15 16 2.600000E+01 +RIS 11 15 2.003862E+02 +DIP 11 12 MDTH 400E-12 +DIN 15 14 MDTH 400E-12 +VOFP 12 13 DC 0 +VOFN 13 14 DC 0 +IPOL 13 5 1.000000E-05 +CPS 11 15 3.783376E-09 +DINN 17 13 MDTH 400E-12 +VIN 17 5 0.000000e+00 +DINR 15 18 MDTH 400E-12 +VIP 4 18 2.000000E+00 +FCP 4 5 VOFP 3.400000E+01 +FCN 5 4 VOFN 3.400000E+01 +FIBP 2 5 VOFN 2.000000E-03 +FIBN 5 1 VOFP 2.000000E-03 + +* AMPLIFYING STAGE +FIP 5 19 VOFP 3.600000E+02 +FIN 5 19 VOFN 3.600000E+02 +RG1 19 5 3.652997E+06 +RG2 19 4 3.652997E+06 +CC 19 5 6.000000E-09 +DOPM 19 22 MDTH 400E-12 +DONM 21 19 MDTH 400E-12 +HOPM 22 28 VOUT 7.500000E+03 +VIPM 28 4 1.500000E+02 +HONM 21 27 VOUT 7.500000E+03 +VINM 5 27 1.500000E+02 +EOUT 26 23 19 5 1 +VOUT 23 5 0 +ROUT 26 3 20 +COUT 3 5 1.000000E-12 +DOP 19 25 MDTH 400E-12 +VOP 4 25 2.242230E+00 +DON 24 19 MDTH 400E-12 +VON 24 5 7.922301E-01 +.ENDS + + +*** circuit *** +V1 in 0 dc 0 +V2 Vcc 0 dc 5 +X_U1__1 anon_net_1 0 out Vcc Vneg schrnd__spice_model_card_lm358 +V3 0 Vneg dc 5 +R1 in anon_net_1 1k +R2 anon_net_1 out 100k + +*** sch-rnd/export_spice: commands *** +.control + + dc V1 -50m 60m 2m +plot v(in) v(out) + +.endc +.end Index: tags/1.0.5/tests/export_spice/18_opamp_ac.cir.ref =================================================================== --- tags/1.0.5/tests/export_spice/18_opamp_ac.cir.ref (nonexistent) +++ tags/1.0.5/tests/export_spice/18_opamp_ac.cir.ref (revision 10414) @@ -0,0 +1,94 @@ +.title sch-rnd export using export_spice + +*** sch-rnd/export_spice: model card: _spice_model_card_lm358 *** +* lm358 - low power opamp model (single slot) +* +* (C) 2023 Tibor 'Igor2' Palinkas +* License: CC0 (no rights reserved): https://creativecommons.org/publicdomain/zero/1.0/ +* Source: from ST's datasheet: https://archive.org/details/st-ts321 +* (st321 is reasonably close to lm358 for simple simulation cases; see +* warnings on page 7) +* +* +** CONNECTIONS: +* 1 inverting input +* 2 non-inverting INPUT +* 3 output +* 4 positive power supply +* 5 negative power supply +.SUBCKT schrnd__spice_model_card_lm358 1 2 3 4 5 + +.MODEL MDTH D IS=1E-8 KF=3.104131E-15 CJO=10F + +* INPUT STAGE +CIP 2 5 1.000000E-12 +CIN 1 5 1.000000E-12 +EIP 10 5 2 5 1 +EIN 16 5 1 5 1 +RIP 10 11 2.600000E+01 +RIN 15 16 2.600000E+01 +RIS 11 15 2.003862E+02 +DIP 11 12 MDTH 400E-12 +DIN 15 14 MDTH 400E-12 +VOFP 12 13 DC 0 +VOFN 13 14 DC 0 +IPOL 13 5 1.000000E-05 +CPS 11 15 3.783376E-09 +DINN 17 13 MDTH 400E-12 +VIN 17 5 0.000000e+00 +DINR 15 18 MDTH 400E-12 +VIP 4 18 2.000000E+00 +FCP 4 5 VOFP 3.400000E+01 +FCN 5 4 VOFN 3.400000E+01 +FIBP 2 5 VOFN 2.000000E-03 +FIBN 5 1 VOFP 2.000000E-03 + +* AMPLIFYING STAGE +FIP 5 19 VOFP 3.600000E+02 +FIN 5 19 VOFN 3.600000E+02 +RG1 19 5 3.652997E+06 +RG2 19 4 3.652997E+06 +CC 19 5 6.000000E-09 +DOPM 19 22 MDTH 400E-12 +DONM 21 19 MDTH 400E-12 +HOPM 22 28 VOUT 7.500000E+03 +VIPM 28 4 1.500000E+02 +HONM 21 27 VOUT 7.500000E+03 +VINM 5 27 1.500000E+02 +EOUT 26 23 19 5 1 +VOUT 23 5 0 +ROUT 26 3 20 +COUT 3 5 1.000000E-12 +DOP 19 25 MDTH 400E-12 +VOP 4 25 2.242230E+00 +DON 24 19 MDTH 400E-12 +VON 24 5 7.922301E-01 +.ENDS + + +*** circuit *** +R5 anon_net_9 0 10k +R4 out anon_net_9 250 +V1 in 0 dc 0 ac 0.1 +V2 Vcc 0 dc 5 +X_U1__1 out anon_net_13 out Vcc Vneg schrnd__spice_model_card_lm358 +V3 0 Vneg dc 5 +X_U1__2 anon_net_12 anon_net_9 anon_net_12 Vcc Vneg schrnd__spice_model_card_lm358 +C2 anon_net_10 anon_net_13 100n +C3 anon_net_11 anon_net_12 200n +C1 in anon_net_10 100n +R1 in anon_net_11 1600 +R2 anon_net_11 anon_net_13 1600 +R3 anon_net_10 anon_net_12 800 + +*** sch-rnd/export_spice: commands *** +.control + +ac dec 10 1 1000k +settype decibel out +plot vdb(out) xlimit 1 1000k ylabel 'small signal gain' +settype phase out +plot cph(out) xlimit 1 1000k ylabel 'phase (in rad)' + +.endc +.end Index: tags/1.0.5/tests/export_spice/22_custom_sym.cir.ref =================================================================== --- tags/1.0.5/tests/export_spice/22_custom_sym.cir.ref (nonexistent) +++ tags/1.0.5/tests/export_spice/22_custom_sym.cir.ref (revision 10414) @@ -0,0 +1,18 @@ +.title sch-rnd export using export_spice + +*** sch-rnd/export_spice: model card: U1 *** +.MODEL schrnd_U1 D (IS=2f RS=3.4 N=2.2) + +*** circuit *** +V1 in 0 SINE(0 20 1k) +D_U1 0 out schrnd_U1 +R1 in out 100 + +*** sch-rnd/export_spice: commands *** +.control + +tran 1u 4m +plot v(out) v(in) + +.endc +.end Index: tags/1.0.5/tests/export_spice/30_mixed.cir.ref =================================================================== --- tags/1.0.5/tests/export_spice/30_mixed.cir.ref (nonexistent) +++ tags/1.0.5/tests/export_spice/30_mixed.cir.ref (revision 10414) @@ -0,0 +1,43 @@ +.title sch-rnd export using export_spice + +*** sch-rnd/export_spice: model card: U1 *** +.MODEL schrnd_U1 d_xor (rise_delay=1.0e-6 fall_delay=2.0e-6 ++ input_load=1.0e-12) + +*** sch-rnd/export_spice: model card: bridge_dac_ttl *** +* (C) 2023 Tibor 'Igor2' Palinkas +* License: CC0 (no rights reserved): https://creativecommons.org/publicdomain/zero/1.0/ +* +* source: https://www.allaboutcircuits.com/textbook/digital/chpt-3/logic-signal-voltage-levels/ + +.MODEL bridge_dac_ttl dac_bridge( ++ out_low = 0 out_high = 5 out_undef = 1.4 ++ input_load = 5.0e-12 t_rise = 50e-9 t_fall = 20e-9) + + +*** sch-rnd/export_spice: model card: bridge_adc_ttl *** +* (C) 2023 Tibor 'Igor2' Palinkas +* License: CC0 (no rights reserved): https://creativecommons.org/publicdomain/zero/1.0/ +* +* source: https://www.allaboutcircuits.com/textbook/digital/chpt-3/logic-signal-voltage-levels/ + +.MODEL bridge_adc_ttl adc_bridge ++ (in_low=0.8 in_high=2.0 rise_delay=1.0e-12 fall_delay=1.0e-12) + + +*** circuit *** +A_U1 [br_bridge_adc_ttl_0 br_bridge_adc_ttl_1] br_bridge_dac_ttl_0 schrnd_U1 +V1 input1 0 PULSE (0 5 1 0.3 0.3 2 10) +V2 input2 0 PULSE (0 5 2 0.3 0.3 2 4) +A_sch_rnd_br_bridge_dac_ttl [br_bridge_dac_ttl_0] [output] bridge_dac_ttl +A_sch_rnd_br_bridge_adc_ttl [input1 input2] [br_bridge_adc_ttl_0 br_bridge_adc_ttl_1] bridge_adc_ttl +R1 output 0 100k + +*** sch-rnd/export_spice: commands *** +.control + +tran 10ms 6s +plot v(input1)+0.04 v(input2)+0.08 v(output) xlimit 0 6s + +.endc +.end Index: tags/1.0.5/tests/export_spice/Makefile =================================================================== --- tags/1.0.5/tests/export_spice/Makefile (nonexistent) +++ tags/1.0.5/tests/export_spice/Makefile (revision 10414) @@ -0,0 +1,11 @@ +all: + +test: + ./test.sh + +clean: + touch dummy.cir.out + rm *.cir.out + +distclean: clean + Index: tags/1.0.5/tests/export_spice/test.sh =================================================================== --- tags/1.0.5/tests/export_spice/test.sh (nonexistent) +++ tags/1.0.5/tests/export_spice/test.sh (revision 10414) @@ -0,0 +1,34 @@ +#!/bin/sh +root=../.. +tut=$root/doc/tutorial/simulation/raw +src=$root/src/sch-rnd +here=`pwd` +refs=`ls *.cir.ref` +opts="-c rc/quiet=1" + +bad=0 +all=0 +cd $src +for n in $refs +do + bn=${n%%.cir.ref} + ./sch-rnd $opts -x spice --view spice_raw --outfile $here/$bn.cir.out $tut/$bn.rs + diff $here/$bn.cir.ref $here/$bn.cir.out + if test $? = 0 + then + rm $here/$bn.cir.out + else + echo "BROKEN spice: $n" + bad=$(($bad+1)) + fi + all=$(($all+1)) +done + +if test $bad = 0 +then + echo "*** QC PASS ***" + true +else + echo "Failed raw spice tests: $bad of $all" + false +fi Property changes on: tags/1.0.5/tests/export_spice/test.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/1.0.5/tests/hier/Makefile =================================================================== --- tags/1.0.5/tests/hier/Makefile (nonexistent) +++ tags/1.0.5/tests/hier/Makefile (revision 10414) @@ -0,0 +1,11 @@ +all: + +test: + @for n in *; do if test -d $$n; then cd $$n && make test || exit 1; cd ..; fi; done + @echo "*** QC PASS ***" + +clean: + @for n in *; do if test -d $$n; then cd $$n && make clean; cd ..; fi; done + +distclean: + @for n in *; do if test -d $$n; then cd $$n && make distclean; cd ..; fi; done Index: tags/1.0.5/tests/hier/cl1/Makefile =================================================================== --- tags/1.0.5/tests/hier/cl1/Makefile (nonexistent) +++ tags/1.0.5/tests/hier/cl1/Makefile (revision 10414) @@ -0,0 +1,14 @@ +ROOT=../../.. +SRC=$(ROOT)/src/sch-rnd +HERE=$(shell pwd) + +all: + +test: + @cd $(SRC) && ./sch-rnd -x abst --outfile $(HERE)/abst.out $(HERE)/project.lht && cd $(HERE) + @diff -u abst.ref abst.out + @rm abst.out + +distclean clean: + touch abst.out + rm abst.out Index: tags/1.0.5/tests/hier/cl1/abst.ref =================================================================== --- tags/1.0.5/tests/hier/cl1/abst.ref (nonexistent) +++ tags/1.0.5/tests/hier/cl1/abst.ref (revision 10414) @@ -0,0 +1,46 @@ +cschem abstract model v1 +components + S0 + OMIT + attributes + ports + foo1 + attributes + loc_l1=1 + spice/omit=yes + loc_l2=1 + role=symbol + loc_l0=1 + name=foo1 + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + foo2 + attributes + loc_l1=1 + spice/omit=yes + loc_l2=1 + role=symbol + loc_l0=1 + name=foo2 + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + S0/S1 + OMIT + attributes + ports +nets + foo + attributes + role=wire-net + name=foo + conns 2 + foo1-1 + foo2-1 Index: tags/1.0.5/tests/hier/cl1/l0.rs =================================================================== --- tags/1.0.5/tests/hier/cl1/l0.rs (nonexistent) +++ tags/1.0.5/tests/hier/cl1/l0.rs (revision 10414) @@ -0,0 +1,158 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=aym2tojMMW6UVaugMwQAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.2 { + uuid=aym2tojMMW6UVaugMwQAAAAH; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=76000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAI; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=foo1 + loc_l0=1 + role=symbol + spice/omit=yes + } + } + ha:group.4 { + uuid=aym2tojMMW6UVaugMwQAAAAP; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=104000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAQ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=foo2 + loc_l0=1 + role=symbol + spice/omit=yes + } + } + ha:group.5 { + uuid=aym2tojMMW6UVaugMwQAAAAR; + li:objects { + ha:line.1 { x1=76000; y1=136000; x2=104000; y2=136000; stroke=wire; } + ha:text.2 { x1=92000; y1=136000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=foo + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.6 { + li:conn { + /2/5/1 + /2/2/1/1 + } + } + ha:connection.7 { + li:conn { + /2/5/1 + /2/4/1/1 + } + } + ha:group.9 { + uuid=aym2tojMMW6UVaugMwQAAAAS; + x=120000; y=116000; + li:objects { + ha:polygon.1 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=-20000; } + ha:line { x1=0; y1=-20000; x2=20000; y2=-20000; } + ha:line { x1=20000; y1=-20000; x2=20000; y2=0; } + ha:line { x1=20000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + ha:text.2 { x1=8000; y1=-12000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + cschem/child/name=l1 + name=S0 + role=symbol + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer= + page= + print_page=A/4 + title= + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 2 + grid = 4.0960 mm + } + } + } +} Index: tags/1.0.5/tests/hier/cl1/l1.rs =================================================================== --- tags/1.0.5/tests/hier/cl1/l1.rs (nonexistent) +++ tags/1.0.5/tests/hier/cl1/l1.rs (revision 10414) @@ -0,0 +1,135 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=aym2tojMMW6UVaugMwQAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.2 { + uuid=aym2tojMMW6UVaugMwQAAAAH; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=76000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAI; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + loc_l1=1 + name=foo1 + role=symbol + spice/omit=yes + } + } + ha:group.4 { + uuid=aym2tojMMW6UVaugMwQAAAAP; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=104000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAQ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + loc_l1=1 + name=foo2 + role=symbol + spice/omit=yes + } + } + ha:group.9 { + uuid=aym2tojMMW6UVaugMwQAAAAS; + x=120000; y=116000; + li:objects { + ha:polygon.1 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=-20000; } + ha:line { x1=0; y1=-20000; x2=20000; y2=-20000; } + ha:line { x1=20000; y1=-20000; x2=20000; y2=0; } + ha:line { x1=20000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + ha:text.2 { x1=8000; y1=-12000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + cschem/child/name=l2 + name=S1 + role=symbol + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer= + page= + print_page=A/4 + title= + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 2 + grid = 4.0960 mm + } + } + } +} Index: tags/1.0.5/tests/hier/cl1/l2.rs =================================================================== --- tags/1.0.5/tests/hier/cl1/l2.rs (nonexistent) +++ tags/1.0.5/tests/hier/cl1/l2.rs (revision 10414) @@ -0,0 +1,113 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=aym2tojMMW6UVaugMwQAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.2 { + uuid=aym2tojMMW6UVaugMwQAAAAH; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=76000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAI; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + loc_l2=1 + name=foo1 + role=symbol + spice/omit=yes + } + } + ha:group.4 { + uuid=aym2tojMMW6UVaugMwQAAAAP; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=104000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAQ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + loc_l2=1 + name=foo2 + role=symbol + spice/omit=yes + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer= + page= + print_page=A/4 + title= + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 2 + grid = 4.0960 mm + } + } + } +} Index: tags/1.0.5/tests/hier/cl1/project.lht =================================================================== --- tags/1.0.5/tests/hier/cl1/project.lht (nonexistent) +++ tags/1.0.5/tests/hier/cl1/project.lht (revision 10414) @@ -0,0 +1,15 @@ +ha:coraleda-project-v1 { + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:prj { + li:root_sheets { + l0.rs + } + li:aux_sheets { + l1.rs + l2.rs + } + } + } + } +} Index: tags/1.0.5/tests/hier/cl2/Makefile =================================================================== --- tags/1.0.5/tests/hier/cl2/Makefile (nonexistent) +++ tags/1.0.5/tests/hier/cl2/Makefile (revision 10414) @@ -0,0 +1,14 @@ +ROOT=../../.. +SRC=$(ROOT)/src/sch-rnd +HERE=$(shell pwd) + +all: + +test: + @cd $(SRC) && ./sch-rnd -x abst --outfile $(HERE)/abst.out $(HERE)/project.lht && cd $(HERE) + @diff -u abst.ref abst.out + @rm abst.out + +distclean clean: + touch abst.out + rm abst.out Index: tags/1.0.5/tests/hier/cl2/abst.ref =================================================================== --- tags/1.0.5/tests/hier/cl2/abst.ref (nonexistent) +++ tags/1.0.5/tests/hier/cl2/abst.ref (revision 10414) @@ -0,0 +1,92 @@ +cschem abstract model v1 +components + S0 + OMIT + attributes + ports + S0/foo1 + attributes + spice/omit=yes + role=symbol + name=foo1 + loc_l1=1 + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + S0/foo2 + attributes + spice/omit=yes + role=symbol + name=foo2 + loc_l1=1 + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + S0/S1 + OMIT + attributes + ports + foo1 + attributes + spice/omit=yes + role=symbol + loc_l0=1 + name=foo1 + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + foo2 + attributes + spice/omit=yes + role=symbol + loc_l0=1 + name=foo2 + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + S0/S1/foo1 + attributes + loc_l2=1 + spice/omit=yes + role=symbol + name=foo1 + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + S0/S1/foo2 + attributes + loc_l2=1 + spice/omit=yes + role=symbol + name=foo2 + ports + 1 + attributes + role=terminal + display/name=1 + name=1 +nets + foo + attributes + role=wire-net + name=foo + conns 4 + S0/foo1-1 + S0/foo2-1 + foo1-1 + foo2-1 Index: tags/1.0.5/tests/hier/cl2/l0.rs =================================================================== --- tags/1.0.5/tests/hier/cl2/l0.rs (nonexistent) +++ tags/1.0.5/tests/hier/cl2/l0.rs (revision 10414) @@ -0,0 +1,158 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=aym2tojMMW6UVaugMwQAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.2 { + uuid=aym2tojMMW6UVaugMwQAAAAH; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=76000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAI; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=foo1 + loc_l0=1 + role=symbol + spice/omit=yes + } + } + ha:group.4 { + uuid=aym2tojMMW6UVaugMwQAAAAP; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=104000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAQ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=foo2 + loc_l0=1 + role=symbol + spice/omit=yes + } + } + ha:group.5 { + uuid=aym2tojMMW6UVaugMwQAAAAR; + li:objects { + ha:line.1 { x1=76000; y1=136000; x2=104000; y2=136000; stroke=wire; } + ha:text.2 { x1=92000; y1=136000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=foo + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.6 { + li:conn { + /2/5/1 + /2/2/1/1 + } + } + ha:connection.7 { + li:conn { + /2/5/1 + /2/4/1/1 + } + } + ha:group.9 { + uuid=aym2tojMMW6UVaugMwQAAAAS; + x=120000; y=116000; + li:objects { + ha:polygon.1 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=-20000; } + ha:line { x1=0; y1=-20000; x2=20000; y2=-20000; } + ha:line { x1=20000; y1=-20000; x2=20000; y2=0; } + ha:line { x1=20000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + ha:text.2 { x1=8000; y1=-12000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + cschem/child/name=l1 + name=S0 + role=symbol + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer= + page= + print_page=A/4 + title= + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 2 + grid = 4.0960 mm + } + } + } +} Index: tags/1.0.5/tests/hier/cl2/l1.rs =================================================================== --- tags/1.0.5/tests/hier/cl2/l1.rs (nonexistent) +++ tags/1.0.5/tests/hier/cl2/l1.rs (revision 10414) @@ -0,0 +1,158 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=aym2tojMMW6UVaugMwQAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.2 { + uuid=aym2tojMMW6UVaugMwQAAAAH; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=76000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAI; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + loc_l1=1 + name=./foo1 + role=symbol + spice/omit=yes + } + } + ha:group.4 { + uuid=aym2tojMMW6UVaugMwQAAAAP; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=104000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAQ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + loc_l1=1 + name=./foo2 + role=symbol + spice/omit=yes + } + } + ha:group.9 { + uuid=aym2tojMMW6UVaugMwQAAAAS; + x=120000; y=116000; + li:objects { + ha:polygon.1 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=-20000; } + ha:line { x1=0; y1=-20000; x2=20000; y2=-20000; } + ha:line { x1=20000; y1=-20000; x2=20000; y2=0; } + ha:line { x1=20000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + ha:text.2 { x1=8000; y1=-12000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + cschem/child/name=l2 + name=S1 + role=symbol + } + } + ha:group.10 { + uuid=VengxTD2fZSSXcqWCxwAAAAR; src_uuid=aym2tojMMW6UVaugMwQAAAAR; + li:objects { + ha:line.1 { x1=76000; y1=136000; x2=104000; y2=136000; stroke=wire; } + ha:text.2 { x1=92000; y1=136000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=foo + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.11 { + li:conn { + /2/10/1 + /2/2/1/1 + } + } + ha:connection.12 { + li:conn { + /2/10/1 + /2/4/1/1 + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer= + page= + print_page=A/4 + title= + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 2 + grid = 4.0960 mm + } + } + } +} Index: tags/1.0.5/tests/hier/cl2/l2.rs =================================================================== --- tags/1.0.5/tests/hier/cl2/l2.rs (nonexistent) +++ tags/1.0.5/tests/hier/cl2/l2.rs (revision 10414) @@ -0,0 +1,113 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=aym2tojMMW6UVaugMwQAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.2 { + uuid=aym2tojMMW6UVaugMwQAAAAH; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=76000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAI; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + loc_l2=1 + name=./foo1 + role=symbol + spice/omit=yes + } + } + ha:group.4 { + uuid=aym2tojMMW6UVaugMwQAAAAP; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=104000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAQ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + loc_l2=1 + name=./foo2 + role=symbol + spice/omit=yes + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer= + page= + print_page=A/4 + title= + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 2 + grid = 4.0960 mm + } + } + } +} Index: tags/1.0.5/tests/hier/cl2/project.lht =================================================================== --- tags/1.0.5/tests/hier/cl2/project.lht (nonexistent) +++ tags/1.0.5/tests/hier/cl2/project.lht (revision 10414) @@ -0,0 +1,15 @@ +ha:coraleda-project-v1 { + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:prj { + li:root_sheets { + l0.rs + } + li:aux_sheets { + l1.rs + l2.rs + } + } + } + } +} Index: tags/1.0.5/tests/hier/cl3/Makefile =================================================================== --- tags/1.0.5/tests/hier/cl3/Makefile (nonexistent) +++ tags/1.0.5/tests/hier/cl3/Makefile (revision 10414) @@ -0,0 +1,14 @@ +ROOT=../../.. +SRC=$(ROOT)/src/sch-rnd +HERE=$(shell pwd) + +all: + +test: + @cd $(SRC) && ./sch-rnd -x abst --outfile $(HERE)/abst.out $(HERE)/project.lht && cd $(HERE) + @diff -u abst.ref abst.out + @rm abst.out + +distclean clean: + touch abst.out + rm abst.out Index: tags/1.0.5/tests/hier/cl3/abst.ref =================================================================== --- tags/1.0.5/tests/hier/cl3/abst.ref (nonexistent) +++ tags/1.0.5/tests/hier/cl3/abst.ref (revision 10414) @@ -0,0 +1,70 @@ +cschem abstract model v1 +components + S0 + OMIT + attributes + ports + S0/foo1 + attributes + spice/omit=yes + role=symbol + name=foo1 + loc_l1=1 + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + foo1 + attributes + loc_l2=1 + spice/omit=yes + role=symbol + loc_l0=1 + name=foo1 + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + foo2 + attributes + loc_l2=1 + spice/omit=yes + role=symbol + loc_l0=1 + name=foo2 + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + S0/foo2 + attributes + spice/omit=yes + role=symbol + name=foo2 + loc_l1=1 + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + S0/S1 + OMIT + attributes + ports +nets + foo + attributes + role=wire-net + name=foo + conns 4 + S0/foo1-1 + S0/foo2-1 + foo1-1 + foo2-1 Index: tags/1.0.5/tests/hier/cl3/l0.rs =================================================================== --- tags/1.0.5/tests/hier/cl3/l0.rs (nonexistent) +++ tags/1.0.5/tests/hier/cl3/l0.rs (revision 10414) @@ -0,0 +1,158 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=aym2tojMMW6UVaugMwQAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.2 { + uuid=aym2tojMMW6UVaugMwQAAAAH; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=76000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAI; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=foo1 + loc_l0=1 + role=symbol + spice/omit=yes + } + } + ha:group.4 { + uuid=aym2tojMMW6UVaugMwQAAAAP; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=104000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAQ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=foo2 + loc_l0=1 + role=symbol + spice/omit=yes + } + } + ha:group.5 { + uuid=aym2tojMMW6UVaugMwQAAAAR; + li:objects { + ha:line.1 { x1=76000; y1=136000; x2=104000; y2=136000; stroke=wire; } + ha:text.2 { x1=92000; y1=136000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=foo + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.6 { + li:conn { + /2/5/1 + /2/2/1/1 + } + } + ha:connection.7 { + li:conn { + /2/5/1 + /2/4/1/1 + } + } + ha:group.9 { + uuid=aym2tojMMW6UVaugMwQAAAAS; + x=120000; y=116000; + li:objects { + ha:polygon.1 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=-20000; } + ha:line { x1=0; y1=-20000; x2=20000; y2=-20000; } + ha:line { x1=20000; y1=-20000; x2=20000; y2=0; } + ha:line { x1=20000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + ha:text.2 { x1=8000; y1=-12000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + cschem/child/name=l1 + name=S0 + role=symbol + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer= + page= + print_page=A/4 + title= + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 2 + grid = 4.0960 mm + } + } + } +} Index: tags/1.0.5/tests/hier/cl3/l1.rs =================================================================== --- tags/1.0.5/tests/hier/cl3/l1.rs (nonexistent) +++ tags/1.0.5/tests/hier/cl3/l1.rs (revision 10414) @@ -0,0 +1,158 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=aym2tojMMW6UVaugMwQAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.2 { + uuid=aym2tojMMW6UVaugMwQAAAAH; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=76000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAI; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + loc_l1=1 + name=./foo1 + role=symbol + spice/omit=yes + } + } + ha:group.4 { + uuid=aym2tojMMW6UVaugMwQAAAAP; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=104000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAQ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + loc_l1=1 + name=./foo2 + role=symbol + spice/omit=yes + } + } + ha:group.9 { + uuid=aym2tojMMW6UVaugMwQAAAAS; + x=120000; y=116000; + li:objects { + ha:polygon.1 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=-20000; } + ha:line { x1=0; y1=-20000; x2=20000; y2=-20000; } + ha:line { x1=20000; y1=-20000; x2=20000; y2=0; } + ha:line { x1=20000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + ha:text.2 { x1=8000; y1=-12000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + cschem/child/name=l2 + name=S1 + role=symbol + } + } + ha:group.10 { + uuid=VengxTD2fZSSXcqWCxwAAAAR; src_uuid=aym2tojMMW6UVaugMwQAAAAR; + li:objects { + ha:line.1 { x1=76000; y1=136000; x2=104000; y2=136000; stroke=wire; } + ha:text.2 { x1=92000; y1=136000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=foo + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.11 { + li:conn { + /2/10/1 + /2/2/1/1 + } + } + ha:connection.12 { + li:conn { + /2/10/1 + /2/4/1/1 + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer= + page= + print_page=A/4 + title= + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 2 + grid = 4.0960 mm + } + } + } +} Index: tags/1.0.5/tests/hier/cl3/l2.rs =================================================================== --- tags/1.0.5/tests/hier/cl3/l2.rs (nonexistent) +++ tags/1.0.5/tests/hier/cl3/l2.rs (revision 10414) @@ -0,0 +1,113 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=aym2tojMMW6UVaugMwQAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.2 { + uuid=aym2tojMMW6UVaugMwQAAAAH; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=76000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAI; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + loc_l2=1 + name=foo1 + role=symbol + spice/omit=yes + } + } + ha:group.4 { + uuid=aym2tojMMW6UVaugMwQAAAAP; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=104000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAQ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + loc_l2=1 + name=foo2 + role=symbol + spice/omit=yes + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer= + page= + print_page=A/4 + title= + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 2 + grid = 4.0960 mm + } + } + } +} Index: tags/1.0.5/tests/hier/cl3/project.lht =================================================================== --- tags/1.0.5/tests/hier/cl3/project.lht (nonexistent) +++ tags/1.0.5/tests/hier/cl3/project.lht (revision 10414) @@ -0,0 +1,15 @@ +ha:coraleda-project-v1 { + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:prj { + li:root_sheets { + l0.rs + } + li:aux_sheets { + l1.rs + l2.rs + } + } + } + } +} Index: tags/1.0.5/tests/hier/clg/Makefile =================================================================== --- tags/1.0.5/tests/hier/clg/Makefile (nonexistent) +++ tags/1.0.5/tests/hier/clg/Makefile (revision 10414) @@ -0,0 +1,14 @@ +ROOT=../../.. +SRC=$(ROOT)/src/sch-rnd +HERE=$(shell pwd) + +all: + +test: + @cd $(SRC) && ./sch-rnd -x abst --outfile $(HERE)/abst.out $(HERE)/project.lht && cd $(HERE) + @diff -u abst.ref abst.out + @rm abst.out + +distclean clean: + touch abst.out + rm abst.out Index: tags/1.0.5/tests/hier/clg/abst.ref =================================================================== --- tags/1.0.5/tests/hier/clg/abst.ref (nonexistent) +++ tags/1.0.5/tests/hier/clg/abst.ref (revision 10414) @@ -0,0 +1,68 @@ +cschem abstract model v1 +components + S0 + OMIT + attributes + ports + S0/foo1 + attributes + spice/omit=yes + role=symbol + name=foo1 + loc_l1=1 + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + foo1 + attributes + loc_l2=1 + spice/omit=yes + role=symbol + loc_l0=1 + name=foo1 + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + foo2 + attributes + loc_l2=1 + spice/omit=yes + role=symbol + loc_l0=1 + name=foo2 + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + S0/foo2 + attributes + spice/omit=yes + role=symbol + name=foo2 + loc_l1=1 + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + S0/S1 + OMIT + attributes + ports +nets + foo + attributes + role=wire-net + name=foo + conns 2 + foo1-1 + foo2-1 Index: tags/1.0.5/tests/hier/clg/l0.rs =================================================================== --- tags/1.0.5/tests/hier/clg/l0.rs (nonexistent) +++ tags/1.0.5/tests/hier/clg/l0.rs (revision 10414) @@ -0,0 +1,158 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=aym2tojMMW6UVaugMwQAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.2 { + uuid=aym2tojMMW6UVaugMwQAAAAH; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=76000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAI; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=foo1 + loc_l0=1 + role=symbol + spice/omit=yes + } + } + ha:group.4 { + uuid=aym2tojMMW6UVaugMwQAAAAP; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=104000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAQ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=foo2 + loc_l0=1 + role=symbol + spice/omit=yes + } + } + ha:group.5 { + uuid=aym2tojMMW6UVaugMwQAAAAR; + li:objects { + ha:line.1 { x1=76000; y1=136000; x2=104000; y2=136000; stroke=wire; } + ha:text.2 { x1=92000; y1=136000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=foo + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.6 { + li:conn { + /2/5/1 + /2/2/1/1 + } + } + ha:connection.7 { + li:conn { + /2/5/1 + /2/4/1/1 + } + } + ha:group.9 { + uuid=aym2tojMMW6UVaugMwQAAAAS; + x=120000; y=116000; + li:objects { + ha:polygon.1 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=-20000; } + ha:line { x1=0; y1=-20000; x2=20000; y2=-20000; } + ha:line { x1=20000; y1=-20000; x2=20000; y2=0; } + ha:line { x1=20000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + ha:text.2 { x1=8000; y1=-12000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + cschem/child/name=l1 + name=S0 + role=symbol + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer= + page= + print_page=A/4 + title= + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 2 + grid = 4.0960 mm + } + } + } +} Index: tags/1.0.5/tests/hier/clg/l1.rs =================================================================== --- tags/1.0.5/tests/hier/clg/l1.rs (nonexistent) +++ tags/1.0.5/tests/hier/clg/l1.rs (revision 10414) @@ -0,0 +1,135 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=aym2tojMMW6UVaugMwQAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.2 { + uuid=aym2tojMMW6UVaugMwQAAAAH; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=76000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAI; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + loc_l1=1 + name=v/foo1 + role=symbol + spice/omit=yes + } + } + ha:group.4 { + uuid=aym2tojMMW6UVaugMwQAAAAP; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=104000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAQ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + loc_l1=1 + name=v/foo2 + role=symbol + spice/omit=yes + } + } + ha:group.9 { + uuid=aym2tojMMW6UVaugMwQAAAAS; + x=120000; y=116000; + li:objects { + ha:polygon.1 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=-20000; } + ha:line { x1=0; y1=-20000; x2=20000; y2=-20000; } + ha:line { x1=20000; y1=-20000; x2=20000; y2=0; } + ha:line { x1=20000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + ha:text.2 { x1=8000; y1=-12000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + cschem/child/name=l2 + name=S1 + role=symbol + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer= + page= + print_page=A/4 + title= + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 2 + grid = 4.0960 mm + } + } + } +} Index: tags/1.0.5/tests/hier/clg/l2.rs =================================================================== --- tags/1.0.5/tests/hier/clg/l2.rs (nonexistent) +++ tags/1.0.5/tests/hier/clg/l2.rs (revision 10414) @@ -0,0 +1,113 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=aym2tojMMW6UVaugMwQAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.2 { + uuid=aym2tojMMW6UVaugMwQAAAAH; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=76000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAI; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + loc_l2=1 + name=/foo1 + role=symbol + spice/omit=yes + } + } + ha:group.4 { + uuid=aym2tojMMW6UVaugMwQAAAAP; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=104000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAQ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + loc_l2=1 + name=/foo2 + role=symbol + spice/omit=yes + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer= + page= + print_page=A/4 + title= + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 2 + grid = 4.0960 mm + } + } + } +} Index: tags/1.0.5/tests/hier/clg/project.lht =================================================================== --- tags/1.0.5/tests/hier/clg/project.lht (nonexistent) +++ tags/1.0.5/tests/hier/clg/project.lht (revision 10414) @@ -0,0 +1,15 @@ +ha:coraleda-project-v1 { + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:prj { + li:root_sheets { + l0.rs + } + li:aux_sheets { + l1.rs + l2.rs + } + } + } + } +} Index: tags/1.0.5/tests/hier/clup/Makefile =================================================================== --- tags/1.0.5/tests/hier/clup/Makefile (nonexistent) +++ tags/1.0.5/tests/hier/clup/Makefile (revision 10414) @@ -0,0 +1,14 @@ +ROOT=../../.. +SRC=$(ROOT)/src/sch-rnd +HERE=$(shell pwd) + +all: + +test: + @cd $(SRC) && ./sch-rnd -x abst --outfile $(HERE)/abst.out $(HERE)/project.lht && cd $(HERE) + @diff -u abst.ref abst.out + @rm abst.out + +distclean clean: + touch abst.out + rm abst.out Index: tags/1.0.5/tests/hier/clup/abst.ref =================================================================== --- tags/1.0.5/tests/hier/clup/abst.ref (nonexistent) +++ tags/1.0.5/tests/hier/clup/abst.ref (revision 10414) @@ -0,0 +1,68 @@ +cschem abstract model v1 +components + S0 + OMIT + attributes + ports + S0/foo1 + attributes + loc_l2=1 + spice/omit=yes + role=symbol + name=foo1 + loc_l1=1 + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + foo1 + attributes + spice/omit=yes + role=symbol + loc_l0=1 + name=foo1 + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + foo2 + attributes + spice/omit=yes + role=symbol + loc_l0=1 + name=foo2 + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + S0/foo2 + attributes + loc_l2=1 + spice/omit=yes + role=symbol + name=foo2 + loc_l1=1 + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + S0/S1 + OMIT + attributes + ports +nets + foo + attributes + role=wire-net + name=foo + conns 2 + foo1-1 + foo2-1 Index: tags/1.0.5/tests/hier/clup/l0.rs =================================================================== --- tags/1.0.5/tests/hier/clup/l0.rs (nonexistent) +++ tags/1.0.5/tests/hier/clup/l0.rs (revision 10414) @@ -0,0 +1,158 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=aym2tojMMW6UVaugMwQAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.2 { + uuid=aym2tojMMW6UVaugMwQAAAAH; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=76000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAI; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=foo1 + loc_l0=1 + role=symbol + spice/omit=yes + } + } + ha:group.4 { + uuid=aym2tojMMW6UVaugMwQAAAAP; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=104000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAQ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=foo2 + loc_l0=1 + role=symbol + spice/omit=yes + } + } + ha:group.5 { + uuid=aym2tojMMW6UVaugMwQAAAAR; + li:objects { + ha:line.1 { x1=76000; y1=136000; x2=104000; y2=136000; stroke=wire; } + ha:text.2 { x1=92000; y1=136000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=foo + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.6 { + li:conn { + /2/5/1 + /2/2/1/1 + } + } + ha:connection.7 { + li:conn { + /2/5/1 + /2/4/1/1 + } + } + ha:group.9 { + uuid=aym2tojMMW6UVaugMwQAAAAS; + x=120000; y=116000; + li:objects { + ha:polygon.1 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=-20000; } + ha:line { x1=0; y1=-20000; x2=20000; y2=-20000; } + ha:line { x1=20000; y1=-20000; x2=20000; y2=0; } + ha:line { x1=20000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + ha:text.2 { x1=8000; y1=-12000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + cschem/child/name=l1 + name=S0 + role=symbol + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer= + page= + print_page=A/4 + title= + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 2 + grid = 4.0960 mm + } + } + } +} Index: tags/1.0.5/tests/hier/clup/l1.rs =================================================================== --- tags/1.0.5/tests/hier/clup/l1.rs (nonexistent) +++ tags/1.0.5/tests/hier/clup/l1.rs (revision 10414) @@ -0,0 +1,135 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=aym2tojMMW6UVaugMwQAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.2 { + uuid=aym2tojMMW6UVaugMwQAAAAH; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=76000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAI; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + loc_l1=1 + name=v/foo1 + role=symbol + spice/omit=yes + } + } + ha:group.4 { + uuid=aym2tojMMW6UVaugMwQAAAAP; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=104000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAQ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + loc_l1=1 + name=v/foo2 + role=symbol + spice/omit=yes + } + } + ha:group.9 { + uuid=aym2tojMMW6UVaugMwQAAAAS; + x=120000; y=116000; + li:objects { + ha:polygon.1 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=-20000; } + ha:line { x1=0; y1=-20000; x2=20000; y2=-20000; } + ha:line { x1=20000; y1=-20000; x2=20000; y2=0; } + ha:line { x1=20000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + ha:text.2 { x1=8000; y1=-12000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + cschem/child/name=l2 + name=S1 + role=symbol + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer= + page= + print_page=A/4 + title= + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 2 + grid = 4.0960 mm + } + } + } +} Index: tags/1.0.5/tests/hier/clup/l2.rs =================================================================== --- tags/1.0.5/tests/hier/clup/l2.rs (nonexistent) +++ tags/1.0.5/tests/hier/clup/l2.rs (revision 10414) @@ -0,0 +1,113 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=aym2tojMMW6UVaugMwQAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.2 { + uuid=aym2tojMMW6UVaugMwQAAAAH; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=76000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAI; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + loc_l2=1 + name=foo1 + role=symbol + spice/omit=yes + } + } + ha:group.4 { + uuid=aym2tojMMW6UVaugMwQAAAAP; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=104000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAQ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + loc_l2=1 + name=foo2 + role=symbol + spice/omit=yes + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer= + page= + print_page=A/4 + title= + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 2 + grid = 4.0960 mm + } + } + } +} Index: tags/1.0.5/tests/hier/clup/project.lht =================================================================== --- tags/1.0.5/tests/hier/clup/project.lht (nonexistent) +++ tags/1.0.5/tests/hier/clup/project.lht (revision 10414) @@ -0,0 +1,15 @@ +ha:coraleda-project-v1 { + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:prj { + li:root_sheets { + l0.rs + } + li:aux_sheets { + l1.rs + l2.rs + } + } + } + } +} Index: tags/1.0.5/tests/hier/nl1/Makefile =================================================================== --- tags/1.0.5/tests/hier/nl1/Makefile (nonexistent) +++ tags/1.0.5/tests/hier/nl1/Makefile (revision 10414) @@ -0,0 +1,14 @@ +ROOT=../../.. +SRC=$(ROOT)/src/sch-rnd +HERE=$(shell pwd) + +all: + +test: + @cd $(SRC) && ./sch-rnd -x abst --outfile $(HERE)/abst.out $(HERE)/project.lht && cd $(HERE) + @diff -u abst.ref abst.out + @rm abst.out + +distclean clean: + touch abst.out + rm abst.out Index: tags/1.0.5/tests/hier/nl1/abst.ref =================================================================== --- tags/1.0.5/tests/hier/nl1/abst.ref (nonexistent) +++ tags/1.0.5/tests/hier/nl1/abst.ref (revision 10414) @@ -0,0 +1,88 @@ +cschem abstract model v1 +components + S0 + OMIT + attributes + ports + TP11 + attributes + spice/omit=yes + role=symbol + name=TP11 + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + TP12 + attributes + spice/omit=yes + role=symbol + name=TP12 + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + S0/S1 + OMIT + attributes + ports + TP21 + attributes + spice/omit=yes + role=symbol + name=TP21 + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + TP22 + attributes + spice/omit=yes + role=symbol + name=TP22 + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + TP01 + attributes + spice/omit=yes + role=symbol + name=TP01 + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + TP02 + attributes + spice/omit=yes + role=symbol + name=TP02 + ports + 1 + attributes + role=terminal + display/name=1 + name=1 +nets + foo + attributes + role=wire-net + name=foo + conns 6 + TP21-1 + TP22-1 + TP11-1 + TP12-1 + TP01-1 + TP02-1 Index: tags/1.0.5/tests/hier/nl1/l0.rs =================================================================== --- tags/1.0.5/tests/hier/nl1/l0.rs (nonexistent) +++ tags/1.0.5/tests/hier/nl1/l0.rs (revision 10414) @@ -0,0 +1,156 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=aym2tojMMW6UVaugMwQAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.2 { + uuid=aym2tojMMW6UVaugMwQAAAAH; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=76000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAI; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=TP01 + role=symbol + spice/omit=yes + } + } + ha:group.4 { + uuid=aym2tojMMW6UVaugMwQAAAAP; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=104000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAQ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=TP02 + role=symbol + spice/omit=yes + } + } + ha:group.5 { + uuid=aym2tojMMW6UVaugMwQAAAAR; + li:objects { + ha:line.1 { x1=76000; y1=136000; x2=104000; y2=136000; stroke=wire; } + ha:text.2 { x1=92000; y1=136000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=foo + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.6 { + li:conn { + /2/5/1 + /2/2/1/1 + } + } + ha:connection.7 { + li:conn { + /2/5/1 + /2/4/1/1 + } + } + ha:group.9 { + uuid=aym2tojMMW6UVaugMwQAAAAS; + x=120000; y=116000; + li:objects { + ha:polygon.1 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=-20000; } + ha:line { x1=0; y1=-20000; x2=20000; y2=-20000; } + ha:line { x1=20000; y1=-20000; x2=20000; y2=0; } + ha:line { x1=20000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + ha:text.2 { x1=8000; y1=-12000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + cschem/child/name=l1 + name=S0 + role=symbol + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer= + page= + print_page=A/4 + title= + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 2 + grid = 4.0960 mm + } + } + } +} Index: tags/1.0.5/tests/hier/nl1/l1.rs =================================================================== --- tags/1.0.5/tests/hier/nl1/l1.rs (nonexistent) +++ tags/1.0.5/tests/hier/nl1/l1.rs (revision 10414) @@ -0,0 +1,156 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=aym2tojMMW6UVaugMwQAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.2 { + uuid=aym2tojMMW6UVaugMwQAAAAH; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=76000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAI; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=TP11 + role=symbol + spice/omit=yes + } + } + ha:group.4 { + uuid=aym2tojMMW6UVaugMwQAAAAP; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=104000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAQ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=TP12 + role=symbol + spice/omit=yes + } + } + ha:group.5 { + uuid=aym2tojMMW6UVaugMwQAAAAR; + li:objects { + ha:line.1 { x1=76000; y1=136000; x2=104000; y2=136000; stroke=wire; } + ha:text.2 { x1=92000; y1=136000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=foo + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.6 { + li:conn { + /2/5/1 + /2/2/1/1 + } + } + ha:connection.7 { + li:conn { + /2/5/1 + /2/4/1/1 + } + } + ha:group.9 { + uuid=aym2tojMMW6UVaugMwQAAAAS; + x=120000; y=116000; + li:objects { + ha:polygon.1 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=-20000; } + ha:line { x1=0; y1=-20000; x2=20000; y2=-20000; } + ha:line { x1=20000; y1=-20000; x2=20000; y2=0; } + ha:line { x1=20000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + ha:text.2 { x1=8000; y1=-12000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + cschem/child/name=l2 + name=S1 + role=symbol + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer= + page= + print_page=A/4 + title= + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 1 + grid = 2.0480 mm + } + } + } +} Index: tags/1.0.5/tests/hier/nl1/l2.rs =================================================================== --- tags/1.0.5/tests/hier/nl1/l2.rs (nonexistent) +++ tags/1.0.5/tests/hier/nl1/l2.rs (revision 10414) @@ -0,0 +1,134 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=aym2tojMMW6UVaugMwQAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.2 { + uuid=aym2tojMMW6UVaugMwQAAAAH; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=76000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAI; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=TP21 + role=symbol + spice/omit=yes + } + } + ha:group.4 { + uuid=aym2tojMMW6UVaugMwQAAAAP; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=104000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAQ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=TP22 + role=symbol + spice/omit=yes + } + } + ha:group.5 { + uuid=aym2tojMMW6UVaugMwQAAAAR; + li:objects { + ha:line.1 { x1=76000; y1=136000; x2=104000; y2=136000; stroke=wire; } + ha:text.2 { x1=92000; y1=136000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=foo + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.6 { + li:conn { + /2/5/1 + /2/2/1/1 + } + } + ha:connection.7 { + li:conn { + /2/5/1 + /2/4/1/1 + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer= + page= + print_page=A/4 + title= + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 1 + grid = 2.0480 mm + } + } + } +} Index: tags/1.0.5/tests/hier/nl1/project.lht =================================================================== --- tags/1.0.5/tests/hier/nl1/project.lht (nonexistent) +++ tags/1.0.5/tests/hier/nl1/project.lht (revision 10414) @@ -0,0 +1,15 @@ +ha:coraleda-project-v1 { + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:prj { + li:root_sheets { + l0.rs + } + li:aux_sheets { + l1.rs + l2.rs + } + } + } + } +} Index: tags/1.0.5/tests/hier/nl1a/Makefile =================================================================== --- tags/1.0.5/tests/hier/nl1a/Makefile (nonexistent) +++ tags/1.0.5/tests/hier/nl1a/Makefile (revision 10414) @@ -0,0 +1,14 @@ +ROOT=../../.. +SRC=$(ROOT)/src/sch-rnd +HERE=$(shell pwd) + +all: + +test: + @cd $(SRC) && ./sch-rnd -x abst --outfile $(HERE)/abst.out $(HERE)/project.lht && cd $(HERE) + @diff -u abst.ref abst.out + @rm abst.out + +distclean clean: + touch abst.out + rm abst.out Index: tags/1.0.5/tests/hier/nl1a/abst.ref =================================================================== --- tags/1.0.5/tests/hier/nl1a/abst.ref (nonexistent) +++ tags/1.0.5/tests/hier/nl1a/abst.ref (revision 10414) @@ -0,0 +1,98 @@ +cschem abstract model v1 +components + S0 + OMIT + attributes + ports + TP11 + attributes + spice/omit=yes + role=symbol + name=TP11 + connect [] + 1:foo + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + TP12 + attributes + spice/omit=yes + role=symbol + name=TP12 + connect [] + 1:foo + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + S0/S1 + OMIT + attributes + ports + TP21 + attributes + spice/omit=yes + role=symbol + name=TP21 + connect [] + 1:foo + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + TP22 + attributes + spice/omit=yes + role=symbol + name=TP22 + connect [] + 1:foo + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + TP01 + attributes + spice/omit=yes + role=symbol + name=TP01 + connect [] + 1:foo + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + TP02 + attributes + spice/omit=yes + role=symbol + name=TP02 + connect [] + 1:foo + ports + 1 + attributes + role=terminal + display/name=1 + name=1 +nets + foo + attributes + conns 6 + TP01-1 + TP02-1 + TP11-1 + TP12-1 + TP21-1 + TP22-1 Index: tags/1.0.5/tests/hier/nl1a/l0.rs =================================================================== --- tags/1.0.5/tests/hier/nl1a/l0.rs (nonexistent) +++ tags/1.0.5/tests/hier/nl1a/l0.rs (revision 10414) @@ -0,0 +1,139 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=aym2tojMMW6UVaugMwQAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.2 { + uuid=aym2tojMMW6UVaugMwQAAAAH; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=76000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAI; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:foo} + } + name=TP01 + role=symbol + spice/omit=yes + } + } + ha:group.4 { + uuid=aym2tojMMW6UVaugMwQAAAAP; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=104000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAQ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:foo} + } + name=TP02 + role=symbol + spice/omit=yes + } + } + ha:group.9 { + uuid=aym2tojMMW6UVaugMwQAAAAS; + x=120000; y=116000; + li:objects { + ha:polygon.1 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=-20000; } + ha:line { x1=0; y1=-20000; x2=20000; y2=-20000; } + ha:line { x1=20000; y1=-20000; x2=20000; y2=0; } + ha:line { x1=20000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + ha:text.2 { x1=8000; y1=-12000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + cschem/child/name=l1 + name=S0 + role=symbol + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer= + page= + print_page=A/4 + title= + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 2 + grid = 4.0960 mm + } + } + } +} Index: tags/1.0.5/tests/hier/nl1a/l1.rs =================================================================== --- tags/1.0.5/tests/hier/nl1a/l1.rs (nonexistent) +++ tags/1.0.5/tests/hier/nl1a/l1.rs (revision 10414) @@ -0,0 +1,139 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=aym2tojMMW6UVaugMwQAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.2 { + uuid=aym2tojMMW6UVaugMwQAAAAH; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=76000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAI; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:foo} + } + name=TP11 + role=symbol + spice/omit=yes + } + } + ha:group.4 { + uuid=aym2tojMMW6UVaugMwQAAAAP; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=104000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAQ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:foo} + } + name=TP12 + role=symbol + spice/omit=yes + } + } + ha:group.9 { + uuid=aym2tojMMW6UVaugMwQAAAAS; + x=120000; y=116000; + li:objects { + ha:polygon.1 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=-20000; } + ha:line { x1=0; y1=-20000; x2=20000; y2=-20000; } + ha:line { x1=20000; y1=-20000; x2=20000; y2=0; } + ha:line { x1=20000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + ha:text.2 { x1=8000; y1=-12000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + cschem/child/name=l2 + name=S1 + role=symbol + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer= + page= + print_page=A/4 + title= + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 1 + grid = 2.0480 mm + } + } + } +} Index: tags/1.0.5/tests/hier/nl1a/l2.rs =================================================================== --- tags/1.0.5/tests/hier/nl1a/l2.rs (nonexistent) +++ tags/1.0.5/tests/hier/nl1a/l2.rs (revision 10414) @@ -0,0 +1,117 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=aym2tojMMW6UVaugMwQAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.2 { + uuid=aym2tojMMW6UVaugMwQAAAAH; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=76000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAI; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:foo} + } + name=TP21 + role=symbol + spice/omit=yes + } + } + ha:group.4 { + uuid=aym2tojMMW6UVaugMwQAAAAP; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=104000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAQ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:foo} + } + name=TP22 + role=symbol + spice/omit=yes + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer= + page= + print_page=A/4 + title= + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 1 + grid = 2.0480 mm + } + } + } +} Index: tags/1.0.5/tests/hier/nl1a/project.lht =================================================================== --- tags/1.0.5/tests/hier/nl1a/project.lht (nonexistent) +++ tags/1.0.5/tests/hier/nl1a/project.lht (revision 10414) @@ -0,0 +1,15 @@ +ha:coraleda-project-v1 { + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:prj { + li:root_sheets { + l0.rs + } + li:aux_sheets { + l1.rs + l2.rs + } + } + } + } +} Index: tags/1.0.5/tests/hier/nl2/Makefile =================================================================== --- tags/1.0.5/tests/hier/nl2/Makefile (nonexistent) +++ tags/1.0.5/tests/hier/nl2/Makefile (revision 10414) @@ -0,0 +1,14 @@ +ROOT=../../.. +SRC=$(ROOT)/src/sch-rnd +HERE=$(shell pwd) + +all: + +test: + @cd $(SRC) && ./sch-rnd -x abst --outfile $(HERE)/abst.out $(HERE)/project.lht && cd $(HERE) + @diff -u abst.ref abst.out + @rm abst.out + +distclean clean: + touch abst.out + rm abst.out Index: tags/1.0.5/tests/hier/nl2/abst.ref =================================================================== --- tags/1.0.5/tests/hier/nl2/abst.ref (nonexistent) +++ tags/1.0.5/tests/hier/nl2/abst.ref (revision 10414) @@ -0,0 +1,98 @@ +cschem abstract model v1 +components + S0 + OMIT + attributes + ports + TP11 + attributes + spice/omit=yes + role=symbol + name=TP11 + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + TP12 + attributes + spice/omit=yes + role=symbol + name=TP12 + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + S0/S1 + OMIT + attributes + ports + TP21 + attributes + spice/omit=yes + role=symbol + name=TP21 + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + TP22 + attributes + spice/omit=yes + role=symbol + name=TP22 + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + TP01 + attributes + spice/omit=yes + role=symbol + name=TP01 + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + TP02 + attributes + spice/omit=yes + role=symbol + name=TP02 + ports + 1 + attributes + role=terminal + display/name=1 + name=1 +nets + S0/S1/foo + attributes + role=wire-net + name=foo + conns 2 + TP21-1 + TP22-1 + S0/foo + attributes + role=wire-net + name=foo + conns 2 + TP11-1 + TP12-1 + foo + attributes + role=wire-net + name=foo + conns 2 + TP01-1 + TP02-1 Index: tags/1.0.5/tests/hier/nl2/l0.rs =================================================================== --- tags/1.0.5/tests/hier/nl2/l0.rs (nonexistent) +++ tags/1.0.5/tests/hier/nl2/l0.rs (revision 10414) @@ -0,0 +1,156 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=aym2tojMMW6UVaugMwQAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.2 { + uuid=aym2tojMMW6UVaugMwQAAAAH; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=76000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAI; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=TP01 + role=symbol + spice/omit=yes + } + } + ha:group.4 { + uuid=aym2tojMMW6UVaugMwQAAAAP; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=104000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAQ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=TP02 + role=symbol + spice/omit=yes + } + } + ha:group.5 { + uuid=aym2tojMMW6UVaugMwQAAAAR; + li:objects { + ha:line.1 { x1=76000; y1=136000; x2=104000; y2=136000; stroke=wire; } + ha:text.2 { x1=92000; y1=136000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=foo + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.6 { + li:conn { + /2/5/1 + /2/2/1/1 + } + } + ha:connection.7 { + li:conn { + /2/5/1 + /2/4/1/1 + } + } + ha:group.9 { + uuid=aym2tojMMW6UVaugMwQAAAAS; + x=120000; y=116000; + li:objects { + ha:polygon.1 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=-20000; } + ha:line { x1=0; y1=-20000; x2=20000; y2=-20000; } + ha:line { x1=20000; y1=-20000; x2=20000; y2=0; } + ha:line { x1=20000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + ha:text.2 { x1=8000; y1=-12000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + cschem/child/name=l1 + name=S0 + role=symbol + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer= + page= + print_page=A/4 + title= + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 2 + grid = 4.0960 mm + } + } + } +} Index: tags/1.0.5/tests/hier/nl2/l1.rs =================================================================== --- tags/1.0.5/tests/hier/nl2/l1.rs (nonexistent) +++ tags/1.0.5/tests/hier/nl2/l1.rs (revision 10414) @@ -0,0 +1,156 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=aym2tojMMW6UVaugMwQAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.2 { + uuid=aym2tojMMW6UVaugMwQAAAAH; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=76000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAI; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=TP11 + role=symbol + spice/omit=yes + } + } + ha:group.4 { + uuid=aym2tojMMW6UVaugMwQAAAAP; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=104000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAQ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=TP12 + role=symbol + spice/omit=yes + } + } + ha:group.5 { + uuid=aym2tojMMW6UVaugMwQAAAAR; + li:objects { + ha:line.1 { x1=76000; y1=136000; x2=104000; y2=136000; stroke=wire; } + ha:text.2 { x1=92000; y1=136000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=./foo + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.6 { + li:conn { + /2/5/1 + /2/2/1/1 + } + } + ha:connection.7 { + li:conn { + /2/5/1 + /2/4/1/1 + } + } + ha:group.9 { + uuid=aym2tojMMW6UVaugMwQAAAAS; + x=120000; y=116000; + li:objects { + ha:polygon.1 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=-20000; } + ha:line { x1=0; y1=-20000; x2=20000; y2=-20000; } + ha:line { x1=20000; y1=-20000; x2=20000; y2=0; } + ha:line { x1=20000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + ha:text.2 { x1=8000; y1=-12000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + cschem/child/name=l2 + name=S1 + role=symbol + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer= + page= + print_page=A/4 + title= + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 1 + grid = 2.0480 mm + } + } + } +} Index: tags/1.0.5/tests/hier/nl2/l2.rs =================================================================== --- tags/1.0.5/tests/hier/nl2/l2.rs (nonexistent) +++ tags/1.0.5/tests/hier/nl2/l2.rs (revision 10414) @@ -0,0 +1,134 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=aym2tojMMW6UVaugMwQAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.2 { + uuid=aym2tojMMW6UVaugMwQAAAAH; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=76000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAI; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=TP21 + role=symbol + spice/omit=yes + } + } + ha:group.4 { + uuid=aym2tojMMW6UVaugMwQAAAAP; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=104000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAQ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=TP22 + role=symbol + spice/omit=yes + } + } + ha:group.5 { + uuid=aym2tojMMW6UVaugMwQAAAAR; + li:objects { + ha:line.1 { x1=76000; y1=136000; x2=104000; y2=136000; stroke=wire; } + ha:text.2 { x1=92000; y1=136000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=./foo + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.6 { + li:conn { + /2/5/1 + /2/2/1/1 + } + } + ha:connection.7 { + li:conn { + /2/5/1 + /2/4/1/1 + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer= + page= + print_page=A/4 + title= + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 1 + grid = 2.0480 mm + } + } + } +} Index: tags/1.0.5/tests/hier/nl2/project.lht =================================================================== --- tags/1.0.5/tests/hier/nl2/project.lht (nonexistent) +++ tags/1.0.5/tests/hier/nl2/project.lht (revision 10414) @@ -0,0 +1,15 @@ +ha:coraleda-project-v1 { + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:prj { + li:root_sheets { + l0.rs + } + li:aux_sheets { + l1.rs + l2.rs + } + } + } + } +} Index: tags/1.0.5/tests/hier/nl2a/Makefile =================================================================== --- tags/1.0.5/tests/hier/nl2a/Makefile (nonexistent) +++ tags/1.0.5/tests/hier/nl2a/Makefile (revision 10414) @@ -0,0 +1,14 @@ +ROOT=../../.. +SRC=$(ROOT)/src/sch-rnd +HERE=$(shell pwd) + +all: + +test: + @cd $(SRC) && ./sch-rnd -x abst --outfile $(HERE)/abst.out $(HERE)/project.lht && cd $(HERE) + @diff -u abst.ref abst.out + @rm abst.out + +distclean clean: + touch abst.out + rm abst.out Index: tags/1.0.5/tests/hier/nl2a/abst.ref =================================================================== --- tags/1.0.5/tests/hier/nl2a/abst.ref (nonexistent) +++ tags/1.0.5/tests/hier/nl2a/abst.ref (revision 10414) @@ -0,0 +1,104 @@ +cschem abstract model v1 +components + S0 + OMIT + attributes + ports + TP11 + attributes + spice/omit=yes + role=symbol + name=TP11 + connect [] + 1:./foo + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + TP12 + attributes + spice/omit=yes + role=symbol + name=TP12 + connect [] + 1:./foo + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + S0/S1 + OMIT + attributes + ports + TP21 + attributes + spice/omit=yes + role=symbol + name=TP21 + connect [] + 1:./foo + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + TP22 + attributes + spice/omit=yes + role=symbol + name=TP22 + connect [] + 1:./foo + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + TP01 + attributes + spice/omit=yes + role=symbol + name=TP01 + connect [] + 1:foo + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + TP02 + attributes + spice/omit=yes + role=symbol + name=TP02 + connect [] + 1:foo + ports + 1 + attributes + role=terminal + display/name=1 + name=1 +nets + S0/S1/foo + attributes + conns 2 + TP21-1 + TP22-1 + S0/foo + attributes + conns 2 + TP11-1 + TP12-1 + foo + attributes + conns 2 + TP01-1 + TP02-1 Index: tags/1.0.5/tests/hier/nl2a/l0.rs =================================================================== --- tags/1.0.5/tests/hier/nl2a/l0.rs (nonexistent) +++ tags/1.0.5/tests/hier/nl2a/l0.rs (revision 10414) @@ -0,0 +1,139 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=aym2tojMMW6UVaugMwQAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.2 { + uuid=aym2tojMMW6UVaugMwQAAAAH; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=76000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAI; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:foo} + } + name=TP01 + role=symbol + spice/omit=yes + } + } + ha:group.4 { + uuid=aym2tojMMW6UVaugMwQAAAAP; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=104000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAQ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:foo} + } + name=TP02 + role=symbol + spice/omit=yes + } + } + ha:group.9 { + uuid=aym2tojMMW6UVaugMwQAAAAS; + x=120000; y=116000; + li:objects { + ha:polygon.1 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=-20000; } + ha:line { x1=0; y1=-20000; x2=20000; y2=-20000; } + ha:line { x1=20000; y1=-20000; x2=20000; y2=0; } + ha:line { x1=20000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + ha:text.2 { x1=8000; y1=-12000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + cschem/child/name=l1 + name=S0 + role=symbol + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer= + page= + print_page=A/4 + title= + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 2 + grid = 4.0960 mm + } + } + } +} Index: tags/1.0.5/tests/hier/nl2a/l1.rs =================================================================== --- tags/1.0.5/tests/hier/nl2a/l1.rs (nonexistent) +++ tags/1.0.5/tests/hier/nl2a/l1.rs (revision 10414) @@ -0,0 +1,139 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=aym2tojMMW6UVaugMwQAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.2 { + uuid=aym2tojMMW6UVaugMwQAAAAH; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=76000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAI; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:./foo} + } + name=TP11 + role=symbol + spice/omit=yes + } + } + ha:group.4 { + uuid=aym2tojMMW6UVaugMwQAAAAP; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=104000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAQ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:./foo} + } + name=TP12 + role=symbol + spice/omit=yes + } + } + ha:group.9 { + uuid=aym2tojMMW6UVaugMwQAAAAS; + x=120000; y=116000; + li:objects { + ha:polygon.1 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=-20000; } + ha:line { x1=0; y1=-20000; x2=20000; y2=-20000; } + ha:line { x1=20000; y1=-20000; x2=20000; y2=0; } + ha:line { x1=20000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + ha:text.2 { x1=8000; y1=-12000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + cschem/child/name=l2 + name=S1 + role=symbol + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer= + page= + print_page=A/4 + title= + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 1 + grid = 2.0480 mm + } + } + } +} Index: tags/1.0.5/tests/hier/nl2a/l2.rs =================================================================== --- tags/1.0.5/tests/hier/nl2a/l2.rs (nonexistent) +++ tags/1.0.5/tests/hier/nl2a/l2.rs (revision 10414) @@ -0,0 +1,117 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=aym2tojMMW6UVaugMwQAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.2 { + uuid=aym2tojMMW6UVaugMwQAAAAH; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=76000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAI; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:./foo} + } + name=TP21 + role=symbol + spice/omit=yes + } + } + ha:group.4 { + uuid=aym2tojMMW6UVaugMwQAAAAP; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=104000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAQ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:./foo} + } + name=TP22 + role=symbol + spice/omit=yes + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer= + page= + print_page=A/4 + title= + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 1 + grid = 2.0480 mm + } + } + } +} Index: tags/1.0.5/tests/hier/nl2a/project.lht =================================================================== --- tags/1.0.5/tests/hier/nl2a/project.lht (nonexistent) +++ tags/1.0.5/tests/hier/nl2a/project.lht (revision 10414) @@ -0,0 +1,15 @@ +ha:coraleda-project-v1 { + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:prj { + li:root_sheets { + l0.rs + } + li:aux_sheets { + l1.rs + l2.rs + } + } + } + } +} Index: tags/1.0.5/tests/hier/nl3/Makefile =================================================================== --- tags/1.0.5/tests/hier/nl3/Makefile (nonexistent) +++ tags/1.0.5/tests/hier/nl3/Makefile (revision 10414) @@ -0,0 +1,14 @@ +ROOT=../../.. +SRC=$(ROOT)/src/sch-rnd +HERE=$(shell pwd) + +all: + +test: + @cd $(SRC) && ./sch-rnd -x abst --outfile $(HERE)/abst.out $(HERE)/project.lht && cd $(HERE) + @diff -u abst.ref abst.out + @rm abst.out + +distclean clean: + touch abst.out + rm abst.out Index: tags/1.0.5/tests/hier/nl3/abst.ref =================================================================== --- tags/1.0.5/tests/hier/nl3/abst.ref (nonexistent) +++ tags/1.0.5/tests/hier/nl3/abst.ref (revision 10414) @@ -0,0 +1,93 @@ +cschem abstract model v1 +components + S0 + OMIT + attributes + ports + TP11 + attributes + spice/omit=yes + role=symbol + name=TP11 + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + TP12 + attributes + spice/omit=yes + role=symbol + name=TP12 + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + S0/S1 + OMIT + attributes + ports + TP21 + attributes + spice/omit=yes + role=symbol + name=TP21 + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + TP22 + attributes + spice/omit=yes + role=symbol + name=TP22 + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + TP01 + attributes + spice/omit=yes + role=symbol + name=TP01 + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + TP02 + attributes + spice/omit=yes + role=symbol + name=TP02 + ports + 1 + attributes + role=terminal + display/name=1 + name=1 +nets + S0/foo + attributes + role=wire-net + name=foo + conns 2 + TP11-1 + TP12-1 + foo + attributes + role=wire-net + name=foo + conns 4 + TP21-1 + TP22-1 + TP01-1 + TP02-1 Index: tags/1.0.5/tests/hier/nl3/l0.rs =================================================================== --- tags/1.0.5/tests/hier/nl3/l0.rs (nonexistent) +++ tags/1.0.5/tests/hier/nl3/l0.rs (revision 10414) @@ -0,0 +1,156 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=aym2tojMMW6UVaugMwQAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.2 { + uuid=aym2tojMMW6UVaugMwQAAAAH; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=76000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAI; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=TP01 + role=symbol + spice/omit=yes + } + } + ha:group.4 { + uuid=aym2tojMMW6UVaugMwQAAAAP; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=104000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAQ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=TP02 + role=symbol + spice/omit=yes + } + } + ha:group.5 { + uuid=aym2tojMMW6UVaugMwQAAAAR; + li:objects { + ha:line.1 { x1=76000; y1=136000; x2=104000; y2=136000; stroke=wire; } + ha:text.2 { x1=92000; y1=136000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=foo + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.6 { + li:conn { + /2/5/1 + /2/2/1/1 + } + } + ha:connection.7 { + li:conn { + /2/5/1 + /2/4/1/1 + } + } + ha:group.9 { + uuid=aym2tojMMW6UVaugMwQAAAAS; + x=120000; y=116000; + li:objects { + ha:polygon.1 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=-20000; } + ha:line { x1=0; y1=-20000; x2=20000; y2=-20000; } + ha:line { x1=20000; y1=-20000; x2=20000; y2=0; } + ha:line { x1=20000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + ha:text.2 { x1=8000; y1=-12000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + cschem/child/name=l1 + name=S0 + role=symbol + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer= + page= + print_page=A/4 + title= + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 2 + grid = 4.0960 mm + } + } + } +} Index: tags/1.0.5/tests/hier/nl3/l1.rs =================================================================== --- tags/1.0.5/tests/hier/nl3/l1.rs (nonexistent) +++ tags/1.0.5/tests/hier/nl3/l1.rs (revision 10414) @@ -0,0 +1,156 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=aym2tojMMW6UVaugMwQAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.2 { + uuid=aym2tojMMW6UVaugMwQAAAAH; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=76000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAI; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=TP11 + role=symbol + spice/omit=yes + } + } + ha:group.4 { + uuid=aym2tojMMW6UVaugMwQAAAAP; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=104000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAQ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=TP12 + role=symbol + spice/omit=yes + } + } + ha:group.5 { + uuid=aym2tojMMW6UVaugMwQAAAAR; + li:objects { + ha:line.1 { x1=76000; y1=136000; x2=104000; y2=136000; stroke=wire; } + ha:text.2 { x1=92000; y1=136000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=./foo + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.6 { + li:conn { + /2/5/1 + /2/2/1/1 + } + } + ha:connection.7 { + li:conn { + /2/5/1 + /2/4/1/1 + } + } + ha:group.9 { + uuid=aym2tojMMW6UVaugMwQAAAAS; + x=120000; y=116000; + li:objects { + ha:polygon.1 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=-20000; } + ha:line { x1=0; y1=-20000; x2=20000; y2=-20000; } + ha:line { x1=20000; y1=-20000; x2=20000; y2=0; } + ha:line { x1=20000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + ha:text.2 { x1=8000; y1=-12000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + cschem/child/name=l2 + name=S1 + role=symbol + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer= + page= + print_page=A/4 + title= + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 1 + grid = 2.0480 mm + } + } + } +} Index: tags/1.0.5/tests/hier/nl3/l2.rs =================================================================== --- tags/1.0.5/tests/hier/nl3/l2.rs (nonexistent) +++ tags/1.0.5/tests/hier/nl3/l2.rs (revision 10414) @@ -0,0 +1,134 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=aym2tojMMW6UVaugMwQAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.2 { + uuid=aym2tojMMW6UVaugMwQAAAAH; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=76000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAI; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=TP21 + role=symbol + spice/omit=yes + } + } + ha:group.4 { + uuid=aym2tojMMW6UVaugMwQAAAAP; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=104000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAQ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=TP22 + role=symbol + spice/omit=yes + } + } + ha:group.5 { + uuid=aym2tojMMW6UVaugMwQAAAAR; + li:objects { + ha:line.1 { x1=76000; y1=136000; x2=104000; y2=136000; stroke=wire; } + ha:text.2 { x1=92000; y1=136000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=foo + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.6 { + li:conn { + /2/5/1 + /2/2/1/1 + } + } + ha:connection.7 { + li:conn { + /2/5/1 + /2/4/1/1 + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer= + page= + print_page=A/4 + title= + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 1 + grid = 2.0480 mm + } + } + } +} Index: tags/1.0.5/tests/hier/nl3/project.lht =================================================================== --- tags/1.0.5/tests/hier/nl3/project.lht (nonexistent) +++ tags/1.0.5/tests/hier/nl3/project.lht (revision 10414) @@ -0,0 +1,15 @@ +ha:coraleda-project-v1 { + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:prj { + li:root_sheets { + l0.rs + } + li:aux_sheets { + l1.rs + l2.rs + } + } + } + } +} Index: tags/1.0.5/tests/hier/nl3a/Makefile =================================================================== --- tags/1.0.5/tests/hier/nl3a/Makefile (nonexistent) +++ tags/1.0.5/tests/hier/nl3a/Makefile (revision 10414) @@ -0,0 +1,14 @@ +ROOT=../../.. +SRC=$(ROOT)/src/sch-rnd +HERE=$(shell pwd) + +all: + +test: + @cd $(SRC) && ./sch-rnd -x abst --outfile $(HERE)/abst.out $(HERE)/project.lht && cd $(HERE) + @diff -u abst.ref abst.out + @rm abst.out + +distclean clean: + touch abst.out + rm abst.out Index: tags/1.0.5/tests/hier/nl3a/abst.ref =================================================================== --- tags/1.0.5/tests/hier/nl3a/abst.ref (nonexistent) +++ tags/1.0.5/tests/hier/nl3a/abst.ref (revision 10414) @@ -0,0 +1,101 @@ +cschem abstract model v1 +components + S0 + OMIT + attributes + ports + TP11 + attributes + spice/omit=yes + role=symbol + name=TP11 + connect [] + 1:./foo + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + TP12 + attributes + spice/omit=yes + role=symbol + name=TP12 + connect [] + 1:./foo + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + S0/S1 + OMIT + attributes + ports + TP21 + attributes + spice/omit=yes + role=symbol + name=TP21 + connect [] + 1:foo + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + TP22 + attributes + spice/omit=yes + role=symbol + name=TP22 + connect [] + 1:foo + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + TP01 + attributes + spice/omit=yes + role=symbol + name=TP01 + connect [] + 1:foo + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + TP02 + attributes + spice/omit=yes + role=symbol + name=TP02 + connect [] + 1:foo + ports + 1 + attributes + role=terminal + display/name=1 + name=1 +nets + S0/foo + attributes + conns 2 + TP11-1 + TP12-1 + foo + attributes + conns 4 + TP01-1 + TP02-1 + TP21-1 + TP22-1 Index: tags/1.0.5/tests/hier/nl3a/l0.rs =================================================================== --- tags/1.0.5/tests/hier/nl3a/l0.rs (nonexistent) +++ tags/1.0.5/tests/hier/nl3a/l0.rs (revision 10414) @@ -0,0 +1,139 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=aym2tojMMW6UVaugMwQAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.2 { + uuid=aym2tojMMW6UVaugMwQAAAAH; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=76000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAI; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:foo} + } + name=TP01 + role=symbol + spice/omit=yes + } + } + ha:group.4 { + uuid=aym2tojMMW6UVaugMwQAAAAP; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=104000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAQ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:foo} + } + name=TP02 + role=symbol + spice/omit=yes + } + } + ha:group.9 { + uuid=aym2tojMMW6UVaugMwQAAAAS; + x=120000; y=116000; + li:objects { + ha:polygon.1 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=-20000; } + ha:line { x1=0; y1=-20000; x2=20000; y2=-20000; } + ha:line { x1=20000; y1=-20000; x2=20000; y2=0; } + ha:line { x1=20000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + ha:text.2 { x1=8000; y1=-12000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + cschem/child/name=l1 + name=S0 + role=symbol + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer= + page= + print_page=A/4 + title= + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 2 + grid = 4.0960 mm + } + } + } +} Index: tags/1.0.5/tests/hier/nl3a/l1.rs =================================================================== --- tags/1.0.5/tests/hier/nl3a/l1.rs (nonexistent) +++ tags/1.0.5/tests/hier/nl3a/l1.rs (revision 10414) @@ -0,0 +1,139 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=aym2tojMMW6UVaugMwQAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.2 { + uuid=aym2tojMMW6UVaugMwQAAAAH; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=76000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAI; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:./foo} + } + name=TP11 + role=symbol + spice/omit=yes + } + } + ha:group.4 { + uuid=aym2tojMMW6UVaugMwQAAAAP; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=104000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAQ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:./foo} + } + name=TP12 + role=symbol + spice/omit=yes + } + } + ha:group.9 { + uuid=aym2tojMMW6UVaugMwQAAAAS; + x=120000; y=116000; + li:objects { + ha:polygon.1 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=-20000; } + ha:line { x1=0; y1=-20000; x2=20000; y2=-20000; } + ha:line { x1=20000; y1=-20000; x2=20000; y2=0; } + ha:line { x1=20000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + ha:text.2 { x1=8000; y1=-12000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + cschem/child/name=l2 + name=S1 + role=symbol + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer= + page= + print_page=A/4 + title= + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 1 + grid = 2.0480 mm + } + } + } +} Index: tags/1.0.5/tests/hier/nl3a/l2.rs =================================================================== --- tags/1.0.5/tests/hier/nl3a/l2.rs (nonexistent) +++ tags/1.0.5/tests/hier/nl3a/l2.rs (revision 10414) @@ -0,0 +1,117 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=aym2tojMMW6UVaugMwQAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.2 { + uuid=aym2tojMMW6UVaugMwQAAAAH; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=76000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAI; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:foo} + } + name=TP21 + role=symbol + spice/omit=yes + } + } + ha:group.4 { + uuid=aym2tojMMW6UVaugMwQAAAAP; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=104000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAQ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:foo} + } + name=TP22 + role=symbol + spice/omit=yes + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer= + page= + print_page=A/4 + title= + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 1 + grid = 2.0480 mm + } + } + } +} Index: tags/1.0.5/tests/hier/nl3a/project.lht =================================================================== --- tags/1.0.5/tests/hier/nl3a/project.lht (nonexistent) +++ tags/1.0.5/tests/hier/nl3a/project.lht (revision 10414) @@ -0,0 +1,15 @@ +ha:coraleda-project-v1 { + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:prj { + li:root_sheets { + l0.rs + } + li:aux_sheets { + l1.rs + l2.rs + } + } + } + } +} Index: tags/1.0.5/tests/hier/nlg/Makefile =================================================================== --- tags/1.0.5/tests/hier/nlg/Makefile (nonexistent) +++ tags/1.0.5/tests/hier/nlg/Makefile (revision 10414) @@ -0,0 +1,14 @@ +ROOT=../../.. +SRC=$(ROOT)/src/sch-rnd +HERE=$(shell pwd) + +all: + +test: + @cd $(SRC) && ./sch-rnd -x abst --outfile $(HERE)/abst.out $(HERE)/project.lht && cd $(HERE) + @diff -u abst.ref abst.out + @rm abst.out + +distclean clean: + touch abst.out + rm abst.out Index: tags/1.0.5/tests/hier/nlg/abst.ref =================================================================== --- tags/1.0.5/tests/hier/nlg/abst.ref (nonexistent) +++ tags/1.0.5/tests/hier/nlg/abst.ref (revision 10414) @@ -0,0 +1,93 @@ +cschem abstract model v1 +components + S0 + OMIT + attributes + ports + TP11 + attributes + spice/omit=yes + role=symbol + name=TP11 + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + TP12 + attributes + spice/omit=yes + role=symbol + name=TP12 + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + S0/S1 + OMIT + attributes + ports + TP21 + attributes + spice/omit=yes + role=symbol + name=TP21 + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + TP22 + attributes + spice/omit=yes + role=symbol + name=TP22 + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + TP01 + attributes + spice/omit=yes + role=symbol + name=TP01 + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + TP02 + attributes + spice/omit=yes + role=symbol + name=TP02 + ports + 1 + attributes + role=terminal + display/name=1 + name=1 +nets + S0/foo + attributes + role=wire-net + name=foo + conns 2 + TP11-1 + TP12-1 + foo + attributes + role=wire-net + name=foo + conns 4 + TP21-1 + TP22-1 + TP01-1 + TP02-1 Index: tags/1.0.5/tests/hier/nlg/l0.rs =================================================================== --- tags/1.0.5/tests/hier/nlg/l0.rs (nonexistent) +++ tags/1.0.5/tests/hier/nlg/l0.rs (revision 10414) @@ -0,0 +1,156 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=aym2tojMMW6UVaugMwQAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.2 { + uuid=aym2tojMMW6UVaugMwQAAAAH; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=76000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAI; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=TP01 + role=symbol + spice/omit=yes + } + } + ha:group.4 { + uuid=aym2tojMMW6UVaugMwQAAAAP; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=104000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAQ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=TP02 + role=symbol + spice/omit=yes + } + } + ha:group.5 { + uuid=aym2tojMMW6UVaugMwQAAAAR; + li:objects { + ha:line.1 { x1=76000; y1=136000; x2=104000; y2=136000; stroke=wire; } + ha:text.2 { x1=92000; y1=136000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=foo + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.6 { + li:conn { + /2/5/1 + /2/2/1/1 + } + } + ha:connection.7 { + li:conn { + /2/5/1 + /2/4/1/1 + } + } + ha:group.9 { + uuid=aym2tojMMW6UVaugMwQAAAAS; + x=120000; y=116000; + li:objects { + ha:polygon.1 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=-20000; } + ha:line { x1=0; y1=-20000; x2=20000; y2=-20000; } + ha:line { x1=20000; y1=-20000; x2=20000; y2=0; } + ha:line { x1=20000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + ha:text.2 { x1=8000; y1=-12000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + cschem/child/name=l1 + name=S0 + role=symbol + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer= + page= + print_page=A/4 + title= + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 2 + grid = 4.0960 mm + } + } + } +} Index: tags/1.0.5/tests/hier/nlg/l1.rs =================================================================== --- tags/1.0.5/tests/hier/nlg/l1.rs (nonexistent) +++ tags/1.0.5/tests/hier/nlg/l1.rs (revision 10414) @@ -0,0 +1,156 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=aym2tojMMW6UVaugMwQAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.2 { + uuid=aym2tojMMW6UVaugMwQAAAAH; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=76000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAI; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=TP11 + role=symbol + spice/omit=yes + } + } + ha:group.4 { + uuid=aym2tojMMW6UVaugMwQAAAAP; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=104000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAQ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=TP12 + role=symbol + spice/omit=yes + } + } + ha:group.5 { + uuid=aym2tojMMW6UVaugMwQAAAAR; + li:objects { + ha:line.1 { x1=76000; y1=136000; x2=104000; y2=136000; stroke=wire; } + ha:text.2 { x1=92000; y1=136000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=v/foo + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.6 { + li:conn { + /2/5/1 + /2/2/1/1 + } + } + ha:connection.7 { + li:conn { + /2/5/1 + /2/4/1/1 + } + } + ha:group.9 { + uuid=aym2tojMMW6UVaugMwQAAAAS; + x=120000; y=116000; + li:objects { + ha:polygon.1 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=-20000; } + ha:line { x1=0; y1=-20000; x2=20000; y2=-20000; } + ha:line { x1=20000; y1=-20000; x2=20000; y2=0; } + ha:line { x1=20000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + ha:text.2 { x1=8000; y1=-12000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + cschem/child/name=l2 + name=S1 + role=symbol + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer= + page= + print_page=A/4 + title= + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 1 + grid = 2.0480 mm + } + } + } +} Index: tags/1.0.5/tests/hier/nlg/l2.rs =================================================================== --- tags/1.0.5/tests/hier/nlg/l2.rs (nonexistent) +++ tags/1.0.5/tests/hier/nlg/l2.rs (revision 10414) @@ -0,0 +1,134 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=aym2tojMMW6UVaugMwQAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.2 { + uuid=aym2tojMMW6UVaugMwQAAAAH; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=76000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAI; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=TP21 + role=symbol + spice/omit=yes + } + } + ha:group.4 { + uuid=aym2tojMMW6UVaugMwQAAAAP; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=104000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAQ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=TP22 + role=symbol + spice/omit=yes + } + } + ha:group.5 { + uuid=aym2tojMMW6UVaugMwQAAAAR; + li:objects { + ha:line.1 { x1=76000; y1=136000; x2=104000; y2=136000; stroke=wire; } + ha:text.2 { x1=92000; y1=136000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=/foo + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.6 { + li:conn { + /2/5/1 + /2/2/1/1 + } + } + ha:connection.7 { + li:conn { + /2/5/1 + /2/4/1/1 + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer= + page= + print_page=A/4 + title= + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 1 + grid = 2.0480 mm + } + } + } +} Index: tags/1.0.5/tests/hier/nlg/project.lht =================================================================== --- tags/1.0.5/tests/hier/nlg/project.lht (nonexistent) +++ tags/1.0.5/tests/hier/nlg/project.lht (revision 10414) @@ -0,0 +1,15 @@ +ha:coraleda-project-v1 { + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:prj { + li:root_sheets { + l0.rs + } + li:aux_sheets { + l1.rs + l2.rs + } + } + } + } +} Index: tags/1.0.5/tests/hier/nlga/Makefile =================================================================== --- tags/1.0.5/tests/hier/nlga/Makefile (nonexistent) +++ tags/1.0.5/tests/hier/nlga/Makefile (revision 10414) @@ -0,0 +1,14 @@ +ROOT=../../.. +SRC=$(ROOT)/src/sch-rnd +HERE=$(shell pwd) + +all: + +test: + @cd $(SRC) && ./sch-rnd -x abst --outfile $(HERE)/abst.out $(HERE)/project.lht && cd $(HERE) + @diff -u abst.ref abst.out + @rm abst.out + +distclean clean: + touch abst.out + rm abst.out Index: tags/1.0.5/tests/hier/nlga/abst.ref =================================================================== --- tags/1.0.5/tests/hier/nlga/abst.ref (nonexistent) +++ tags/1.0.5/tests/hier/nlga/abst.ref (revision 10414) @@ -0,0 +1,101 @@ +cschem abstract model v1 +components + S0 + OMIT + attributes + ports + TP11 + attributes + spice/omit=yes + role=symbol + name=TP11 + connect [] + 1:v/foo + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + TP12 + attributes + spice/omit=yes + role=symbol + name=TP12 + connect [] + 1:v/foo + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + S0/S1 + OMIT + attributes + ports + TP21 + attributes + spice/omit=yes + role=symbol + name=TP21 + connect [] + 1:/foo + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + TP22 + attributes + spice/omit=yes + role=symbol + name=TP22 + connect [] + 1:/foo + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + TP01 + attributes + spice/omit=yes + role=symbol + name=TP01 + connect [] + 1:foo + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + TP02 + attributes + spice/omit=yes + role=symbol + name=TP02 + connect [] + 1:foo + ports + 1 + attributes + role=terminal + display/name=1 + name=1 +nets + S0/foo + attributes + conns 2 + TP11-1 + TP12-1 + foo + attributes + conns 4 + TP01-1 + TP02-1 + TP21-1 + TP22-1 Index: tags/1.0.5/tests/hier/nlga/l0.rs =================================================================== --- tags/1.0.5/tests/hier/nlga/l0.rs (nonexistent) +++ tags/1.0.5/tests/hier/nlga/l0.rs (revision 10414) @@ -0,0 +1,139 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=aym2tojMMW6UVaugMwQAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.2 { + uuid=aym2tojMMW6UVaugMwQAAAAH; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=76000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAI; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:foo} + } + name=TP01 + role=symbol + spice/omit=yes + } + } + ha:group.4 { + uuid=aym2tojMMW6UVaugMwQAAAAP; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=104000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAQ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:foo} + } + name=TP02 + role=symbol + spice/omit=yes + } + } + ha:group.9 { + uuid=aym2tojMMW6UVaugMwQAAAAS; + x=120000; y=116000; + li:objects { + ha:polygon.1 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=-20000; } + ha:line { x1=0; y1=-20000; x2=20000; y2=-20000; } + ha:line { x1=20000; y1=-20000; x2=20000; y2=0; } + ha:line { x1=20000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + ha:text.2 { x1=8000; y1=-12000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + cschem/child/name=l1 + name=S0 + role=symbol + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer= + page= + print_page=A/4 + title= + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 2 + grid = 4.0960 mm + } + } + } +} Index: tags/1.0.5/tests/hier/nlga/l1.rs =================================================================== --- tags/1.0.5/tests/hier/nlga/l1.rs (nonexistent) +++ tags/1.0.5/tests/hier/nlga/l1.rs (revision 10414) @@ -0,0 +1,139 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=aym2tojMMW6UVaugMwQAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.2 { + uuid=aym2tojMMW6UVaugMwQAAAAH; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=76000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAI; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:v/foo} + } + name=TP11 + role=symbol + spice/omit=yes + } + } + ha:group.4 { + uuid=aym2tojMMW6UVaugMwQAAAAP; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=104000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAQ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:v/foo} + } + name=TP12 + role=symbol + spice/omit=yes + } + } + ha:group.9 { + uuid=aym2tojMMW6UVaugMwQAAAAS; + x=120000; y=116000; + li:objects { + ha:polygon.1 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=-20000; } + ha:line { x1=0; y1=-20000; x2=20000; y2=-20000; } + ha:line { x1=20000; y1=-20000; x2=20000; y2=0; } + ha:line { x1=20000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + ha:text.2 { x1=8000; y1=-12000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + cschem/child/name=l2 + name=S1 + role=symbol + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer= + page= + print_page=A/4 + title= + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 1 + grid = 2.0480 mm + } + } + } +} Index: tags/1.0.5/tests/hier/nlga/l2.rs =================================================================== --- tags/1.0.5/tests/hier/nlga/l2.rs (nonexistent) +++ tags/1.0.5/tests/hier/nlga/l2.rs (revision 10414) @@ -0,0 +1,117 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=aym2tojMMW6UVaugMwQAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.2 { + uuid=aym2tojMMW6UVaugMwQAAAAH; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=76000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAI; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:/foo} + } + name=TP21 + role=symbol + spice/omit=yes + } + } + ha:group.4 { + uuid=aym2tojMMW6UVaugMwQAAAAP; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=104000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAQ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:/foo} + } + name=TP22 + role=symbol + spice/omit=yes + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer= + page= + print_page=A/4 + title= + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 1 + grid = 2.0480 mm + } + } + } +} Index: tags/1.0.5/tests/hier/nlga/project.lht =================================================================== --- tags/1.0.5/tests/hier/nlga/project.lht (nonexistent) +++ tags/1.0.5/tests/hier/nlga/project.lht (revision 10414) @@ -0,0 +1,15 @@ +ha:coraleda-project-v1 { + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:prj { + li:root_sheets { + l0.rs + } + li:aux_sheets { + l1.rs + l2.rs + } + } + } + } +} Index: tags/1.0.5/tests/hier/nlmix/Makefile =================================================================== --- tags/1.0.5/tests/hier/nlmix/Makefile (nonexistent) +++ tags/1.0.5/tests/hier/nlmix/Makefile (revision 10414) @@ -0,0 +1,14 @@ +ROOT=../../.. +SRC=$(ROOT)/src/sch-rnd +HERE=$(shell pwd) + +all: + +test: + @cd $(SRC) && ./sch-rnd -x abst --outfile $(HERE)/abst.out $(HERE)/project.lht && cd $(HERE) + @diff -u abst.ref abst.out + @rm abst.out + +distclean clean: + touch abst.out + rm abst.out Index: tags/1.0.5/tests/hier/nlmix/abst.ref =================================================================== --- tags/1.0.5/tests/hier/nlmix/abst.ref (nonexistent) +++ tags/1.0.5/tests/hier/nlmix/abst.ref (revision 10414) @@ -0,0 +1,121 @@ +cschem abstract model v1 +components + S0 + OMIT + attributes + ports + TP11 + attributes + spice/omit=yes + role=symbol + name=TP11 + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + TP12 + attributes + spice/omit=yes + role=symbol + name=TP12 + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + TP13 + attributes + spice/omit=yes + role=symbol + name=TP13 + connect [] + 1:v/foo + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + S0/S1 + OMIT + attributes + ports + TP21 + attributes + spice/omit=yes + role=symbol + name=TP21 + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + TP22 + attributes + spice/omit=yes + role=symbol + name=TP22 + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + TP23 + attributes + spice/omit=yes + role=symbol + name=TP23 + connect [] + 1:^/foo + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + TP01 + attributes + spice/omit=yes + role=symbol + name=TP01 + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + TP02 + attributes + spice/omit=yes + role=symbol + name=TP02 + ports + 1 + attributes + role=terminal + display/name=1 + name=1 +nets + S0/foo + attributes + role=wire-net + name=foo + conns 6 + TP21-1 + TP22-1 + TP11-1 + TP12-1 + TP13-1 + TP23-1 + foo + attributes + role=wire-net + name=foo + conns 2 + TP01-1 + TP02-1 Index: tags/1.0.5/tests/hier/nlmix/l0.rs =================================================================== --- tags/1.0.5/tests/hier/nlmix/l0.rs (nonexistent) +++ tags/1.0.5/tests/hier/nlmix/l0.rs (revision 10414) @@ -0,0 +1,156 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=aym2tojMMW6UVaugMwQAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.2 { + uuid=aym2tojMMW6UVaugMwQAAAAH; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=76000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAI; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=TP01 + role=symbol + spice/omit=yes + } + } + ha:group.4 { + uuid=aym2tojMMW6UVaugMwQAAAAP; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=104000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAQ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=TP02 + role=symbol + spice/omit=yes + } + } + ha:group.5 { + uuid=aym2tojMMW6UVaugMwQAAAAR; + li:objects { + ha:line.1 { x1=76000; y1=136000; x2=104000; y2=136000; stroke=wire; } + ha:text.2 { x1=92000; y1=136000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=foo + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.6 { + li:conn { + /2/5/1 + /2/2/1/1 + } + } + ha:connection.7 { + li:conn { + /2/5/1 + /2/4/1/1 + } + } + ha:group.9 { + uuid=aym2tojMMW6UVaugMwQAAAAS; + x=120000; y=116000; + li:objects { + ha:polygon.1 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=-20000; } + ha:line { x1=0; y1=-20000; x2=20000; y2=-20000; } + ha:line { x1=20000; y1=-20000; x2=20000; y2=0; } + ha:line { x1=20000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + ha:text.2 { x1=8000; y1=-12000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + cschem/child/name=l1 + name=S0 + role=symbol + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer= + page= + print_page=A/4 + title= + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 2 + grid = 4.0960 mm + } + } + } +} Index: tags/1.0.5/tests/hier/nlmix/l1.rs =================================================================== --- tags/1.0.5/tests/hier/nlmix/l1.rs (nonexistent) +++ tags/1.0.5/tests/hier/nlmix/l1.rs (revision 10414) @@ -0,0 +1,191 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=aym2tojMMW6UVaugMwQAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.2 { + uuid=aym2tojMMW6UVaugMwQAAAAH; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=76000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAI; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=TP11 + role=symbol + spice/omit=yes + } + } + ha:group.4 { + uuid=aym2tojMMW6UVaugMwQAAAAP; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=104000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAQ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=TP12 + role=symbol + spice/omit=yes + } + } + ha:group.5 { + uuid=aym2tojMMW6UVaugMwQAAAAR; + li:objects { + ha:line.1 { x1=76000; y1=136000; x2=104000; y2=136000; stroke=wire; } + ha:text.2 { x1=92000; y1=136000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=v/foo + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.6 { + li:conn { + /2/5/1 + /2/2/1/1 + } + } + ha:connection.7 { + li:conn { + /2/5/1 + /2/4/1/1 + } + } + ha:group.9 { + uuid=aym2tojMMW6UVaugMwQAAAAS; + x=120000; y=116000; + li:objects { + ha:polygon.1 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=-20000; } + ha:line { x1=0; y1=-20000; x2=20000; y2=-20000; } + ha:line { x1=20000; y1=-20000; x2=20000; y2=0; } + ha:line { x1=20000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + ha:text.2 { x1=8000; y1=-12000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + cschem/child/name=l2 + name=S1 + role=symbol + } + } + ha:group.11 { + uuid=1XC2Ip0Y88BuKoGF3VEAAAAY; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=116000; y=136000; + li:objects { + ha:group.1 { + uuid=1XC2Ip0Y88BuKoGF3VEAAAAZ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:v/foo} + } + name=TP13 + role=symbol + spice/omit=yes + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer= + page= + print_page=A/4 + title= + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 2 + grid = 4.0960 mm + } + } + } +} Index: tags/1.0.5/tests/hier/nlmix/l2.rs =================================================================== --- tags/1.0.5/tests/hier/nlmix/l2.rs (nonexistent) +++ tags/1.0.5/tests/hier/nlmix/l2.rs (revision 10414) @@ -0,0 +1,169 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=aym2tojMMW6UVaugMwQAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.2 { + uuid=aym2tojMMW6UVaugMwQAAAAH; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=76000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAI; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=TP21 + role=symbol + spice/omit=yes + } + } + ha:group.4 { + uuid=aym2tojMMW6UVaugMwQAAAAP; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=104000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAQ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=TP22 + role=symbol + spice/omit=yes + } + } + ha:group.5 { + uuid=aym2tojMMW6UVaugMwQAAAAR; + li:objects { + ha:line.1 { x1=76000; y1=136000; x2=104000; y2=136000; stroke=wire; } + ha:text.2 { x1=92000; y1=136000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=foo + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.6 { + li:conn { + /2/5/1 + /2/2/1/1 + } + } + ha:connection.7 { + li:conn { + /2/5/1 + /2/4/1/1 + } + } + ha:group.8 { + uuid=Jn/1doAod7jWLeqBD30AAAAW; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=118000; y=136000; + li:objects { + ha:group.1 { + uuid=Jn/1doAod7jWLeqBD30AAAAX; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:^/foo} + } + name=TP23 + role=symbol + spice/omit=yes + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer= + page= + print_page=A/4 + title= + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 1 + grid = 2.0480 mm + } + } + } +} Index: tags/1.0.5/tests/hier/nlmix/project.lht =================================================================== --- tags/1.0.5/tests/hier/nlmix/project.lht (nonexistent) +++ tags/1.0.5/tests/hier/nlmix/project.lht (revision 10414) @@ -0,0 +1,15 @@ +ha:coraleda-project-v1 { + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:prj { + li:root_sheets { + l0.rs + } + li:aux_sheets { + l1.rs + l2.rs + } + } + } + } +} Index: tags/1.0.5/tests/hier/nlup/Makefile =================================================================== --- tags/1.0.5/tests/hier/nlup/Makefile (nonexistent) +++ tags/1.0.5/tests/hier/nlup/Makefile (revision 10414) @@ -0,0 +1,14 @@ +ROOT=../../.. +SRC=$(ROOT)/src/sch-rnd +HERE=$(shell pwd) + +all: + +test: + @cd $(SRC) && ./sch-rnd -x abst --outfile $(HERE)/abst.out $(HERE)/project.lht && cd $(HERE) + @diff -u abst.ref abst.out + @rm abst.out + +distclean clean: + touch abst.out + rm abst.out Index: tags/1.0.5/tests/hier/nlup/abst.ref =================================================================== --- tags/1.0.5/tests/hier/nlup/abst.ref (nonexistent) +++ tags/1.0.5/tests/hier/nlup/abst.ref (revision 10414) @@ -0,0 +1,93 @@ +cschem abstract model v1 +components + S0 + OMIT + attributes + ports + TP11 + attributes + spice/omit=yes + role=symbol + name=TP11 + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + TP12 + attributes + spice/omit=yes + role=symbol + name=TP12 + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + S0/S1 + OMIT + attributes + ports + TP21 + attributes + spice/omit=yes + role=symbol + name=TP21 + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + TP22 + attributes + spice/omit=yes + role=symbol + name=TP22 + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + TP01 + attributes + spice/omit=yes + role=symbol + name=TP01 + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + TP02 + attributes + spice/omit=yes + role=symbol + name=TP02 + ports + 1 + attributes + role=terminal + display/name=1 + name=1 +nets + S0/foo + attributes + role=wire-net + name=foo + conns 4 + TP21-1 + TP22-1 + TP11-1 + TP12-1 + foo + attributes + role=wire-net + name=foo + conns 2 + TP01-1 + TP02-1 Index: tags/1.0.5/tests/hier/nlup/l0.rs =================================================================== --- tags/1.0.5/tests/hier/nlup/l0.rs (nonexistent) +++ tags/1.0.5/tests/hier/nlup/l0.rs (revision 10414) @@ -0,0 +1,156 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=aym2tojMMW6UVaugMwQAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.2 { + uuid=aym2tojMMW6UVaugMwQAAAAH; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=76000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAI; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=TP01 + role=symbol + spice/omit=yes + } + } + ha:group.4 { + uuid=aym2tojMMW6UVaugMwQAAAAP; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=104000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAQ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=TP02 + role=symbol + spice/omit=yes + } + } + ha:group.5 { + uuid=aym2tojMMW6UVaugMwQAAAAR; + li:objects { + ha:line.1 { x1=76000; y1=136000; x2=104000; y2=136000; stroke=wire; } + ha:text.2 { x1=92000; y1=136000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=foo + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.6 { + li:conn { + /2/5/1 + /2/2/1/1 + } + } + ha:connection.7 { + li:conn { + /2/5/1 + /2/4/1/1 + } + } + ha:group.9 { + uuid=aym2tojMMW6UVaugMwQAAAAS; + x=120000; y=116000; + li:objects { + ha:polygon.1 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=-20000; } + ha:line { x1=0; y1=-20000; x2=20000; y2=-20000; } + ha:line { x1=20000; y1=-20000; x2=20000; y2=0; } + ha:line { x1=20000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + ha:text.2 { x1=8000; y1=-12000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + cschem/child/name=l1 + name=S0 + role=symbol + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer= + page= + print_page=A/4 + title= + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 2 + grid = 4.0960 mm + } + } + } +} Index: tags/1.0.5/tests/hier/nlup/l1.rs =================================================================== --- tags/1.0.5/tests/hier/nlup/l1.rs (nonexistent) +++ tags/1.0.5/tests/hier/nlup/l1.rs (revision 10414) @@ -0,0 +1,156 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=aym2tojMMW6UVaugMwQAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.2 { + uuid=aym2tojMMW6UVaugMwQAAAAH; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=76000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAI; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=TP11 + role=symbol + spice/omit=yes + } + } + ha:group.4 { + uuid=aym2tojMMW6UVaugMwQAAAAP; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=104000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAQ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=TP12 + role=symbol + spice/omit=yes + } + } + ha:group.5 { + uuid=aym2tojMMW6UVaugMwQAAAAR; + li:objects { + ha:line.1 { x1=76000; y1=136000; x2=104000; y2=136000; stroke=wire; } + ha:text.2 { x1=92000; y1=136000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=v/foo + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.6 { + li:conn { + /2/5/1 + /2/2/1/1 + } + } + ha:connection.7 { + li:conn { + /2/5/1 + /2/4/1/1 + } + } + ha:group.9 { + uuid=aym2tojMMW6UVaugMwQAAAAS; + x=120000; y=116000; + li:objects { + ha:polygon.1 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=-20000; } + ha:line { x1=0; y1=-20000; x2=20000; y2=-20000; } + ha:line { x1=20000; y1=-20000; x2=20000; y2=0; } + ha:line { x1=20000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + ha:text.2 { x1=8000; y1=-12000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + cschem/child/name=l2 + name=S1 + role=symbol + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer= + page= + print_page=A/4 + title= + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 1 + grid = 2.0480 mm + } + } + } +} Index: tags/1.0.5/tests/hier/nlup/l2.rs =================================================================== --- tags/1.0.5/tests/hier/nlup/l2.rs (nonexistent) +++ tags/1.0.5/tests/hier/nlup/l2.rs (revision 10414) @@ -0,0 +1,134 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=aym2tojMMW6UVaugMwQAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.2 { + uuid=aym2tojMMW6UVaugMwQAAAAH; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=76000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAI; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=TP21 + role=symbol + spice/omit=yes + } + } + ha:group.4 { + uuid=aym2tojMMW6UVaugMwQAAAAP; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=104000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAQ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=TP22 + role=symbol + spice/omit=yes + } + } + ha:group.5 { + uuid=aym2tojMMW6UVaugMwQAAAAR; + li:objects { + ha:line.1 { x1=76000; y1=136000; x2=104000; y2=136000; stroke=wire; } + ha:text.2 { x1=92000; y1=136000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=foo + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.6 { + li:conn { + /2/5/1 + /2/2/1/1 + } + } + ha:connection.7 { + li:conn { + /2/5/1 + /2/4/1/1 + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer= + page= + print_page=A/4 + title= + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 1 + grid = 2.0480 mm + } + } + } +} Index: tags/1.0.5/tests/hier/nlup/project.lht =================================================================== --- tags/1.0.5/tests/hier/nlup/project.lht (nonexistent) +++ tags/1.0.5/tests/hier/nlup/project.lht (revision 10414) @@ -0,0 +1,15 @@ +ha:coraleda-project-v1 { + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:prj { + li:root_sheets { + l0.rs + } + li:aux_sheets { + l1.rs + l2.rs + } + } + } + } +} Index: tags/1.0.5/tests/hier/nlupa/Makefile =================================================================== --- tags/1.0.5/tests/hier/nlupa/Makefile (nonexistent) +++ tags/1.0.5/tests/hier/nlupa/Makefile (revision 10414) @@ -0,0 +1,14 @@ +ROOT=../../.. +SRC=$(ROOT)/src/sch-rnd +HERE=$(shell pwd) + +all: + +test: + @cd $(SRC) && ./sch-rnd -x abst --outfile $(HERE)/abst.out $(HERE)/project.lht && cd $(HERE) + @diff -u abst.ref abst.out + @rm abst.out + +distclean clean: + touch abst.out + rm abst.out Index: tags/1.0.5/tests/hier/nlupa/abst.ref =================================================================== --- tags/1.0.5/tests/hier/nlupa/abst.ref (nonexistent) +++ tags/1.0.5/tests/hier/nlupa/abst.ref (revision 10414) @@ -0,0 +1,101 @@ +cschem abstract model v1 +components + S0 + OMIT + attributes + ports + TP11 + attributes + spice/omit=yes + role=symbol + name=TP11 + connect [] + 1:v/foo + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + TP12 + attributes + spice/omit=yes + role=symbol + name=TP12 + connect [] + 1:v/foo + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + S0/S1 + OMIT + attributes + ports + TP21 + attributes + spice/omit=yes + role=symbol + name=TP21 + connect [] + 1:foo + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + TP22 + attributes + spice/omit=yes + role=symbol + name=TP22 + connect [] + 1:foo + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + TP01 + attributes + spice/omit=yes + role=symbol + name=TP01 + connect [] + 1:foo + ports + 1 + attributes + role=terminal + display/name=1 + name=1 + TP02 + attributes + spice/omit=yes + role=symbol + name=TP02 + connect [] + 1:foo + ports + 1 + attributes + role=terminal + display/name=1 + name=1 +nets + S0/foo + attributes + conns 4 + TP11-1 + TP12-1 + TP21-1 + TP22-1 + foo + attributes + conns 2 + TP01-1 + TP02-1 Index: tags/1.0.5/tests/hier/nlupa/l0.rs =================================================================== --- tags/1.0.5/tests/hier/nlupa/l0.rs (nonexistent) +++ tags/1.0.5/tests/hier/nlupa/l0.rs (revision 10414) @@ -0,0 +1,139 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=aym2tojMMW6UVaugMwQAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.2 { + uuid=aym2tojMMW6UVaugMwQAAAAH; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=76000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAI; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:foo} + } + name=TP01 + role=symbol + spice/omit=yes + } + } + ha:group.4 { + uuid=aym2tojMMW6UVaugMwQAAAAP; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=104000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAQ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:foo} + } + name=TP02 + role=symbol + spice/omit=yes + } + } + ha:group.9 { + uuid=aym2tojMMW6UVaugMwQAAAAS; + x=120000; y=116000; + li:objects { + ha:polygon.1 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=-20000; } + ha:line { x1=0; y1=-20000; x2=20000; y2=-20000; } + ha:line { x1=20000; y1=-20000; x2=20000; y2=0; } + ha:line { x1=20000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + ha:text.2 { x1=8000; y1=-12000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + cschem/child/name=l1 + name=S0 + role=symbol + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer= + page= + print_page=A/4 + title= + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 2 + grid = 4.0960 mm + } + } + } +} Index: tags/1.0.5/tests/hier/nlupa/l1.rs =================================================================== --- tags/1.0.5/tests/hier/nlupa/l1.rs (nonexistent) +++ tags/1.0.5/tests/hier/nlupa/l1.rs (revision 10414) @@ -0,0 +1,139 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=aym2tojMMW6UVaugMwQAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.2 { + uuid=aym2tojMMW6UVaugMwQAAAAH; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=76000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAI; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:v/foo} + } + name=TP11 + role=symbol + spice/omit=yes + } + } + ha:group.4 { + uuid=aym2tojMMW6UVaugMwQAAAAP; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=104000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAQ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:v/foo} + } + name=TP12 + role=symbol + spice/omit=yes + } + } + ha:group.9 { + uuid=aym2tojMMW6UVaugMwQAAAAS; + x=120000; y=116000; + li:objects { + ha:polygon.1 { + li:outline { + ha:line { x1=0; y1=0; x2=0; y2=-20000; } + ha:line { x1=0; y1=-20000; x2=20000; y2=-20000; } + ha:line { x1=20000; y1=-20000; x2=20000; y2=0; } + ha:line { x1=20000; y1=0; x2=0; y2=0; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + ha:text.2 { x1=8000; y1=-12000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + cschem/child/name=l2 + name=S1 + role=symbol + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer= + page= + print_page=A/4 + title= + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 1 + grid = 2.0480 mm + } + } + } +} Index: tags/1.0.5/tests/hier/nlupa/l2.rs =================================================================== --- tags/1.0.5/tests/hier/nlupa/l2.rs (nonexistent) +++ tags/1.0.5/tests/hier/nlupa/l2.rs (revision 10414) @@ -0,0 +1,117 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=aym2tojMMW6UVaugMwQAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.2 { + uuid=aym2tojMMW6UVaugMwQAAAAH; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=76000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAI; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:foo} + } + name=TP21 + role=symbol + spice/omit=yes + } + } + ha:group.4 { + uuid=aym2tojMMW6UVaugMwQAAAAP; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=104000; y=136000; + li:objects { + ha:group.1 { + uuid=aym2tojMMW6UVaugMwQAAAAQ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:foo} + } + name=TP22 + role=symbol + spice/omit=yes + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer= + page= + print_page=A/4 + title= + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 1 + grid = 2.0480 mm + } + } + } +} Index: tags/1.0.5/tests/hier/nlupa/project.lht =================================================================== --- tags/1.0.5/tests/hier/nlupa/project.lht (nonexistent) +++ tags/1.0.5/tests/hier/nlupa/project.lht (revision 10414) @@ -0,0 +1,15 @@ +ha:coraleda-project-v1 { + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:prj { + li:root_sheets { + l0.rs + } + li:aux_sheets { + l1.rs + l2.rs + } + } + } + } +} Index: tags/1.0.5/tests/hier/slot/Makefile =================================================================== --- tags/1.0.5/tests/hier/slot/Makefile (nonexistent) +++ tags/1.0.5/tests/hier/slot/Makefile (revision 10414) @@ -0,0 +1,14 @@ +ROOT=../../.. +SRC=$(ROOT)/src/sch-rnd +HERE=$(shell pwd) + +all: + +test: + @cd $(SRC) && ./sch-rnd -x abst --outfile $(HERE)/abst.out $(HERE)/project.lht && cd $(HERE) + @diff -u abst.ref abst.out + @rm abst.out + +distclean clean: + touch abst.out + rm abst.out Index: tags/1.0.5/tests/hier/slot/abst.ref =================================================================== --- tags/1.0.5/tests/hier/slot/abst.ref (nonexistent) +++ tags/1.0.5/tests/hier/slot/abst.ref (revision 10414) @@ -0,0 +1,130 @@ +cschem abstract model v1 +components + S1 + OMIT + attributes + ports + inB + attributes + role=terminal + display/name=inB + name=inB + inA + attributes + role=terminal + display/name=inA + name=inA + outA + attributes + role=terminal + display/name=outA + name=outA + outB + attributes + role=terminal + display/name=outB + name=outB + S1/anon_comp_3 + attributes + role=symbol + connect [] + 1:GND + ports + 1 + attributes + role=terminal + display/name=1 + drc/require_graphical_conn=1 + name=1 + S1/U1 + attributes + portmap [] + 1/in- -> pcb/pinnum=2 + 1/in+ -> pcb/pinnum=3 + 1/out -> pcb/pinnum=1 + 1/V+ -> pcb/pinnum=8 + 1/V- -> pcb/pinnum=4 + 2/in- -> pcb/pinnum=6 + 2/in+ -> pcb/pinnum=5 + 2/out -> pcb/pinnum=7 + 2/V+ -> pcb/pinnum=8 + 2/V- -> pcb/pinnum=4 + devmap=lm358_so8 + role=symbol + device=lm358 + name=U1 + footprint=so(8) + ports + 1/V- + attributes + pcb/pinnum=4 + display/name=4 + role=terminal + spice/pinnum=5 + name=V- + 1/in+ + attributes + pcb/pinnum=3 + display/name=3 + role=terminal + spice/pinnum=2 + name=in+ + 1/in- + attributes + pcb/pinnum=2 + display/name=2 + role=terminal + spice/pinnum=1 + name=in- + 1/out + attributes + pcb/pinnum=1 + display/name=1 + role=terminal + spice/pinnum=3 + name=out + 1/V+ + attributes + pcb/pinnum=8 + display/name=8 + role=terminal + spice/pinnum=4 + name=V+ +nets + net_ina + attributes + role=wire-net + name=net_ina + conns 3 + (via S1-inA) + S1/U1-1/in+ + (omit S1-inA) + net_inb + attributes + role=wire-net + name=net_inb + conns 3 + (via S1-inB) + S1/U1-1/in- + (omit S1-inB) + GND + attributes + conns 2 + S1/anon_comp_3-1 + S1/U1-1/V- + net_outa + attributes + role=wire-net + name=net_outa + conns 3 + S1/U1-1/V+ + (via S1-outA) + (omit S1-outA) + net_outb + attributes + role=wire-net + name=net_outb + conns 3 + S1/U1-1/out + (via S1-outB) + (omit S1-outB) Index: tags/1.0.5/tests/hier/slot/child.rs =================================================================== --- tags/1.0.5/tests/hier/slot/child.rs (nonexistent) +++ tags/1.0.5/tests/hier/slot/child.rs (revision 10414) @@ -0,0 +1,405 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + ha:group.1 { + uuid=gNCuJ00G+cWbegsDojwAAAAd; + li:objects { + ha:group.1 { + uuid=gNCuJ00G+cWbegsDojwAAAAe; loclib_name=lm358_so8; + li:objects { + } + ha:attrib { + device=lm358 + footprint=so(8) + li:portmap { + {1/in- -> pcb/pinnum=2} + {1/in+ -> pcb/pinnum=3} + {1/out -> pcb/pinnum=1} + {1/V+ -> pcb/pinnum=8} + {1/V- -> pcb/pinnum=4} + {2/in- -> pcb/pinnum=6} + {2/in+ -> pcb/pinnum=5} + {2/out -> pcb/pinnum=7} + {2/V+ -> pcb/pinnum=8} + {2/V- -> pcb/pinnum=4} + } + } + } + } + ha:attrib { + ha:purpose = { value=devmap; prio=0; } + } + } + } + } + ha:obj_direct.2 { + uuid=gNCuJ00G+cWbegsDojwAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.1 { + uuid=8/SYZ/pfBzxyqFA12WQAAAAC; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAg; + li:objects { + ha:polygon.11 { + li:outline { + ha:line { x1=0; y1=0; x2=80000; y2=0; } + ha:line { x1=80000; y1=0; x2=80000; y2=20000; } + ha:line { x1=80000; y1=20000; x2=0; y2=20000; } + ha:line { x1=0; y1=20000; x2=0; y2=0; } + } + stroke=titlebox-frame; + fill=titlebox-fill; + } + ha:line.12 { x1=0; y1=10000; x2=80000; y2=10000; stroke=titlebox-frame; } + ha:line.13 { x1=40000; y1=10000; x2=40000; y2=0; stroke=titlebox-frame; } + ha:text.20 { x1=1000; y1=16500; dyntext=0; stroke=titlebox-big; text=TITLE; } + ha:text.21 { x1=1000; y1=10500; x2=79000; y2=16000; dyntext=1; stroke=titlebox-big; text=%../../A.title%; } + ha:text.22 { x1=1000; y1=5500; dyntext=0; stroke=titlebox-small; text={PROJECT:}; } + ha:text.23 { x1=13000; y1=5500; x2=39000; y2=9500; dyntext=1; stroke=titlebox-big; text=%project.name%; } + ha:text.24 { x1=1000; y1=500; dyntext=0; stroke=titlebox-small; text={PAGE:}; } + ha:text.25 { x1=10000; y1=500; x2=39000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.page%; } + ha:text.26 { x1=41000; y1=5500; dyntext=0; stroke=titlebox-small; text={FILE:}; } + ha:text.27 { x1=48000; y1=5500; x2=79000; y2=9500; dyntext=1; stroke=titlebox-big; text=%filename%; } + ha:text.28 { x1=41000; y1=500; dyntext=0; stroke=titlebox-small; text={MAINTAINER:}; } + ha:text.29 { x1=55000; y1=500; x2=79000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.maintainer%; } + ha:text.30 { x1=79000; y1=16000; mirx=1; dyntext=1; stroke=sheet-decor; text=%stance.model% %stance.sub_major% %stance.sub_minor% %stance.test_bench% %view.name%; } + } + ha:attrib { + purpose=titlebox + } + } + ha:group.2 { + uuid=gNCuJ00G+cWbegsDojwAAAAF; src_uuid=AHibvjaMiL5NH+9/wR0AAAAG; + x=76000; y=124000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-5000; y1=-1500; mirx=1; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:line.3 { x1=-4000; y1=0; x2=-5000; y2=2000; stroke=sheet-decor; } + ha:line.4 { x1=-4000; y1=0; x2=-5000; y2=-2000; stroke=sheet-decor; } + ha:line.5 { x1=-5000; y1=-2000; x2=-17000; y2=-2000; stroke=sheet-decor; } + ha:line.6 { x1=-17000; y1=2000; x2=-5000; y2=2000; stroke=sheet-decor; } + ha:line.7 { x1=-17000; y1=2000; x2=-17000; y2=-2000; stroke=sheet-decor; } + } + ha:attrib { + -sym-comment={ Sheet level terminal (not really a symbol) for subsheet input net in a hierarchy } + -sym-copyright=(C) 2024 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=inA + role=terminal + } + } + ha:group.3 { + uuid=gNCuJ00G+cWbegsDojwAAAAG; src_uuid=AHibvjaMiL5NH+9/wR0AAAAG; + x=76000; y=116000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-5000; y1=-1500; mirx=1; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:line.3 { x1=-4000; y1=0; x2=-5000; y2=2000; stroke=sheet-decor; } + ha:line.4 { x1=-4000; y1=0; x2=-5000; y2=-2000; stroke=sheet-decor; } + ha:line.5 { x1=-5000; y1=-2000; x2=-17000; y2=-2000; stroke=sheet-decor; } + ha:line.6 { x1=-17000; y1=2000; x2=-5000; y2=2000; stroke=sheet-decor; } + ha:line.7 { x1=-17000; y1=2000; x2=-17000; y2=-2000; stroke=sheet-decor; } + } + ha:attrib { + -sym-comment={ Sheet level terminal (not really a symbol) for subsheet input net in a hierarchy } + -sym-copyright=(C) 2024 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=inB + role=terminal + } + } + ha:group.4 { + uuid=gNCuJ00G+cWbegsDojwAAAAJ; src_uuid=AHibvjaMiL5NH+9/wR0AAAAI; + x=132000; y=124000; + li:objects { + ha:line.1 { x1=4000; y1=0; x2=0; y2=0; stroke=term-decor; } + ha:text.2 { x1=4500; y1=-1500; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:line.3 { x1=17000; y1=0; x2=16000; y2=2000; stroke=sheet-decor; } + ha:line.4 { x1=17000; y1=0; x2=16000; y2=-2000; stroke=sheet-decor; } + ha:line.5 { x1=16000; y1=-2000; x2=4000; y2=-2000; stroke=sheet-decor; } + ha:line.6 { x1=4000; y1=2000; x2=16000; y2=2000; stroke=sheet-decor; } + ha:line.7 { x1=4000; y1=2000; x2=4000; y2=-2000; stroke=sheet-decor; } + } + ha:attrib { + -sym-comment={ Sheet level terminal (not really a symbol) for subsheet output net in a hierarchy } + -sym-copyright=(C) 2024 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=outA + role=terminal + } + } + ha:group.5 { + uuid=gNCuJ00G+cWbegsDojwAAAAK; src_uuid=AHibvjaMiL5NH+9/wR0AAAAI; + x=132000; y=116000; + li:objects { + ha:line.1 { x1=4000; y1=0; x2=0; y2=0; stroke=term-decor; } + ha:text.2 { x1=4500; y1=-1500; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:line.3 { x1=17000; y1=0; x2=16000; y2=2000; stroke=sheet-decor; } + ha:line.4 { x1=17000; y1=0; x2=16000; y2=-2000; stroke=sheet-decor; } + ha:line.5 { x1=16000; y1=-2000; x2=4000; y2=-2000; stroke=sheet-decor; } + ha:line.6 { x1=4000; y1=2000; x2=16000; y2=2000; stroke=sheet-decor; } + ha:line.7 { x1=4000; y1=2000; x2=4000; y2=-2000; stroke=sheet-decor; } + } + ha:attrib { + -sym-comment={ Sheet level terminal (not really a symbol) for subsheet output net in a hierarchy } + -sym-copyright=(C) 2024 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=outB + role=terminal + } + } + ha:group.6 { + uuid=gNCuJ00G+cWbegsDojwAAAAX; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAH; + x=116000; y=120000; + li:objects { + ha:group.1 { + uuid=gNCuJ00G+cWbegsDojwAAAAY; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAI; + x=-20000; y=4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=in+ + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.2 { + uuid=gNCuJ00G+cWbegsDojwAAAAZ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAJ; + x=-20000; y=-4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=in- + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:group.3 { + uuid=gNCuJ00G+cWbegsDojwAAAAa; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAK; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=out + role=terminal + ha:spice/pinnum = { value=3; prio=31050; } + } + } + ha:line.4 { x1=-20000; y1=-8000; x2=-20000; y2=8000; stroke=sym-decor; } + ha:line.5 { x1=-20000; y1=8000; x2=-4000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=-4000; y1=0; x2=-20000; y2=-8000; stroke=sym-decor; } + ha:line.7 { x1=-18000; y1=5000; x2=-18000; y2=3000; stroke=sym-decor; } + ha:line.8 { x1=-19000; y1=4000; x2=-17000; y2=4000; stroke=sym-decor; } + ha:line.9 { x1=-19000; y1=-4000; x2=-17000; y2=-4000; stroke=sym-decor; } + ha:group.10 { + uuid=gNCuJ00G+cWbegsDojwAAAAb; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAL; + x=-12000; y=-4000; rot=270.000000; mirx=1; miry=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=0; y1=-1000; rot=180.000000; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=V- + role=terminal + ha:spice/pinnum = { value=5; prio=31050; } + } + } + ha:group.11 { + uuid=gNCuJ00G+cWbegsDojwAAAAc; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAM; + x=-12000; y=8000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=-4000; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=V+ + role=terminal + ha:spice/pinnum = { value=4; prio=31050; } + } + } + ha:text.12 { x1=-21000; y1=9000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -slot=1 + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + devmap=lm358_so8 + name=./U1 + role=symbol + } + } + ha:group.7 { + uuid=gNCuJ00G+cWbegsDojwAAAAf; + li:objects { + ha:line.1 { x1=76000; y1=124000; x2=92000; y2=124000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.8 { + li:conn { + /2/7/1 + /2/2/1 + } + } + ha:connection.9 { + li:conn { + /2/7/1 + /2/6/1/1 + } + } + ha:group.10 { + uuid=gNCuJ00G+cWbegsDojwAAAAg; + li:objects { + ha:line.1 { x1=76000; y1=116000; x2=92000; y2=116000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.11 { + li:conn { + /2/10/1 + /2/3/1 + } + } + ha:connection.12 { + li:conn { + /2/10/1 + /2/6/2/1 + } + } + ha:group.13 { + uuid=gNCuJ00G+cWbegsDojwAAAAh; + li:objects { + ha:line.1 { x1=116000; y1=120000; x2=124000; y2=120000; stroke=wire; } + ha:line.2 { x1=124000; y1=120000; x2=124000; y2=116000; stroke=wire; } + ha:line.3 { x1=124000; y1=116000; x2=132000; y2=116000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.14 { + li:conn { + /2/13/1 + /2/6/3/1 + } + } + ha:connection.15 { + li:conn { + /2/13/3 + /2/5/1 + } + } + ha:group.16 { + uuid=gNCuJ00G+cWbegsDojwAAAAi; + li:objects { + ha:line.1 { x1=104000; y1=128000; x2=128000; y2=128000; stroke=wire; } + ha:line.2 { x1=128000; y1=128000; x2=128000; y2=124000; stroke=wire; } + ha:line.3 { x1=128000; y1=124000; x2=132000; y2=124000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.17 { + li:conn { + /2/16/1 + /2/6/11/1 + } + } + ha:connection.18 { + li:conn { + /2/16/3 + /2/4/1 + } + } + ha:group.19 { + uuid=gNCuJ00G+cWbegsDojwAAAAn; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=104000; y=112000; + li:objects { + ha:group.1 { + uuid=gNCuJ00G+cWbegsDojwAAAAo; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + drc/require_graphical_conn=1 + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:connection.20 { + li:conn { + /2/19/1/1 + /2/6/10/1 + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer= + page= + print_page=A/4 + title= + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + } + } + } +} Index: tags/1.0.5/tests/hier/slot/main.rs =================================================================== --- tags/1.0.5/tests/hier/slot/main.rs (nonexistent) +++ tags/1.0.5/tests/hier/slot/main.rs (revision 10414) @@ -0,0 +1,242 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=sJumnHXrZ0A1+is6v5YAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.1 { + uuid=8/SYZ/pfBzxyqFA12WQAAAAC; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAg; + li:objects { + ha:polygon.11 { + li:outline { + ha:line { x1=0; y1=0; x2=80000; y2=0; } + ha:line { x1=80000; y1=0; x2=80000; y2=20000; } + ha:line { x1=80000; y1=20000; x2=0; y2=20000; } + ha:line { x1=0; y1=20000; x2=0; y2=0; } + } + stroke=titlebox-frame; + fill=titlebox-fill; + } + ha:line.12 { x1=0; y1=10000; x2=80000; y2=10000; stroke=titlebox-frame; } + ha:line.13 { x1=40000; y1=10000; x2=40000; y2=0; stroke=titlebox-frame; } + ha:text.20 { x1=1000; y1=16500; dyntext=0; stroke=titlebox-big; text=TITLE; } + ha:text.21 { x1=1000; y1=10500; x2=79000; y2=16000; dyntext=1; stroke=titlebox-big; text=%../../A.title%; } + ha:text.22 { x1=1000; y1=5500; dyntext=0; stroke=titlebox-small; text={PROJECT:}; } + ha:text.23 { x1=13000; y1=5500; x2=39000; y2=9500; dyntext=1; stroke=titlebox-big; text=%project.name%; } + ha:text.24 { x1=1000; y1=500; dyntext=0; stroke=titlebox-small; text={PAGE:}; } + ha:text.25 { x1=10000; y1=500; x2=39000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.page%; } + ha:text.26 { x1=41000; y1=5500; dyntext=0; stroke=titlebox-small; text={FILE:}; } + ha:text.27 { x1=48000; y1=5500; x2=79000; y2=9500; dyntext=1; stroke=titlebox-big; text=%filename%; } + ha:text.28 { x1=41000; y1=500; dyntext=0; stroke=titlebox-small; text={MAINTAINER:}; } + ha:text.29 { x1=55000; y1=500; x2=79000; y2=4500; dyntext=1; stroke=titlebox-big; text=%../../A.maintainer%; } + ha:text.30 { x1=79000; y1=16000; mirx=1; dyntext=1; stroke=sheet-decor; text=%stance.model% %stance.sub_major% %stance.sub_minor% %stance.test_bench% %view.name%; } + } + ha:attrib { + purpose=titlebox + } + } + ha:group.6 { + uuid=sJumnHXrZ0A1+is6v5YAAAAG; + x=76000; y=124000; + li:objects { + ha:polygon.1 { + li:outline { + ha:line { x1=-4000; y1=4000; x2=-4000; y2=-4000; } + ha:line { x1=-4000; y1=-4000; x2=8000; y2=-4000; } + ha:line { x1=8000; y1=-4000; x2=8000; y2=4000; } + ha:line { x1=8000; y1=4000; x2=-4000; y2=4000; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + ha:group.2 { + uuid=sJumnHXrZ0A1+is6v5YAAAAH; src_uuid=sJumnHXrZ0A1+is6v5YAAAAD; + x=12000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=outA + role=terminal + } + } + ha:group.3 { + uuid=sJumnHXrZ0A1+is6v5YAAAAI; src_uuid=sJumnHXrZ0A1+is6v5YAAAAD; + x=-8000; y=0; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=inA + role=terminal + } + } + ha:text.4 { x1=-4000; y1=4000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:text.5 { x1=-2000; y1=-2000; dyntext=1; stroke=sym-secondary; text=%../A.cschem/child/name%; floater=1; } + } + ha:attrib { + cschem/child/name=child.rs + name=S1 + role=symbol + } + } + ha:group.7 { + uuid=sJumnHXrZ0A1+is6v5YAAAAM; src_uuid=sJumnHXrZ0A1+is6v5YAAAAG; + x=76000; y=112000; + li:objects { + ha:polygon.1 { + li:outline { + ha:line { x1=-4000; y1=4000; x2=-4000; y2=-4000; } + ha:line { x1=-4000; y1=-4000; x2=8000; y2=-4000; } + ha:line { x1=8000; y1=-4000; x2=8000; y2=4000; } + ha:line { x1=8000; y1=4000; x2=-4000; y2=4000; } + } + stroke=sym-decor; + fill=sym-decor-fill; + } + ha:group.2 { + uuid=sJumnHXrZ0A1+is6v5YAAAAN; src_uuid=sJumnHXrZ0A1+is6v5YAAAAD; + x=12000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=outB + role=terminal + } + } + ha:group.3 { + uuid=sJumnHXrZ0A1+is6v5YAAAAO; src_uuid=sJumnHXrZ0A1+is6v5YAAAAD; + x=-8000; y=0; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=inB + role=terminal + } + } + ha:text.4 { x1=-4000; y1=4000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:text.5 { x1=-2000; y1=-2000; dyntext=1; stroke=sym-secondary; text=%../A.cschem/child/name%; floater=1; } + } + ha:attrib { + cschem/child/name=child.rs + name=S1 + role=symbol + } + } + ha:group.8 { + uuid=sJumnHXrZ0A1+is6v5YAAAAP; + li:objects { + ha:line.1 { x1=68000; y1=124000; x2=62000; y2=124000; stroke=wire; } + ha:text.2 { x1=58000; y1=124000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=net_ina + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.9 { + li:conn { + /2/8/1 + /2/6/3/1 + } + } + ha:group.12 { + uuid=sJumnHXrZ0A1+is6v5YAAAAT; src_uuid=sJumnHXrZ0A1+is6v5YAAAAP; + x=0; y=-12000; + li:objects { + ha:line.1 { x1=68000; y1=124000; x2=62000; y2=124000; stroke=wire; } + ha:text.2 { x1=58000; y1=124000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=net_inb + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.13 { + li:conn { + /2/12/1 + /2/7/3/1 + } + } + ha:group.14 { + uuid=sJumnHXrZ0A1+is6v5YAAAAU; + li:objects { + ha:line.1 { x1=88000; y1=124000; x2=98000; y2=124000; stroke=wire; } + ha:text.2 { x1=90000; y1=124000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=net_outa + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.15 { + li:conn { + /2/14/1 + /2/6/2/1 + } + } + ha:group.17 { + uuid=sJumnHXrZ0A1+is6v5YAAAAY; src_uuid=sJumnHXrZ0A1+is6v5YAAAAU; + x=0; y=-12000; + li:objects { + ha:line.1 { x1=88000; y1=124000; x2=98000; y2=124000; stroke=wire; } + ha:text.2 { x1=90000; y1=124000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=net_outb + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.18 { + li:conn { + /2/17/1 + /2/7/2/1 + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer= + page= + print_page=A/4 + title= + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 2 + grid = 4.0960 mm + } + } + } +} Index: tags/1.0.5/tests/hier/slot/project.lht =================================================================== --- tags/1.0.5/tests/hier/slot/project.lht (nonexistent) +++ tags/1.0.5/tests/hier/slot/project.lht (revision 10414) @@ -0,0 +1,14 @@ +ha:coraleda-project-v1 { + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:prj { + li:root_sheets { + main.rs + } + li:aux_sheets { + child.rs + } + } + } + } +} Index: tags/1.0.5/tests/hier/spice_slot/Makefile =================================================================== --- tags/1.0.5/tests/hier/spice_slot/Makefile (nonexistent) +++ tags/1.0.5/tests/hier/spice_slot/Makefile (revision 10414) @@ -0,0 +1,14 @@ +ROOT=../../.. +SRC=$(ROOT)/src/sch-rnd +HERE=$(shell pwd) + +all: + +test: + @cd $(SRC) && ./sch-rnd -x spice --outfile $(HERE)/spc.out $(HERE)/project.lht && cd $(HERE) + @diff -u spc.ref spc.out + @rm spc.out + +distclean clean: + touch spc.out + rm spc.out Index: tags/1.0.5/tests/hier/spice_slot/child.rs =================================================================== --- tags/1.0.5/tests/hier/spice_slot/child.rs (nonexistent) +++ tags/1.0.5/tests/hier/spice_slot/child.rs (revision 10414) @@ -0,0 +1,434 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + ha:group.1 { + uuid=TXsYkAVvycDUg/6VRmIAAAAV; + li:objects { + ha:group.1 { + uuid=TXsYkAVvycDUg/6VRmIAAAAW; loclib_name=lm358_so8; + li:objects { + } + ha:attrib { + device=lm358 + footprint=so(8) + li:portmap { + {1/in- -> pcb/pinnum=2} + {1/in+ -> pcb/pinnum=3} + {1/out -> pcb/pinnum=1} + {1/V+ -> pcb/pinnum=8} + {1/V- -> pcb/pinnum=4} + {2/in- -> pcb/pinnum=6} + {2/in+ -> pcb/pinnum=5} + {2/out -> pcb/pinnum=7} + {2/V+ -> pcb/pinnum=8} + {2/V- -> pcb/pinnum=4} + } + } + } + } + ha:attrib { + ha:purpose = { value=devmap; prio=0; } + } + } + } + } + ha:obj_direct.2 { + uuid=TXsYkAVvycDUg/6VRmIAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.2 { + uuid=TXsYkAVvycDUg/6VRmIAAAAP; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAH; + x=124000; y=128000; + li:objects { + ha:group.1 { + uuid=TXsYkAVvycDUg/6VRmIAAAAQ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAI; + x=-20000; y=4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=in+ + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.2 { + uuid=TXsYkAVvycDUg/6VRmIAAAAR; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAJ; + x=-20000; y=-4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=in- + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:group.3 { + uuid=TXsYkAVvycDUg/6VRmIAAAAS; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAK; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=out + role=terminal + ha:spice/pinnum = { value=3; prio=31050; } + } + } + ha:line.4 { x1=-20000; y1=-8000; x2=-20000; y2=8000; stroke=sym-decor; } + ha:line.5 { x1=-20000; y1=8000; x2=-4000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=-4000; y1=0; x2=-20000; y2=-8000; stroke=sym-decor; } + ha:line.7 { x1=-18000; y1=5000; x2=-18000; y2=3000; stroke=sym-decor; } + ha:line.8 { x1=-19000; y1=4000; x2=-17000; y2=4000; stroke=sym-decor; } + ha:line.9 { x1=-19000; y1=-4000; x2=-17000; y2=-4000; stroke=sym-decor; } + ha:group.10 { + uuid=TXsYkAVvycDUg/6VRmIAAAAT; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAL; + x=-12000; y=-4000; rot=270.000000; mirx=1; miry=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=0; y1=-1000; rot=180.000000; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=V- + role=terminal + ha:spice/pinnum = { value=5; prio=31050; } + } + } + ha:group.11 { + uuid=TXsYkAVvycDUg/6VRmIAAAAU; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAM; + x=-12000; y=8000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=-4000; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=V+ + role=terminal + ha:spice/pinnum = { value=4; prio=31050; } + } + } + ha:text.12 { x1=-21000; y1=9000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:text.13 { x1=-15000; y1=9000; dyntext=1; stroke=sym-secondary; text=%../A.-slot%; floater=1; } + } + ha:attrib { + -slot=1 + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + devmap=lm358_so8 + name=./U1 + role=symbol + spice/prefix=A + } + } + ha:group.4 { + uuid=TXsYkAVvycDUg/6VRmIAAAAj; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAH; + x=160000; y=128000; + li:objects { + ha:group.1 { + uuid=TXsYkAVvycDUg/6VRmIAAAAk; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAI; + x=-20000; y=4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=in+ + role=terminal + ha:spice/pinnum = { value=2; prio=31050; } + } + } + ha:group.2 { + uuid=TXsYkAVvycDUg/6VRmIAAAAl; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAJ; + x=-20000; y=-4000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=in- + role=terminal + ha:spice/pinnum = { value=1; prio=31050; } + } + } + ha:group.3 { + uuid=TXsYkAVvycDUg/6VRmIAAAAm; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAK; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=out + role=terminal + ha:spice/pinnum = { value=3; prio=31050; } + } + } + ha:line.4 { x1=-20000; y1=-8000; x2=-20000; y2=8000; stroke=sym-decor; } + ha:line.5 { x1=-20000; y1=8000; x2=-4000; y2=0; stroke=sym-decor; } + ha:line.6 { x1=-4000; y1=0; x2=-20000; y2=-8000; stroke=sym-decor; } + ha:line.7 { x1=-18000; y1=5000; x2=-18000; y2=3000; stroke=sym-decor; } + ha:line.8 { x1=-19000; y1=4000; x2=-17000; y2=4000; stroke=sym-decor; } + ha:line.9 { x1=-19000; y1=-4000; x2=-17000; y2=-4000; stroke=sym-decor; } + ha:group.10 { + uuid=TXsYkAVvycDUg/6VRmIAAAAn; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAL; + x=-12000; y=-4000; rot=270.000000; mirx=1; miry=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=0; y1=-1000; rot=180.000000; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=V- + role=terminal + ha:spice/pinnum = { value=5; prio=31050; } + } + } + ha:group.11 { + uuid=TXsYkAVvycDUg/6VRmIAAAAo; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAM; + x=-12000; y=8000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=-4000; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=V+ + role=terminal + ha:spice/pinnum = { value=4; prio=31050; } + } + } + ha:text.12 { x1=-21000; y1=9000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:text.13 { x1=-15000; y1=9000; dyntext=1; stroke=sym-secondary; text=%../A.-slot%; floater=1; } + } + ha:attrib { + -slot=2 + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + devmap=lm358_so8 + name=./U1 + role=symbol + spice/prefix=A + } + } + ha:connection.6 { + li:conn { + /2/2/3/1 + /2/24/6 + } + } + ha:connection.7 { + li:conn { + /2/4/1/1 + /2/24/5 + } + } + ha:group.8 { + uuid=TXsYkAVvycDUg/6VRmIAAAAq; + li:objects { + ha:line.1 { x1=100000; y1=132000; x2=80000; y2=132000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.9 { + li:conn { + /2/8/1 + /2/2/1/1 + } + } + ha:connection.11 { + li:conn { + /2/4/3/1 + /2/22/4 + } + } + ha:group.12 { + uuid=TXsYkAVvycDUg/6VRmIAAAAu; src_uuid=AHibvjaMiL5NH+9/wR0AAAAG; + x=80000; y=132000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-5000; y1=-1500; mirx=1; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:line.3 { x1=-4000; y1=0; x2=-5000; y2=2000; stroke=sheet-decor; } + ha:line.4 { x1=-4000; y1=0; x2=-5000; y2=-2000; stroke=sheet-decor; } + ha:line.5 { x1=-5000; y1=-2000; x2=-17000; y2=-2000; stroke=sheet-decor; } + ha:line.6 { x1=-17000; y1=2000; x2=-5000; y2=2000; stroke=sheet-decor; } + ha:line.7 { x1=-17000; y1=2000; x2=-17000; y2=-2000; stroke=sheet-decor; } + } + ha:attrib { + -sym-comment={ Sheet level terminal (not really a symbol) for subsheet input net in a hierarchy } + -sym-copyright=(C) 2024 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=in + role=terminal + } + } + ha:connection.13 { + li:conn { + /2/12/1 + /2/8/1 + } + } + ha:group.14 { + uuid=TXsYkAVvycDUg/6VRmIAAAAx; src_uuid=AHibvjaMiL5NH+9/wR0AAAAI; + x=176000; y=128000; + li:objects { + ha:line.1 { x1=4000; y1=0; x2=0; y2=0; stroke=term-decor; } + ha:text.2 { x1=4500; y1=-1500; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + ha:line.3 { x1=17000; y1=0; x2=16000; y2=2000; stroke=sheet-decor; } + ha:line.4 { x1=17000; y1=0; x2=16000; y2=-2000; stroke=sheet-decor; } + ha:line.5 { x1=16000; y1=-2000; x2=4000; y2=-2000; stroke=sheet-decor; } + ha:line.6 { x1=4000; y1=2000; x2=16000; y2=2000; stroke=sheet-decor; } + ha:line.7 { x1=4000; y1=2000; x2=4000; y2=-2000; stroke=sheet-decor; } + } + ha:attrib { + -sym-comment={ Sheet level terminal (not really a symbol) for subsheet output net in a hierarchy } + -sym-copyright=(C) 2024 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=out + role=terminal + } + } + ha:connection.15 { + li:conn { + /2/14/1 + /2/22/4 + } + } + ha:group.16 { + uuid=TXsYkAVvycDUg/6VRmIAAAAy; + li:objects { + ha:line.1 { x1=112000; y1=136000; x2=112000; y2=152000; stroke=wire; } + ha:text.4 { x1=108000; y1=153000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + ha:line.5 { x1=112000; y1=148000; x2=148000; y2=148000; stroke=wire; } + ha:line.6 { x1=112000; y1=148000; x2=112000; y2=148000; stroke=junction; } + ha:line.7 { x1=148000; y1=148000; x2=148000; y2=136000; stroke=wire; } + } + ha:attrib { + name=opa_plus + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.17 { + li:conn { + /2/16/1 + /2/2/11/1 + } + } + ha:group.19 { + uuid=TXsYkAVvycDUg/6VRmIAAAAz; + li:objects { + ha:line.1 { x1=112000; y1=120000; x2=112000; y2=104000; stroke=wire; } + ha:text.4 { x1=107000; y1=100000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + ha:line.5 { x1=112000; y1=108000; x2=148000; y2=108000; stroke=wire; } + ha:line.6 { x1=112000; y1=108000; x2=112000; y2=108000; stroke=junction; } + ha:line.7 { x1=148000; y1=108000; x2=148000; y2=120000; stroke=wire; } + } + ha:attrib { + name=opa_minus + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.20 { + li:conn { + /2/19/1 + /2/2/10/1 + } + } + ha:group.22 { + uuid=TXsYkAVvycDUg/6VRmIAAAA0; + li:objects { + ha:line.1 { x1=136000; y1=124000; x2=132000; y2=124000; stroke=wire; } + ha:line.2 { x1=132000; y1=124000; x2=132000; y2=116000; stroke=wire; } + ha:line.3 { x1=132000; y1=116000; x2=164000; y2=116000; stroke=wire; } + ha:line.4 { x1=160000; y1=128000; x2=176000; y2=128000; stroke=wire; } + ha:line.5 { x1=164000; y1=116000; x2=164000; y2=128000; stroke=wire; } + ha:line.6 { x1=164000; y1=128000; x2=164000; y2=128000; stroke=junction; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.23 { + li:conn { + /2/22/1 + /2/4/2/1 + } + } + ha:group.24 { + uuid=TXsYkAVvycDUg/6VRmIAAAA1; + li:objects { + ha:line.1 { x1=100000; y1=124000; x2=92000; y2=124000; stroke=wire; } + ha:line.2 { x1=92000; y1=124000; x2=92000; y2=112000; stroke=wire; } + ha:line.3 { x1=92000; y1=112000; x2=124000; y2=112000; stroke=wire; } + ha:line.5 { x1=124000; y1=132000; x2=136000; y2=132000; stroke=wire; } + ha:line.6 { x1=124000; y1=112000; x2=124000; y2=132000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.25 { + li:conn { + /2/24/1 + /2/2/2/1 + } + } + ha:connection.26 { + li:conn { + /2/16/7 + /2/4/11/1 + } + } + ha:connection.27 { + li:conn { + /2/19/7 + /2/4/10/1 + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer= + page= + print_page=A/4 + title= + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 2 + grid = 4.0960 mm + } + } + } +} Index: tags/1.0.5/tests/hier/spice_slot/project.lht =================================================================== --- tags/1.0.5/tests/hier/spice_slot/project.lht (nonexistent) +++ tags/1.0.5/tests/hier/spice_slot/project.lht (revision 10414) @@ -0,0 +1,14 @@ +ha:coraleda-project-v1 { + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:prj { + li:root_sheets { + root.rs + } + li:aux_sheets { + child.rs + } + } + } + } +} Index: tags/1.0.5/tests/hier/spice_slot/root.rs =================================================================== --- tags/1.0.5/tests/hier/spice_slot/root.rs (nonexistent) +++ tags/1.0.5/tests/hier/spice_slot/root.rs (revision 10414) @@ -0,0 +1,409 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=JKMrlvmRpJSOuz679xUAAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.8 { + uuid=JKMrlvmRpJSOuz679xUAAAAG; + x=112000; y=84000; + li:objects { + ha:group.1 { + uuid=JKMrlvmRpJSOuz679xUAAAAH; src_uuid=JKMrlvmRpJSOuz679xUAAAAD; + x=4000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=in + role=terminal + } + } + ha:group.2 { + uuid=JKMrlvmRpJSOuz679xUAAAAI; src_uuid=JKMrlvmRpJSOuz679xUAAAAD; + x=8000; y=0; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=out + role=terminal + } + } + ha:polygon.3 { + li:outline { + ha:line { x1=4000; y1=4000; x2=4000; y2=-4000; } + ha:line { x1=4000; y1=-4000; x2=8000; y2=0; } + ha:line { x1=8000; y1=0; x2=4000; y2=4000; } + } + stroke=sym-decor; + } + ha:text.4 { x1=3000; y1=4000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + cschem/child/name=child.rs + name=S1 + role=symbol + } + } + ha:group.9 { + uuid=JKMrlvmRpJSOuz679xUAAAAP; src_uuid=JKMrlvmRpJSOuz679xUAAAAG; + x=132000; y=84000; + li:objects { + ha:group.1 { + uuid=JKMrlvmRpJSOuz679xUAAAAQ; src_uuid=JKMrlvmRpJSOuz679xUAAAAD; + x=4000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=in + role=terminal + } + } + ha:group.2 { + uuid=JKMrlvmRpJSOuz679xUAAAAR; src_uuid=JKMrlvmRpJSOuz679xUAAAAD; + x=8000; y=0; mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=out + role=terminal + } + } + ha:polygon.3 { + li:outline { + ha:line { x1=4000; y1=4000; x2=4000; y2=-4000; } + ha:line { x1=4000; y1=-4000; x2=8000; y2=0; } + ha:line { x1=8000; y1=0; x2=4000; y2=4000; } + } + stroke=sym-decor; + } + ha:text.4 { x1=3000; y1=4000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + cschem/child/name=child.rs + name=S2 + role=symbol + } + } + ha:group.10 { + uuid=JKMrlvmRpJSOuz679xUAAAAS; + li:objects { + ha:line.1 { x1=124000; y1=84000; x2=132000; y2=84000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.11 { + li:conn { + /2/10/1 + /2/8/2/1 + } + } + ha:connection.12 { + li:conn { + /2/10/1 + /2/9/1/1 + } + } + ha:group.13 { + uuid=JKMrlvmRpJSOuz679xUAAAAT; + li:objects { + ha:line.1 { x1=112000; y1=84000; x2=104000; y2=84000; stroke=wire; } + ha:text.2 { x1=107000; y1=84000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=inp + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.14 { + li:conn { + /2/13/1 + /2/8/1/1 + } + } + ha:group.15 { + uuid=JKMrlvmRpJSOuz679xUAAAAY; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB6; + x=80000; y=84000; + li:objects { + ha:group.1 { + uuid=JKMrlvmRpJSOuz679xUAAAAZ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAB7; + rot=270.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + drc/require_graphical_conn=1 + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=2500; y1=4000; x2=-2500; y2=4000; stroke=sym-decor; } + ha:text.3 { x1=-4000; y1=4000; x2=4000; y2=7000; halign=center; dyntext=0; stroke=sym-primary; text=Vcc; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:Vcc} + } + role=symbol + } + } + ha:group.17 { + uuid=JKMrlvmRpJSOuz679xUAAAAg; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=152000; y=84000; + li:objects { + ha:group.1 { + uuid=JKMrlvmRpJSOuz679xUAAAAh; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=JKMrlvmRpJSOuz679xUAAAAi; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + ha:device = { value=resistor; prio=31050; } + name=R2 + role=symbol + ha:spice/prefix = { value=R; prio=31050; } + value=10k + } + } + ha:group.18 { + uuid=JKMrlvmRpJSOuz679xUAAAAj; + li:objects { + ha:line.1 { x1=144000; y1=84000; x2=152000; y2=84000; stroke=wire; } + ha:text.2 { x1=146000; y1=84000; dyntext=1; stroke=wire; text=%../A.name%; floater=1; } + } + ha:attrib { + name=outp + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.19 { + li:conn { + /2/18/1 + /2/9/2/1 + } + } + ha:connection.20 { + li:conn { + /2/18/1 + /2/17/2/1 + } + } + ha:group.21 { + uuid=JKMrlvmRpJSOuz679xUAAAAk; + li:objects { + ha:line.1 { x1=172000; y1=84000; x2=172000; y2=76000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.22 { + li:conn { + /2/21/1 + /2/17/1/1 + } + } + ha:group.23 { + uuid=JKMrlvmRpJSOuz679xUAAAAp; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=172000; y=76000; + li:objects { + ha:group.1 { + uuid=JKMrlvmRpJSOuz679xUAAAAq; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + drc/require_graphical_conn=1 + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:connection.24 { + li:conn { + /2/23/1/1 + /2/21/1 + } + } + ha:group.25 { + uuid=BI86VBN8v61qXqHhRMoAAAAq; src_uuid=iNOQfJpO6hT/HFDFGjoAAABC; + x=84000; y=84000; + li:objects { + ha:group.1 { + uuid=BI86VBN8v61qXqHhRMoAAAAr; src_uuid=iNOQfJpO6hT/HFDFGjoAAABD; + x=20000; y=0; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=2 + role=terminal + } + } + ha:group.2 { + uuid=BI86VBN8v61qXqHhRMoAAAAs; src_uuid=iNOQfJpO6hT/HFDFGjoAAABE; + mirx=1; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-3000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:text.3 { x1=12000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../a.value%; floater=1; } + ha:text.4 { x1=8000; y1=2000; rot=90.000000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + ha:polygon.5 { + li:outline { + ha:line { x1=4000; y1=2000; x2=4000; y2=-2000; } + ha:line { x1=4000; y1=-2000; x2=16000; y2=-2000; } + ha:line { x1=16000; y1=-2000; x2=16000; y2=2000; } + ha:line { x1=16000; y1=2000; x2=4000; y2=2000; } + } + stroke=sym-decor; + } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + ha:device = { value=resistor; prio=31050; } + name=R1 + role=symbol + ha:spice/prefix = { value=R; prio=31050; } + value=10k + } + } + ha:connection.26 { + li:conn { + /2/25/1/1 + /2/13/1 + } + } + ha:group.28 { + uuid=BI86VBN8v61qXqHhRMoAAAAt; + li:objects { + ha:line.1 { x1=80000; y1=84000; x2=84000; y2=84000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.29 { + li:conn { + /2/28/1 + /2/25/2/1 + } + } + ha:connection.30 { + li:conn { + /2/28/1 + /2/15/1/1 + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer= + page= + print_page=A/4 + title= + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grids_idx = 2 + grid = 4.0960 mm + } + } + } +} Index: tags/1.0.5/tests/hier/spice_slot/spc.ref =================================================================== --- tags/1.0.5/tests/hier/spice_slot/spc.ref (nonexistent) +++ tags/1.0.5/tests/hier/spice_slot/spc.ref (revision 10414) @@ -0,0 +1,8 @@ +.title sch-rnd export using export_spice + +*** circuit *** +S2/U1 anon_net_15 anon_net_15 anon_net_11 opa_minus anon_net_15 outp outp opa_plus +S1/U1 anon_net_10 anon_net_10 inp opa_minus anon_net_10 anon_net_11 anon_net_11 opa_plus +R1 Vcc inp 10k +R2 outp GND 10k +.end Index: tags/1.0.5/tests/lib_plot/Makefile =================================================================== --- tags/1.0.5/tests/lib_plot/Makefile (nonexistent) +++ tags/1.0.5/tests/lib_plot/Makefile (revision 10414) @@ -0,0 +1,18 @@ +ROOT=../.. + +CFLAGS = -g -I$(ROOT)/src $(CFLAGS_LIBRND) -DRND_INLINE=static +LDFLAGS = $(LDFLAGS_LIBRND) +#LDRND = -lrnd_3rd +LDRND = -lgenht + +#CFLAGS += -pg -O3 +#LDFLAGS += -pg + +main: main.o $(ROOT)/src/plugins/lib_plot/plot_data.o + $(CC) -o main main.o $(ROOT)/src/plugins/lib_plot/plot_data.o $(LDRND) $(LDFLAGS) $(LDLIBS) + +include $(ROOT)/Makefile.conf +include $(LIBRND_MAK) + +main.o: main.c + $(CC) -c $(CFLAGS) -o main.o main.c Index: tags/1.0.5/tests/lib_plot/main.c =================================================================== --- tags/1.0.5/tests/lib_plot/main.c (nonexistent) +++ tags/1.0.5/tests/lib_plot/main.c (revision 10414) @@ -0,0 +1,103 @@ +#include +#include + +#define BUFFLEN 1024 + +static int fill(plot_trace_t *tr, plot_trdata_t *trdata, plot_which_t which, long from, long len) +{ + double tmp[1024]; + long n; + plot_pos_t pw; + + if (plot_write_init(&pw, tr, trdata, PLOT_MAIN, 0, 0, tmp, sizeof(tmp)/sizeof(tmp[0])) != 0) + return -1; + + for(n = 0; n < len; n++) + plot_write(&pw, n); + + plot_flush(&pw); + return 0; +} + + +static void dump(plot_trace_t *tr, plot_trdata_t *td) +{ + double bmain[BUFFLEN], bmin[BUFFLEN], bmax[BUFFLEN], dmain, dmin, dmax; + long n; + plot_pos_t pmain, pmin, pmax; + + printf(" trace level %d of %ld pts\n", td->level, td->main.len); + + if (td->level == 0) { + if (plot_read_init(&pmain, tr, td, PLOT_MAIN, 0, 0, bmain, sizeof(bmain)/sizeof(bmain[0])) != 0) { + printf(" \n"); + return; + } + while(plot_read(&pmain, &dmain) == 0) + printf(" %.2f\n", dmain); + } + else { + if (plot_read_init(&pmain, tr, td, PLOT_MAIN, 0, 0, bmain, sizeof(bmain)/sizeof(bmain[0])) != 0) { + printf(" \n"); + return; + } + if (plot_read_init(&pmin, tr, td, PLOT_MIN, 0, 0, bmin, sizeof(bmin)/sizeof(bmin[0])) != 0) { + printf(" \n"); + return; + } + if (plot_read_init(&pmax, tr, td, PLOT_MAX, 0, 0, bmax, sizeof(bmax)/sizeof(bmax[0])) != 0) { + printf(" \n"); + return; + } + while((plot_read(&pmain, &dmain) == 0) && (plot_read(&pmin, &dmin) == 0) && (plot_read(&pmax, &dmax) == 0)) + printf(" %.2f [%.2f %.2f]\n", dmain, dmin, dmax); + } +} + +static void verify0(plot_trace_t *tr, plot_trdata_t *td) +{ + double bmain[BUFFLEN], dmain; + long n; + plot_pos_t pmain; + + if (plot_read_init(&pmain, tr, td, PLOT_MAIN, 0, 0, bmain, sizeof(bmain)/sizeof(bmain[0])) != 0) + abort(); + + n = 0; + while(plot_read(&pmain, &dmain) == 0) { + if (dmain != n) + abort(); + n++; + } +} + +#define LEN 29 + +int main() +{ + plot_data_t *pt; + FILE *fc = fopen("cache", "w+"); + plot_trace_t *tr; + plot_trdata_t *td; + + pt = plot_data_alloc(1); + tr = &pt->trace[0]; + plot_trace_init(tr, fc); + + td = plot_trdata_alloc(tr, 0, LEN); + fill(tr, td, PLOT_MAIN, 0, LEN); + + td = plot_trdata_get(tr, 0, 1); + dump(tr, td); +/* verify0(tr, td);*/ + + td = plot_trdata_get(tr, 1, 1); + dump(tr, td); + + td = plot_trdata_get(tr, 2, 1); + dump(tr, td); + + fclose(fc); + plot_data_free(pt); + return 0; +} Index: tags/1.0.5/tests/manual/README =================================================================== --- tags/1.0.5/tests/manual/README (nonexistent) +++ tags/1.0.5/tests/manual/README (revision 10414) @@ -0,0 +1,2 @@ +Manual test cases: these are referenced from the code as tests/manual/xxx. +They are typically used to manually reproduce some corner case in GUI editing. Index: tags/1.0.5/tests/manual/cn1/README =================================================================== --- tags/1.0.5/tests/manual/cn1/README (nonexistent) +++ tags/1.0.5/tests/manual/cn1/README (revision 10414) @@ -0,0 +1,15 @@ +- BUG: load bug_files net-bug.ry, then using cursor, click/drag the + bottom of the wire attached to TP? until it meets the GND + symbol terminal. lengthened wire connects to horizontal wire, + but fails to connect to GND terminal [report: Erich] + + +util_wirenet/csch_wirenet_recalc_line_chg() @ r8878 + + /* Install conns at new coords before net merge; order matters, because if + the wirenet of the edited line gets merged into another, existing wirenet, + that will inherit the connections we find here; but if connections + are calculated only after the merge in csch_wirenet_newline_merge_parent(), + then "line" is already a deleted object from the old, now deleted wirenet + and the connection is not made on deleted objects. + Test case: tests/manual/cn1 */ Index: tags/1.0.5/tests/manual/cn1/test.rs =================================================================== --- tags/1.0.5/tests/manual/cn1/test.rs (nonexistent) +++ tags/1.0.5/tests/manual/cn1/test.rs (revision 10414) @@ -0,0 +1,131 @@ +ha:cschem-sheet-v1 { + ha:obj_indirect.1 { + li:objects { + } + } + ha:obj_direct.2 { + uuid=+ph4ZKM0lNHoy0cEyY8AAAAC; + li:objects { + ha:pen.sheet-decor { shape=round; size=125; color=#777777; font_height=3000; font_family=sans; } + ha:pen.sheet-decor-fill { shape=round; size=125; color=#bbbbbb; font_height=3000; font_family=sans; } + ha:pen.titlebox-frame { shape=round; size=250; color=#777777; font_height=0; } + ha:pen.titlebox-fill { shape=round; size=250; color=#bbffbb; font_height=0; } + ha:pen.titlebox-big { shape=round; size=250; color=#777777; font_height=3000; font_family=sans; } + ha:pen.titlebox-small { shape=round; size=250; color=#777777; font_height=1500; font_family=sans; } + ha:pen.wire { shape=round; size=250; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.bus { shape=round; size=1500; color=#2222bb; font_height=3000; font_family=sans; } + ha:pen.hub { shape=round; size=3000; color=#6666ff; font_height=3000; font_family=sans; } + ha:pen.sym-decor { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; } + ha:pen.sym-decor-fill { shape=round; size=125; color=#99ff99; font_height=3000; font_family=sans; } + ha:pen.sym-primary { shape=round; size=125; color=#119911; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.sym-secondary { shape=round; size=125; color=#33bb33; font_height=3000; font_family=sans; } + ha:pen.term-decor { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; } + ha:pen.term-primary { shape=round; size=250; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.term-secondary { shape=round; size=250; color=#555555; font_height=3000; font_family=sans; } + ha:pen.busterm-decor { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; } + ha:pen.busterm-primary { shape=round; size=1500; color=#222222; font_height=3000; font_family=sans; font_style=bold; } + ha:pen.busterm-secondary { shape=round; size=1500; color=#555555; font_height=3000; font_family=sans; } + ha:pen.junction { shape=round; size=1000; color=#2222bb; font_height=3000; font_family=sans; } + ha:group.2 { + uuid=+ph4ZKM0lNHoy0cEyY8AAAAI; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAe; + x=20000; y=40000; + li:objects { + ha:group.1 { + uuid=+ph4ZKM0lNHoy0cEyY8AAAAJ; src_uuid=iNOQfJpO6hT/HFDFGjoAAAAf; + x=0; y=4000; rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + ha:text.2 { x1=-4000; y1=0; dyntext=1; stroke=term-primary; text=%../a.display/name%; } + } + ha:attrib { + name=1 + role=terminal + } + } + ha:line.2 { x1=0; y1=4000; x2=-2000; y2=6000; stroke=sym-decor; } + ha:line.3 { x1=-2000; y1=6000; x2=0; y2=8000; stroke=sym-decor; } + ha:line.4 { x1=0; y1=8000; x2=2000; y2=6000; stroke=sym-decor; } + ha:line.5 { x1=2000; y1=6000; x2=0; y2=4000; stroke=sym-decor; } + ha:text.6 { x1=-4000; y1=8000; dyntext=1; stroke=sym-primary; text=%../A.name%; floater=1; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + name=TP?? + role=symbol + spice/omit=yes + } + } + ha:group.3 { + uuid=+ph4ZKM0lNHoy0cEyY8AAAAO; src_uuid=iNOQfJpO6hT/HFDFGjoAAABm; + x=20000; y=8000; + li:objects { + ha:group.1 { + uuid=+ph4ZKM0lNHoy0cEyY8AAAAP; src_uuid=iNOQfJpO6hT/HFDFGjoAAABn; + rot=90.000000; + li:objects { + ha:line.1 { x1=0; y1=0; x2=-4000; y2=0; stroke=term-decor; } + } + ha:attrib { + ha:name = { value=1; prio=220; } + role=terminal + } + } + ha:line.2 { x1=-1500; y1=-5000; x2=1500; y2=-5000; stroke=sym-decor; } + ha:line.3 { x1=-500; y1=-6000; x2=500; y2=-6000; stroke=sym-decor; } + ha:line.4 { x1=-2500; y1=-4000; x2=2500; y2=-4000; stroke=sym-decor; } + } + ha:attrib { + -sym-copyright=(C) 2022 Tibor 'Igor2' Palinkas + -sym-license-dist=GPLv2+ + -sym-license-use=Public Domain + -sym-source=sch-rnd default symbol lib + li:connect { + {1:GND} + } + role=symbol + } + } + ha:group.4 { + uuid=+ph4ZKM0lNHoy0cEyY8AAAAQ; + li:objects { + ha:line.1 { x1=20000; y1=40000; x2=20000; y2=28000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + ha:connection.5 { + li:conn { + /2/2/1/1 + /2/4/1 + } + } + ha:group.6 { + uuid=+ph4ZKM0lNHoy0cEyY8AAAAR; + li:objects { + ha:line.1 { x1=20000; y1=16000; x2=36000; y2=16000; stroke=wire; } + } + ha:attrib { + ha:role = { value=wire-net; prio=0; } + } + } + } + ha:attrib { + drawing_min_height=200000 + drawing_min_width=287000 + maintainer= + page= + print_page=A/4 + title= + } + } + li:sch-rnd-conf-v1 { + ha:overwrite { + ha:editor { + } + } + } +} Index: tags/1.0.5/tests/relative_path/Makefile =================================================================== --- tags/1.0.5/tests/relative_path/Makefile (nonexistent) +++ tags/1.0.5/tests/relative_path/Makefile (revision 10414) @@ -0,0 +1,14 @@ +ROOT=../.. + +CFLAGS = -I$(ROOT)/src -I$(ROOT)/src_3rd $(CFLAGS_LIBRND) +LDFLAGS = $(LDFLAGS_LIBRND) +LDRND = -lrnd-core -lrnd-3rd + +main: main.o $(ROOT)/src/libcschem/util_path.o + $(CC) -o main main.o $(ROOT)/src/libcschem/util_path.o $(LDRND) $(LDFLAGS) $(LDLIBS) + +include $(ROOT)/Makefile.conf +include $(LIBRND_MAK) + +main.o: main.c + $(CC) -c $(CFLAGS) -o main.o main.c Index: tags/1.0.5/tests/relative_path/main.c =================================================================== --- tags/1.0.5/tests/relative_path/main.c (nonexistent) +++ tags/1.0.5/tests/relative_path/main.c (revision 10414) @@ -0,0 +1,22 @@ +#include +#include + +char *csch_relative_path_files(const char *pth, const char *relto); + +static void test(const char *p1, const char *p2) +{ + char *res = csch_relative_path_files(p1, p2); + printf("(%s, %s) = %s\n", p1, p2, res); + free(res); +} + +int main() +{ + test("/home/foo/bar/baz.pcb", "/home/foo/heh.txt"); + test("/home/foo/heh.txt", "/home/foo/bar/baz.pcb"); + + test("/home/foo/bar/baz.pcb", "/tmp/heh.txt"); + test("/tmp/heh.txt", "/home/foo/bar/baz.pcb"); + + return 0; +} Index: tags/1.0.5/tests/relative_path/ref =================================================================== --- tags/1.0.5/tests/relative_path/ref (nonexistent) +++ tags/1.0.5/tests/relative_path/ref (revision 10414) @@ -0,0 +1,4 @@ +(/home/foo/bar/baz.pcb, /home/foo/heh.txt) = bar/baz.pcb +(/home/foo/heh.txt, /home/foo/bar/baz.pcb) = ../heh.txt +(/home/foo/bar/baz.pcb, /tmp/heh.txt) = ../home/foo/bar/baz.pcb +(/tmp/heh.txt, /home/foo/bar/baz.pcb) = ../../../tmp/heh.txt Index: tags/1.0.5/tests/std_forge_cond/Makefile =================================================================== --- tags/1.0.5/tests/std_forge_cond/Makefile (nonexistent) +++ tags/1.0.5/tests/std_forge_cond/Makefile (revision 10414) @@ -0,0 +1,30 @@ +TRUNK=../.. +STDFRG=$(TRUNK)/src/plugins/std_forge + +include $(TRUNK)/Makefile.conf +include $(LIBRND_MAK) + +CFLAGS = $(CFLAGS_LIBRND) -I$(STDFRG) -I$(TRUNK)/src -I$(TRUNK)/src/plugins +LDFLAGS = $(LIB_RND_LDFLAGS_EXTRA) $(LDFLAGS_LIBRND) +LDLIBS = -lrnd-3rd + + +all: std_forge_cond + +std_forge_cond: $(STDFRG)/cond_gram.o std_forge_cond.o + $(CC) -o std_forge_cond std_forge_cond.o $(STDFRG)/cond_gram.o $(LDFLAGS) $(LDLIBS) + +$(STDFRG)/cond_gram.o: $(STDFRG)/cond_gram.c $(STDFRG)/cond.h + $(CC) -c $(CFLAGS) -o $(STDFRG)/cond_gram.o $(STDFRG)/cond_gram.c + +$(STDFRG)/cond_gram.c $(STDFRG)/cond_gram.h: $(STDFRG)/cond_gram.y + @echo "(not running byaccic from make test)" + +std_forge_cond.o: std_forge_cond.c $(STDFRG)/cond.h + $(CC) -c $(CFLAGS) -o std_forge_cond.o std_forge_cond.c + +test: + cd regression && ./Test.sh + +clean: + -rm cond cond.c regression/*.out Index: tags/1.0.5/tests/std_forge_cond/regression/Test.sh =================================================================== --- tags/1.0.5/tests/std_forge_cond/regression/Test.sh (nonexistent) +++ tags/1.0.5/tests/std_forge_cond/regression/Test.sh (revision 10414) @@ -0,0 +1,20 @@ +#!/bin/sh +tester=../std_forge_cond +bad=0 +for n in *.in +do + base=${n%%.in} + $tester <$n >$base.out 2>&1 + diff $base.ref $base.out + if test "$?" = "0" + then + rm $base.out + else + bad=1 + fi +done + +if test "$bad" = "0" +then + echo "*** QC PASS ***" +fi Property changes on: tags/1.0.5/tests/std_forge_cond/regression/Test.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/1.0.5/tests/std_forge_cond/regression/algeb.in =================================================================== --- tags/1.0.5/tests/std_forge_cond/regression/algeb.in (nonexistent) +++ tags/1.0.5/tests/std_forge_cond/regression/algeb.in (revision 10414) @@ -0,0 +1 @@ +100 % (20+(8/2)-7) Index: tags/1.0.5/tests/std_forge_cond/regression/algeb.ref =================================================================== --- tags/1.0.5/tests/std_forge_cond/regression/algeb.ref (nonexistent) +++ tags/1.0.5/tests/std_forge_cond/regression/algeb.ref (revision 10414) @@ -0,0 +1,15 @@ +prg: + NUM: 100 + NUM: 20 + NUM: 8 + NUM: 2 + DIV + ADD + NUM: 7 + SUB + MOD +strings: +-- compile -- +-- AST -- +-- execute -- +res=15 Index: tags/1.0.5/tests/std_forge_cond/regression/bin_and.in =================================================================== --- tags/1.0.5/tests/std_forge_cond/regression/bin_and.in (nonexistent) +++ tags/1.0.5/tests/std_forge_cond/regression/bin_and.in (revision 10414) @@ -0,0 +1,4 @@ +15 & (8+32) + + + Index: tags/1.0.5/tests/std_forge_cond/regression/bin_and.ref =================================================================== --- tags/1.0.5/tests/std_forge_cond/regression/bin_and.ref (nonexistent) +++ tags/1.0.5/tests/std_forge_cond/regression/bin_and.ref (revision 10414) @@ -0,0 +1,11 @@ +prg: + NUM: 15 + NUM: 8 + NUM: 32 + ADD + & +strings: +-- compile -- +-- AST -- +-- execute -- +res=8 Index: tags/1.0.5/tests/std_forge_cond/regression/bin_or.in =================================================================== --- tags/1.0.5/tests/std_forge_cond/regression/bin_or.in (nonexistent) +++ tags/1.0.5/tests/std_forge_cond/regression/bin_or.in (revision 10414) @@ -0,0 +1,3 @@ +1 | 2 + + Index: tags/1.0.5/tests/std_forge_cond/regression/bin_or.ref =================================================================== --- tags/1.0.5/tests/std_forge_cond/regression/bin_or.ref (nonexistent) +++ tags/1.0.5/tests/std_forge_cond/regression/bin_or.ref (revision 10414) @@ -0,0 +1,9 @@ +prg: + NUM: 1 + NUM: 2 + | +strings: +-- compile -- +-- AST -- +-- execute -- +res=3 Index: tags/1.0.5/tests/std_forge_cond/regression/cmp.in =================================================================== --- tags/1.0.5/tests/std_forge_cond/regression/cmp.in (nonexistent) +++ tags/1.0.5/tests/std_forge_cond/regression/cmp.in (revision 10414) @@ -0,0 +1,2 @@ +(12 == 12) && (12 != 11) && (4 < 5) && (5 > 4) && (4 <= 5) && (5 <= 5) && (5 >= 4) && (5 >= 5) + Index: tags/1.0.5/tests/std_forge_cond/regression/cmp.ref =================================================================== --- tags/1.0.5/tests/std_forge_cond/regression/cmp.ref (nonexistent) +++ tags/1.0.5/tests/std_forge_cond/regression/cmp.ref (revision 10414) @@ -0,0 +1,37 @@ +prg: + NUM: 12 + NUM: 12 + EQ + NUM: 12 + NUM: 11 + NEQ + && + NUM: 4 + NUM: 5 + LT + && + NUM: 5 + NUM: 4 + GT + && + NUM: 4 + NUM: 5 + LTE + && + NUM: 5 + NUM: 5 + LTE + && + NUM: 5 + NUM: 4 + GTE + && + NUM: 5 + NUM: 5 + GTE + && +strings: +-- compile -- +-- AST -- +-- execute -- +res=1 Index: tags/1.0.5/tests/std_forge_cond/regression/str.in =================================================================== --- tags/1.0.5/tests/std_forge_cond/regression/str.in (nonexistent) +++ tags/1.0.5/tests/std_forge_cond/regression/str.in (revision 10414) @@ -0,0 +1 @@ +(first != second) && (first == fourth) && (first == "one") && (first != "foo") && ("foo" == "foo") && ("foo" != "bar") \ No newline at end of file Index: tags/1.0.5/tests/std_forge_cond/regression/str.ref =================================================================== --- tags/1.0.5/tests/std_forge_cond/regression/str.ref (nonexistent) +++ tags/1.0.5/tests/std_forge_cond/regression/str.ref (revision 10414) @@ -0,0 +1,41 @@ +prg: + VAR1: [0] + VAR1: [6] + SNQ + VAR1: [13] + VAR1: [19] + SEQ + && + VAR1: [26] + STR: [32] + SEQ + && + VAR1: [36] + STR: [42] + SNQ + && + STR: [46] + STR: [50] + SEQ + && + STR: [54] + STR: [58] + SNQ + && +strings: + [0] 'first' + [6] 'second' + [13] 'first' + [19] 'fourth' + [26] 'first' + [32] 'one' + [36] 'first' + [42] 'foo' + [46] 'foo' + [50] 'foo' + [54] 'foo' + [58] 'bar' +-- compile -- +-- AST -- +-- execute -- +res=1 Index: tags/1.0.5/tests/std_forge_cond/regression/str_empty.in =================================================================== --- tags/1.0.5/tests/std_forge_cond/regression/str_empty.in (nonexistent) +++ tags/1.0.5/tests/std_forge_cond/regression/str_empty.in (revision 10414) @@ -0,0 +1,2 @@ +(first != "") && (empty == "") && ("" == "") + Index: tags/1.0.5/tests/std_forge_cond/regression/str_empty.ref =================================================================== --- tags/1.0.5/tests/std_forge_cond/regression/str_empty.ref (nonexistent) +++ tags/1.0.5/tests/std_forge_cond/regression/str_empty.ref (revision 10414) @@ -0,0 +1,22 @@ +prg: + VAR1: [0] + STR: [5] + SNQ + VAR1: [7] + STR: [12] + SEQ + && + STR: [13] + STR: [14] + SEQ + && +strings: + [0] 'first' + [6] '' + [7] 'empty' + [13] '' + [14] '' +-- compile -- +-- AST -- +-- execute -- +res=1 Index: tags/1.0.5/tests/std_forge_cond/regression/unary.in =================================================================== --- tags/1.0.5/tests/std_forge_cond/regression/unary.in (nonexistent) +++ tags/1.0.5/tests/std_forge_cond/regression/unary.in (revision 10414) @@ -0,0 +1 @@ +!((-1 + -2) > 0) Index: tags/1.0.5/tests/std_forge_cond/regression/unary.ref =================================================================== --- tags/1.0.5/tests/std_forge_cond/regression/unary.ref (nonexistent) +++ tags/1.0.5/tests/std_forge_cond/regression/unary.ref (revision 10414) @@ -0,0 +1,14 @@ +prg: + NUM: 1 + NEG + NUM: 2 + NEG + ADD + NUM: 0 + GT + NOT +strings: +-- compile -- +-- AST -- +-- execute -- +res=1 Index: tags/1.0.5/tests/std_forge_cond/std_forge_cond.c =================================================================== --- tags/1.0.5/tests/std_forge_cond/std_forge_cond.c (nonexistent) +++ tags/1.0.5/tests/std_forge_cond/std_forge_cond.c (revision 10414) @@ -0,0 +1,49 @@ +#include +#include +#ifndef RND_INLINE +#define RND_INLINE static +#endif +#include "cond.h" + +const char *forgecond_var_resolve_cb(forgecond_ctx_t *ctx, const char *name1, const char *name2) +{ + if (strcmp(name1, "first") == 0) return "one"; + if (strcmp(name1, "second") == 0) return "two"; + if (strcmp(name1, "third") == 0) return "three"; + if (strcmp(name1, "fourth") == 0) return "one"; + if (strcmp(name1, "empty") == 0) return ""; + return NULL; +} + +void forgecond_error_cb(forgecond_ctx_t *ctx, const char *s) +{ + fprintf(stderr, "%s\n", s); +} + + +int main(void) +{ + long res; + forgecond_ctx_t ctx = {0}; + vtl0_t stack = {0}; + char line[256], *s; + + + printf("-- compile --\n"); + s = fgets(line, sizeof(line), stdin); + if (forgecond_parse_str(&ctx, s) != 0) + return 1; + + printf("-- AST --\n"); + forgecond_dump(stderr, &ctx); + + printf("-- execute --\n"); + res = forgecond_exec(&ctx, &stack); + printf("res=%ld\n", res); + + forgecond_uninit(&ctx); + vtl0_uninit(&stack); + + return 0; +} + Index: tags/1.0.5/util/Makefile =================================================================== --- tags/1.0.5/util/Makefile (nonexistent) +++ tags/1.0.5/util/Makefile (revision 10414) @@ -0,0 +1,25 @@ +ROOT=.. +MINUID=$(ROOT)/src_3rd/libminuid + +all: + +clean: + +distclean: + +# install from util/ +install_: + +install: + $(MAKE) install_ CPC="$(SCCBOX) install" + cd boxsym-rnd && $(MAKE) install + +linstall: + $(MAKE) install_ CPC="$(SCCBOX) linstall" + cd boxsym-rnd && $(MAKE) linstall + +uninstall: + $(MAKE) install_ CPC="$(SCCBOX) uninstall" + cd boxsym-rnd && $(MAKE) uninstall + +include $(ROOT)/Makefile.conf Index: tags/1.0.5/util/boxsym-rnd/7400.bs =================================================================== --- tags/1.0.5/util/boxsym-rnd/7400.bs (nonexistent) +++ tags/1.0.5/util/boxsym-rnd/7400.bs (revision 10414) @@ -0,0 +1,52 @@ +refdes U?? + +pinalign right center +pinalign bottom center +pinalign top center +attr device 7400 + +begin slot power + shape box + begin pin Vcc + num 14 + loc top + end pin + begin pin gnd + num 7 + loc bottom + end pin + pinalign top center + pinalign bottom center +end slot + + +begin slot logic + shape box right=halfcirc + label "4*NAND" + attr device 7400 + attr_both -slot 1 +# attr_invis foo bar + + begin pin A + num 1:4:9:12 + loc left + dir in + end pin + + begin pin B + num 2:5:10:13 + loc left + dir in + end pin + + begin pin Z + num 3:6:8:11 + loc right + dir out + invcirc + end pin + + pinalign left center + pinalign right center +end slot + Index: tags/1.0.5/util/boxsym-rnd/Makefile =================================================================== --- tags/1.0.5/util/boxsym-rnd/Makefile (nonexistent) +++ tags/1.0.5/util/boxsym-rnd/Makefile (revision 10414) @@ -0,0 +1,25 @@ +ROOT=../.. + +all: + +clean: + +distclean: + +install_: + -$(SCCBOX) mkdir -p $(BINDIR) $(LIBDIR)/boxsym-rnd + $(CPC) "`pwd`/boxsym-rnd" "$(BINDIR)/boxsym-rnd" + $(CPC) "`pwd`/generator.awk" "$(LIBDIR)/boxsym-rnd/generator.awk" + $(CPC) "`pwd`/parser.awk" "$(LIBDIR)/boxsym-rnd/parser.awk" + $(CPC) "`pwd`/util.awk" "$(LIBDIR)/boxsym-rnd/util.awk" + +install: + $(MAKE) install_ CPC="$(SCCBOX) install" + +linstall: + $(MAKE) install_ CPC="$(SCCBOX) linstall" + +uninstall: + $(MAKE) install_ CPC="$(SCCBOX) uninstall" + +include $(ROOT)/Makefile.conf Index: tags/1.0.5/util/boxsym-rnd/boxsym-rnd =================================================================== --- tags/1.0.5/util/boxsym-rnd/boxsym-rnd (nonexistent) +++ tags/1.0.5/util/boxsym-rnd/boxsym-rnd (revision 10414) @@ -0,0 +1,50 @@ +#!/bin/sh +# COPYRIGHT +# +# cschem - modular/flexible schematics editor - box symbol generator utility +# Copyright (C) 2022 Tibor 'Igor2' Palinkas +# +# (Supported by NLnet NGI0 PET Fund in 2022) +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Contact: +# Project page: http://repo.hu/projects/sch-rnd +# contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html +# mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + +PREFIX="`dirname $0`/.." + +if test -z "$1" +then + echo "Need an input file name" >&2 + exit 1 +fi + +if test -f util.awk -a -f generator.awk +then + # running from source + LIBDIR=. + COMSYM=../../library/symbol/common_sym.awk + MINUID=../../src_3rd/libminuid/minuid +else + # running the installed version + LIBDIR=$PREFIX/lib/sch-rnd/boxsym-rnd + COMSYM=$PREFIX/share/sch-rnd/symbol/common_sym.awk + MINUID=$PREFIX/lib/sch-rnd/minuid +fi + +awk -v "MINUID=$MINUID" -f "$LIBDIR/util.awk" -f "$LIBDIR/parser.awk" \ + -f "$COMSYM" -f "$LIBDIR/generator.awk" "$1" Property changes on: tags/1.0.5/util/boxsym-rnd/boxsym-rnd ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/1.0.5/util/boxsym-rnd/generator.awk =================================================================== --- tags/1.0.5/util/boxsym-rnd/generator.awk (nonexistent) +++ tags/1.0.5/util/boxsym-rnd/generator.awk (revision 10414) @@ -0,0 +1,433 @@ +# COPYRIGHT +# +# cschem - modular/flexible schematics editor - box symbol generator utility +# Copyright (C) 2022,2023 Tibor 'Igor2' Palinkas +# +# (Supported by NLnet NGI0 PET Fund in 2022) +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Contact: +# Project page: http://repo.hu/projects/sch-rnd +# contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html +# mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + +BEGIN { + refdes="U?" + cmd = MINUID " --gen" + cmd | getline uid0 + close(cmd) + uid0 = substr(uid0, 1, 19) + minuid_init(uid0) + text_size_mult=0.45 +} + +function count_pin_txtbrd(loc, pin, TXTBRD, pname,len) +{ + if (PIN[pin, "label"] == "") { + pname = pin + sub(".*::", "", pname) + } + else + pname = PIN[pin, "label"] + + if ((!(pname in TEXTW))) { + len = length(pname) + if (PIN[pin, "dir"] != "") + len++; + len = int(len * text_size_mult + 0.5) + } + else + len = int(TEXTW[pname] / 1000 + 0.5) + +# dbg("name=" pname " " len) + if (len > TXTBRD[loc]) + TXTBRD[loc] = len +} + +function count_pins(slot, loc, expand_slot, TXTBRD, n,cnt, pin, cinc, TMP) +{ + cnt = 0 + + if (slot == "") { # all slots + for(n = 0; n < nslots; n++) + cnt += count_pins(SLOTS[n], loc, expand_slot, TXTBRD) + } + + for(n = 0; n < SLOT[slot, "npins"]; n++) { + pin = PINS[slot, n] + if (PIN[pin, "loc"] == loc) { + if (expand_slot) + cinc = split(PIN[pin, "num"], TMP, "[:]") + else + cinc = 1 + cnt += cinc + count_pin_txtbrd(loc, pin, TXTBRD) + } + } + return cnt +} + +function draw_pin(pin, ST, slotidx, SLT ,x2,y2,pname,pnum,pindecor,intdecor,label2) +{ + x2 = ST["x"] * pin_grid + y2 = ST["y"] * pin_grid + + pname = pin + sub(/^.*::/,"", pname) + + if (slotidx == "") { + pnum = PIN[pin, "num"] + if (pnum ~ ":") { +# if slotted, use first and then rely on portmap + sub(":.*$", "", pnum) + } + } + else { + pnum = SLT[slotidx] +# if slotted and we are generating monolith, prefix with slot number + if (PIN[pin, "num"] ~ ":") + pname = slotidx pname + } + + + if (PIN[pin, "invcirc"]) + pindecor = "circle" + + if (PIN[pin, "dir"] == "in") + intdecor = "intri" + else if (PIN[pin, "dir"] == "out") + intdecor = "outtri" + + if ((pin SUBSEP "funcmap") in PIN) + label2 = "%../a.funcmap/name%" + else + label2=PIN[pin, "label"]; + +# dbg("draw_pin(): pname=" pname " dir=" ST["pdir"] " at " x2 ";" y2) + sym_term(SYM, x2, y2, ST["pdir"], pnum, pname, pindecor, intdecor, label2) +} + +# draw pins of a given slot:loc, with first pin touching the box at x0;y0 +# px and py are x and y dir for the pin line, stx and sty are stepping to +# the next coord. State is stored in ST +function draw_pins_(slot, ALIGN, loc, stx, sty, ST, currslot ,n,v,i,siden,A,pin) +{ + ST["pdir"] = loc + siden = 0 + for(n = 0; n < SLOT[slot, "npins"]; n++) { + pin = PINS[slot, n] + if (PIN[pin, "loc"] == loc) { + if (ALIGN["cfg", "expand_slot"]) { + v = split(PIN[pin, "num"], A, "[:]") + i = currslot + if (i > v) continue + draw_pin(pin, ST, i, A) + ST["x"] += stx + ST["y"] += sty + if ((ALIGN["midgap", loc] != "") && (siden == ALIGN["midgap", loc])) { + ST["x"] += stx + ST["y"] += sty + } + siden++ + } + else { + draw_pin(pin, ST, "", A) + ST["x"] += stx + ST["y"] += sty + if ((ALIGN["midgap", loc] != "") && (siden == ALIGN["midgap", loc])) { + ST["x"] += stx + ST["y"] += sty + } + siden++ + } + } + } + return siden +} + +function draw_pins(slot, ALIGN, loc, x0, y0, stx, sty, ST,save_last, n,currslot,orig_STx,orig_STy) +{ + if (slot == "") { # all slots + LAST_CRD[loc, "x"] = "" + LAST_CRD[loc, "y"] = "" + for(n = 0; n < nslots; n++) + draw_pins(SLOTS[n], ALIGN, loc, x0, y0, stx, sty, ST, 1) + } + + if ((LAST_CRD[loc, "x"] != "") && save_last) + ST["x"] = LAST_CRD[loc, "x"] + else + ST["x"] = x0 + ALIGN[loc, "x0"] + + if ((LAST_CRD[loc, "y"] != "") && save_last) + ST["y"] = LAST_CRD[loc, "y"] + else + ST["y"] = y0 + ALIGN[loc, "y0"] + + orig_STx = ST["x"] + orig_STy = ST["y"] + + + if (ALIGN["cfg", "expand_slot"]) { +# generate pins in a per slot fashion until slots run out (or at most 256 of them to avoid infinite loop) + for(currslot = 1; currslot <= 256; currslot++) { + if (draw_pins_(slot, ALIGN, loc, stx, sty, ST, currslot) == 0) + break + } + } + else + draw_pins_(slot, ALIGN, loc, stx, sty, ST, "") + + if (save_last) { + # monolith: remember last X and Y st so the next slot can continue from there + # if not the first slot on the given side, also add step (stx/sty) to separate + if (orig_STx != ST["x"]) { + if (LAST_CRD[loc, "x"] != "") + ST["x"] += stx + LAST_CRD[loc, "x"] = ST["x"] + } + if (orig_STy != ST["y"]) { + if (LAST_CRD[loc, "y"] != "") + ST["y"] += sty + LAST_CRD[loc, "y"] = ST["y"] + sty + } + } +} + + +function draw_all_pin(sn, ALIGN, bw, bh) +{ + bw = ALIGN["box","width"] + bh = ALIGN["box","height"] + + ALIGN["left", "y0"] = -ALIGN["left", "y0"] + ALIGN["right", "y0"] = -ALIGN["right", "y0"] + + # x0 y0 stx sty + draw_pins(sn, ALIGN, "left", -border, bh, +0, -1) + draw_pins(sn, ALIGN, "right", bw+border, bh, +0, -1) + draw_pins(sn, ALIGN, "top", border, bh+border, +1, +0) + draw_pins(sn, ALIGN, "bottom", border, -border, +1, +0) +} + +function align_calc(ALIGN, loc, boxloc, target_field, how ,diff) +{ + diff = ALIGN["box",boxloc] - ALIGN[loc,"count"] + if (how == "center") + ALIGN[loc, target_field] = diff/2-0.5 + else if ((how == "begin") || (how == "")) + ALIGN[loc, target_field] = 0 + else if (how == "end") + ALIGN[loc, target_field] = diff + else + print "Invalid alignment: " how > stderr + + ALIGN[loc, target_field] = int(ALIGN[loc, target_field])+1 + + dbg("align_calc: loc=" loc " boxloc=" boxloc " how=" how " res=" ALIGN[loc, target_field] " boxloc=" ALIGN["box",boxloc] " count=" ALIGN[loc,"count"] " target_field=" target_field) +} + +function align_adjust_center(size, pins1, how1, pins2, how2 ,adj1,adj2) +{ + adj1 = 0 + adj2 = 0 + + if ((how1 == "center") && (pins1 == 1)) + adj1 = (size % 2) + if ((how2 == "center") && (pins2 == 1)) + adj2 = (size % 2) + + return adj1 || adj2 +} + +# Calculate where to place a gap (after which pin) so that an even number of +# pins on an odd sized side distribute symmetrical +function align_get_midgap(size, numpins, how) +{ + if (how != "center") + return "" + + if ((numpins < 2) || (numpins % 2) || ((size % 2) != 0)) + return "" + +# we have even number of pins for odd size + return numpins/2-1 +} + +function align_pins(sn, ALIGN, TXTBRD) +{ + ALIGN["top","count"] = count_pins(sn, "top", ALIGN["cfg", "expand_slot"], TXTBRD) + ALIGN["bottom","count"] =count_pins(sn, "bottom", ALIGN["cfg", "expand_slot"], TXTBRD) + ALIGN["left","count"] = count_pins(sn, "left", ALIGN["cfg", "expand_slot"], TXTBRD) + ALIGN["right","count"] = count_pins(sn, "right", ALIGN["cfg", "expand_slot"], TXTBRD) + + ALIGN["box","width"] = max(max(ALIGN["top","count"]+1, ALIGN["bottom","count"]+1), 1) + ALIGN["box","height"] = max(max(ALIGN["left","count"]+1, ALIGN["right","count"]+1), 1) + +# dbg("TXTBRD: " ALIGN["box","width"] " " TXTBRD["left"] " " TXTBRD["right"]) + delta = TXTBRD["left"] + TXTBRD["right"]-1 + if (delta > 0) + ALIGN["box","width"] += delta + +# dbg("TXTBRD: " ALIGN["box","height"] " " TXTBRD["top"] " " TXTBRD["bottom"]) + delta = TXTBRD["top"] + TXTBRD["bottom"] + if (ALIGN["box","height"] < delta) + ALIGN["box","height"] = delta + + ALIGN["box","height"] += align_adjust_center(ALIGN["box","height"], ALIGN["left", "count"], SLOT[sn, "pinalign", "left"], ALIGN["right", "count"], SLOT[sn, "pinalign", "right"]) + ALIGN["box","width"] += align_adjust_center(ALIGN["box","width"], ALIGN["bottom", "count"], SLOT[sn, "pinalign", "bottom"], ALIGN["top", "count"], SLOT[sn, "pinalign", "top"]) + + ALIGN["midgap", "left"] = align_get_midgap(ALIGN["box","height"], ALIGN["left", "count"], SLOT[sn, "pinalign", "left"]) + ALIGN["midgap", "right"] = align_get_midgap(ALIGN["box","height"], ALIGN["right", "count"], SLOT[sn, "pinalign", "right"]) + ALIGN["midgap", "top"] = align_get_midgap(ALIGN["box","width"], ALIGN["top", "count"], SLOT[sn, "pinalign", "top"]) + ALIGN["midgap", "bottom"] = align_get_midgap(ALIGN["box","width"], ALIGN["bottom", "count"], SLOT[sn, "pinalign", "bottom"]) + + align_calc(ALIGN, "left", "height", "y0", SLOT[sn, "pinalign", "left"]) + align_calc(ALIGN, "right", "height", "y0", SLOT[sn, "pinalign", "right"]) + align_calc(ALIGN, "top", "width", "x0", SLOT[sn, "pinalign", "top"]) + align_calc(ALIGN, "bottom", "width", "x0", SLOT[sn, "pinalign", "bottom"]) +} + +function draw_all_labels(sn ,key,pat,x,y,ak,prefix,vis) +{ + grp_attr_append(SYM, "-symbol-generator", "boxsym-rnd") + pat = "^" sn SUBSEP "attr" SUBSEP + y = -2*pin_grid + x = -2*pin_grid + for(key in SLOT) { + if (key ~ pat) { + ak = key + sub(pat, "", ak) + vis = SLOT[sn, "attr_vis", ak] + if (vis == "both") + prefix = ak "=" + else + prefix = "" + grp_attr_append(SYM, ak, SLOT[key]) + if (vis != "none") { + sym_text_attr(SYM, x, y, ak, 0, "sym-secondary", prefix) + y -= pin_grid + } + } + } +} + +function gen_portmap(slot ,n,i,v,pin,pname,A,AA,cnt) +{ + dbg("generate portmap for " slot ":") + attrarr_reset(AA) + cnt = 0 + for(n = 0; n < SLOT[slot, "npins"]; n++) { + pin = PINS[slot, n] + v = split(PIN[pin, "num"], A, "[:]") + if (v > 1) { + pname = pin + sub(".*::", "", pname) + for(i = 1; i <= v; i++) { + attrarr_append(AA, i "/" pname " -> pcb/pinnum=" A[i]) + cnt++ + dbg(" " i "/" pname " -> pcb/pinnum=" A[i]) + } + } + } + if (cnt > 0) + grp_attrarr_append(SYM, "portmap", AA) +} + +function gen_monolith( ALIGN) +{ + ofn=basename ".ry" + if (ofn == inputname) { + print "Error: can not generate monolith symbol because of file name collision. Rename your input file so it doesn't end in .ry!" > "/dev/stderr" + return + } + ALIGN["cfg", "expand_slot"] = 1 + align_pins("", ALIGN) + sym_begin(refdes, -2*pin_grid, -pin_grid) + draw_box(SYM, ALIGN["box","width"], ALIGN["box","height"], border, SLOT["", "shape"], SLOT["", "shape_fill"]) + draw_all_pin("", ALIGN, 1) + draw_all_labels("") + sym_end() + delete SYM + ofn="" +} + +function gen_slot(sn ,ALIGN) +{ + ofn=basename "_" sn ".ry" + ALIGN["cfg", "expand_slot"] = 0 + align_pins(sn, ALIGN) + sym_begin(refdes, -2*pin_grid, -pin_grid) + draw_box(SYM, ALIGN["box","width"], ALIGN["box","height"], border, SLOT[sn, "shape"], SLOT[sn, "shape_fill"]) + draw_all_pin(sn, ALIGN, 0) + draw_all_labels(sn) + gen_portmap(sn) + sym_end() + delete SYM + ofn="" +} + +function gen_slots( n) +{ + for(n = 0; n < nslots; n++) { + dbg("gen_slots(): n=" n) + gen_slot(SLOTS[n]) + } +} + +function get_text_size1(cmd, txt) +{ + print "fawk_print(" q "T: " txt q ", fontinfo(\"TextWidth\", " q txt q ", \"term-secondary\"), fontinfo(\"TextHeight\", " q txt q ", \"term-secondary\"));" | cmd +} + +function get_text_sizes( n,pname,tmpfn,cmd) +{ + tmpfn = "boxsym-rnd.est.tmp" + close(tmpfn) + + cmd = "sch-rnd --gui batch > " tmpfn + close(cmd); + + print "fawk" | cmd + + for(n in PIN) { + if (n ~ (SUBSEP "label$")) { + get_text_size1(cmd, PIN[n]); + } + if (n ~ (SUBSEP "num$")) { + pname = n + sub(SUBSEP "num$", "", pname) + sub(".*::", "", pname) + get_text_size1(cmd, pname); + } + } + close(cmd) + while((getline < tmpfn) == 1) { + if ($1 == "T:") { + TEXTW[$2] = $3 + TEXTH[$2] = $4 + } + } + close(tmpfn) +} + + +END { + get_text_sizes() + gen_monolith() + dbg("---------") + gen_slots() +} Index: tags/1.0.5/util/boxsym-rnd/parser.awk =================================================================== --- tags/1.0.5/util/boxsym-rnd/parser.awk (nonexistent) +++ tags/1.0.5/util/boxsym-rnd/parser.awk (revision 10414) @@ -0,0 +1,176 @@ +# COPYRIGHT +# +# cschem - modular/flexible schematics editor - box symbol generator utility +# Copyright (C) 2022,2023 Tibor 'Igor2' Palinkas +# +# (Supported by NLnet NGI0 PET Fund in 2022) +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Contact: +# Project page: http://repo.hu/projects/sch-rnd +# contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html +# mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + +BEGIN { + nslots=0 + SLOT["", "npins"] = 0 +} + +# return $0 in a string with $1 removed +function del1( tmp) +{ + tmp = $0 + sub("^[ \t]*[^ \t]*[ \t]*", "", tmp) + return tmp +} + +# return $0 in a string with $1 and $2 removed +function del2( tmp) +{ + tmp = $0 + sub("^[ \t]*[^ \t]*[ \t]*[^ \t]*[ \t]*", "", tmp) + return tmp +} + +function add_pin() +{ + PINS[slot, SLOT[slot, "npins"]] = pin + SLOT[slot, "npins"]++ + pin = "" + return 0 +} + +function add_slot() +{ + SLOTS[nslots] = slot + nslots++ + slot = "" + return 0 +} + +function parse_pin() +{ + pin=slot "::" $3 + dbg("parse_pin(): pin=" pin) + while(getline == 1) { + if ((/^[ \t]*#/) || (NF == 0)) continue + if (($1 == "end") && ($2 == "pin")) + return add_pin() + if ($1 == "end") { + print "Invalid end - expected slot end in line", NR > stderr + exit 1 + } + if (($1 == "num") || ($1 == "loc") || ($1 == "dir") || ($1 == "label")) { + if (PIN[pin, $1] != "") { + print "ERROR: multiple definitions of " pin "/" $1 " in line " NR > "/dev/stderr" + exit 1 + } + PIN[pin, $1] = strip(del1($0)) + } + else if ($1 == "invcirc") { + if (PIN[pin, $1] != "") { + print "ERROR: multiple definitions of " pin "/" $1 " in line " NR > "/dev/stderr" + exit 1 + } + PIN[pin, $1] = 1 + } + else if ($1 == "funcmap") { + PIN[pin, "funcmap"] = 1 + } + else { + print "Invalid pin command in line", NR > stderr + exit 1 + } + } +} + +# recurse parsing anything (except slots) - expects $0 is the "begin" line +function parse_any() +{ + if ($2 == "pin") + return parse_pin() + + print "Invalid begin in line", NR > stderr + exit 1 +} + + +# recurse parsing a slot - expects $0 is the "begin" line +function parse_slot() +{ + slot=$3 + SLOT[slot, "npins"] = 0 + while(getline == 1) { + if ((/^[ \t]*#/) || (NF == 0)) continue + if (($1 == "end") && ($2 == "slot")) + return add_slot() + if ($1 == "end") { + print "Invalid end - expected slot end in line", NR > stderr + exit 1 + } + if ($1 == "shape") + SLOT[slot, "shape"] = del1($0) + else if ($1 == "shape_fill") + SLOT[slot, "shape_fill"] = tobool($2) + else if ($1 == "pinalign") + SLOT[slot, "pinalign", $2] = $3 + else if ($1 == "label") + SLOT[slot, "label", ++SLOT["", "labels"]] = $2 + else if ($1 == "attr") + SLOT[slot, "attr", $2] = del2($0) + else if ($1 == "attr_both") { + SLOT[slot, "attr", $2] = del2($0) + SLOT[slot, "attr_vis", $2] = "both" + } + else if ($1 == "attr_invis") { + SLOT[slot, "attr", $2] = del2($0) + SLOT[slot, "attr_vis", $2] = "none" + } + else if ($1 == "begin") + parse_any() + else { + print "Invalid slot command in line", NR > stderr + exit 1 + } + } + print "Premature end of file while reading slot in line", NR > stderr + exit 1 +} + +(NR == 1) { + inputname=FILENAME + basename=inputname + sub("[.][^.]*$", "", basename) +} +/^[\t ]*#/ { next } +($1 == refdes) { refdes = $2 } +/begin slot/ { parse_slot(); next } +($1 == "begin") { slot=""; parse_any() } +($1 == "pinalign") { SLOT["", "pinalign", $2] = $3 } +($1 == "label") { SLOT["", "label", ++SLOT["", "labels"]] = $2 } +($1 == "attr") { SLOT["", "attr", $2] = del2($0) } +($1 == "attr_both") { SLOT["", "attr", $2] = del2($0); SLOT["", "attr_vis", $2] = "both"; } +($1 == "attr_invis") { SLOT["", "attr", $2] = del2($0); SLOT["", "attr_vis", $2] = "none"; } +($1 == "shape") { SLOT["", "shape"] = del1($0) } +($1 == "shape_fill") {SLOT["", "shape_fill"] = tobool($2) } + +($1 == "text_size_mult") { + text_size_mult = $2 + 0; + if (text_size_mult <= 0) { + print "text_size_mult must be greater than zero" > "/dev/stderr" + exit 1 + } +} Index: tags/1.0.5/util/boxsym-rnd/util.awk =================================================================== --- tags/1.0.5/util/boxsym-rnd/util.awk (nonexistent) +++ tags/1.0.5/util/boxsym-rnd/util.awk (revision 10414) @@ -0,0 +1,51 @@ +# COPYRIGHT +# +# cschem - modular/flexible schematics editor - box symbol generator utility +# Copyright (C) 2022,2023 Tibor 'Igor2' Palinkas +# +# (Supported by NLnet NGI0 PET Fund in 2022) +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Contact: +# Project page: http://repo.hu/projects/sch-rnd +# contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html +# mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + +BEGIN { + debug=0 + stderr="/dev/stderr" + + # given in pin_grid coords: + border=0 +} + +function min(a, b) { return a < b ? a : b } +function max(a, b) { return a > b ? a : b } +function dbg(s) { if(debug) print s > stderr } +function Dbg(s) { print s > stderr } + +function draw_box(SYM, w, h, border, shape, shape_fill ,fill) +{ + if ((shape ~ "^box") || (shape == "")) { + if (shape_fill) + fill = "sym-decor-fill" + else + fill = "" + sym_rect(SYM, 0-border*pin_grid, 0-border*pin_grid, (w+border)*pin_grid, (h+border)*pin_grid, "sym-decor", fill) + } + else + error("can not draw box of unknown shape " shape) +} Index: tags/1.0.5/util/parametric_help.sh =================================================================== --- tags/1.0.5/util/parametric_help.sh (nonexistent) +++ tags/1.0.5/util/parametric_help.sh (revision 10414) @@ -0,0 +1,196 @@ +#!/bin/sh + +help_params() +{ +awk "$@" ' +BEGIN { + prm=0 + q="\"" + fp_base=fp + sub("[(].*", "", fp_base) +} + +function urlencode(s) +{ + gsub("[#]", "%23", s) + return s +} + +function proc_include(fn) +{ + close(fn) + while(getline < fn) + proc_line() + close(fn) +} + +function proc_line() +{ + if (/^[^\"]*@@include/) { + proc_include(gendir $2) + return + } + + if ((match($0, "@@desc") || match($0, "@@params") || match($0, "@@purpose") || match($0, "@@example"))) { + txt=$0 + key=substr($0, RSTART, RLENGTH) + sub(".*" key "[ \t]*", "", txt) + HELP[key] = HELP[key] " " txt + next + } + + if (/@@param:/) { + sub(".*@@param:", "", $0) + p=$1 + sub(p "[\t ]*", "", $0) + PARAM[prm] = p + PDESC[prm] = $0 + prm++ + return + } + +# build PPROP[paramname,propname], e.g. PPROP[pin_mask, dim]=1 + if (/@@optional:/ || /@@dim:/ || /@@bool:/) { + key = $0 + sub("^.*@@", "", key) + val = key + sub(":.*", "", key) + sub("^[^:]*:", "", val) + PPROP[val,key] = 1 + return + } + +# build PDATA[paramname,propname], e.g. PDATA[pin_mask, default]=123 + if ((/@@default:/) || (/@@preview_args:/)) { + key = $1 + + txt = $0 + txt = substr(txt, length(key)+1, length(txt)) + sub("^[ \t]*", "", txt) + + sub("^.*@@", "", key) + val = key + sub(":.*", "", key) + sub("^[^:]*:", "", val) + PDATA[val,key] = txt + return + } + +# build: +# PDATAK[paramname,n]=key (name of the value) +# PDATAV[paramname,n]=description (of the given value) +# PDATAN[paramname]=n number of parameter values + if (/@@enum:/) { + key = $1 + + txt = $0 + txt = substr(txt, length(key)+1, length(txt)) + sub("^[ \t]*", "", txt) + + sub("^.*@@enum:", "", key) + val = key + sub(":.*", "", key) + sub("^[^:]*:", "", val) + idx = int(PDATAN[key]) + PDATAK[key,idx] = val + PDATAV[key,idx] = txt + PDATAN[key]++ + return + } +} + +{ proc_line() } + +END { + if (header) { + print "" HELP["@@purpose"] "" + print "

    " + print HELP["@@desc"] + } + + if (content) + print "

    " content "

    " + + if ((print_params) && (HELP["@@params"] != "")) + print "

    Ordered list (positions): " HELP["@@params"] + + + if (content) { + print "" + print "
    name man
    dat
    ory
    description value (bold: default)" + for(p = 0; p < prm; p++) { + name=PARAM[p] + print "
    " name + if (PPROP[name, "optional"]) + print "  " + else + print " yes" + print "" PDESC[p] + print "" + vdone=0 + if (PDATAN[name] > 0) { + print "" + for(v = 0; v < PDATAN[name]; v++) { + print "
    " + isdef = (PDATA[name, "default"] == PDATAK[name, v]) + if (isdef) + print "" + print PDATAK[name, v] + if (isdef) + print "" + + print "" PDATAV[name, v] + if (PDATA[name, "preview_args"] != "") { + prv= fp_base "(" PDATA[name, "preview_args"] "," name "=" PDATAK[name, v] ")" + print "" +# TODO: thumbnail +# thumb(prv, thumbsize, PDATA[name, "thumbsize"], PDATA[name, "thumbnum"]) + print " " + } + } + print "
    " + vdone++ + } + if (PPROP[name, "dim"]) { + print "Dimension: a number with an optional unit (mm or mil, default is mil)" + if (PDATA[name, "default"] != "") + print "
    Default: " PDATA[name, "default"] "" + vdone++ + } + if (PPROP[name, "bool"]) { + print "Boolean: yes/no, true/false, 1/0" + if (PDATA[name, "default"] != "") + print "; Default: " PDATA[name, "default"] "" + if (PDATA[name, "preview_args"] != "") { + print "
    " + print "" + print "
    true:" +#TODO thumbnail +# thumb(fp_base "(" PDATA[name, "preview_args"] "," name "=" 1 ")", thumbsize, PDATA[name, "thumbsize"], PDATA[name, "thumbnum"]) + print " " + print "false:" +#TODO thumbnail +# thumb(fp_base "(" PDATA[name, "preview_args"] "," name "=" 0 ")", thumbsize, PDATA[name, "thumbsize"], PDATA[name, "thumbnum"]) + print " " + print "
    " + } + } + if (!vdone) + print " " + } + print "
    " + } + + if (footer) { + print "

    Example

    " + print HELP["@@example"] + print "" + print "" + } +} +' +} + + +help_params "$@" + Property changes on: tags/1.0.5/util/parametric_help.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/1.0.5/util/sign/crl_repo.hu.pem =================================================================== --- tags/1.0.5/util/sign/crl_repo.hu.pem (nonexistent) +++ tags/1.0.5/util/sign/crl_repo.hu.pem (revision 10414) @@ -0,0 +1,19 @@ +-----BEGIN X509 CRL----- +MIIDGzCCAQMwDQYJKoZIhvcNAQELBQAwgb0xCzAJBgNVBAYTAkhVMREwDwYDVQQI +EwhCdWRhcGVzdDERMA8GA1UEBxMIQnVkYXBlc3QxEDAOBgNVBAoTB3JlcG8uaHUx +DjAMBgNVBAsTBUlnb3IyMRMwEQYDVQQDEwpyZXBvLmh1IENBMSwwKgYDVQQpEyNy +ZXBvLmh1IHB1YmxpYyBzc2wgYW5kIGZpbGUgc2lnbmluZzEjMCEGCSqGSIb3DQEJ +ARYUa2V5aW5nQGlnb3IyLnJlcG8uaHUXDTIzMTAxMTEwNTA0OFoXDTI0MTEwOTEw +NTA0OFowFDASAgEBFw0yMDA0MjExNTM5NDNaMA0GCSqGSIb3DQEBCwUAA4ICAQC6 +au6OTwfJ/F4XEyY/6mKHm6o2ri5YJ/2TpRa9hl2HFDlOvw6IiD9cxArVj+Vbgf52 +QJtJY3WeMR1omJ9MBiVFNzaeUuj6WbBnNGEtkrAQTawxjgJ7hzPuh/bKSoSnr22P +gT0hkfRjBqNv4ZBy9oVFgixBU3VYj5vEgc0g0kydqJfCvxX1IdaBPtYq7vK6CHou +2pIB/AQIRNrvde1nfm4tAvq/Zdiv4ToYMFyQqtH7qaigchMPhoU/tAurTocJ5ssS +UtURiR0jsjst/TIBCv1yGr+NTutT/ZxWFb0nYYW4egC6lGoJGRx/Kko0P6zbwqUj +Ocje+s816xqBgDW2Twl00YvqyfG54OA8lw1LW8gwndVbk1HyxoReXgrYr7jIoo7a +vua739FPy3ElC3VchdfusomqPHUsl4egYOG/bwHlnYAEhXFjtYgVt1IGuI0QGwCx +lEcYAnKpTU3roTGyZJbMAbtcln57+e2Oz7c48ZcvA6/RgEp3Y8Kdc3RTz31Tq/jN +wYDpD4GrrQK9nZk1057B8Yzg82Jyv00qN4hBJxdoae9OFS17iar+A44bY+NEikzG ++iife5pp9kZbg0/Xh5MECEUcPKeaiNGJRvs4E8j/8xJeASqtrCOHfEjLicG6VIc3 +Lz8Qd1Je/jbPn/9RrJKinL4nsXz62h25WBRSSOrrhw== +-----END X509 CRL----- Index: tags/1.0.5/util/sign/rootca_repo.hu_2020.crt =================================================================== --- tags/1.0.5/util/sign/rootca_repo.hu_2020.crt (nonexistent) +++ tags/1.0.5/util/sign/rootca_repo.hu_2020.crt (revision 10414) @@ -0,0 +1,41 @@ +-----BEGIN CERTIFICATE----- +MIIHJzCCBQ+gAwIBAgIJAOOTjzdHBDWkMA0GCSqGSIb3DQEBCwUAMIG9MQswCQYD +VQQGEwJIVTERMA8GA1UECBMIQnVkYXBlc3QxETAPBgNVBAcTCEJ1ZGFwZXN0MRAw +DgYDVQQKEwdyZXBvLmh1MQ4wDAYDVQQLEwVJZ29yMjETMBEGA1UEAxMKcmVwby5o +dSBDQTEsMCoGA1UEKRMjcmVwby5odSBwdWJsaWMgc3NsIGFuZCBmaWxlIHNpZ25p +bmcxIzAhBgkqhkiG9w0BCQEWFGtleWluZ0BpZ29yMi5yZXBvLmh1MB4XDTIwMDQy +MTEyMjYwNVoXDTMwMDQxOTEyMjYwNVowgb0xCzAJBgNVBAYTAkhVMREwDwYDVQQI +EwhCdWRhcGVzdDERMA8GA1UEBxMIQnVkYXBlc3QxEDAOBgNVBAoTB3JlcG8uaHUx +DjAMBgNVBAsTBUlnb3IyMRMwEQYDVQQDEwpyZXBvLmh1IENBMSwwKgYDVQQpEyNy +ZXBvLmh1IHB1YmxpYyBzc2wgYW5kIGZpbGUgc2lnbmluZzEjMCEGCSqGSIb3DQEJ +ARYUa2V5aW5nQGlnb3IyLnJlcG8uaHUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw +ggIKAoICAQDXBFlluNaF/Pikec4TeEq/UsZAg1XhhmUJZnzAx7i84ramW0rvvdxN +bdWAAjuaQG7qRSnZNQieDcHKq/xeAz3TMxmXGytclOh7HtXaTbg963dQd4sZ7wK+ +Nv1znTJSR5jx6u5ijiaKqktVRiRndUsWw/pKSZvEY8uCc+4vK0xzPM49cYMOG0VV +Vs3IT47piONWbuCqXgi+ijHFHpPKLW2x4jDP6OXhXHWMg2J8+q/ggqURpUscNnvP +NfIPGyr7ZRsVVrTRNHA1clYDJFbHrkqhcjSodWvEmAbmz31DfYrlxnDVEmYqOqxO +K6y2cn0rYUbuM8yc1hO4MgncXZ1y+3SoFK/LvsPR1MlGeqMRBL4Ru/S7q8/NEak8 ++gPYJiIdy5Pt9hzZv1C7cPlsxXS1xCHJOk2xNbDrUuDV98P0ZYYY/7K98fss43vZ +UzbR/+eVhrjESFiHY/7Gcknaa9d0RMzSNWik/cBUwDty1C9OdxqeOmWE/uRqsViF +6ypxRG9ZRJnuqWxa8+PT3EFJLARizz06uzD0nN0xqMI1k3s5hXDDSloH8eK4UF2j +ZtHLo0m/4b6l3dZmkG5/eJAq2Kg8r6Bzx9oAnRUW8MPjJL95XrDClWAVrABTWs0E +409AklGh8w4+hB2xD8ZbNXDMyu1S+ic1CzYPMa9a3NPsrG1/H9A2WwIDAQABo4IB +JjCCASIwHQYDVR0OBBYEFOxDrX4j1c5ZbQdhCaRmlzxEAKx5MIHyBgNVHSMEgeow +geeAFOxDrX4j1c5ZbQdhCaRmlzxEAKx5oYHDpIHAMIG9MQswCQYDVQQGEwJIVTER +MA8GA1UECBMIQnVkYXBlc3QxETAPBgNVBAcTCEJ1ZGFwZXN0MRAwDgYDVQQKEwdy +ZXBvLmh1MQ4wDAYDVQQLEwVJZ29yMjETMBEGA1UEAxMKcmVwby5odSBDQTEsMCoG +A1UEKRMjcmVwby5odSBwdWJsaWMgc3NsIGFuZCBmaWxlIHNpZ25pbmcxIzAhBgkq +hkiG9w0BCQEWFGtleWluZ0BpZ29yMi5yZXBvLmh1ggkA45OPN0cENaQwDAYDVR0T +BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAJz/MUVFBYvWto1iDHYFQWz2hRitx +AKtphsKtUF0fZ4mwZ/GN8/gItKaEndkFVQt250/ZlDqNOsR0WUwxHUuvKQnZj3yK +QPWqJf4XAiXWD4UHm+xjIKub6K5SgrWKDF+2pM0vWHv80vinpwKCmn1qlFRY9hZY +Cr40yGATb9Ebr5mO3Q+Xacj/EmPxogjPd0IkoC2sHnlaXIkDtD4sZtqQyJc1h1fQ +xfxYh/w3kURTps856Y8wlvpc2R4B592sTf4p78Jv+tQxm400HNE4NNyNUwmHvQ9p +gRW/HWBVy/vjGhYz4645VBwFQ7bt0qLFaEOQBxOHYY+J8uneH8vMGtJduS0gyHvb +Qv/rOS71gPau2niTLH7CbKtqdG1RY1O6npjAxLIKsO5QJN1BN5svg8M6bIvY4KJZ +n3f1ISJQTIUvyu+A2gOe2459qf1Bn3zalYVPWmDqBLkqnR1mnCEhOYuNR1ES05xx +tJWzfQSerBJWQqTZ430E3zwapFVWCOky5H89xFPXBiodWfOzpdenAHBaoSqjG6fM +tqJ0umljL+Xn6EzaHsAjEkJFTK4TZ71SAFugRNRrXlX9+efZmTHpNDXzZ1gs5j71 +o1IQ9wl2eSopft8NU0nbefnfQ1+QcEAqM9z9BM3u0I2kX7ddPI7KzGCqq3nxrP6c +C7BZ2G6M6Jr7pXA= +-----END CERTIFICATE----- Index: tags/1.0.5/util/sign/sign.sh =================================================================== --- tags/1.0.5/util/sign/sign.sh (nonexistent) +++ tags/1.0.5/util/sign/sign.sh (revision 10414) @@ -0,0 +1,17 @@ +#!/bin/sh + +if test $# -lt 3 +then + echo "Usage: ./sign.sh privkey cert file1 [file2 .. fileN]" +fi + +key="$1" +cert="$2" +shift 2 + +for fn in "$@" +do + openssl dgst -sha256 -sign "$key" -out "$fn.sig" "$fn" + cp "$cert" "$fn.crt" +done + Property changes on: tags/1.0.5/util/sign/sign.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/1.0.5/util/sign/verify.sh =================================================================== --- tags/1.0.5/util/sign/verify.sh (nonexistent) +++ tags/1.0.5/util/sign/verify.sh (revision 10414) @@ -0,0 +1,123 @@ +#!/bin/sh + +### defaults ### +ca=rootca_repo.hu_2020.crt +crl=crl_repo.hu.pem + +### implementation ### + +verify() +{ + local base="$1" sig="$1.sig" crt="$1.crt" + + # check if all files are in place + if test ! -f "$base" + then + echo "Content file $base does not exist" >&2 + return 1 + fi + + if test ! -f "$sig" + then + echo "Signature file $sig does not exist - please download that too!" >&2 + return 1 + fi + + if test ! -f "$crt" + then + echo "Certificate file $crt does not exist - please download that too!" >&2 + return 1 + fi + + if test ! -f "$ca" + then + echo "repo.hu CA cert $ca not found. Please download it from multiple sources" >&2 + return 1 + fi + + if test ! -f "$crl" + then + echo "repo.hu CRL $crl not found. Please download it from multiple sources" >&2 + return 1 + fi + + # step 4: check file's cert against repo.hu CA and CRL + cat $ca $crl > .ca_crl.pem + openssl verify -crl_check -CAfile .ca_crl.pem $crt >&2 + if test $? != 0 + then + return 1 + fi + + # step 5: check file's sig against file's cert + openssl x509 -pubkey -noout -in $crt > $crt.pem && \ + openssl dgst -verify $crt.pem -signature $sig $base >&2 +} + +fingerprint() +{ + echo -n "CA " + openssl x509 -fingerprint -noout -in $ca + echo -n "CRL " + openssl crl -fingerprint -noout -in $crl +} + +print_file() +{ + case "$1" in + *.crt) openssl x509 -in "$1" -text ;; + crl*.pem) openssl crl -in "$1" -text ;; + *) echo "Don't know how to print that file" ;; + esac +} + +help() +{ +echo 'verify.sh - pcb-rnd download signature verify script +Usage: ./verify.sh [--fp] [--ca CA_file] [--crl CRL_file] downloaded_file + +Download the CA and CRL files from multiple sources to make sure they match. +Altneratively print the the fingerprint with --fp and check that from +multiple sources. + +The verification process is documented at + +http://www.repo.hu/cgi-bin/pool.cgi?cmd=show&node=sign + +Remember: + + - if you run this for the first time, you absolutely need to verify the CA + from multiple sources + + - before running the script, please get the latest CRL, from multiple sources + +The effective security of this process largely depends on these two steps. +' +} + +### main ### + +bad=0 +while test $# -gt 0 +do + case "$1" in + --help) help "$@"; exit;; + --fp) fingerprint ;; + --ca) shift 1; ca="$1";; + --crl) shift 1; crl="$1";; + --print) shift 1; print_file "$1" ;; + *) + verify "$1" + if test $? = 0 + then + echo "*** $1: ok" + else + echo "*** $1: FAILED" + bad=1 + fi + esac + + shift 1 +done + +exit $bad Property changes on: tags/1.0.5/util/sign/verify.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property